+
+ CL_BoundingBoxForEntity(&ent->render);
+ if (ent->render.model && ent->render.model->name[0] == '*' && ent->render.model->type == mod_brush)
+ cl_brushmodel_entities[cl_num_brushmodel_entities++] = &ent->render;
+
+ if (r_refdef.numentities < r_refdef.maxentities)
+ r_refdef.entities[r_refdef.numentities++] = &ent->render;
+
+ if (cl_num_entities < i + 1)
+ cl_num_entities = i + 1;
+ }
+}
+
+void CL_Effect(vec3_t org, int modelindex, int startframe, int framecount, float framerate)
+{
+ int i;
+ cl_effect_t *e;
+ if (!modelindex) // sanity check
+ return;
+ for (i = 0, e = cl_effects;i < cl_max_effects;i++, e++)
+ {
+ if (e->active)
+ continue;
+ e->active = true;
+ VectorCopy(org, e->origin);
+ e->modelindex = modelindex;
+ e->starttime = cl.time;
+ e->startframe = startframe;
+ e->endframe = startframe + framecount;
+ e->framerate = framerate;
+
+ e->frame = 0;
+ e->frame1time = cl.time;
+ e->frame2time = cl.time;
+ break;
+ }
+}
+
+static void CL_RelinkEffects(void)
+{
+ int i, intframe;
+ cl_effect_t *e;
+ entity_t *ent;
+ float frame;
+
+ for (i = 0, e = cl_effects;i < cl_max_effects;i++, e++)
+ {
+ if (e->active)
+ {
+ frame = (cl.time - e->starttime) * e->framerate + e->startframe;
+ intframe = frame;
+ if (intframe < 0 || intframe >= e->endframe)
+ {
+ e->active = false;
+ memset(e, 0, sizeof(*e));
+ continue;
+ }
+
+ if (intframe != e->frame)
+ {
+ e->frame = intframe;
+ e->frame1time = e->frame2time;
+ e->frame2time = cl.time;
+ }
+
+ // if we're drawing effects, get a new temp entity
+ // (NewTempEntity adds it to the render entities list for us)
+ if (r_draweffects.integer && (ent = CL_NewTempEntity()))
+ {
+ // interpolation stuff
+ ent->render.frame1 = intframe;
+ ent->render.frame2 = intframe + 1;
+ if (ent->render.frame2 >= e->endframe)
+ ent->render.frame2 = -1; // disappear
+ ent->render.framelerp = frame - intframe;
+ ent->render.frame1time = e->frame1time;
+ ent->render.frame2time = e->frame2time;
+
+ // normal stuff
+ VectorCopy(e->origin, ent->render.origin);
+ ent->render.model = cl.model_precache[e->modelindex];
+ ent->render.frame = ent->render.frame2;
+ ent->render.colormap = -1; // no special coloring
+ ent->render.scale = 1;
+ ent->render.alpha = 1;
+
+ CL_BoundingBoxForEntity(&ent->render);
+ }
+ }
+ }
+}
+
+void CL_RelinkBeams (void)
+{
+ int i;
+ beam_t *b;
+ vec3_t dist, org;
+ float d;
+ entity_t *ent;
+ float yaw, pitch;
+ float forward;
+
+ for (i = 0, b = cl_beams;i < cl_max_beams;i++, b++)
+ {
+ if (!b->model || b->endtime < cl.time)
+ continue;
+
+ // if coming from the player, update the start position
+ //if (b->entity == cl.viewentity)
+ // VectorCopy (cl_entities[cl.viewentity].render.origin, b->start);
+ if (b->entity && cl_entities[b->entity].state_current.active)
+ {
+ VectorCopy (cl_entities[b->entity].render.origin, b->start);
+ b->start[2] += 16;
+ }
+
+ // calculate pitch and yaw
+ VectorSubtract (b->end, b->start, dist);
+
+ if (dist[1] == 0 && dist[0] == 0)
+ {
+ yaw = 0;
+ if (dist[2] > 0)
+ pitch = 90;
+ else
+ pitch = 270;
+ }
+ else
+ {
+ yaw = (int) (atan2(dist[1], dist[0]) * 180 / M_PI);
+ if (yaw < 0)
+ yaw += 360;
+
+ forward = sqrt (dist[0]*dist[0] + dist[1]*dist[1]);
+ pitch = (int) (atan2(dist[2], forward) * 180 / M_PI);
+ if (pitch < 0)
+ pitch += 360;
+ }
+
+ // add new entities for the lightning
+ VectorCopy (b->start, org);
+ d = VectorNormalizeLength(dist);
+ while (d > 0)
+ {
+ ent = CL_NewTempEntity ();
+ if (!ent)
+ return;
+ VectorCopy (org, ent->render.origin);
+ ent->render.model = b->model;
+ ent->render.effects = EF_FULLBRIGHT;
+ ent->render.angles[0] = pitch;
+ ent->render.angles[1] = yaw;
+ ent->render.angles[2] = rand()%360;
+ CL_BoundingBoxForEntity(&ent->render);
+ VectorMA(org, 30, dist, org);
+ d -= 30;
+ }