📄 cl_tent.c
字号:
break;
case TE_TRACKER_EXPLOSION:
MSG_ReadPos (&net_message, pos);
CL_ColorFlash (pos, 0, 150, -1, -1, -1);
CL_ColorExplosionParticles (pos, 0, 1);
// CL_Tracker_Explode (pos);
S_StartSound (pos, 0, 0, cl_sfx_disrexp, 1, ATTN_NORM, 0);
break;
case TE_TELEPORT_EFFECT:
case TE_DBALL_GOAL:
MSG_ReadPos (&net_message, pos);
CL_TeleportParticles (pos);
break;
case TE_WIDOWBEAMOUT:
CL_ParseWidow ();
break;
case TE_NUKEBLAST:
CL_ParseNuke ();
break;
case TE_WIDOWSPLASH:
MSG_ReadPos (&net_message, pos);
CL_WidowSplash (pos);
break;
//PGM
//==============
default:
Com_Error (ERR_DROP, "CL_ParseTEnt: bad type");
}
}
/*
=================
CL_AddBeams
=================
*/
void CL_AddBeams (void)
{
int i,j;
beam_t *b;
vec3_t dist, org;
float d;
entity_t ent;
float yaw, pitch;
float forward;
float len, steps;
float model_length;
// update beams
for (i=0, b=cl_beams ; i< 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.playernum+1) // entity 0 is the world
{
VectorCopy (cl.refdef.vieworg, b->start);
b->start[2] -= 22; // adjust for view height
}
VectorAdd (b->start, b->offset, org);
// calculate pitch and yaw
VectorSubtract (b->end, org, dist);
if (dist[1] == 0 && dist[0] == 0)
{
yaw = 0;
if (dist[2] > 0)
pitch = 90;
else
pitch = 270;
}
else
{
// PMM - fixed to correct for pitch of 0
if (dist[0])
yaw = (atan2(dist[1], dist[0]) * 180 / M_PI);
else if (dist[1] > 0)
yaw = 90;
else
yaw = 270;
if (yaw < 0)
yaw += 360;
forward = sqrt (dist[0]*dist[0] + dist[1]*dist[1]);
pitch = (atan2(dist[2], forward) * -180.0 / M_PI);
if (pitch < 0)
pitch += 360.0;
}
// add new entities for the beams
d = VectorNormalize(dist);
memset (&ent, 0, sizeof(ent));
if (b->model == cl_mod_lightning)
{
model_length = 35.0;
d-= 20.0; // correction so it doesn't end in middle of tesla
}
else
{
model_length = 30.0;
}
steps = ceil(d/model_length);
len = (d-model_length)/(steps-1);
// PMM - special case for lightning model .. if the real length is shorter than the model,
// flip it around & draw it from the end to the start. This prevents the model from going
// through the tesla mine (instead it goes through the target)
if ((b->model == cl_mod_lightning) && (d <= model_length))
{
// Com_Printf ("special case\n");
VectorCopy (b->end, ent.origin);
// offset to push beam outside of tesla model (negative because dist is from end to start
// for this beam)
// for (j=0 ; j<3 ; j++)
// ent.origin[j] -= dist[j]*10.0;
ent.model = b->model;
ent.flags = RF_FULLBRIGHT;
ent.angles[0] = pitch;
ent.angles[1] = yaw;
ent.angles[2] = rand()%360;
V_AddEntity (&ent);
return;
}
while (d > 0)
{
VectorCopy (org, ent.origin);
ent.model = b->model;
if (b->model == cl_mod_lightning)
{
ent.flags = RF_FULLBRIGHT;
ent.angles[0] = -pitch;
ent.angles[1] = yaw + 180.0;
ent.angles[2] = rand()%360;
}
else
{
ent.angles[0] = pitch;
ent.angles[1] = yaw;
ent.angles[2] = rand()%360;
}
// Com_Printf("B: %d -> %d\n", b->entity, b->dest_entity);
V_AddEntity (&ent);
for (j=0 ; j<3 ; j++)
org[j] += dist[j]*len;
d -= model_length;
}
}
}
/*
// Com_Printf ("Endpoint: %f %f %f\n", b->end[0], b->end[1], b->end[2]);
// Com_Printf ("Pred View Angles: %f %f %f\n", cl.predicted_angles[0], cl.predicted_angles[1], cl.predicted_angles[2]);
// Com_Printf ("Act View Angles: %f %f %f\n", cl.refdef.viewangles[0], cl.refdef.viewangles[1], cl.refdef.viewangles[2]);
// VectorCopy (cl.predicted_origin, b->start);
// b->start[2] += 22; // adjust for view height
// if (fabs(cl.refdef.vieworg[2] - b->start[2]) >= 10) {
// b->start[2] = cl.refdef.vieworg[2];
// }
// Com_Printf ("Time: %d %d %f\n", cl.time, cls.realtime, cls.frametime);
*/
extern cvar_t *hand;
/*
=================
ROGUE - draw player locked beams
CL_AddPlayerBeams
=================
*/
void CL_AddPlayerBeams (void)
{
int i,j;
beam_t *b;
vec3_t dist, org;
float d;
entity_t ent;
float yaw, pitch;
float forward;
float len, steps;
int framenum;
float model_length;
float hand_multiplier;
frame_t *oldframe;
player_state_t *ps, *ops;
//PMM
if (hand)
{
if (hand->value == 2)
hand_multiplier = 0;
else if (hand->value == 1)
hand_multiplier = -1;
else
hand_multiplier = 1;
}
else
{
hand_multiplier = 1;
}
//PMM
// update beams
for (i=0, b=cl_playerbeams ; i< MAX_BEAMS ; i++, b++)
{
vec3_t f,r,u;
if (!b->model || b->endtime < cl.time)
continue;
if(cl_mod_heatbeam && (b->model == cl_mod_heatbeam))
{
// if coming from the player, update the start position
if (b->entity == cl.playernum+1) // entity 0 is the world
{
// set up gun position
// code straight out of CL_AddViewWeapon
ps = &cl.frame.playerstate;
j = (cl.frame.serverframe - 1) & UPDATE_MASK;
oldframe = &cl.frames[j];
if (oldframe->serverframe != cl.frame.serverframe-1 || !oldframe->valid)
oldframe = &cl.frame; // previous frame was dropped or involid
ops = &oldframe->playerstate;
for (j=0 ; j<3 ; j++)
{
b->start[j] = cl.refdef.vieworg[j] + ops->gunoffset[j]
+ cl.lerpfrac * (ps->gunoffset[j] - ops->gunoffset[j]);
}
VectorMA (b->start, (hand_multiplier * b->offset[0]), cl.v_right, org);
VectorMA ( org, b->offset[1], cl.v_forward, org);
VectorMA ( org, b->offset[2], cl.v_up, org);
if ((hand) && (hand->value == 2)) {
VectorMA (org, -1, cl.v_up, org);
}
// FIXME - take these out when final
VectorCopy (cl.v_right, r);
VectorCopy (cl.v_forward, f);
VectorCopy (cl.v_up, u);
}
else
VectorCopy (b->start, org);
}
else
{
// if coming from the player, update the start position
if (b->entity == cl.playernum+1) // entity 0 is the world
{
VectorCopy (cl.refdef.vieworg, b->start);
b->start[2] -= 22; // adjust for view height
}
VectorAdd (b->start, b->offset, org);
}
// calculate pitch and yaw
VectorSubtract (b->end, org, dist);
//PMM
if(cl_mod_heatbeam && (b->model == cl_mod_heatbeam) && (b->entity == cl.playernum+1))
{
vec_t len;
len = VectorLength (dist);
VectorScale (f, len, dist);
VectorMA (dist, (hand_multiplier * b->offset[0]), r, dist);
VectorMA (dist, b->offset[1], f, dist);
VectorMA (dist, b->offset[2], u, dist);
if ((hand) && (hand->value == 2)) {
VectorMA (org, -1, cl.v_up, org);
}
}
//PMM
if (dist[1] == 0 && dist[0] == 0)
{
yaw = 0;
if (dist[2] > 0)
pitch = 90;
else
pitch = 270;
}
else
{
// PMM - fixed to correct for pitch of 0
if (dist[0])
yaw = (atan2(dist[1], dist[0]) * 180 / M_PI);
else if (dist[1] > 0)
yaw = 90;
else
yaw = 270;
if (yaw < 0)
yaw += 360;
forward = sqrt (dist[0]*dist[0] + dist[1]*dist[1]);
pitch = (atan2(dist[2], forward) * -180.0 / M_PI);
if (pitch < 0)
pitch += 360.0;
}
if (cl_mod_heatbeam && (b->model == cl_mod_heatbeam))
{
if (b->entity != cl.playernum+1)
{
framenum = 2;
// Com_Printf ("Third person\n");
ent.angles[0] = -pitch;
ent.angles[1] = yaw + 180.0;
ent.angles[2] = 0;
// Com_Printf ("%f %f - %f %f %f\n", -pitch, yaw+180.0, b->offset[0], b->offset[1], b->offset[2]);
AngleVectors(ent.angles, f, r, u);
// if it's a non-origin offset, it's a player, so use the hardcoded player offset
if (!VectorCompare (b->offset, vec3_origin))
{
VectorMA (org, -(b->offset[0])+1, r, org);
VectorMA (org, -(b->offset[1]), f, org);
VectorMA (org, -(b->offset[2])-10, u, org);
}
else
{
// if it's a monster, do the particle effect
CL_MonsterPlasma_Shell(b->start);
}
}
else
{
framenum = 1;
}
}
// if it's the heatbeam, draw the particle effect
if ((cl_mod_heatbeam && (b->model == cl_mod_heatbeam) && (b->entity == cl.playernum+1)))
{
CL_Heatbeam (org, dist);
}
// add new entities for the beams
d = VectorNormalize(dist);
memset (&ent, 0, sizeof(ent));
if (b->model == cl_mod_heatbeam)
{
model_length = 32.0;
}
else if (b->model == cl_mod_lightning)
{
model_length = 35.0;
d-= 20.0; // correction so it doesn't end in middle of tesla
}
else
{
model_length = 30.0;
}
steps = ceil(d/model_length);
len = (d-model_length)/(steps-1);
// PMM - special case for lightning model .. if the real length is shorter than the model,
// flip it around & draw it from the end to the start. This prevents the model from going
// through the tesla mine (instead it goes through the target)
if ((b->model == cl_mod_lightning) && (d <= model_length))
{
// Com_Printf ("special case\n");
VectorCopy (b->end, ent.origin);
// offset to push beam outside of tesla model (negative because dist is from end to start
// for this beam)
// for (j=0 ; j<3 ; j++)
// ent.origin[j] -= dist[j]*10.0;
ent.model = b->model;
ent.flags = RF_FULLBRIGHT;
ent.angles[0] = pitch;
ent.angles[1] = yaw;
ent.angles[2] = rand()%360;
V_AddEntity (&ent);
return;
}
while (d > 0)
{
VectorCopy (org, ent.origin);
ent.model = b->model;
if(cl_mod_heatbeam && (b->model == cl_mod_heatbeam))
{
// ent.flags = RF_FULLBRIGHT|RF_TRANSLUCENT;
// ent.alpha = 0.3;
ent.flags = RF_FULLBRIGHT;
ent.angles[0] = -pitch;
ent.angles[1] = yaw + 180.0;
ent.angles[2] = (cl.time) % 360;
// ent.angles[2] = rand()%360;
ent.frame = framenum;
}
else if (b->model == cl_mod_lightning)
{
ent.flags = RF_FULLBRIGHT;
ent.angles[0] = -pitch;
ent.angles[1] = yaw + 180.0;
ent.angles[2] = rand()%360;
}
else
{
ent.angles[0] = pitch;
ent.angles[1] = yaw;
ent.angles[2] = rand()%360;
}
// Com_Printf("B: %d -> %d\n", b->entity, b->dest_entity);
V_AddEntity (&ent);
for (j=0 ; j<3 ; j++)
org[j] += dist[j]*len;
d -= model_length;
}
}
}
/*
=================
CL_AddExplosions
=================
*/
void CL_AddExplosions (void)
{
entity_t *ent;
int i;
explosion_t *ex;
float frac;
int f;
memset (&ent, 0, sizeof(ent));
for (i=0, ex=cl_explosions ; i< MAX_EXPLOSIONS ; i++, ex++)
{
if (ex->type == ex_free)
continue;
frac = (cl.time - ex->start)/100.0;
f = floor(frac);
ent = &ex->ent;
switch (ex->type)
{
case ex_mflash:
if (f >= ex->frames-1)
ex->type = ex_free;
break;
case ex_misc:
if (f >= ex->frames-1)
{
ex->type = ex_free;
break;
}
ent->alpha = 1.0 - frac/(ex->frames-1);
break;
case ex_flash:
if (f >= 1)
{
ex->type = ex_free;
break;
}
ent->alpha = 1.0;
break;
case ex_poly:
if (f >= ex->frames-1)
{
ex->type = ex_free;
break;
}
ent->alpha = (16.0 - (float)f)/16.0;
if (f < 10)
{
ent->skinnum = (f>>1);
if (ent->skinnum < 0)
ent->skinnum = 0;
}
else
{
ent->flags |= RF_TRANSLUCENT;
if (f < 13)
ent->skinnum = 5;
else
ent->skinnum = 6;
}
break;
case ex_poly2:
if (f >= ex->frames-1)
{
ex->type = ex_free;
break;
}
ent->alpha = (5.0 - (float)f)/5.0;
ent->skinnum = 0;
ent->flags |= RF_TRANSLUCENT;
break;
}
if (ex->type == ex_free)
continue;
if (ex->light)
{
V_AddLight (ent->origin, ex->light*ent->alpha,
ex->lightcolor[0], ex->lightcolor[1], ex->lightcolor[2]);
}
VectorCopy (ent->origin, ent->oldorigin);
if (f < 0)
f = 0;
ent->frame = ex->baseframe + f + 1;
ent->oldframe = ex->baseframe + f;
ent->backlerp = 1.0 - cl.lerpfrac;
V_AddEntity (ent);
}
}
/*
=================
CL_AddLasers
=================
*/
void CL_AddLasers (void)
{
laser_t *l;
int i;
for (i=0, l=cl_lasers ; i< MAX_LASERS ; i++, l++)
{
if (l->endtime >= cl.time)
V_AddEntity (&l->ent);
}
}
/* PMM - CL_Sustains */
void CL_ProcessSustain ()
{
cl_sustain_t *s;
int i;
for (i=0, s=cl_sustains; i< MAX_SUSTAINS; i++, s++)
{
if (s->id)
if ((s->endtime >= cl.time) && (cl.time >= s->nextthink))
{
// Com_Printf ("think %d %d %d\n", cl.time, s->nextthink, s->thinkinterval);
s->think (s);
}
else if (s->endtime < cl.time)
s->id = 0;
}
}
/*
=================
CL_AddTEnts
=================
*/
void CL_AddTEnts (void)
{
CL_AddBeams ();
// PMM - draw plasma beams
CL_AddPlayerBeams ();
CL_AddExplosions ();
CL_AddLasers ();
// PMM - set up sustain
CL_ProcessSustain();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -