convert line ends
[canaan.git] / prj / cam / src / engfeat / flinder.cpp
blob7c96091dd77c08a4e9b63a63e48b5748bab14288
1 /*
2 @Copyright Looking Glass Studios, Inc.
3 1996,1997,1998,1999,2000 Unpublished Work.
4 */
6 ////////////////////////////////////////////////////////////////////////////////
7 // $Header: r:/t2repos/thief2/src/engfeat/flinder.cpp,v 1.2 1999/04/28 13:49:42 XEMU Exp $
9 #include <lg.h>
10 #include <comtools.h>
11 #include <appagg.h>
12 #include <matrix.h>
13 #include <rand.h>
15 #include <iobjsys.h>
16 #include <objedit.h>
17 #include <objpos.h>
18 #include <objdef.h>
19 #include <objshape.h>
21 #include <sphrcst.h>
22 #include <sphrcsts.h>
23 #include <wrtype.h>
24 #include <port.h>
26 #include <phprop.h>
27 #include <physapi.h>
29 #include <flinder.h>
31 // Must be last header
32 #include <dbmem.h>
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)));
39 return;
42 if (count == 0)
44 Warning(("%s attempt to flinderize into %s, but 0 count?\n", ObjWarnName(victim), ObjWarnName(flinder)));
45 return;
48 mxs_vector flinder_loc;
49 Position *pPos;
50 int i, j;
52 if ((pPos = ObjPosGet(victim)) == NULL)
54 Warning(("Attempt to flinderize object %d w/o position!\n", victim));
55 return;
58 if (!scatter)
60 mxs_matrix obj_rot;
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++)
71 // create the flinder
72 ObjID flinder_obj = pObjSys->BeginCreate(flinder, kObjectConcrete);
74 // find a valid location for this flinder, if we're scattering
75 if (scatter)
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);
84 return;
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);
93 for (j=0; j<3; j++)
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];
99 Location start, end;
101 MakeHintedLocationFromVector(&start, &pPos->loc.vec, &pPos->loc);
102 MakeHintedLocationFromVector(&end, &flinder_loc, &pPos->loc);
104 if (pDimsProp->radius[0] == 0.0)
106 Location hit;
108 if (!PortalRaycast(&start, &end, &hit, FALSE))
109 mx_interpolate_vec(&flinder_loc, &start.vec, &hit.vec, 0.95);
110 else
111 flinder_loc = end.vec;
113 else
115 int contact_count;
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);
128 else
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
138 mxs_vector velocity;
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
152 for (j=0; j<3; j++)
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);