2 @Copyright Looking Glass Studios, Inc.
3 1996,1997,1998,1999,2000 Unpublished Work.
6 // $Header: r:/t2repos/thief2/src/shock/shksloop.cpp,v 1.57 1999/11/19 14:58:22 adurant Exp $
52 //#include <pklogin.h>
80 // Must be last header
83 /////////////////////////////////////////////////////////////
84 // SHOCK SIMULATION LOOP CLIENT
85 ////////////////////////////////////////////////////////////
92 // These are just here to separate out boiler-plate code and leave it untouched
96 #define MY_FACTORY ShockSimLoopFactory
97 #define MY_GUID LOOPID_ShockSim
100 typedef void Context
;
103 typedef struct _StateRecord
105 Context
* context
; // a pointer to the context data I got.
107 // State fields go here
110 static IPlayerGun
*g_pPlayerGun
= NULL
;
111 static IShockCamera
*g_pShockCamera
= NULL
;
113 ////////////////////////////////////////
115 // LOOP/DISPATCH callback
116 // Here's where we do the dirty work.
119 static void db_message(DispatchData
* msg
)
121 msgDatabaseData data
;
122 data
.raw
= msg
->data
;
124 switch (DB_MSG(msg
->subtype
))
129 AutoAppIPtr(PlayerGun
);
133 case kDatabasePostLoad
:
134 case kDatabaseDefault
:
135 InitProjectileArchetype();
136 InitParticleArchetype();
138 //gChar->ClearEquip();
139 ShockReactionsPostLoad();
141 // Clear some variables that will get awkward if we begin running
142 // frames without the sim on (which will happen in multiplayer).
143 frobWorldSelectObj
= OBJ_NULL
;
144 g_ifaceFocusObj
= OBJ_NULL
;
145 gHelpString
[0] = '\0';
150 void EquipWeapon(void)
152 if (PlayerObjectExists())
155 //AutoAppIPtr(PlayerGun);
156 AutoAppIPtr(ShockPlayer
);
157 gunobj
= pShockPlayer
->GetEquip(PlayerObject(),kEquipWeapon
);
158 //pPlayerGun->Set(gunobj);
159 pShockPlayer
->SetWeaponModel(gunobj
,FALSE
);
160 ShockAmmoRefreshButtons();
164 void UnequipWeapon(void)
166 if (PlayerObjectExists())
168 AutoAppIPtr(ShockPlayer
);
169 pShockPlayer
->SetWeaponModel(OBJ_NULL
,FALSE
);
173 #pragma off(unreferenced)
174 static eLoopMessageResult LGAPI
_LoopFunc(void* data
, eLoopMessage msg
, tLoopMessageData hdata
)
176 // useful stuff for most clients
177 eLoopMessageResult result
= kLoopDispatchContinue
;
178 StateRecord
* state
= (StateRecord
*)data
;
183 AutoAppIPtr(ShockPlayer
);
190 //ResOpenFile("shkres.res");
191 g_pPlayerGun
= AppGetObj(IPlayerGun
);
192 g_pShockCamera
= AppGetObj(IShockCamera
);
198 // gee, maybe we should terminate some stuff here
201 SafeRelease(g_pPlayerGun
);
202 SafeRelease(g_pShockCamera
);
207 state
->in_game_mode
= IsEqualGUID(*info
.mode
->to
.pID
,LOOPID_GameMode
);
208 if (state
->in_game_mode
)
210 // @HACK: start player with pistol and shotgun
212 gChar->AddGun(0, (Label*)"Pistol");
213 gChar->AddGun(1, (Label*)"Shotgun");
218 // center so mouse look around will work
221 shock_start_gamemode();
222 // since we may have updated the difficulty level
223 pShockPlayer
->RecalcData(PlayerObject());
227 if (state
->in_game_mode
)
229 shock_end_gamemode();
235 case kMsgNormalFrame
:
236 if (SimStateCheckFlags(kSimGameSpec
))
239 AutoAppIPtr(PlayerPsi
);
240 pPlayerPsi
->Frame(info
.frame
->dTicks
);
241 g_pShockCamera
->Frame();
242 g_pPlayerGun
->Frame(info
.frame
->dTicks
);
243 AutoAppIPtr(CameraObjects
);
244 pCameraObjects
->Frame(info
.frame
->dTicks
);
246 shock_sim_update_frame(info
.frame
->dTicks
);
248 // The player started a quicksave, and we've delayed a frame
249 // in order to display a message:
250 if (gQuickSaveHack
> 0)
253 if (gQuickSaveHack
== 0)
257 // We've changed levels, so let's do a save now:
260 gTransSaveHack
= FALSE
;
262 // If we're networked, then only the host decides to save.
263 // As a side-effect, this will tell everyone else to save
265 AutoAppIPtr(NetManager
);
266 if (!pNetManager
->IsNetworkGame() ||
267 pNetManager
->AmDefaultHost())
270 ShockStringFetch(temp
,sizeof(temp
),"QuickSaveName","misc");
271 ShockSaveGame(-1,temp
);
276 // Some other player initiated a save, and we've delayed a frame
277 // in order to display a message. This will *often* happen when
278 // the sim is paused...
279 if (gRemoteSaveHack
> 0)
282 if (gRemoteSaveHack
== 0)
284 DoShockSaveGame(gRemoteSaveSlot
, gpRemoteSaveDesc
);
285 if (gpRemoteSaveDesc
)
287 free(gpRemoteSaveDesc
);
288 gpRemoteSaveDesc
= NULL
;
295 db_message(info
.dispatch
);
298 // MAHK 7/2/99 Why is suspend/resume totally divergent from exit/enter?
299 // I am fixing this so that it does nothing in non-game modes,
300 // since our db_message implies that we are in the base mode.
301 // I bet there are other suspend/resume bugs, but fuck, we
302 // were supposed to ship this yesterday.
303 case kMsgSuspendMode
:
304 if (state
->in_game_mode
)
309 MouseMode(FALSE
,FALSE
);
317 if (state
->in_game_mode
)
321 MouseMode(TRUE
,FALSE
);
329 centerx
= smode
.w
/ 2; //grd_visible_canvas->bm.w / 2;
330 centery
= smode
.h
/ 2; //grd_visible_canvas->bm.h / 2;
331 mouse_put_xy(centerx
, centery
);
334 // since we may have updated the difficulty level
335 pShockPlayer
->RecalcData(PlayerObject());
345 ////////////////////////////////////////////////////////////
347 // Loop client factory function.
350 #pragma off(unreferenced)
351 static ILoopClient
* LGAPI
_CreateClient(const sLoopClientDesc
* desc
, tLoopClientData data
)
354 // allocate space for our state, and fill out the fields
355 state
= (StateRecord
*)Malloc(sizeof(StateRecord
));
356 state
->context
= (Context
*)data
;
358 return CreateSimpleLoopClient(_LoopFunc
,state
,desc
);
360 #pragma on(unreferenced)
366 sLoopClientDesc ShockSimLoopClientDesc
=
369 "Shock Simulation", // NAME
370 kPriorityNormal
, // PRIORITY
371 kMsgEnd
| kMsgsMode
| kMsgsFrameMid
| kMsgsAppOuter
| kMsgDatabase
, // INTERESTS
379 {kConstrainAfter
, &LOOPID_Physics
, kMsgsFrame
},
380 {kConstrainBefore
, &LOOPID_SimFinish
, kMsgsFrame
},
381 {kConstrainAfter
, &LOOPID_UI
, kMsgsMode
},
382 {kConstrainAfter
, &LOOPID_Game
, kMsgsMode
},
383 {kConstrainAfter
, &LOOPID_Biped
, kMsgsAppOuter
},
384 {kConstrainBefore
, &LOOPID_Biped
, kMsgsFrame
},
385 {kConstrainAfter
, &LOOPID_Player
, kMsgsFrame
},
386 {kConstrainBefore
, &LOOPID_AI
, kMsgsAppOuter
},
387 //{kConstrainAfter, &LOOPID_Render, kMsgsFrame},
388 // @Note (toml 04-13-98) dark has the following constraint for the equivalent client:
389 {kConstrainAfter
, &LOOPID_ObjSys
, kMsgDatabase
},
390 {kNullConstraint
} // terminator