mirror of
https://git.code.sf.net/p/quake/newtree
synced 2024-11-24 21:12:27 +00:00
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:
parent
3669d78d1b
commit
dd3ea544ce
13 changed files with 202 additions and 194 deletions
|
@ -50,8 +50,8 @@ void CL_BeginServerConnect(void);
|
|||
|
||||
#define MAX_VISEDICTS 256
|
||||
extern int cl_numvisedicts, cl_oldnumvisedicts;
|
||||
extern entity_t *cl_visedicts, *cl_oldvisedicts;
|
||||
extern entity_t cl_visedicts_list[2][MAX_VISEDICTS];
|
||||
extern entity_t **cl_visedicts, **cl_oldvisedicts;
|
||||
extern entity_t *cl_visedicts_list[2][MAX_VISEDICTS];
|
||||
|
||||
extern char emodel_name[], pmodel_name[], prespawn_name[], modellist_name[], soundlist_name[];
|
||||
|
||||
|
|
|
@ -30,6 +30,8 @@
|
|||
#define _CL_TENT_H
|
||||
|
||||
void CL_TEnts_Init (void);
|
||||
void CL_ClearEnts (void);
|
||||
void CL_ClearTEnts (void);
|
||||
void CL_Init_Entity (struct entity_s *ent);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
|
||||
#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_RunPuffEffect (vec3_t org, byte type, byte count);
|
||||
void R_RunSpikeEffect (vec3_t org, byte type);
|
||||
|
|
|
@ -54,6 +54,7 @@ typedef struct entity_s
|
|||
{
|
||||
int keynum; // for matching entities in different frames
|
||||
vec3_t origin;
|
||||
vec3_t old_origin;
|
||||
vec3_t angles;
|
||||
struct model_s *model; // NULL = no model
|
||||
int frame;
|
||||
|
|
237
source/cl_ents.c
237
source/cl_ents.c
|
@ -51,6 +51,7 @@
|
|||
#include "cl_main.h"
|
||||
#include "cl_ents.h"
|
||||
#include "cl_input.h"
|
||||
#include "cl_tent.h"
|
||||
|
||||
extern cvar_t *cl_predict_players;
|
||||
extern cvar_t *cl_predict_players2;
|
||||
|
@ -64,8 +65,30 @@ static struct predicted_player {
|
|||
vec3_t origin; // predicted origin
|
||||
} 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
|
||||
|
@ -453,12 +476,11 @@ CL_LinkPacketEntities
|
|||
void
|
||||
CL_LinkPacketEntities (void)
|
||||
{
|
||||
entity_t *ent;
|
||||
entity_t **ent;
|
||||
packet_entities_t *pack;
|
||||
entity_state_t *s1, *s2;
|
||||
float f;
|
||||
model_t *model;
|
||||
vec3_t old_origin;
|
||||
float autorotate;
|
||||
int i;
|
||||
int pnum;
|
||||
|
@ -515,52 +537,52 @@ CL_LinkPacketEntities (void)
|
|||
continue;
|
||||
|
||||
// create a new entity
|
||||
if (cl_numvisedicts == MAX_VISEDICTS)
|
||||
ent = CL_NewTempEntity ();
|
||||
if (!ent)
|
||||
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
|
||||
if (s1->colormap && (s1->colormap < MAX_CLIENTS)
|
||||
&& !strcmp (ent->model->name, "progs/player.mdl")) {
|
||||
ent->colormap = cl.players[s1->colormap - 1].translations;
|
||||
ent->scoreboard = &cl.players[s1->colormap - 1];
|
||||
&& !strcmp ((*ent)->model->name, "progs/player.mdl")) {
|
||||
(*ent)->colormap = cl.players[s1->colormap - 1].translations;
|
||||
(*ent)->scoreboard = &cl.players[s1->colormap - 1];
|
||||
} else {
|
||||
ent->colormap = vid.colormap;
|
||||
ent->scoreboard = NULL;
|
||||
(*ent)->colormap = vid.colormap;
|
||||
(*ent)->scoreboard = NULL;
|
||||
}
|
||||
|
||||
// LordHavoc: cleaned up Endy's coding style, and fixed Endy's bugs
|
||||
// Ender: Extend (Colormod) [QSG - Begin]
|
||||
// N.B: All messy code below is the sole fault of LordHavoc and
|
||||
// his futile attempts to save bandwidth. :)
|
||||
ent->glowsize = s1->glowsize < 128 ? s1->glowsize * 8.0 : (s1->glowsize - 256) * 8.0;
|
||||
ent->glowcolor = s1->glowcolor;
|
||||
ent->alpha = s1->alpha / 255.0;
|
||||
ent->scale = s1->scale / 16.0;
|
||||
(*ent)->glowsize = s1->glowsize < 128 ? s1->glowsize * 8.0 : (s1->glowsize - 256) * 8.0;
|
||||
(*ent)->glowcolor = s1->glowcolor;
|
||||
(*ent)->alpha = s1->alpha / 255.0;
|
||||
(*ent)->scale = s1->scale / 16.0;
|
||||
|
||||
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 {
|
||||
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[2] = (float) (s1->colormod & 3) * (1.0 / 3.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[2] = (float) (s1->colormod & 3) * (1.0 / 3.0);
|
||||
}
|
||||
// Ender: Extend (Colormod) [QSG - End]
|
||||
|
||||
// set skin
|
||||
ent->skinnum = s1->skinnum;
|
||||
(*ent)->skinnum = s1->skinnum;
|
||||
|
||||
// set frame
|
||||
ent->frame = s1->frame;
|
||||
(*ent)->frame = s1->frame;
|
||||
|
||||
if (model->flags & EF_ROTATE) { // rotate binary objects locally
|
||||
ent->angles[0] = 0;
|
||||
ent->angles[1] = autorotate;
|
||||
ent->angles[2] = 0;
|
||||
(*ent)->angles[0] = 0;
|
||||
(*ent)->angles[1] = autorotate;
|
||||
(*ent)->angles[2] = 0;
|
||||
} else {
|
||||
float a1, a2;
|
||||
|
||||
|
@ -571,60 +593,44 @@ CL_LinkPacketEntities (void)
|
|||
a1 -= 360;
|
||||
if (a1 - a2 < -180)
|
||||
a1 += 360;
|
||||
ent->angles[i] = a2 + f * (a1 - a2);
|
||||
(*ent)->angles[i] = a2 + f * (a1 - a2);
|
||||
}
|
||||
}
|
||||
|
||||
VectorCopy ((*ent)->origin, (*ent)->old_origin);
|
||||
// calculate origin
|
||||
for (i = 0; i < 3; 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;
|
||||
}
|
||||
(*ent)->origin[i] = s2->origin[i] + f * (s1->origin[i] - s2->origin[i]);
|
||||
|
||||
// add automatic particle trails
|
||||
if (!model->flags)
|
||||
continue;
|
||||
|
||||
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
|
||||
VectorCopy (ent->origin, old_origin);
|
||||
VectorCopy ((*ent)->origin, (*ent)->old_origin);
|
||||
break;
|
||||
}
|
||||
|
||||
if (model->flags & EF_ROCKET) {
|
||||
R_RocketTrail (old_origin, ent->origin, 0, ent);
|
||||
R_RocketTrail (0, (*ent));
|
||||
dl = CL_AllocDlight (s1->number);
|
||||
VectorCopy (ent->origin, dl->origin);
|
||||
VectorCopy ((*ent)->origin, dl->origin);
|
||||
dl->radius = 200;
|
||||
dl->die = cl.time + 0.1;
|
||||
} else if (model->flags & EF_GRENADE)
|
||||
R_RocketTrail (old_origin, ent->origin, 1, ent);
|
||||
R_RocketTrail (1, (*ent));
|
||||
else if (model->flags & EF_GIB)
|
||||
R_RocketTrail (old_origin, ent->origin, 2, ent);
|
||||
R_RocketTrail (2, (*ent));
|
||||
else if (model->flags & EF_ZOMGIB)
|
||||
R_RocketTrail (old_origin, ent->origin, 4, ent);
|
||||
R_RocketTrail (4, (*ent));
|
||||
else if (model->flags & EF_TRACER)
|
||||
R_RocketTrail (old_origin, ent->origin, 3, ent);
|
||||
R_RocketTrail (3, (*ent));
|
||||
else if (model->flags & EF_TRACER2)
|
||||
R_RocketTrail (old_origin, ent->origin, 5, ent);
|
||||
R_RocketTrail (5, (*ent));
|
||||
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 {
|
||||
int modelindex;
|
||||
vec3_t origin;
|
||||
vec3_t angles;
|
||||
entity_t ent;
|
||||
} projectile_t;
|
||||
|
||||
#define MAX_PROJECTILES 32
|
||||
|
@ -681,11 +686,11 @@ CL_ParseProjectiles (void)
|
|||
cl_num_projectiles++;
|
||||
|
||||
pr->modelindex = cl_spikeindex;
|
||||
pr->origin[0] = ((bits[0] + ((bits[1] & 15) << 8)) << 1) - 4096;
|
||||
pr->origin[1] = (((bits[1] >> 4) + (bits[2] << 4)) << 1) - 4096;
|
||||
pr->origin[2] = ((bits[3] + ((bits[4] & 15) << 8)) << 1) - 4096;
|
||||
pr->angles[0] = 360 * (bits[4] >> 4) / 16;
|
||||
pr->angles[1] = 360 * bits[5] / 256;
|
||||
pr->ent.origin[0] = ((bits[0] + ((bits[1] & 15) << 8)) << 1) - 4096;
|
||||
pr->ent.origin[1] = (((bits[1] >> 4) + (bits[2] << 4)) << 1) - 4096;
|
||||
pr->ent.origin[2] = ((bits[3] + ((bits[4] & 15) << 8)) << 1) - 4096;
|
||||
pr->ent.angles[0] = 360 * (bits[4] >> 4) / 16;
|
||||
pr->ent.angles[1] = 360 * bits[5] / 256;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -700,32 +705,30 @@ CL_LinkProjectiles (void)
|
|||
{
|
||||
int i;
|
||||
projectile_t *pr;
|
||||
entity_t *ent;
|
||||
entity_t **ent;
|
||||
|
||||
for (i = 0, pr = cl_projectiles; i < cl_num_projectiles; i++, pr++) {
|
||||
if (pr->modelindex < 1)
|
||||
continue;
|
||||
|
||||
// grab an entity to fill in
|
||||
if (cl_numvisedicts == MAX_VISEDICTS)
|
||||
ent = CL_NewTempEntity ();
|
||||
if (!ent)
|
||||
break; // object list is full
|
||||
ent = &cl_visedicts[cl_numvisedicts];
|
||||
*ent = &pr->ent;
|
||||
cl_numvisedicts++;
|
||||
ent->keynum = 0;
|
||||
ent->model = cl.model_precache[pr->modelindex];
|
||||
ent->skinnum = 0;
|
||||
ent->frame = 0;
|
||||
ent->colormap = vid.colormap;
|
||||
ent->scoreboard = NULL;
|
||||
VectorCopy (pr->origin, ent->origin);
|
||||
VectorCopy (pr->angles, ent->angles);
|
||||
(*ent)->model = cl.model_precache[pr->modelindex];
|
||||
(*ent)->skinnum = 0;
|
||||
(*ent)->frame = 0;
|
||||
(*ent)->colormap = vid.colormap;
|
||||
(*ent)->scoreboard = NULL;
|
||||
// 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;
|
||||
(*ent)->glowsize = 0;
|
||||
(*ent)->glowcolor = 254;
|
||||
(*ent)->alpha = 1;
|
||||
(*ent)->scale = 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;
|
||||
|
||||
entity_t *CL_NewTempEntity (void);
|
||||
|
||||
/*
|
||||
===================
|
||||
CL_ParsePlayerinfo
|
||||
|
@ -826,7 +827,7 @@ CL_AddFlagModels (entity_t *ent, int team)
|
|||
int i;
|
||||
float f;
|
||||
vec3_t v_forward, v_right, v_up;
|
||||
entity_t *newent;
|
||||
entity_t **newent;
|
||||
|
||||
if (cl_flagindex == -1)
|
||||
return;
|
||||
|
@ -872,17 +873,20 @@ CL_AddFlagModels (entity_t *ent, int team)
|
|||
}
|
||||
|
||||
newent = CL_NewTempEntity ();
|
||||
newent->model = cl.model_precache[cl_flagindex];
|
||||
newent->skinnum = team;
|
||||
if (!newent)
|
||||
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);
|
||||
v_forward[2] = -v_forward[2]; // reverse z component
|
||||
for (i = 0; i < 3; i++)
|
||||
newent->origin[i] = ent->origin[i] - f * v_forward[i] + 22 * v_right[i];
|
||||
newent->origin[2] -= 16;
|
||||
(*newent)->origin[i] = ent->origin[i] - f * v_forward[i] + 22 * v_right[i];
|
||||
(*newent)->origin[2] -= 16;
|
||||
|
||||
VectorCopy (ent->angles, newent->angles)
|
||||
newent->angles[2] -= 45;
|
||||
VectorCopy (ent->angles, (*newent)->angles)
|
||||
(*newent)->angles[2] -= 45;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -901,7 +905,7 @@ CL_LinkPlayers (void)
|
|||
player_state_t *state;
|
||||
player_state_t exact;
|
||||
double playertime;
|
||||
entity_t *ent;
|
||||
entity_t **ent;
|
||||
int msec;
|
||||
frame_t *frame;
|
||||
int oldphysent;
|
||||
|
@ -959,54 +963,41 @@ CL_LinkPlayers (void)
|
|||
continue;
|
||||
|
||||
// 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;
|
||||
*ent = &cl_player_ents[state - frame->playerstate];
|
||||
|
||||
ent = &cl_visedicts[cl_numvisedicts++];
|
||||
|
||||
ent->frame = state->frame;
|
||||
|
||||
// scan the old entity display list for a matching player
|
||||
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;
|
||||
(*ent)->frame = state->frame;
|
||||
(*ent)->keynum = state - frame->playerstate;
|
||||
(*ent)->model = cl.model_precache[state->modelindex];
|
||||
(*ent)->skinnum = state->skinnum;
|
||||
(*ent)->colormap = info->translations;
|
||||
if (state->modelindex == cl_playerindex)
|
||||
ent->scoreboard = info; // use custom skin
|
||||
(*ent)->scoreboard = info; // use custom skin
|
||||
else
|
||||
ent->scoreboard = NULL;
|
||||
(*ent)->scoreboard = NULL;
|
||||
|
||||
// LordHavoc: more QSG VERSION 2 stuff, FIXME: players don't have
|
||||
// extend stuff
|
||||
ent->glowsize = 0;
|
||||
ent->glowcolor = 254;
|
||||
ent->alpha = 1;
|
||||
ent->scale = 1;
|
||||
ent->colormod[0] = ent->colormod[1] = ent->colormod[2] = 1;
|
||||
(*ent)->glowsize = 0;
|
||||
(*ent)->glowcolor = 254;
|
||||
(*ent)->alpha = 1;
|
||||
(*ent)->scale = 1;
|
||||
(*ent)->colormod[0] = (*ent)->colormod[1] = (*ent)->colormod[2] = 1;
|
||||
|
||||
//
|
||||
// angles
|
||||
//
|
||||
ent->angles[PITCH] = -state->viewangles[PITCH] / 3;
|
||||
ent->angles[YAW] = state->viewangles[YAW];
|
||||
ent->angles[ROLL] = 0;
|
||||
ent->angles[ROLL] = V_CalcRoll (ent->angles, state->velocity) * 4;
|
||||
(*ent)->angles[PITCH] = -state->viewangles[PITCH] / 3;
|
||||
(*ent)->angles[YAW] = state->viewangles[YAW];
|
||||
(*ent)->angles[ROLL] = 0;
|
||||
(*ent)->angles[ROLL] = V_CalcRoll ((*ent)->angles, state->velocity) * 4;
|
||||
|
||||
// only predict half the move to minimize overruns
|
||||
msec = 500 * (playertime - state->state_time);
|
||||
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
|
||||
state->command.msec = msec = min (msec, 255);
|
||||
|
||||
|
@ -1014,13 +1005,13 @@ CL_LinkPlayers (void)
|
|||
CL_SetSolidPlayers (j);
|
||||
CL_PredictUsercmd (state, &exact, &state->command, false);
|
||||
pmove.numphysent = oldphysent;
|
||||
VectorCopy (exact.origin, ent->origin);
|
||||
VectorCopy (exact.origin, (*ent)->origin);
|
||||
}
|
||||
|
||||
if (state->effects & EF_FLAG1)
|
||||
CL_AddFlagModels (ent, 0);
|
||||
CL_AddFlagModels ((*ent), 0);
|
||||
else if (state->effects & EF_FLAG2)
|
||||
CL_AddFlagModels (ent, 1);
|
||||
CL_AddFlagModels ((*ent), 1);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -167,8 +167,8 @@ dlight_t cl_dlights[MAX_DLIGHTS];
|
|||
// this is double buffered so the last frame
|
||||
// can be scanned for oldorigins of trailing objects
|
||||
int cl_numvisedicts, cl_oldnumvisedicts;
|
||||
entity_t *cl_visedicts, *cl_oldvisedicts;
|
||||
entity_t cl_visedicts_list[2][MAX_VISEDICTS];
|
||||
entity_t **cl_visedicts, **cl_oldvisedicts;
|
||||
entity_t *cl_visedicts_list[2][MAX_VISEDICTS];
|
||||
|
||||
double connect_time = -1; // for connection retransmits
|
||||
|
||||
|
@ -437,6 +437,7 @@ CL_ClearState (void)
|
|||
if (host_hunklevel) // FIXME: check this...
|
||||
Hunk_FreeToLowMark (host_hunklevel);
|
||||
|
||||
CL_ClearEnts ();
|
||||
CL_ClearTEnts ();
|
||||
|
||||
// wipe the entire cl structure
|
||||
|
|
|
@ -48,20 +48,22 @@
|
|||
#endif
|
||||
|
||||
#define MAX_BEAMS 8
|
||||
#define MAX_BEAM_ENTS 20
|
||||
typedef struct {
|
||||
int entity;
|
||||
struct model_s *model;
|
||||
float endtime;
|
||||
vec3_t start, end;
|
||||
entity_t ent_list[MAX_BEAM_ENTS];
|
||||
int ent_count;
|
||||
} beam_t;
|
||||
|
||||
beam_t cl_beams[MAX_BEAMS];
|
||||
|
||||
#define MAX_EXPLOSIONS 8
|
||||
typedef struct {
|
||||
vec3_t origin;
|
||||
float start;
|
||||
model_t *model;
|
||||
entity_t ent;
|
||||
} explosion_t;
|
||||
|
||||
explosion_t cl_explosions[MAX_EXPLOSIONS];
|
||||
|
@ -97,11 +99,38 @@ CL_TEnts_Init (void)
|
|||
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
|
||||
CL_ClearTEnts (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
memset (&cl_beams, 0, sizeof (cl_beams));
|
||||
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;
|
||||
|
||||
for (i = 0; i < MAX_EXPLOSIONS; i++)
|
||||
if (!cl_explosions[i].model)
|
||||
if (!cl_explosions[i].ent.model)
|
||||
return &cl_explosions[i];
|
||||
// find the oldest explosion
|
||||
time = cl.time;
|
||||
|
@ -274,9 +303,9 @@ CL_ParseTEnt (void)
|
|||
|
||||
// sprite
|
||||
ex = CL_AllocExplosion ();
|
||||
VectorCopy (pos, ex->origin);
|
||||
VectorCopy (pos, ex->ent.origin);
|
||||
ex->start = cl.time;
|
||||
ex->model = Mod_ForName ("progs/s_explod.spr", true);
|
||||
ex->ent.model = Mod_ForName ("progs/s_explod.spr", true);
|
||||
break;
|
||||
|
||||
case TE_TAREXPLOSION: // tarbaby explosion
|
||||
|
@ -337,31 +366,15 @@ CL_ParseTEnt (void)
|
|||
CL_NewTempEntity
|
||||
=================
|
||||
*/
|
||||
entity_t *
|
||||
entity_t **
|
||||
CL_NewTempEntity (void)
|
||||
{
|
||||
entity_t *ent;
|
||||
|
||||
if (cl_numvisedicts == MAX_VISEDICTS)
|
||||
return NULL;
|
||||
ent = &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;
|
||||
return &cl_visedicts[cl_numvisedicts++];
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
CL_UpdateBeams
|
||||
|
@ -374,7 +387,7 @@ CL_UpdateBeams (void)
|
|||
beam_t *b;
|
||||
vec3_t dist, org;
|
||||
float d;
|
||||
entity_t *ent;
|
||||
entity_t **ent;
|
||||
float yaw, pitch;
|
||||
float forward;
|
||||
|
||||
|
@ -412,21 +425,22 @@ CL_UpdateBeams (void)
|
|||
// add new entities for the lightning
|
||||
VectorCopy (b->start, org);
|
||||
d = VectorNormalize (dist);
|
||||
while (d > 0) {
|
||||
b->ent_count = 0;
|
||||
while (d > 0 && b->ent_count < MAX_BEAM_ENTS) {
|
||||
ent = CL_NewTempEntity ();
|
||||
if (!ent)
|
||||
return;
|
||||
VectorCopy (org, ent->origin);
|
||||
ent->model = b->model;
|
||||
ent->angles[0] = pitch;
|
||||
ent->angles[1] = yaw;
|
||||
ent->angles[2] = rand () % 360;
|
||||
*ent = &b->ent_list[b->ent_count++];
|
||||
VectorCopy (org, (*ent)->origin);
|
||||
(*ent)->model = b->model;
|
||||
(*ent)->angles[0] = pitch;
|
||||
(*ent)->angles[1] = yaw;
|
||||
(*ent)->angles[2] = rand () % 360;
|
||||
|
||||
VectorMA(org, 30, dist, org);
|
||||
d -= 30;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -440,23 +454,22 @@ CL_UpdateExplosions (void)
|
|||
int i;
|
||||
int f;
|
||||
explosion_t *ex;
|
||||
entity_t *ent;
|
||||
entity_t **ent;
|
||||
|
||||
for (i = 0, ex = cl_explosions; i < MAX_EXPLOSIONS; i++, ex++) {
|
||||
if (!ex->model)
|
||||
if (!ex->ent.model)
|
||||
continue;
|
||||
f = 10 * (cl.time - ex->start);
|
||||
if (f >= ex->model->numframes) {
|
||||
ex->model = NULL;
|
||||
if (f >= ex->ent.model->numframes) {
|
||||
ex->ent.model = NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
ent = CL_NewTempEntity ();
|
||||
if (!ent)
|
||||
return;
|
||||
VectorCopy (ex->origin, ent->origin);
|
||||
ent->model = ex->model;
|
||||
ent->frame = f;
|
||||
ex->ent.frame = f;
|
||||
*ent = &ex->ent;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -65,7 +65,7 @@ R_AddFire (vec3_t start, vec3_t end, entity_t *ent)
|
|||
|
||||
VectorSubtract (end, start, vec);
|
||||
len = VectorNormalize (vec);
|
||||
key = ent - cl_visedicts + 1;
|
||||
key = ent->keynum;
|
||||
|
||||
if (len) {
|
||||
f = R_AllocFire (key);
|
||||
|
@ -76,7 +76,7 @@ R_AddFire (vec3_t start, vec3_t end, entity_t *ent)
|
|||
f->decay = -1;
|
||||
f->color = r_firecolor;
|
||||
|
||||
dl = CL_AllocDlight (key);
|
||||
dl = CL_AllocDlight (-key);
|
||||
VectorCopy (end, dl->origin);
|
||||
dl->radius = 200;
|
||||
dl->die = cl.time + 0.5;
|
||||
|
|
|
@ -441,7 +441,7 @@ R_TeleportSplash (vec3_t org)
|
|||
}
|
||||
|
||||
void
|
||||
R_RocketTrail (vec3_t start, vec3_t end, int type, entity_t *ent)
|
||||
R_RocketTrail (int type, entity_t *ent)
|
||||
{
|
||||
vec3_t vec;
|
||||
float len;
|
||||
|
@ -452,12 +452,12 @@ R_RocketTrail (vec3_t start, vec3_t end, int type, entity_t *ent)
|
|||
byte palpha, pcolor;
|
||||
|
||||
if (type == 0)
|
||||
R_AddFire (start, end, ent);
|
||||
R_AddFire (ent->old_origin, ent->origin, ent);
|
||||
|
||||
if (!gl_particles->int_val)
|
||||
return;
|
||||
|
||||
VectorSubtract (end, start, vec);
|
||||
VectorSubtract (ent->origin, ent->old_origin, vec);
|
||||
len = VectorNormalize (vec);
|
||||
while (len > 0) {
|
||||
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);
|
||||
ptype = pt_smoke;
|
||||
pdie = cl.time + 1;
|
||||
VectorCopy (start, porg);
|
||||
VectorCopy (ent->old_origin, porg);
|
||||
break;
|
||||
case 2: // 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;
|
||||
for (j = 0; j < 3; j++) {
|
||||
pvel[j] = (rand () & 15) - 8;
|
||||
porg[j] = start[j] + ((rand () % 3) - 2);
|
||||
porg[j] = ent->old_origin[j] + ((rand () % 3) - 2);
|
||||
}
|
||||
ptype = pt_grav;
|
||||
palpha = 255;
|
||||
|
@ -506,7 +506,7 @@ R_RocketTrail (vec3_t start, vec3_t end, int type, entity_t *ent)
|
|||
pscale = lhrandom (1, 2);
|
||||
pdie = cl.time + 0.3;
|
||||
for (j = 0; j < 3; j++)
|
||||
porg[j] = start[j] + ((rand () & 15) - 8);
|
||||
porg[j] = ent->old_origin[j] + ((rand () & 15) - 8);
|
||||
break;
|
||||
case 3:
|
||||
case 5: // tracer
|
||||
|
@ -524,7 +524,7 @@ R_RocketTrail (vec3_t start, vec3_t end, int type, entity_t *ent)
|
|||
|
||||
tracercount++;
|
||||
|
||||
VectorCopy (start, porg);
|
||||
VectorCopy (ent->old_origin, porg);
|
||||
if (tracercount & 1) {
|
||||
pvel[0] = 30 * vec[1];
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -901,27 +901,27 @@ R_DrawEntitiesOnList (void)
|
|||
|
||||
// LordHavoc: split into 3 loops to simplify state changes
|
||||
for (i = 0; i < cl_numvisedicts; i++) {
|
||||
if (cl_visedicts[i].model->type != mod_brush)
|
||||
if (cl_visedicts[i]->model->type != mod_brush)
|
||||
continue;
|
||||
currententity = &cl_visedicts[i];
|
||||
currententity = cl_visedicts[i];
|
||||
modelalpha = currententity->alpha;
|
||||
|
||||
R_DrawBrushModel (currententity);
|
||||
}
|
||||
|
||||
for (i = 0; i < cl_numvisedicts; i++) {
|
||||
if (cl_visedicts[i].model->type != mod_alias)
|
||||
if (cl_visedicts[i]->model->type != mod_alias)
|
||||
continue;
|
||||
currententity = &cl_visedicts[i];
|
||||
currententity = cl_visedicts[i];
|
||||
modelalpha = currententity->alpha;
|
||||
|
||||
R_DrawAliasModel (currententity);
|
||||
}
|
||||
|
||||
for (i = 0; i < cl_numvisedicts; i++) {
|
||||
if (cl_visedicts[i].model->type != mod_sprite)
|
||||
if (cl_visedicts[i]->model->type != mod_sprite)
|
||||
continue;
|
||||
currententity = &cl_visedicts[i];
|
||||
currententity = cl_visedicts[i];
|
||||
modelalpha = currententity->alpha;
|
||||
|
||||
R_DrawSpriteModel (currententity);
|
||||
|
|
|
@ -259,7 +259,7 @@ R_StoreEfrags (efrag_t **ppefrag)
|
|||
|
||||
if ((pent->visframe != r_framecount) &&
|
||||
(cl_numvisedicts < MAX_VISEDICTS)) {
|
||||
cl_visedicts[cl_numvisedicts++] = *pent;
|
||||
cl_visedicts[cl_numvisedicts++] = pent;
|
||||
|
||||
// mark that we've recorded this entity for this frame
|
||||
pent->visframe = r_framecount;
|
||||
|
|
|
@ -594,7 +594,7 @@ R_DrawEntitiesOnList (void)
|
|||
return;
|
||||
|
||||
for (i = 0; i < cl_numvisedicts; i++) {
|
||||
currententity = &cl_visedicts[i];
|
||||
currententity = cl_visedicts[i];
|
||||
|
||||
switch (currententity->model->type) {
|
||||
case mod_sprite:
|
||||
|
@ -798,7 +798,7 @@ R_DrawBEntitiesOnList (void)
|
|||
r_dlightframecount = r_framecount;
|
||||
|
||||
for (i = 0; i < cl_numvisedicts; i++) {
|
||||
currententity = &cl_visedicts[i];
|
||||
currententity = cl_visedicts[i];
|
||||
|
||||
switch (currententity->model->type) {
|
||||
case mod_brush:
|
||||
|
|
|
@ -388,14 +388,14 @@ R_TeleportSplash (vec3_t org)
|
|||
}
|
||||
|
||||
void
|
||||
R_RocketTrail (vec3_t start, vec3_t end, int type, entity_t *ent)
|
||||
R_RocketTrail (int type, entity_t *ent)
|
||||
{
|
||||
vec3_t vec;
|
||||
float len;
|
||||
int j;
|
||||
particle_t *p;
|
||||
|
||||
VectorSubtract (end, start, vec);
|
||||
VectorSubtract (ent->origin, ent->old_origin, vec);
|
||||
len = VectorNormalize (vec);
|
||||
while (len > 0) {
|
||||
len -= 3;
|
||||
|
@ -414,31 +414,31 @@ R_RocketTrail (vec3_t start, vec3_t end, int type, entity_t *ent)
|
|||
p->type = pt_slowgrav;
|
||||
p->color = 67 + (rand () & 3);
|
||||
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;
|
||||
} else if (type == 2) { // blood
|
||||
p->type = pt_slowgrav;
|
||||
p->color = 67 + (rand () & 3);
|
||||
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
|
||||
p->color = 9 * 16 + 8 + (rand () & 3);
|
||||
p->type = pt_static;
|
||||
p->die = cl.time + 0.3;
|
||||
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
|
||||
p->ramp = (rand () & 3) + 2;
|
||||
p->color = ramp3[(int) p->ramp];
|
||||
p->type = pt_fire;
|
||||
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
|
||||
p->ramp = (rand () & 3);
|
||||
p->color = ramp3[(int) p->ramp];
|
||||
p->type = pt_fire;
|
||||
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
|
||||
static int tracercount;
|
||||
|
||||
|
@ -451,7 +451,7 @@ R_RocketTrail (vec3_t start, vec3_t end, int type, entity_t *ent)
|
|||
|
||||
tracercount++;
|
||||
|
||||
VectorCopy (start, p->org);
|
||||
VectorCopy (ent->old_origin, p->org);
|
||||
if (tracercount & 1) {
|
||||
p->vel[0] = 30 * vec[1];
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue