cl_visedict re-write. lerping works MUCH better now, and lerping of torches

should be possible. client should also be microscopicly faster.
This commit is contained in:
Bill Currie 2000-12-20 06:18:55 +00:00
parent 3669d78d1b
commit dd3ea544ce
13 changed files with 202 additions and 194 deletions

View file

@ -50,8 +50,8 @@ void CL_BeginServerConnect(void);
#define MAX_VISEDICTS 256 #define MAX_VISEDICTS 256
extern int cl_numvisedicts, cl_oldnumvisedicts; extern int cl_numvisedicts, cl_oldnumvisedicts;
extern entity_t *cl_visedicts, *cl_oldvisedicts; extern entity_t **cl_visedicts, **cl_oldvisedicts;
extern entity_t cl_visedicts_list[2][MAX_VISEDICTS]; extern entity_t *cl_visedicts_list[2][MAX_VISEDICTS];
extern char emodel_name[], pmodel_name[], prespawn_name[], modellist_name[], soundlist_name[]; extern char emodel_name[], pmodel_name[], prespawn_name[], modellist_name[], soundlist_name[];

View file

@ -30,6 +30,8 @@
#define _CL_TENT_H #define _CL_TENT_H
void CL_TEnts_Init (void); void CL_TEnts_Init (void);
void CL_ClearEnts (void);
void CL_ClearTEnts (void); void CL_ClearTEnts (void);
void CL_Init_Entity (struct entity_s *ent);
#endif #endif

View file

@ -31,7 +31,7 @@
#include "mathlib.h" #include "mathlib.h"
void R_RocketTrail (vec3_t start, vec3_t end, int type, entity_t *ent); void R_RocketTrail (int type, entity_t *ent);
void R_RunParticleEffect (vec3_t org, int color, int count); void R_RunParticleEffect (vec3_t org, int color, int count);
void R_RunPuffEffect (vec3_t org, byte type, byte count); void R_RunPuffEffect (vec3_t org, byte type, byte count);
void R_RunSpikeEffect (vec3_t org, byte type); void R_RunSpikeEffect (vec3_t org, byte type);

View file

@ -54,6 +54,7 @@ typedef struct entity_s
{ {
int keynum; // for matching entities in different frames int keynum; // for matching entities in different frames
vec3_t origin; vec3_t origin;
vec3_t old_origin;
vec3_t angles; vec3_t angles;
struct model_s *model; // NULL = no model struct model_s *model; // NULL = no model
int frame; int frame;

View file

@ -51,6 +51,7 @@
#include "cl_main.h" #include "cl_main.h"
#include "cl_ents.h" #include "cl_ents.h"
#include "cl_input.h" #include "cl_input.h"
#include "cl_tent.h"
extern cvar_t *cl_predict_players; extern cvar_t *cl_predict_players;
extern cvar_t *cl_predict_players2; extern cvar_t *cl_predict_players2;
@ -64,8 +65,30 @@ static struct predicted_player {
vec3_t origin; // predicted origin vec3_t origin; // predicted origin
} predicted_players[MAX_CLIENTS]; } predicted_players[MAX_CLIENTS];
entity_t **CL_NewTempEntity (void);
entity_t cl_packet_ents[512]; // FIXME: magic number
entity_t cl_flag_ents[MAX_CLIENTS];
entity_t cl_player_ents[MAX_CLIENTS];
//============================================================ //============================================================
/*
CL_ClearEnts
*/
void
CL_ClearEnts ()
{
int i;
for (i = 0; i < sizeof (cl_packet_ents) / sizeof (cl_packet_ents[0]); i++)
CL_Init_Entity (&cl_packet_ents[i]);
for (i = 0; i < sizeof (cl_flag_ents) / sizeof (cl_flag_ents[0]); i++)
CL_Init_Entity (&cl_flag_ents[i]);
for (i = 0; i < sizeof (cl_player_ents) / sizeof (cl_player_ents[0]); i++)
CL_Init_Entity (&cl_player_ents[i]);
}
/* /*
=============== ===============
CL_AllocDlight CL_AllocDlight
@ -453,12 +476,11 @@ CL_LinkPacketEntities
void void
CL_LinkPacketEntities (void) CL_LinkPacketEntities (void)
{ {
entity_t *ent; entity_t **ent;
packet_entities_t *pack; packet_entities_t *pack;
entity_state_t *s1, *s2; entity_state_t *s1, *s2;
float f; float f;
model_t *model; model_t *model;
vec3_t old_origin;
float autorotate; float autorotate;
int i; int i;
int pnum; int pnum;
@ -515,52 +537,52 @@ CL_LinkPacketEntities (void)
continue; continue;
// create a new entity // create a new entity
if (cl_numvisedicts == MAX_VISEDICTS) ent = CL_NewTempEntity ();
if (!ent)
break; // object list is full break; // object list is full
*ent = &cl_packet_ents[s1->number];
ent = &cl_visedicts[cl_numvisedicts++]; (*ent)->keynum = s1->number;
(*ent)->model = model = cl.model_precache[s1->modelindex];
ent->keynum = s1->number;
ent->model = model = cl.model_precache[s1->modelindex];
// set colormap // set colormap
if (s1->colormap && (s1->colormap < MAX_CLIENTS) if (s1->colormap && (s1->colormap < MAX_CLIENTS)
&& !strcmp (ent->model->name, "progs/player.mdl")) { && !strcmp ((*ent)->model->name, "progs/player.mdl")) {
ent->colormap = cl.players[s1->colormap - 1].translations; (*ent)->colormap = cl.players[s1->colormap - 1].translations;
ent->scoreboard = &cl.players[s1->colormap - 1]; (*ent)->scoreboard = &cl.players[s1->colormap - 1];
} else { } else {
ent->colormap = vid.colormap; (*ent)->colormap = vid.colormap;
ent->scoreboard = NULL; (*ent)->scoreboard = NULL;
} }
// LordHavoc: cleaned up Endy's coding style, and fixed Endy's bugs // LordHavoc: cleaned up Endy's coding style, and fixed Endy's bugs
// Ender: Extend (Colormod) [QSG - Begin] // Ender: Extend (Colormod) [QSG - Begin]
// N.B: All messy code below is the sole fault of LordHavoc and // N.B: All messy code below is the sole fault of LordHavoc and
// his futile attempts to save bandwidth. :) // his futile attempts to save bandwidth. :)
ent->glowsize = s1->glowsize < 128 ? s1->glowsize * 8.0 : (s1->glowsize - 256) * 8.0; (*ent)->glowsize = s1->glowsize < 128 ? s1->glowsize * 8.0 : (s1->glowsize - 256) * 8.0;
ent->glowcolor = s1->glowcolor; (*ent)->glowcolor = s1->glowcolor;
ent->alpha = s1->alpha / 255.0; (*ent)->alpha = s1->alpha / 255.0;
ent->scale = s1->scale / 16.0; (*ent)->scale = s1->scale / 16.0;
if (s1->colormod == 255) { if (s1->colormod == 255) {
ent->colormod[0] = ent->colormod[1] = ent->colormod[2] = 1; (*ent)->colormod[0] = (*ent)->colormod[1] = (*ent)->colormod[2] = 1;
} else { } else {
ent->colormod[0] = (float) ((s1->colormod >> 5) & 7) * (1.0 / 7.0); (*ent)->colormod[0] = (float) ((s1->colormod >> 5) & 7) * (1.0 / 7.0);
ent->colormod[1] = (float) ((s1->colormod >> 2) & 7) * (1.0 / 7.0); (*ent)->colormod[1] = (float) ((s1->colormod >> 2) & 7) * (1.0 / 7.0);
ent->colormod[2] = (float) (s1->colormod & 3) * (1.0 / 3.0); (*ent)->colormod[2] = (float) (s1->colormod & 3) * (1.0 / 3.0);
} }
// Ender: Extend (Colormod) [QSG - End] // Ender: Extend (Colormod) [QSG - End]
// set skin // set skin
ent->skinnum = s1->skinnum; (*ent)->skinnum = s1->skinnum;
// set frame // set frame
ent->frame = s1->frame; (*ent)->frame = s1->frame;
if (model->flags & EF_ROTATE) { // rotate binary objects locally if (model->flags & EF_ROTATE) { // rotate binary objects locally
ent->angles[0] = 0; (*ent)->angles[0] = 0;
ent->angles[1] = autorotate; (*ent)->angles[1] = autorotate;
ent->angles[2] = 0; (*ent)->angles[2] = 0;
} else { } else {
float a1, a2; float a1, a2;
@ -571,60 +593,44 @@ CL_LinkPacketEntities (void)
a1 -= 360; a1 -= 360;
if (a1 - a2 < -180) if (a1 - a2 < -180)
a1 += 360; a1 += 360;
ent->angles[i] = a2 + f * (a1 - a2); (*ent)->angles[i] = a2 + f * (a1 - a2);
} }
} }
VectorCopy ((*ent)->origin, (*ent)->old_origin);
// calculate origin // calculate origin
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)
ent->origin[i] = s2->origin[i] + f * (s1->origin[i] - s2->origin[i]); (*ent)->origin[i] = s2->origin[i] + f * (s1->origin[i] - s2->origin[i]);
// scan the old entity display list for a matching
for (i = 0; i < cl_oldnumvisedicts; i++) {
if (cl_oldvisedicts[i].keynum == ent->keynum) {
ent->frame_start_time = cl_oldvisedicts[i].frame_start_time;
ent->frame_interval = cl_oldvisedicts[i].frame_interval;
ent->pose1 = cl_oldvisedicts[i].pose1;
ent->pose2 = cl_oldvisedicts[i].pose2;
VectorCopy (cl_oldvisedicts[i].origin, old_origin);
break;
}
}
if (i == cl_oldnumvisedicts) { // not in last message, don't lerp
ent->pose1 = ent->pose2 = -1;
continue;
}
// add automatic particle trails // add automatic particle trails
if (!model->flags) if (!model->flags)
continue; continue;
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)
if (abs (old_origin[i] - ent->origin[i]) > 128) { // no trail if (abs ((*ent)->old_origin[i] - (*ent)->origin[i]) > 128) { // no trail
// if too far // if too far
VectorCopy (ent->origin, old_origin); VectorCopy ((*ent)->origin, (*ent)->old_origin);
break; break;
} }
if (model->flags & EF_ROCKET) { if (model->flags & EF_ROCKET) {
R_RocketTrail (old_origin, ent->origin, 0, ent); R_RocketTrail (0, (*ent));
dl = CL_AllocDlight (s1->number); dl = CL_AllocDlight (s1->number);
VectorCopy (ent->origin, dl->origin); VectorCopy ((*ent)->origin, dl->origin);
dl->radius = 200; dl->radius = 200;
dl->die = cl.time + 0.1; dl->die = cl.time + 0.1;
} else if (model->flags & EF_GRENADE) } else if (model->flags & EF_GRENADE)
R_RocketTrail (old_origin, ent->origin, 1, ent); R_RocketTrail (1, (*ent));
else if (model->flags & EF_GIB) else if (model->flags & EF_GIB)
R_RocketTrail (old_origin, ent->origin, 2, ent); R_RocketTrail (2, (*ent));
else if (model->flags & EF_ZOMGIB) else if (model->flags & EF_ZOMGIB)
R_RocketTrail (old_origin, ent->origin, 4, ent); R_RocketTrail (4, (*ent));
else if (model->flags & EF_TRACER) else if (model->flags & EF_TRACER)
R_RocketTrail (old_origin, ent->origin, 3, ent); R_RocketTrail (3, (*ent));
else if (model->flags & EF_TRACER2) else if (model->flags & EF_TRACER2)
R_RocketTrail (old_origin, ent->origin, 5, ent); R_RocketTrail (5, (*ent));
else if (model->flags & EF_TRACER3) else if (model->flags & EF_TRACER3)
R_RocketTrail (old_origin, ent->origin, 6, ent); R_RocketTrail (6, (*ent));
} }
} }
@ -639,8 +645,7 @@ PROJECTILE PARSING / LINKING
typedef struct { typedef struct {
int modelindex; int modelindex;
vec3_t origin; entity_t ent;
vec3_t angles;
} projectile_t; } projectile_t;
#define MAX_PROJECTILES 32 #define MAX_PROJECTILES 32
@ -681,11 +686,11 @@ CL_ParseProjectiles (void)
cl_num_projectiles++; cl_num_projectiles++;
pr->modelindex = cl_spikeindex; pr->modelindex = cl_spikeindex;
pr->origin[0] = ((bits[0] + ((bits[1] & 15) << 8)) << 1) - 4096; pr->ent.origin[0] = ((bits[0] + ((bits[1] & 15) << 8)) << 1) - 4096;
pr->origin[1] = (((bits[1] >> 4) + (bits[2] << 4)) << 1) - 4096; pr->ent.origin[1] = (((bits[1] >> 4) + (bits[2] << 4)) << 1) - 4096;
pr->origin[2] = ((bits[3] + ((bits[4] & 15) << 8)) << 1) - 4096; pr->ent.origin[2] = ((bits[3] + ((bits[4] & 15) << 8)) << 1) - 4096;
pr->angles[0] = 360 * (bits[4] >> 4) / 16; pr->ent.angles[0] = 360 * (bits[4] >> 4) / 16;
pr->angles[1] = 360 * bits[5] / 256; pr->ent.angles[1] = 360 * bits[5] / 256;
} }
} }
@ -700,32 +705,30 @@ CL_LinkProjectiles (void)
{ {
int i; int i;
projectile_t *pr; projectile_t *pr;
entity_t *ent; entity_t **ent;
for (i = 0, pr = cl_projectiles; i < cl_num_projectiles; i++, pr++) { for (i = 0, pr = cl_projectiles; i < cl_num_projectiles; i++, pr++) {
if (pr->modelindex < 1) if (pr->modelindex < 1)
continue; continue;
// grab an entity to fill in // grab an entity to fill in
if (cl_numvisedicts == MAX_VISEDICTS) ent = CL_NewTempEntity ();
if (!ent)
break; // object list is full break; // object list is full
ent = &cl_visedicts[cl_numvisedicts]; *ent = &pr->ent;
cl_numvisedicts++; cl_numvisedicts++;
ent->keynum = 0; (*ent)->model = cl.model_precache[pr->modelindex];
ent->model = cl.model_precache[pr->modelindex]; (*ent)->skinnum = 0;
ent->skinnum = 0; (*ent)->frame = 0;
ent->frame = 0; (*ent)->colormap = vid.colormap;
ent->colormap = vid.colormap; (*ent)->scoreboard = NULL;
ent->scoreboard = NULL;
VectorCopy (pr->origin, ent->origin);
VectorCopy (pr->angles, ent->angles);
// LordHavoc: Endy had neglected to do this as part of the QSG // LordHavoc: Endy had neglected to do this as part of the QSG
// VERSION 2 stuff // VERSION 2 stuff
ent->glowsize = 0; (*ent)->glowsize = 0;
ent->glowcolor = 254; (*ent)->glowcolor = 254;
ent->alpha = 1; (*ent)->alpha = 1;
ent->scale = 1; (*ent)->scale = 1;
ent->colormod[0] = ent->colormod[1] = ent->colormod[2] = 1; (*ent)->colormod[0] = (*ent)->colormod[1] = (*ent)->colormod[2] = 1;
} }
} }
@ -733,8 +736,6 @@ CL_LinkProjectiles (void)
extern int cl_spikeindex, cl_playerindex, cl_flagindex; extern int cl_spikeindex, cl_playerindex, cl_flagindex;
entity_t *CL_NewTempEntity (void);
/* /*
=================== ===================
CL_ParsePlayerinfo CL_ParsePlayerinfo
@ -826,7 +827,7 @@ CL_AddFlagModels (entity_t *ent, int team)
int i; int i;
float f; float f;
vec3_t v_forward, v_right, v_up; vec3_t v_forward, v_right, v_up;
entity_t *newent; entity_t **newent;
if (cl_flagindex == -1) if (cl_flagindex == -1)
return; return;
@ -872,17 +873,20 @@ CL_AddFlagModels (entity_t *ent, int team)
} }
newent = CL_NewTempEntity (); newent = CL_NewTempEntity ();
newent->model = cl.model_precache[cl_flagindex]; if (!newent)
newent->skinnum = team; return;
*newent = &cl_flag_ents[ent->keynum];
(*newent)->model = cl.model_precache[cl_flagindex];
(*newent)->skinnum = team;
AngleVectors (ent->angles, v_forward, v_right, v_up); AngleVectors (ent->angles, v_forward, v_right, v_up);
v_forward[2] = -v_forward[2]; // reverse z component v_forward[2] = -v_forward[2]; // reverse z component
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)
newent->origin[i] = ent->origin[i] - f * v_forward[i] + 22 * v_right[i]; (*newent)->origin[i] = ent->origin[i] - f * v_forward[i] + 22 * v_right[i];
newent->origin[2] -= 16; (*newent)->origin[2] -= 16;
VectorCopy (ent->angles, newent->angles) VectorCopy (ent->angles, (*newent)->angles)
newent->angles[2] -= 45; (*newent)->angles[2] -= 45;
} }
/* /*
@ -901,7 +905,7 @@ CL_LinkPlayers (void)
player_state_t *state; player_state_t *state;
player_state_t exact; player_state_t exact;
double playertime; double playertime;
entity_t *ent; entity_t **ent;
int msec; int msec;
frame_t *frame; frame_t *frame;
int oldphysent; int oldphysent;
@ -959,54 +963,41 @@ CL_LinkPlayers (void)
continue; continue;
// grab an entity to fill in // grab an entity to fill in
if (cl_numvisedicts == MAX_VISEDICTS) // object list is full ent = CL_NewTempEntity ();
if (!ent) // object list is full
break; break;
*ent = &cl_player_ents[state - frame->playerstate];
ent = &cl_visedicts[cl_numvisedicts++]; (*ent)->frame = state->frame;
(*ent)->keynum = state - frame->playerstate;
ent->frame = state->frame; (*ent)->model = cl.model_precache[state->modelindex];
(*ent)->skinnum = state->skinnum;
// scan the old entity display list for a matching player (*ent)->colormap = info->translations;
for (i = 0; i < cl_oldnumvisedicts; i++) {
if (cl_oldvisedicts[i].keynum == state->number) {
ent->frame_start_time = cl_oldvisedicts[i].frame_start_time;
ent->frame_interval = cl_oldvisedicts[i].frame_interval;
ent->pose1 = cl_oldvisedicts[i].pose1;
ent->pose2 = cl_oldvisedicts[i].pose2;
break;
}
}
ent->keynum = 0;
// ent->keynum = state->number;
ent->model = cl.model_precache[state->modelindex];
ent->skinnum = state->skinnum;
ent->colormap = info->translations;
if (state->modelindex == cl_playerindex) if (state->modelindex == cl_playerindex)
ent->scoreboard = info; // use custom skin (*ent)->scoreboard = info; // use custom skin
else else
ent->scoreboard = NULL; (*ent)->scoreboard = NULL;
// LordHavoc: more QSG VERSION 2 stuff, FIXME: players don't have // LordHavoc: more QSG VERSION 2 stuff, FIXME: players don't have
// extend stuff // extend stuff
ent->glowsize = 0; (*ent)->glowsize = 0;
ent->glowcolor = 254; (*ent)->glowcolor = 254;
ent->alpha = 1; (*ent)->alpha = 1;
ent->scale = 1; (*ent)->scale = 1;
ent->colormod[0] = ent->colormod[1] = ent->colormod[2] = 1; (*ent)->colormod[0] = (*ent)->colormod[1] = (*ent)->colormod[2] = 1;
// //
// angles // angles
// //
ent->angles[PITCH] = -state->viewangles[PITCH] / 3; (*ent)->angles[PITCH] = -state->viewangles[PITCH] / 3;
ent->angles[YAW] = state->viewangles[YAW]; (*ent)->angles[YAW] = state->viewangles[YAW];
ent->angles[ROLL] = 0; (*ent)->angles[ROLL] = 0;
ent->angles[ROLL] = V_CalcRoll (ent->angles, state->velocity) * 4; (*ent)->angles[ROLL] = V_CalcRoll ((*ent)->angles, state->velocity) * 4;
// only predict half the move to minimize overruns // only predict half the move to minimize overruns
msec = 500 * (playertime - state->state_time); msec = 500 * (playertime - state->state_time);
if (msec <= 0 || (!cl_predict_players->int_val && !cl_predict_players2->int_val)) { if (msec <= 0 || (!cl_predict_players->int_val && !cl_predict_players2->int_val)) {
VectorCopy (state->origin, ent->origin); VectorCopy (state->origin, (*ent)->origin);
} else { // predict players movement } else { // predict players movement
state->command.msec = msec = min (msec, 255); state->command.msec = msec = min (msec, 255);
@ -1014,13 +1005,13 @@ CL_LinkPlayers (void)
CL_SetSolidPlayers (j); CL_SetSolidPlayers (j);
CL_PredictUsercmd (state, &exact, &state->command, false); CL_PredictUsercmd (state, &exact, &state->command, false);
pmove.numphysent = oldphysent; pmove.numphysent = oldphysent;
VectorCopy (exact.origin, ent->origin); VectorCopy (exact.origin, (*ent)->origin);
} }
if (state->effects & EF_FLAG1) if (state->effects & EF_FLAG1)
CL_AddFlagModels (ent, 0); CL_AddFlagModels ((*ent), 0);
else if (state->effects & EF_FLAG2) else if (state->effects & EF_FLAG2)
CL_AddFlagModels (ent, 1); CL_AddFlagModels ((*ent), 1);
} }
} }

View file

@ -167,8 +167,8 @@ dlight_t cl_dlights[MAX_DLIGHTS];
// this is double buffered so the last frame // this is double buffered so the last frame
// can be scanned for oldorigins of trailing objects // can be scanned for oldorigins of trailing objects
int cl_numvisedicts, cl_oldnumvisedicts; int cl_numvisedicts, cl_oldnumvisedicts;
entity_t *cl_visedicts, *cl_oldvisedicts; entity_t **cl_visedicts, **cl_oldvisedicts;
entity_t cl_visedicts_list[2][MAX_VISEDICTS]; entity_t *cl_visedicts_list[2][MAX_VISEDICTS];
double connect_time = -1; // for connection retransmits double connect_time = -1; // for connection retransmits
@ -437,6 +437,7 @@ CL_ClearState (void)
if (host_hunklevel) // FIXME: check this... if (host_hunklevel) // FIXME: check this...
Hunk_FreeToLowMark (host_hunklevel); Hunk_FreeToLowMark (host_hunklevel);
CL_ClearEnts ();
CL_ClearTEnts (); CL_ClearTEnts ();
// wipe the entire cl structure // wipe the entire cl structure

View file

@ -48,20 +48,22 @@
#endif #endif
#define MAX_BEAMS 8 #define MAX_BEAMS 8
#define MAX_BEAM_ENTS 20
typedef struct { typedef struct {
int entity; int entity;
struct model_s *model; struct model_s *model;
float endtime; float endtime;
vec3_t start, end; vec3_t start, end;
entity_t ent_list[MAX_BEAM_ENTS];
int ent_count;
} beam_t; } beam_t;
beam_t cl_beams[MAX_BEAMS]; beam_t cl_beams[MAX_BEAMS];
#define MAX_EXPLOSIONS 8 #define MAX_EXPLOSIONS 8
typedef struct { typedef struct {
vec3_t origin;
float start; float start;
model_t *model; entity_t ent;
} explosion_t; } explosion_t;
explosion_t cl_explosions[MAX_EXPLOSIONS]; explosion_t cl_explosions[MAX_EXPLOSIONS];
@ -97,11 +99,38 @@ CL_TEnts_Init (void)
CL_ClearTEnts CL_ClearTEnts
================= =================
*/ */
void
CL_Init_Entity (entity_t *ent)
{
memset (ent, 0, sizeof (*ent));
ent->colormap = vid.colormap;
// LordHavoc: Endy had neglected to do this as part of the QSG VERSION 2
// stuff
ent->glowsize = 0;
ent->glowcolor = 254;
ent->alpha = 1;
ent->scale = 1;
ent->colormod[0] = ent->colormod[1] = ent->colormod[2] = 1;
}
void void
CL_ClearTEnts (void) CL_ClearTEnts (void)
{ {
int i;
memset (&cl_beams, 0, sizeof (cl_beams)); memset (&cl_beams, 0, sizeof (cl_beams));
memset (&cl_explosions, 0, sizeof (cl_explosions)); memset (&cl_explosions, 0, sizeof (cl_explosions));
for (i = 0; i < MAX_BEAMS; i++) {
int j;
for (j = 0; j < MAX_BEAM_ENTS; j++) {
CL_Init_Entity(&cl_beams[i].ent_list[j]);
}
}
for (i = 0; i < MAX_EXPLOSIONS; i++) {
CL_Init_Entity(&cl_explosions[i].ent);
}
} }
/* /*
@ -117,7 +146,7 @@ CL_AllocExplosion (void)
int index; int index;
for (i = 0; i < MAX_EXPLOSIONS; i++) for (i = 0; i < MAX_EXPLOSIONS; i++)
if (!cl_explosions[i].model) if (!cl_explosions[i].ent.model)
return &cl_explosions[i]; return &cl_explosions[i];
// find the oldest explosion // find the oldest explosion
time = cl.time; time = cl.time;
@ -274,9 +303,9 @@ CL_ParseTEnt (void)
// sprite // sprite
ex = CL_AllocExplosion (); ex = CL_AllocExplosion ();
VectorCopy (pos, ex->origin); VectorCopy (pos, ex->ent.origin);
ex->start = cl.time; ex->start = cl.time;
ex->model = Mod_ForName ("progs/s_explod.spr", true); ex->ent.model = Mod_ForName ("progs/s_explod.spr", true);
break; break;
case TE_TAREXPLOSION: // tarbaby explosion case TE_TAREXPLOSION: // tarbaby explosion
@ -337,31 +366,15 @@ CL_ParseTEnt (void)
CL_NewTempEntity CL_NewTempEntity
================= =================
*/ */
entity_t * entity_t **
CL_NewTempEntity (void) CL_NewTempEntity (void)
{ {
entity_t *ent;
if (cl_numvisedicts == MAX_VISEDICTS) if (cl_numvisedicts == MAX_VISEDICTS)
return NULL; return NULL;
ent = &cl_visedicts[cl_numvisedicts]; return &cl_visedicts[cl_numvisedicts++];
cl_numvisedicts++;
ent->keynum = 0;
memset (ent, 0, sizeof (*ent));
ent->colormap = vid.colormap;
// LordHavoc: Endy had neglected to do this as part of the QSG VERSION 2
// stuff
ent->glowsize = 0;
ent->glowcolor = 254;
ent->alpha = 1;
ent->scale = 1;
ent->colormod[0] = ent->colormod[1] = ent->colormod[2] = 1;
return ent;
} }
/* /*
================= =================
CL_UpdateBeams CL_UpdateBeams
@ -374,7 +387,7 @@ CL_UpdateBeams (void)
beam_t *b; beam_t *b;
vec3_t dist, org; vec3_t dist, org;
float d; float d;
entity_t *ent; entity_t **ent;
float yaw, pitch; float yaw, pitch;
float forward; float forward;
@ -412,21 +425,22 @@ CL_UpdateBeams (void)
// add new entities for the lightning // add new entities for the lightning
VectorCopy (b->start, org); VectorCopy (b->start, org);
d = VectorNormalize (dist); d = VectorNormalize (dist);
while (d > 0) { b->ent_count = 0;
while (d > 0 && b->ent_count < MAX_BEAM_ENTS) {
ent = CL_NewTempEntity (); ent = CL_NewTempEntity ();
if (!ent) if (!ent)
return; return;
VectorCopy (org, ent->origin); *ent = &b->ent_list[b->ent_count++];
ent->model = b->model; VectorCopy (org, (*ent)->origin);
ent->angles[0] = pitch; (*ent)->model = b->model;
ent->angles[1] = yaw; (*ent)->angles[0] = pitch;
ent->angles[2] = rand () % 360; (*ent)->angles[1] = yaw;
(*ent)->angles[2] = rand () % 360;
VectorMA(org, 30, dist, org); VectorMA(org, 30, dist, org);
d -= 30; d -= 30;
} }
} }
} }
/* /*
@ -440,23 +454,22 @@ CL_UpdateExplosions (void)
int i; int i;
int f; int f;
explosion_t *ex; explosion_t *ex;
entity_t *ent; entity_t **ent;
for (i = 0, ex = cl_explosions; i < MAX_EXPLOSIONS; i++, ex++) { for (i = 0, ex = cl_explosions; i < MAX_EXPLOSIONS; i++, ex++) {
if (!ex->model) if (!ex->ent.model)
continue; continue;
f = 10 * (cl.time - ex->start); f = 10 * (cl.time - ex->start);
if (f >= ex->model->numframes) { if (f >= ex->ent.model->numframes) {
ex->model = NULL; ex->ent.model = NULL;
continue; continue;
} }
ent = CL_NewTempEntity (); ent = CL_NewTempEntity ();
if (!ent) if (!ent)
return; return;
VectorCopy (ex->origin, ent->origin); ex->ent.frame = f;
ent->model = ex->model; *ent = &ex->ent;
ent->frame = f;
} }
} }

View file

@ -65,7 +65,7 @@ R_AddFire (vec3_t start, vec3_t end, entity_t *ent)
VectorSubtract (end, start, vec); VectorSubtract (end, start, vec);
len = VectorNormalize (vec); len = VectorNormalize (vec);
key = ent - cl_visedicts + 1; key = ent->keynum;
if (len) { if (len) {
f = R_AllocFire (key); f = R_AllocFire (key);
@ -76,7 +76,7 @@ R_AddFire (vec3_t start, vec3_t end, entity_t *ent)
f->decay = -1; f->decay = -1;
f->color = r_firecolor; f->color = r_firecolor;
dl = CL_AllocDlight (key); dl = CL_AllocDlight (-key);
VectorCopy (end, dl->origin); VectorCopy (end, dl->origin);
dl->radius = 200; dl->radius = 200;
dl->die = cl.time + 0.5; dl->die = cl.time + 0.5;

View file

@ -441,7 +441,7 @@ R_TeleportSplash (vec3_t org)
} }
void void
R_RocketTrail (vec3_t start, vec3_t end, int type, entity_t *ent) R_RocketTrail (int type, entity_t *ent)
{ {
vec3_t vec; vec3_t vec;
float len; float len;
@ -452,12 +452,12 @@ R_RocketTrail (vec3_t start, vec3_t end, int type, entity_t *ent)
byte palpha, pcolor; byte palpha, pcolor;
if (type == 0) if (type == 0)
R_AddFire (start, end, ent); R_AddFire (ent->old_origin, ent->origin, ent);
if (!gl_particles->int_val) if (!gl_particles->int_val)
return; return;
VectorSubtract (end, start, vec); VectorSubtract (ent->origin, ent->old_origin, vec);
len = VectorNormalize (vec); len = VectorNormalize (vec);
while (len > 0) { while (len > 0) {
VectorCopy (vec3_origin, pvel); VectorCopy (vec3_origin, pvel);
@ -483,7 +483,7 @@ R_RocketTrail (vec3_t start, vec3_t end, int type, entity_t *ent)
palpha = 48 + (rand () & 31); palpha = 48 + (rand () & 31);
ptype = pt_smoke; ptype = pt_smoke;
pdie = cl.time + 1; pdie = cl.time + 1;
VectorCopy (start, porg); VectorCopy (ent->old_origin, porg);
break; break;
case 2: // blood case 2: // blood
case 4: // slight blood case 4: // slight blood
@ -494,7 +494,7 @@ R_RocketTrail (vec3_t start, vec3_t end, int type, entity_t *ent)
pdie = cl.time + 2; pdie = cl.time + 2;
for (j = 0; j < 3; j++) { for (j = 0; j < 3; j++) {
pvel[j] = (rand () & 15) - 8; pvel[j] = (rand () & 15) - 8;
porg[j] = start[j] + ((rand () % 3) - 2); porg[j] = ent->old_origin[j] + ((rand () % 3) - 2);
} }
ptype = pt_grav; ptype = pt_grav;
palpha = 255; palpha = 255;
@ -506,7 +506,7 @@ R_RocketTrail (vec3_t start, vec3_t end, int type, entity_t *ent)
pscale = lhrandom (1, 2); pscale = lhrandom (1, 2);
pdie = cl.time + 0.3; pdie = cl.time + 0.3;
for (j = 0; j < 3; j++) for (j = 0; j < 3; j++)
porg[j] = start[j] + ((rand () & 15) - 8); porg[j] = ent->old_origin[j] + ((rand () & 15) - 8);
break; break;
case 3: case 3:
case 5: // tracer case 5: // tracer
@ -524,7 +524,7 @@ R_RocketTrail (vec3_t start, vec3_t end, int type, entity_t *ent)
tracercount++; tracercount++;
VectorCopy (start, porg); VectorCopy (ent->old_origin, porg);
if (tracercount & 1) { if (tracercount & 1) {
pvel[0] = 30 * vec[1]; pvel[0] = 30 * vec[1];
pvel[1] = 30 * -vec[0]; pvel[1] = 30 * -vec[0];
@ -536,7 +536,7 @@ R_RocketTrail (vec3_t start, vec3_t end, int type, entity_t *ent)
} }
} }
VectorAdd (start, vec, start); VectorAdd (ent->old_origin, vec, ent->old_origin);
particle_new (ptype, ptex, porg, pscale, pvel, pdie, pcolor, palpha); particle_new (ptype, ptex, porg, pscale, pvel, pdie, pcolor, palpha);
} }

View file

@ -901,27 +901,27 @@ R_DrawEntitiesOnList (void)
// LordHavoc: split into 3 loops to simplify state changes // LordHavoc: split into 3 loops to simplify state changes
for (i = 0; i < cl_numvisedicts; i++) { for (i = 0; i < cl_numvisedicts; i++) {
if (cl_visedicts[i].model->type != mod_brush) if (cl_visedicts[i]->model->type != mod_brush)
continue; continue;
currententity = &cl_visedicts[i]; currententity = cl_visedicts[i];
modelalpha = currententity->alpha; modelalpha = currententity->alpha;
R_DrawBrushModel (currententity); R_DrawBrushModel (currententity);
} }
for (i = 0; i < cl_numvisedicts; i++) { for (i = 0; i < cl_numvisedicts; i++) {
if (cl_visedicts[i].model->type != mod_alias) if (cl_visedicts[i]->model->type != mod_alias)
continue; continue;
currententity = &cl_visedicts[i]; currententity = cl_visedicts[i];
modelalpha = currententity->alpha; modelalpha = currententity->alpha;
R_DrawAliasModel (currententity); R_DrawAliasModel (currententity);
} }
for (i = 0; i < cl_numvisedicts; i++) { for (i = 0; i < cl_numvisedicts; i++) {
if (cl_visedicts[i].model->type != mod_sprite) if (cl_visedicts[i]->model->type != mod_sprite)
continue; continue;
currententity = &cl_visedicts[i]; currententity = cl_visedicts[i];
modelalpha = currententity->alpha; modelalpha = currententity->alpha;
R_DrawSpriteModel (currententity); R_DrawSpriteModel (currententity);

View file

@ -259,7 +259,7 @@ R_StoreEfrags (efrag_t **ppefrag)
if ((pent->visframe != r_framecount) && if ((pent->visframe != r_framecount) &&
(cl_numvisedicts < MAX_VISEDICTS)) { (cl_numvisedicts < MAX_VISEDICTS)) {
cl_visedicts[cl_numvisedicts++] = *pent; cl_visedicts[cl_numvisedicts++] = pent;
// mark that we've recorded this entity for this frame // mark that we've recorded this entity for this frame
pent->visframe = r_framecount; pent->visframe = r_framecount;

View file

@ -594,7 +594,7 @@ R_DrawEntitiesOnList (void)
return; return;
for (i = 0; i < cl_numvisedicts; i++) { for (i = 0; i < cl_numvisedicts; i++) {
currententity = &cl_visedicts[i]; currententity = cl_visedicts[i];
switch (currententity->model->type) { switch (currententity->model->type) {
case mod_sprite: case mod_sprite:
@ -798,7 +798,7 @@ R_DrawBEntitiesOnList (void)
r_dlightframecount = r_framecount; r_dlightframecount = r_framecount;
for (i = 0; i < cl_numvisedicts; i++) { for (i = 0; i < cl_numvisedicts; i++) {
currententity = &cl_visedicts[i]; currententity = cl_visedicts[i];
switch (currententity->model->type) { switch (currententity->model->type) {
case mod_brush: case mod_brush:

View file

@ -388,14 +388,14 @@ R_TeleportSplash (vec3_t org)
} }
void void
R_RocketTrail (vec3_t start, vec3_t end, int type, entity_t *ent) R_RocketTrail (int type, entity_t *ent)
{ {
vec3_t vec; vec3_t vec;
float len; float len;
int j; int j;
particle_t *p; particle_t *p;
VectorSubtract (end, start, vec); VectorSubtract (ent->origin, ent->old_origin, vec);
len = VectorNormalize (vec); len = VectorNormalize (vec);
while (len > 0) { while (len > 0) {
len -= 3; len -= 3;
@ -414,31 +414,31 @@ R_RocketTrail (vec3_t start, vec3_t end, int type, entity_t *ent)
p->type = pt_slowgrav; p->type = pt_slowgrav;
p->color = 67 + (rand () & 3); p->color = 67 + (rand () & 3);
for (j = 0; j < 3; j++) for (j = 0; j < 3; j++)
p->org[j] = start[j] + ((rand () % 6) - 3); p->org[j] = ent->old_origin[j] + ((rand () % 6) - 3);
len -= 3; len -= 3;
} else if (type == 2) { // blood } else if (type == 2) { // blood
p->type = pt_slowgrav; p->type = pt_slowgrav;
p->color = 67 + (rand () & 3); p->color = 67 + (rand () & 3);
for (j = 0; j < 3; j++) for (j = 0; j < 3; j++)
p->org[j] = start[j] + ((rand () % 6) - 3); p->org[j] = ent->old_origin[j] + ((rand () % 6) - 3);
} else if (type == 6) { // voor trail } else if (type == 6) { // voor trail
p->color = 9 * 16 + 8 + (rand () & 3); p->color = 9 * 16 + 8 + (rand () & 3);
p->type = pt_static; p->type = pt_static;
p->die = cl.time + 0.3; p->die = cl.time + 0.3;
for (j = 0; j < 3; j++) for (j = 0; j < 3; j++)
p->org[j] = start[j] + ((rand () & 15) - 8); p->org[j] = ent->old_origin[j] + ((rand () & 15) - 8);
} else if (type == 1) { // smoke smoke } else if (type == 1) { // smoke smoke
p->ramp = (rand () & 3) + 2; p->ramp = (rand () & 3) + 2;
p->color = ramp3[(int) p->ramp]; p->color = ramp3[(int) p->ramp];
p->type = pt_fire; p->type = pt_fire;
for (j = 0; j < 3; j++) for (j = 0; j < 3; j++)
p->org[j] = start[j] + ((rand () % 6) - 3); p->org[j] = ent->old_origin[j] + ((rand () % 6) - 3);
} else if (type == 0) { // rocket trail } else if (type == 0) { // rocket trail
p->ramp = (rand () & 3); p->ramp = (rand () & 3);
p->color = ramp3[(int) p->ramp]; p->color = ramp3[(int) p->ramp];
p->type = pt_fire; p->type = pt_fire;
for (j = 0; j < 3; j++) for (j = 0; j < 3; j++)
p->org[j] = start[j] + ((rand () % 6) - 3); p->org[j] = ent->old_origin[j] + ((rand () % 6) - 3);
} else if (type == 3 || type == 5) { // tracer } else if (type == 3 || type == 5) { // tracer
static int tracercount; static int tracercount;
@ -451,7 +451,7 @@ R_RocketTrail (vec3_t start, vec3_t end, int type, entity_t *ent)
tracercount++; tracercount++;
VectorCopy (start, p->org); VectorCopy (ent->old_origin, p->org);
if (tracercount & 1) { if (tracercount & 1) {
p->vel[0] = 30 * vec[1]; p->vel[0] = 30 * vec[1];
p->vel[1] = 30 * -vec[0]; p->vel[1] = 30 * -vec[0];
@ -463,7 +463,7 @@ R_RocketTrail (vec3_t start, vec3_t end, int type, entity_t *ent)
} }
VectorAdd (start, vec, start); VectorAdd (ent->old_origin, vec, ent->old_origin);
} }
} }