7 #define NULL ((void *)0)
10 static double gametime, frametime;
13 typedef struct localentity_s
15 int active; // true if the entity is alive (not freed)
16 float freetime; // time this entity was freed
25 float airfrictionscale;
27 void (*framethink)(struct localentity_s *e);
29 //void (*touch)(struct localentity_s *self, struct localentity_s *other);
30 //void (*touchnetwork)(struct *localentity_s *self);
35 #define MAX_LOCALENTITIES 1024
36 static localentity_t *localentity;
38 static cgphysentity_t *phys_entity;
39 static int phys_entities;
41 static float cg_gravity;
43 static void readvector(vec3_t v)
45 v[0] = CGVM_MSG_ReadFloat();
46 v[1] = CGVM_MSG_ReadFloat();
47 v[2] = CGVM_MSG_ReadFloat();
50 static localentity_t *entspawn(void)
54 for (i = 0;i < MAX_LOCALENTITIES;i++)
57 if (!l->active && l->freetime < gametime)
59 memset(l, 0, sizeof(*l));
64 for (i = 0;i < MAX_LOCALENTITIES;i++)
69 memset(l, 0, sizeof(*l));
77 static void entremove(localentity_t *e)
79 memset(e, 0, sizeof(*e));
80 e->freetime = (float)gametime + 1.0f;
83 static void phys_setupphysentities(void)
87 for (i = 0;i < MAX_LOCALENTITIES;i++)
89 l = localentities + i;
90 if (l->active && l->solid)
97 static void phys_moveentities(void)
101 for (i = 0;i < MAX_LOCALENTITIES;i++)
108 if (l->active && l->draw.model)
109 CGVM_Draw_Entity(&l->draw);
114 static void phys_updateentities(void)
116 phys_setupphysentities();
120 static void phys_update(localentity_t *e)
122 vec3_t impactpos, impactnormal, end;
124 float t, f, frac, bounce;
125 t = (float)frametime;
128 VectorMA(e->draw.angles, t, e->avelocity, e->draw.angles);
129 VectorMA(e->draw.origin, t, e->velocity, end);
130 frac = CGVM_TracePhysics(e->draw.origin, end, e->worldmins, e->worldmaxs, e->entitymins, e->entitymaxs, phys_entity, phys_entities, impactpos, impactnormal, &impactentnum);
131 VectorCopy(impactpos, e->draw.origin);
134 bounce = DotProduct(e->velocity, impactnormal) * -e->bouncescale;
135 VectorMA(e->velocity, bounce, impactnormal, e->velocity);
136 // FIXME: do some kind of touch code here if physentities get implemented
138 if (impactnormal[2] >= 0.7 && DotProduct(e->velocity, e->velocity) < 100*100)
140 VectorClear(e->velocity);
141 VectorClear(e->avelocity);
145 if (e->airfrictionscale)
147 if (DotProduct(e->velocity, e->velocity) < 10*10)
149 VectorClear(e->velocity);
150 VectorClear(e->avelocity);
154 f = 1 - (t * e->airfrictionscale);
157 VectorScale(e->velocity, f, e->velocity);
158 if (DotProduct(e->avelocity, e->avelocity) < 10*10)
160 VectorClear(e->avelocity);
164 VectorScale(e->avelocity, f, e->avelocity);
169 VectorClear(e->velocity);
170 VectorClear(e->avelocity);
175 e->velocity[2] += cg_gravity * e->gravityscale * t;
178 static void explosiondebris_framethink(localentity_t *self)
180 if (gametime > self->dietime)
182 self->draw.scale -= (float)frametime * 3.0f;
183 if (self->draw.scale < 0.05f)
192 static void net_explosion(unsigned char num)
199 // need the time to know when the rubble should fade
201 // read the network data
204 for (i = 0;i < 40;i++)
210 VectorCopy(org, e->draw.origin);
211 e->draw.angles[0] = CGVM_RandomRange(0, 360);
212 e->draw.angles[1] = CGVM_RandomRange(0, 360);
213 e->draw.angles[2] = CGVM_RandomRange(0, 360);
214 VectorRandom(e->velocity);
215 VectorScale(e->velocity, 300, e->velocity);
216 e->velocity[2] -= (float)cg_gravity * 0.1f;
217 e->avelocity[0] = CGVM_RandomRange(0, 1440);
218 e->avelocity[1] = CGVM_RandomRange(0, 1440);
219 e->avelocity[2] = CGVM_RandomRange(0, 1440);
220 r = CGVM_RandomRange(0, 3);
222 e->draw.model = CGVM_Model("progs/rubble1.mdl");
224 e->draw.model = CGVM_Model("progs/rubble2.mdl");
226 e->draw.model = CGVM_Model("progs/rubble3.mdl");
231 e->draw.framelerp = 0;
233 VectorSet(e->worldmins, 0, 0, -8);
234 VectorSet(e->worldmaxs, 0, 0, -8);
235 VectorSet(e->entitymins, -8, -8, -8);
236 VectorSet(e->entitymaxs, 8, 8, 8);
237 e->bouncescale = 1.4f;
239 e->airfrictionscale = 1;
240 e->framethink = explosiondebris_framethink;
241 e->dietime = (float)time + 5.0f;
248 localentity = CGVM_Malloc(sizeof(localentity_t) * MAX_LOCALENTITIES);
249 phys_entity = CGVM_Malloc(sizeof(cgphysentity_t) * MAX_LOCALENTITIES);
250 CGVM_RegisterNetworkCode(1, net_explosion);
255 void CG_Frame(double time)
257 cg_gravity = -CGVM_GetCvarFloat("sv_gravity");
258 frametime = time - gametime;
260 phys_updateentities();