📄 cl_tent.c
字号:
/*
Copyright (C) 1997-2001 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// cl_tent.c -- client side temporary entities
#include "client.h"
typedef enum
{
ex_free, ex_explosion, ex_misc, ex_flash, ex_mflash, ex_poly, ex_poly2
} exptype_t;
typedef struct
{
exptype_t type;
entity_t ent;
int frames;
float light;
vec3_t lightcolor;
float start;
int baseframe;
} explosion_t;
#define MAX_EXPLOSIONS 32
explosion_t cl_explosions[MAX_EXPLOSIONS];
#define MAX_BEAMS 32
typedef struct
{
int entity;
int dest_entity;
struct model_s *model;
int endtime;
vec3_t offset;
vec3_t start, end;
} beam_t;
beam_t cl_beams[MAX_BEAMS];
//PMM - added this for player-linked beams. Currently only used by the plasma beam
beam_t cl_playerbeams[MAX_BEAMS];
#define MAX_LASERS 32
typedef struct
{
entity_t ent;
int endtime;
} laser_t;
laser_t cl_lasers[MAX_LASERS];
//ROGUE
cl_sustain_t cl_sustains[MAX_SUSTAINS];
//ROGUE
//PGM
extern void CL_TeleportParticles (vec3_t org);
//PGM
void CL_BlasterParticles (vec3_t org, vec3_t dir);
void CL_ExplosionParticles (vec3_t org);
void CL_BFGExplosionParticles (vec3_t org);
// RAFAEL
void CL_BlueBlasterParticles (vec3_t org, vec3_t dir);
struct sfx_s *cl_sfx_ric1;
struct sfx_s *cl_sfx_ric2;
struct sfx_s *cl_sfx_ric3;
struct sfx_s *cl_sfx_lashit;
struct sfx_s *cl_sfx_spark5;
struct sfx_s *cl_sfx_spark6;
struct sfx_s *cl_sfx_spark7;
struct sfx_s *cl_sfx_railg;
struct sfx_s *cl_sfx_rockexp;
struct sfx_s *cl_sfx_grenexp;
struct sfx_s *cl_sfx_watrexp;
// RAFAEL
struct sfx_s *cl_sfx_plasexp;
struct sfx_s *cl_sfx_footsteps[4];
struct model_s *cl_mod_explode;
struct model_s *cl_mod_smoke;
struct model_s *cl_mod_flash;
struct model_s *cl_mod_parasite_segment;
struct model_s *cl_mod_grapple_cable;
struct model_s *cl_mod_parasite_tip;
struct model_s *cl_mod_explo4;
struct model_s *cl_mod_bfg_explo;
struct model_s *cl_mod_powerscreen;
// RAFAEL
struct model_s *cl_mod_plasmaexplo;
//ROGUE
struct sfx_s *cl_sfx_lightning;
struct sfx_s *cl_sfx_disrexp;
struct model_s *cl_mod_lightning;
struct model_s *cl_mod_heatbeam;
struct model_s *cl_mod_monster_heatbeam;
struct model_s *cl_mod_explo4_big;
//ROGUE
/*
=================
CL_RegisterTEntSounds
=================
*/
void CL_RegisterTEntSounds (void)
{
int i;
char name[MAX_QPATH];
// PMM - version stuff
// Com_Printf ("%s\n", ROGUE_VERSION_STRING);
// PMM
cl_sfx_ric1 = S_RegisterSound ("world/ric1.wav");
cl_sfx_ric2 = S_RegisterSound ("world/ric2.wav");
cl_sfx_ric3 = S_RegisterSound ("world/ric3.wav");
cl_sfx_lashit = S_RegisterSound("weapons/lashit.wav");
cl_sfx_spark5 = S_RegisterSound ("world/spark5.wav");
cl_sfx_spark6 = S_RegisterSound ("world/spark6.wav");
cl_sfx_spark7 = S_RegisterSound ("world/spark7.wav");
cl_sfx_railg = S_RegisterSound ("weapons/railgf1a.wav");
cl_sfx_rockexp = S_RegisterSound ("weapons/rocklx1a.wav");
cl_sfx_grenexp = S_RegisterSound ("weapons/grenlx1a.wav");
cl_sfx_watrexp = S_RegisterSound ("weapons/xpld_wat.wav");
// RAFAEL
// cl_sfx_plasexp = S_RegisterSound ("weapons/plasexpl.wav");
S_RegisterSound ("player/land1.wav");
S_RegisterSound ("player/fall2.wav");
S_RegisterSound ("player/fall1.wav");
for (i=0 ; i<4 ; i++)
{
Com_sprintf (name, sizeof(name), "player/step%i.wav", i+1);
cl_sfx_footsteps[i] = S_RegisterSound (name);
}
//PGM
cl_sfx_lightning = S_RegisterSound ("weapons/tesla.wav");
cl_sfx_disrexp = S_RegisterSound ("weapons/disrupthit.wav");
// version stuff
// sprintf (name, "weapons/sound%d.wav", ROGUE_VERSION_ID);
// if (name[0] == 'w')
// name[0] = 'W';
//PGM
}
/*
=================
CL_RegisterTEntModels
=================
*/
void CL_RegisterTEntModels (void)
{
cl_mod_explode = re.RegisterModel ("models/objects/explode/tris.md2");
cl_mod_smoke = re.RegisterModel ("models/objects/smoke/tris.md2");
cl_mod_flash = re.RegisterModel ("models/objects/flash/tris.md2");
cl_mod_parasite_segment = re.RegisterModel ("models/monsters/parasite/segment/tris.md2");
cl_mod_grapple_cable = re.RegisterModel ("models/ctf/segment/tris.md2");
cl_mod_parasite_tip = re.RegisterModel ("models/monsters/parasite/tip/tris.md2");
cl_mod_explo4 = re.RegisterModel ("models/objects/r_explode/tris.md2");
cl_mod_bfg_explo = re.RegisterModel ("sprites/s_bfg2.sp2");
cl_mod_powerscreen = re.RegisterModel ("models/items/armor/effect/tris.md2");
re.RegisterModel ("models/objects/laser/tris.md2");
re.RegisterModel ("models/objects/grenade2/tris.md2");
re.RegisterModel ("models/weapons/v_machn/tris.md2");
re.RegisterModel ("models/weapons/v_handgr/tris.md2");
re.RegisterModel ("models/weapons/v_shotg2/tris.md2");
re.RegisterModel ("models/objects/gibs/bone/tris.md2");
re.RegisterModel ("models/objects/gibs/sm_meat/tris.md2");
re.RegisterModel ("models/objects/gibs/bone2/tris.md2");
// RAFAEL
// re.RegisterModel ("models/objects/blaser/tris.md2");
re.RegisterPic ("w_machinegun");
re.RegisterPic ("a_bullets");
re.RegisterPic ("i_health");
re.RegisterPic ("a_grenades");
//ROGUE
cl_mod_explo4_big = re.RegisterModel ("models/objects/r_explode2/tris.md2");
cl_mod_lightning = re.RegisterModel ("models/proj/lightning/tris.md2");
cl_mod_heatbeam = re.RegisterModel ("models/proj/beam/tris.md2");
cl_mod_monster_heatbeam = re.RegisterModel ("models/proj/widowbeam/tris.md2");
//ROGUE
}
/*
=================
CL_ClearTEnts
=================
*/
void CL_ClearTEnts (void)
{
memset (cl_beams, 0, sizeof(cl_beams));
memset (cl_explosions, 0, sizeof(cl_explosions));
memset (cl_lasers, 0, sizeof(cl_lasers));
//ROGUE
memset (cl_playerbeams, 0, sizeof(cl_playerbeams));
memset (cl_sustains, 0, sizeof(cl_sustains));
//ROGUE
}
/*
=================
CL_AllocExplosion
=================
*/
explosion_t *CL_AllocExplosion (void)
{
int i;
int time;
int index;
for (i=0 ; i<MAX_EXPLOSIONS ; i++)
{
if (cl_explosions[i].type == ex_free)
{
memset (&cl_explosions[i], 0, sizeof (cl_explosions[i]));
return &cl_explosions[i];
}
}
// find the oldest explosion
time = cl.time;
index = 0;
for (i=0 ; i<MAX_EXPLOSIONS ; i++)
if (cl_explosions[i].start < time)
{
time = cl_explosions[i].start;
index = i;
}
memset (&cl_explosions[index], 0, sizeof (cl_explosions[index]));
return &cl_explosions[index];
}
/*
=================
CL_SmokeAndFlash
=================
*/
void CL_SmokeAndFlash(vec3_t origin)
{
explosion_t *ex;
ex = CL_AllocExplosion ();
VectorCopy (origin, ex->ent.origin);
ex->type = ex_misc;
ex->frames = 4;
ex->ent.flags = RF_TRANSLUCENT;
ex->start = cl.frame.servertime - 100;
ex->ent.model = cl_mod_smoke;
ex = CL_AllocExplosion ();
VectorCopy (origin, ex->ent.origin);
ex->type = ex_flash;
ex->ent.flags = RF_FULLBRIGHT;
ex->frames = 2;
ex->start = cl.frame.servertime - 100;
ex->ent.model = cl_mod_flash;
}
/*
=================
CL_ParseParticles
=================
*/
void CL_ParseParticles (void)
{
int color, count;
vec3_t pos, dir;
MSG_ReadPos (&net_message, pos);
MSG_ReadDir (&net_message, dir);
color = MSG_ReadByte (&net_message);
count = MSG_ReadByte (&net_message);
CL_ParticleEffect (pos, dir, color, count);
}
/*
=================
CL_ParseBeam
=================
*/
int CL_ParseBeam (struct model_s *model)
{
int ent;
vec3_t start, end;
beam_t *b;
int i;
ent = MSG_ReadShort (&net_message);
MSG_ReadPos (&net_message, start);
MSG_ReadPos (&net_message, end);
// override any beam with the same entity
for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++)
if (b->entity == ent)
{
b->entity = ent;
b->model = model;
b->endtime = cl.time + 200;
VectorCopy (start, b->start);
VectorCopy (end, b->end);
VectorClear (b->offset);
return ent;
}
// find a free beam
for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++)
{
if (!b->model || b->endtime < cl.time)
{
b->entity = ent;
b->model = model;
b->endtime = cl.time + 200;
VectorCopy (start, b->start);
VectorCopy (end, b->end);
VectorClear (b->offset);
return ent;
}
}
Com_Printf ("beam list overflow!\n");
return ent;
}
/*
=================
CL_ParseBeam2
=================
*/
int CL_ParseBeam2 (struct model_s *model)
{
int ent;
vec3_t start, end, offset;
beam_t *b;
int i;
ent = MSG_ReadShort (&net_message);
MSG_ReadPos (&net_message, start);
MSG_ReadPos (&net_message, end);
MSG_ReadPos (&net_message, offset);
// Com_Printf ("end- %f %f %f\n", end[0], end[1], end[2]);
// override any beam with the same entity
for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++)
if (b->entity == ent)
{
b->entity = ent;
b->model = model;
b->endtime = cl.time + 200;
VectorCopy (start, b->start);
VectorCopy (end, b->end);
VectorCopy (offset, b->offset);
return ent;
}
// find a free beam
for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++)
{
if (!b->model || b->endtime < cl.time)
{
b->entity = ent;
b->model = model;
b->endtime = cl.time + 200;
VectorCopy (start, b->start);
VectorCopy (end, b->end);
VectorCopy (offset, b->offset);
return ent;
}
}
Com_Printf ("beam list overflow!\n");
return ent;
}
// ROGUE
/*
=================
CL_ParsePlayerBeam
- adds to the cl_playerbeam array instead of the cl_beams array
=================
*/
int CL_ParsePlayerBeam (struct model_s *model)
{
int ent;
vec3_t start, end, offset;
beam_t *b;
int i;
ent = MSG_ReadShort (&net_message);
MSG_ReadPos (&net_message, start);
MSG_ReadPos (&net_message, end);
// PMM - network optimization
if (model == cl_mod_heatbeam)
VectorSet(offset, 2, 7, -3);
else if (model == cl_mod_monster_heatbeam)
{
model = cl_mod_heatbeam;
VectorSet(offset, 0, 0, 0);
}
else
MSG_ReadPos (&net_message, offset);
// Com_Printf ("end- %f %f %f\n", end[0], end[1], end[2]);
// override any beam with the same entity
// PMM - For player beams, we only want one per player (entity) so..
for (i=0, b=cl_playerbeams ; i< MAX_BEAMS ; i++, b++)
{
if (b->entity == ent)
{
b->entity = ent;
b->model = model;
b->endtime = cl.time + 200;
VectorCopy (start, b->start);
VectorCopy (end, b->end);
VectorCopy (offset, b->offset);
return ent;
}
}
// find a free beam
for (i=0, b=cl_playerbeams ; i< MAX_BEAMS ; i++, b++)
{
if (!b->model || b->endtime < cl.time)
{
b->entity = ent;
b->model = model;
b->endtime = cl.time + 100; // PMM - this needs to be 100 to prevent multiple heatbeams
VectorCopy (start, b->start);
VectorCopy (end, b->end);
VectorCopy (offset, b->offset);
return ent;
}
}
Com_Printf ("beam list overflow!\n");
return ent;
}
//rogue
/*
=================
CL_ParseLightning
=================
*/
int CL_ParseLightning (struct model_s *model)
{
int srcEnt, destEnt;
vec3_t start, end;
beam_t *b;
int i;
srcEnt = MSG_ReadShort (&net_message);
destEnt = MSG_ReadShort (&net_message);
MSG_ReadPos (&net_message, start);
MSG_ReadPos (&net_message, end);
// override any beam with the same source AND destination entities
for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++)
if (b->entity == srcEnt && b->dest_entity == destEnt)
{
// Com_Printf("%d: OVERRIDE %d -> %d\n", cl.time, srcEnt, destEnt);
b->entity = srcEnt;
b->dest_entity = destEnt;
b->model = model;
b->endtime = cl.time + 200;
VectorCopy (start, b->start);
VectorCopy (end, b->end);
VectorClear (b->offset);
return srcEnt;
}
// find a free beam
for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++)
{
if (!b->model || b->endtime < cl.time)
{
// Com_Printf("%d: NORMAL %d -> %d\n", cl.time, srcEnt, destEnt);
b->entity = srcEnt;
b->dest_entity = destEnt;
b->model = model;
b->endtime = cl.time + 200;
VectorCopy (start, b->start);
VectorCopy (end, b->end);
VectorClear (b->offset);
return srcEnt;
}
}
Com_Printf ("beam list overflow!\n");
return srcEnt;
}
/*
=================
CL_ParseLaser
=================
*/
void CL_ParseLaser (int colors)
{
vec3_t start;
vec3_t end;
laser_t *l;
int i;
MSG_ReadPos (&net_message, start);
MSG_ReadPos (&net_message, end);
for (i=0, l=cl_lasers ; i< MAX_LASERS ; i++, l++)
{
if (l->endtime < cl.time)
{
l->ent.flags = RF_TRANSLUCENT | RF_BEAM;
VectorCopy (start, l->ent.origin);
VectorCopy (end, l->ent.oldorigin);
l->ent.alpha = 0.30;
l->ent.skinnum = (colors >> ((rand() % 4)*8)) & 0xff;
l->ent.model = NULL;
l->ent.frame = 4;
l->endtime = cl.time + 100;
return;
}
}
}
//=============
//ROGUE
void CL_ParseSteam (void)
{
vec3_t pos, dir;
int id, i;
int r;
int cnt;
int color;
int magnitude;
cl_sustain_t *s, *free_sustain;
id = MSG_ReadShort (&net_message); // an id of -1 is an instant effect
if (id != -1) // sustains
{
// Com_Printf ("Sustain effect id %d\n", id);
free_sustain = NULL;
for (i=0, s=cl_sustains; i<MAX_SUSTAINS; i++, s++)
{
if (s->id == 0)
{
free_sustain = s;
break;
}
}
if (free_sustain)
{
s->id = id;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -