2 @Copyright Looking Glass Studios, Inc.
3 1996,1997,1998,1999,2000 Unpublished Work.
6 ////////////////////////////////////////////////////////////////////////////////
7 // $Header: r:/t2repos/thief2/src/engfeat/flinder.cpp,v 1.2 1999/04/28 13:49:42 XEMU Exp $
31 // Must be last header
34 void CreateFlinders(ObjID victim
, ObjID flinder
, int count
, BOOL scatter
, float impulse
, const mxs_vector
&offset
)
36 if (OBJ_IS_CONCRETE(flinder
))
38 Warning(("%s attempts to flinderize with concrete flinders?\n", ObjWarnName(victim
)));
44 Warning(("%s attempt to flinderize into %s, but 0 count?\n", ObjWarnName(victim
), ObjWarnName(flinder
)));
48 mxs_vector flinder_loc
;
52 if ((pPos
= ObjPosGet(victim
)) == NULL
)
54 Warning(("Attempt to flinderize object %d w/o position!\n", victim
));
62 mx_ang2mat(&obj_rot
, &pPos
->fac
);
63 mx_mat_mul_vec(&flinder_loc
, &obj_rot
, &offset
);
64 mx_addeq_vec(&flinder_loc
, &pPos
->loc
.vec
);
67 AutoAppIPtr_(ObjectSystem
, pObjSys
);
69 for (i
=0; i
<count
; i
++)
72 ObjID flinder_obj
= pObjSys
->BeginCreate(flinder
, kObjectConcrete
);
74 // find a valid location for this flinder, if we're scattering
77 cPhysDimsProp
*pDimsProp
;
79 if (!g_pPhysDimsProp
->Get(flinder_obj
, &pDimsProp
))
81 Warning(("Non-physical flinder obj %s?\n", ObjWarnName(flinder
)));
82 pObjSys
->EndCreate(flinder_obj
);
83 pObjSys
->Destroy(flinder_obj
);
87 // this probably should be the object-relative bbox, and then we should
88 // rotate it ourselves, but that forces us to ang2mat for each flinderize
89 // link, and we just don't care that much.
90 mxs_vector bmin
, bmax
;
91 ObjGetWorldBBox(victim
, &bmin
, &bmax
);
95 mxs_real rand_amt
= ((float)(Rand() % 1024) / 1024.0);
96 flinder_loc
.el
[j
] = ((bmax
.el
[j
] - bmin
.el
[j
]) * rand_amt
) + bmin
.el
[j
];
101 MakeHintedLocationFromVector(&start
, &pPos
->loc
.vec
, &pPos
->loc
);
102 MakeHintedLocationFromVector(&end
, &flinder_loc
, &pPos
->loc
);
104 if (pDimsProp
->radius
[0] == 0.0)
108 if (!PortalRaycast(&start
, &end
, &hit
, FALSE
))
109 mx_interpolate_vec(&flinder_loc
, &start
.vec
, &hit
.vec
, 0.95);
111 flinder_loc
= end
.vec
;
117 if ((contact_count
= SphrSpherecastStatic(&start
, &end
, pDimsProp
->radius
[0], 0)) > 0)
119 sSphrContact
*pContact
= &gaSphrContact
[0];
120 for (j
=1; j
<contact_count
; j
++)
122 if (gaSphrContact
[j
].time
< pContact
->time
)
123 pContact
= &gaSphrContact
[j
];
126 mx_interpolate_vec(&flinder_loc
, &start
.vec
, &pContact
->point_on_ray
, 0.95);
129 flinder_loc
= end
.vec
;
133 // update its position
134 ObjPosUpdate(flinder_obj
, &flinder_loc
, &pPos
->fac
);
135 pObjSys
->EndCreate(flinder_obj
);
137 // apply a velocity away
139 mxs_vector rot_velocity
;
140 mxs_real obj_impulse
;
142 mx_sub_vec(&velocity
, &flinder_loc
, &pPos
->loc
.vec
);
143 if (mx_mag2_vec(&velocity
) > 0.0001)
144 mx_normeq_vec(&velocity
);
146 obj_impulse
= impulse
+ (((float)(Rand() % 1024) / 1024.0) * impulse
* 0.5) - impulse
* 0.25;
148 mx_scaleeq_vec(&velocity
, impulse
);
149 PhysSetVelocity(flinder_obj
, &velocity
);
151 // apply a rotational velocity, too
153 rot_velocity
.el
[j
] = ((float)(Rand() % 1024) / 512.0) - 1.0;
155 mx_scaleeq_vec(&rot_velocity
, impulse
* 0.6);
156 PhysSetRotationalVelocity(flinder_obj
, &rot_velocity
);