convert line ends
[canaan.git] / prj / cam / src / motion / crwpnapi.cpp
bloba648d005cfee9694107b3bb2fbe7c4f09dfc1341
1 /*
2 @Copyright Looking Glass Studios, Inc.
3 1996,1997,1998,1999,2000 Unpublished Work.
4 */
7 // $Header: r:/t2repos/thief2/src/motion/crwpnapi.cpp,v 1.2 2000/01/07 14:33:15 BODISAFA Exp $
9 // until this is propertized, this is completely shock/gamesys specific, sadly
10 // if it were propertized, that would be way less true
12 // in particular, we would want a nethandweapon property, or something
13 // which had all the data for a weapon converting from world to handheld
14 // then at init time, we would scan that property and build our table
15 // (which would just be obj->obj)
17 // at that point, we could pass that across, and the actual table data would
18 // be in the property.
20 // if we did that, we could probably make this truly ghost, and not have the
21 // shock dependancy we currently obviously have
23 #include <lg.h>
24 #include <comtools.h>
25 #include <appagg.h>
27 #include <crattach.h>
28 #include <crwpnlst.h>
29 #include <crwpnapi.h>
30 #include <linkman.h>
31 #include <linktype.h>
32 #include <relation.h>
33 #include <appagg.h>
34 #include <linkbase.h>
35 #include <matrix.h>
36 #include <mxmat.h>
37 #include <objsys.h>
38 #include <objdef.h>
39 #include <iobjsys.h>
41 #include <cretprop.h>
42 #include <weapon.h>
43 #include <objedit.h>
44 #include <mprintf.h>
46 #include <refsys.h>
48 #include <crjoint.h> // Range checking on joints.
50 #include <creature.h> // CreatureFromObj
52 // Drop object
53 #include <physapi.h>
54 #include <prjctile.h>
55 #include <phnet.h>
56 #include <traitman.h>
57 #include <traitbas.h>
58 #include <objquery.h>
59 #include <aiapi.h>
61 #include <dbmem.h>
63 // for weapon object solving
64 int (*CreatureWeaponObjSwizzle) (ObjID weapon, int mode) = NULL;
65 BOOL (*CreatureWeaponObjCreate) (ObjID id, int mode) = NULL;
66 void (*CreatureWeaponObjDestroy) (ObjID id) = NULL;
67 void (*CreatureWeaponObjDrop) (ObjID id) = NULL;
69 // @TODO: Bodisafa 12/9/1999
70 // This needs to be in Dark & DeepC.
71 BOOL CreatureWeaponCreate(ObjID id, int mode);
72 void CreatureWeaponDestroy(ObjID id);
73 int CreatureWeaponSwizzle(ObjID id, int mode);
74 void CreatureWeaponDrop(ObjID id);
76 // Init/Term
77 void CreatureWeaponInit(void)
79 // @TODO: Bodisafa 11/30/1999
80 // This needs to be in Dark & DeepC.
81 CreatureWeaponObjCreate = CreatureWeaponCreate;
82 CreatureWeaponObjDestroy = CreatureWeaponDestroy;
83 CreatureWeaponObjSwizzle = CreatureWeaponSwizzle;
84 CreatureWeaponObjDrop = CreatureWeaponDrop;
86 CreatureWeaponListInit();
89 void CreatureWeaponTerm(void)
91 CreatureWeaponListTerm();
94 // @TODO: Bodisafa 11/30/1999
95 // ObjHasWeaponOffset checks should be reduced to the correct code flow.
96 // Otherwise, we're doing too many redundant checks.
97 // Assert in the other cases.
99 // Creature Weapon List
101 // GetWeaponIdForMode: Returns the appropriate ObjID for the current mode.
102 ObjID GetWeaponIdForMode(ObjID id, int mode)
104 if (id != OBJ_NULL && (ObjHasWeaponOffset(id)))
106 if (WeaponOffsetSetActive(id, mode))
108 int referenceID = WeaponOffsetGetDest(id);
109 if (referenceID != OBJ_NULL)
111 return referenceID;
115 // Warning(("GetWeaponIdForMode: No weapon for object '%d' in mode '%d'\n", id, mode));
116 return OBJ_NULL;
119 // CreatureWeaponAttachWeapon: Hooks up creatures weapon for a given mode.
120 // Input:
121 // ppCreat - Creature weapon information.
122 // referenceID - Uses this ID to construct a new weapon.
123 // mode - What mode is the creature in?
124 void CreatureWeaponAttachWeapon(sCreatureWeapon **ppCreat, int referenceID, int mode)
126 const sCreatureWeapon* pCW = *ppCreat;
128 if (!ObjHasWeaponOffset(pCW->obj))
130 mprintf("CreatureWeaponAttachWeapon: returning - !WeaponOffsetProp\n");
131 return;
134 // Same weapon or we have this weapon attached.
135 if (pCW->nWeapon == referenceID || (pCW->weaponObj == referenceID))
137 // Warning(("CreatureWeaponAttachWeapon: returning - nothing to do\n"));
138 return;
141 AutoAppIPtr_(ObjectSystem, pObjSys);
143 // If we currently holding a weapon, destroy it.
144 if (pCW->weaponObj != OBJ_NULL)
146 mprintf("CreatureWeaponAttachWeapon: destroying (%d,%d)\n", (*ppCreat)->nWeapon, referenceID);
147 pObjSys->Destroy(pCW->weaponObj);
148 (*ppCreat)->weaponObj = OBJ_NULL;
151 (*ppCreat)->nWeapon = referenceID;
152 (*ppCreat)->weaponObj = BeginObjectCreate(referenceID, kObjectConcrete);
153 if ((*ppCreat)->weaponObj == OBJ_NULL)
155 Warning(("CreatureWeaponAttachWeapon: Failed to create weapon no object id %d\n", referenceID));
156 return;
159 EndObjectCreate(pCW->weaponObj);
161 sCreatureAttachInfo Info;
162 memset(&Info,0,sizeof(Info));
164 if (WeaponOffsetSetActive(pCW->obj, mode))
166 Info.joint = WeaponOffsetGetJoint(pCW->obj);
167 if (Info.joint >= 0 && Info.joint < kCJ_NumCreatureJoints)
169 mxs_vector* pTransform = WeaponOffsetGetTransform(pCW->obj);
171 Assert_(pTransform != NULL);
172 mxs_trans trans = {pTransform[0].x, pTransform[0].y, pTransform[0].z,
173 pTransform[1].x, pTransform[1].y, pTransform[1].z,
174 pTransform[2].x, pTransform[2].y, pTransform[2].z,
175 pTransform[3].x, pTransform[3].y, pTransform[3].z};
177 mx_copy_trans(&Info.relTrans, &trans);
179 CreatureAttachItem(pCW->obj, pCW->weaponObj, &Info);
181 // Creatures don't support weapons with physics.
182 CreatureMakeWeaponNonPhysical(pCW->obj, pCW->weaponObj);
184 // mprintf("Attach %s to %s\n",ObjWarnName(pCW->weaponObj),ObjWarnName(pCW->obj));
189 inline BOOL WeaponSwizzle(ObjID id, ObjID referenceID, int mode)
191 // Nothing to do.
192 if (!ObjHasWeaponOffset(id) || (referenceID == OBJ_NULL))
194 return FALSE;
197 // We're on the way to the deathbed...or at least we're not feeling better yet.
198 cCreature* pCreat = CreatureFromObj(id);
199 if (pCreat == NULL)
201 return FALSE;
204 IAI* pAI = AppGetObj(IAIManager)->GetAI(id);
205 if (!pCreat->IsPhysical() || !PhysObjHasPhysics(id) || (pAI && pAI->IsDying()))
207 pAI->Release();
208 return FALSE;
211 if (pAI)
213 pAI->Release();
216 sCreatureWeapon *pCW = CreatureWeaponGet(id);
218 // Verify referenceID is valid and creature weapon is in the list.
219 if (pCW != NULL)
221 CreatureWeaponAttachWeapon(&pCW, referenceID, mode);
223 else if (CreatureWeaponObjCreate)
225 (*CreatureWeaponObjCreate)(id, mode);
227 return TRUE;
230 int CreatureWeaponSwizzle(ObjID id, int mode)
232 // Get creature's reference ID for this mode.
233 ObjID referenceID = GetWeaponIdForMode(id, mode);
234 if (referenceID)
236 return WeaponSwizzle(id, referenceID, mode);
238 return FALSE;
241 BOOL CreatureWeaponCreate(ObjID id, int mode)
243 if (!ObjHasWeaponOffset(id))
245 return FALSE;
248 CreatureWeaponAdd(id);
249 // Find and swizzle to this weapon.
250 int referenceID = GetWeaponIdForMode(id, mode);
251 if (referenceID == OBJ_NULL)
253 Warning(("CreatureWeaponCreate: Invalid referenceID for Object '%d'\n", id));
254 return FALSE;
256 return WeaponSwizzle(id, referenceID, mode);
259 void CreatureWeaponDestroy(ObjID id)
261 if (!ObjHasWeaponOffset(id))
263 return;
266 sCreatureWeapon *pCW = CreatureWeaponGet(id);
267 if (pCW)
269 LinkID linkID = (g_pCreatureAttachRelation->GetSingleLink(id, pCW->weaponObj));
270 if (linkID)
272 g_pCreatureAttachRelation->Remove(linkID);
275 CreatureDetachItem(id, pCW->weaponObj);
276 DestroyObject(pCW->weaponObj);
277 pCW->weaponObj = NULL;
278 CreatureWeaponRem(id);
281 // Totally safety - yes it is crude.
282 ClearWeaponOffsetCache();
285 #ifdef DEEPC
286 // EXTERN void ThrowObj(ObjID o, ObjID src);
287 static BOOL DoThrowObj(ObjID thrower, ObjID obj, float power)
289 if (CreatureExists(obj))
291 mxs_matrix orien;
292 mxs_vector launch_pos;
293 mxs_vector launch_dir;
294 mxs_angvec launch_fac;
296 launch_fac = ObjPosGet(thrower)->fac;
297 launch_fac.tx = 0;
298 launch_fac.ty = 0;
299 mx_ang2mat(&orien, &launch_fac);
301 mx_copy_vec(&launch_dir, &orien.vec[0]);
303 mx_scale_add_vec(&launch_pos, &ObjPosGet(thrower)->loc.vec, &launch_dir, 1.0);
305 launch_dir.z = 2.0;
307 ObjPosUpdate(obj, &launch_pos, &launch_fac);
309 VALIDATE_CREATURE_POS(FALSE);
311 CreatureMakeBallistic(obj, kCMB_Compressed);
313 if (!PhysObjValidPos(obj, NULL))
315 CreatureMakeNonBallistic(obj);
316 CreatureMakeNonPhysical(obj);
318 VALIDATE_CREATURE_POS(TRUE);
320 return FALSE;
323 VALIDATE_CREATURE_POS(TRUE);
325 // Set the make-non-physical-on-sleep flag
326 //#define REMOVE_ON_SLEEP
327 #ifdef REMOVE_ON_SLEEP
328 cPhysTypeProp *pTypeProp;
329 g_pPhysTypeProp->Get(obj, &pTypeProp);
330 pTypeProp->remove_on_sleep = TRUE;
331 g_pPhysTypeProp->Set(obj, pTypeProp);
332 #endif
334 launchProjectile(thrower, obj, power / 6,PRJ_FLG_MASSIVE | PRJ_FLG_FROMPOS, NULL, &launch_dir, NULL);
336 return TRUE;
338 else
340 #ifdef NEW_NETWORK_ENABLED
341 // @HACK: This really ought to wait until we see whether we have
342 // successfully launched the thing before doing this. But the timing
343 // of networking currently requires us to tell everyone that we're
344 // physicalizing before we launch. We also need to super-hack this
345 // with ForceContained, because otherwise the physicalize message
346 // won't go through:
347 PhysNetForceContainedMsgs(TRUE);
348 // PhysRegisterSphereDefault(obj);
349 #endif
351 BOOL launched = (launchProjectile(thrower,obj,power,PRJ_FLG_PUSHOUT|PRJ_FLG_MASSIVE,NULL,NULL,NULL) != OBJ_NULL);
353 #ifdef NEW_NETWORK_ENABLED
354 PhysNetBroadcastObjPosByObj(obj);
355 PhysNetForceContainedMsgs(FALSE);
356 #endif
358 return launched;
362 #endif // DEEPC
364 void CreatureWeaponDrop(ObjID id)
366 if (ObjHasWeaponOffset(id))
368 sCreatureWeapon *pCW = CreatureWeaponGet(id);
369 Assert_(pCW != NULL);
371 // @TODO: Bodisafa 12/7/1999
372 // Game callback setup.
374 #ifdef DEEPC
376 // Using Old & New for old & new weapon.
377 IObjectQuery* query = AppGetObj(ITraitManager)->Query(pCW->weaponObj, kTraitQueryAllArchetypes);
378 if (query && !query->Done())
380 // Grab Old's parent.
381 query->Next();
383 // We're at the top of the tree. This should never happen.
384 Assert_(!query->Done());
386 // Grab the Old's parent object id.
387 ObjID parentWeaponId = query->Object();
389 // Create New as using Old's parent id.
390 ObjID newWeaponId = BeginObjectCreate(parentWeaponId, kObjectConcrete);
391 if (newWeaponId == OBJ_NULL)
393 Warning(("CreatureWeaponDrop: Failed to create throwing weapon object '%d'\n", newWeaponId));
394 return;
396 EndObjectCreate(newWeaponId);
398 // Throw New.
399 DoThrowObj(id, newWeaponId, 0.5);
402 else
404 Warning(("CreatureWeaponDrop: No parent for weapon object '%d' \n", pCW->weaponObj));
407 // Get rid of Old.
408 if (CreatureWeaponObjDestroy)
410 (*CreatureWeaponObjDestroy)(id);
413 #else
414 CreatureDetachItem(id, pCW->weaponObj);
415 // throw_obj()
416 #endif // DEEPC
420 ///////////////////////
421 // warning
422 // this has all essentially been desupported
423 // in that the code above has changed to work in the real code
424 // but none of this was changed for new calling conventions, names, etc...
426 // Bodisafa 12/3/1999: This should be happy now.
428 #if 0
430 static void CreatureWeaponOutput(sCreatureAttachInfo *pInfo)
432 mprintf("%g,%g,%g\n",pInfo->relTrans.mat.vec[0].x,pInfo->relTrans.mat.vec[0].y,pInfo->relTrans.mat.vec[0].z);
433 mprintf("%g,%g,%g\n",pInfo->relTrans.mat.vec[1].x,pInfo->relTrans.mat.vec[1].y,pInfo->relTrans.mat.vec[1].z);
434 mprintf("%g,%g,%g\n",pInfo->relTrans.mat.vec[2].x,pInfo->relTrans.mat.vec[2].y,pInfo->relTrans.mat.vec[2].z);
437 static int nWeaponObjId;
439 static sCreatureWeapon CreatureWeapon;
441 void CreatureWeaponSetObj(int nObjid)
443 nWeaponObjId = nObjid;
444 CreatureWeapon.obj = nObjid;
447 void
448 CreatureWeaponRotX(float vD)
450 sCreatureAttachInfo *pInfo = CreatureAttachmentGet(CreatureWeapon.obj, nWeaponObjId, 0);
451 if (pInfo == NULL)
453 mprintf("No info\n");
454 return;
457 mprintf("Rotate X by %g\n",vD);
458 sMxMatrix matrix;
460 mx_copy_mat(&matrix,&(pInfo->relTrans.mat));
461 mx_rot_x_mat_rad(&(pInfo->relTrans.mat),&matrix,(vD/180.0)*MX_REAL_PI);
463 CreatureWeaponOutput(pInfo);
467 void
468 CreatureWeaponRotY(float vD)
470 sCreatureAttachInfo *pInfo = CreatureAttachmentGet(CreatureWeapon.obj, nWeaponObjId, 0);
471 if (pInfo == NULL)
473 mprintf("No info\n");
474 return;
477 mprintf("Rotate Y by %g\n",vD);
478 sMxMatrix matrix;
480 mx_copy_mat(&matrix,&(pInfo->relTrans.mat));
481 mx_rot_y_mat_rad(&(pInfo->relTrans.mat),&matrix,(vD/180.0)*MX_REAL_PI);
483 CreatureWeaponOutput(pInfo);
486 void CreatureWeaponRotZ(float vD)
488 sCreatureAttachInfo *pInfo = CreatureAttachmentGet(CreatureWeapon.obj, nWeaponObjId, 0);
489 if (pInfo == NULL)
491 mprintf("No info\n");
492 return;
495 mprintf("Rotate Z by %g\n",vD);
496 sMxMatrix matrix;
498 mx_copy_mat(&matrix,&(pInfo->relTrans.mat));
499 mx_rot_z_mat_rad(&(pInfo->relTrans.mat),&matrix,(vD/180.0)*MX_REAL_PI);
501 CreatureWeaponOutput(pInfo);
504 void CreatureWeaponTransX(float vD)
506 sCreatureAttachInfo *pInfo = CreatureAttachmentGet(CreatureWeapon.obj, nWeaponObjId, 0);
507 if (pInfo == NULL)
509 mprintf("No info\n");
510 return;
513 mprintf("Translate X by %g\n",vD);
514 pInfo->relTrans.vec.x += vD;
517 void CreatureWeaponTransY(float vD)
519 sCreatureAttachInfo *pInfo = CreatureAttachmentGet(CreatureWeapon.obj, nWeaponObjId, 0);
520 if (pInfo == NULL)
522 mprintf("No info\n");
523 return;
526 mprintf("Translate Y by %g\n",vD);
527 pInfo->relTrans.vec.y += vD;
530 void CreatureWeaponTransZ(float vD)
532 sCreatureAttachInfo *pInfo = CreatureAttachmentGet(CreatureWeapon.obj, nWeaponObjId, 0);
534 if (pInfo == NULL)
536 mprintf("No info\n");
537 return;
540 mprintf("Translate Z by %g\n",vD);
541 pInfo->relTrans.vec.z += vD;
544 void
545 CreatureWeaponDump()
547 sCreatureAttachInfo *pInfo = CreatureAttachmentGet(CreatureWeapon.obj, nWeaponObjId, 0);
548 if (pInfo == NULL)
550 mprintf("No info\n");
551 return;
555 FILE *pFile = fopen("weapon.txt","a+");
556 fprintf(pFile,"************************\n");
557 fprintf(pFile,"%g,%g,%g\n",pInfo->relTrans.mat.vec[0].x,pInfo->relTrans.mat.vec[0].y,pInfo->relTrans.mat.vec[0].z);
558 fprintf(pFile,"%g,%g,%g\n",pInfo->relTrans.mat.vec[1].x,pInfo->relTrans.mat.vec[1].y,pInfo->relTrans.mat.vec[1].z);
559 fprintf(pFile,"%g,%g,%g\n",pInfo->relTrans.mat.vec[2].x,pInfo->relTrans.mat.vec[2].y,pInfo->relTrans.mat.vec[2].z);
560 fprintf(pFile,"%g,%g,%g\n",pInfo->relTrans.vec.x,pInfo->relTrans.vec.y,pInfo->relTrans.vec.z);
561 fclose(pFile);
564 #endif