2 @Copyright Looking Glass Studios, Inc.
3 1996,1997,1998,1999,2000 Unpublished Work.
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
48 #include <crjoint.h> // Range checking on joints.
50 #include <creature.h> // CreatureFromObj
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
);
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
)
115 // Warning(("GetWeaponIdForMode: No weapon for object '%d' in mode '%d'\n", id, mode));
119 // CreatureWeaponAttachWeapon: Hooks up creatures weapon for a given mode.
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");
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"));
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
));
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
)
192 if (!ObjHasWeaponOffset(id
) || (referenceID
== OBJ_NULL
))
197 // We're on the way to the deathbed...or at least we're not feeling better yet.
198 cCreature
* pCreat
= CreatureFromObj(id
);
204 IAI
* pAI
= AppGetObj(IAIManager
)->GetAI(id
);
205 if (!pCreat
->IsPhysical() || !PhysObjHasPhysics(id
) || (pAI
&& pAI
->IsDying()))
216 sCreatureWeapon
*pCW
= CreatureWeaponGet(id
);
218 // Verify referenceID is valid and creature weapon is in the list.
221 CreatureWeaponAttachWeapon(&pCW
, referenceID
, mode
);
223 else if (CreatureWeaponObjCreate
)
225 (*CreatureWeaponObjCreate
)(id
, mode
);
230 int CreatureWeaponSwizzle(ObjID id
, int mode
)
232 // Get creature's reference ID for this mode.
233 ObjID referenceID
= GetWeaponIdForMode(id
, mode
);
236 return WeaponSwizzle(id
, referenceID
, mode
);
241 BOOL
CreatureWeaponCreate(ObjID id
, int mode
)
243 if (!ObjHasWeaponOffset(id
))
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
));
256 return WeaponSwizzle(id
, referenceID
, mode
);
259 void CreatureWeaponDestroy(ObjID id
)
261 if (!ObjHasWeaponOffset(id
))
266 sCreatureWeapon
*pCW
= CreatureWeaponGet(id
);
269 LinkID linkID
= (g_pCreatureAttachRelation
->GetSingleLink(id
, pCW
->weaponObj
));
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();
286 // EXTERN void ThrowObj(ObjID o, ObjID src);
287 static BOOL
DoThrowObj(ObjID thrower
, ObjID obj
, float power
)
289 if (CreatureExists(obj
))
292 mxs_vector launch_pos
;
293 mxs_vector launch_dir
;
294 mxs_angvec launch_fac
;
296 launch_fac
= ObjPosGet(thrower
)->fac
;
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);
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
);
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
);
334 launchProjectile(thrower
, obj
, power
/ 6,PRJ_FLG_MASSIVE
| PRJ_FLG_FROMPOS
, NULL
, &launch_dir
, NULL
);
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
347 PhysNetForceContainedMsgs(TRUE
);
348 // PhysRegisterSphereDefault(obj);
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
);
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.
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.
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
));
396 EndObjectCreate(newWeaponId
);
399 DoThrowObj(id
, newWeaponId
, 0.5);
404 Warning(("CreatureWeaponDrop: No parent for weapon object '%d' \n", pCW
->weaponObj
));
408 if (CreatureWeaponObjDestroy
)
410 (*CreatureWeaponObjDestroy
)(id
);
414 CreatureDetachItem(id
, pCW
->weaponObj
);
420 ///////////////////////
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.
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
;
448 CreatureWeaponRotX(float vD
)
450 sCreatureAttachInfo
*pInfo
= CreatureAttachmentGet(CreatureWeapon
.obj
, nWeaponObjId
, 0);
453 mprintf("No info\n");
457 mprintf("Rotate X by %g\n",vD
);
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
);
468 CreatureWeaponRotY(float vD
)
470 sCreatureAttachInfo
*pInfo
= CreatureAttachmentGet(CreatureWeapon
.obj
, nWeaponObjId
, 0);
473 mprintf("No info\n");
477 mprintf("Rotate Y by %g\n",vD
);
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);
491 mprintf("No info\n");
495 mprintf("Rotate Z by %g\n",vD
);
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);
509 mprintf("No info\n");
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);
522 mprintf("No info\n");
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);
536 mprintf("No info\n");
540 mprintf("Translate Z by %g\n",vD
);
541 pInfo
->relTrans
.vec
.z
+= vD
;
547 sCreatureAttachInfo
*pInfo
= CreatureAttachmentGet(CreatureWeapon
.obj
, nWeaponObjId
, 0);
550 mprintf("No info\n");
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
);