📄 cl_tent.pas
字号:
// cl_tent.c -- client side temporary entities
unit cl_tent;
interface
uses
client,
ref,
vid_dll,
Windows,
Math,
Common,
g_local,
q_shared,
snd_dma,
snd_loc;
type
ExpType_t = (ex_free, ex_explosion, ex_misc, ex_flash, ex_mflash, ex_poly, ex_poly2);
explosion_p = ^explosion_t;
explosion_t = record
type_: ExpType_t;
ent: Entity_t;
Frames: Integer;
Light: Single;
LightColor: vec3_t;
Start: Single;
BaseFrame: Integer;
end;
const
MAX_EXPLOSIONS = 32;
var
cl_explosions: array[0..MAX_EXPLOSIONS - 1] of explosion_t;
const
MAX_BEAMS = 32;
type
beam_p = ^beam_t;
beam_t = record
Entity, Dest_Entity: Integer;
Model: Model_p;
EndTime: Integer;
Offset, Start, End_: vec3_t;
end;
var
cl_beams, cl_playerbeams: array[0..MAX_BEAMS - 1] of beam_t;
//PMM - added this [cl_playerbeams] for player-linked beams. Currently only used by the plasma beam
const
MAX_LASERS = 32;
type
laser_p = ^laser_t;
laser_t = record
Ent: entity_t;
EndTime: Integer;
end;
var
cl_lasers: array[0..MAX_LASERS - 1] of laser_t;
//ROGUE
cl_sustains: array[0..MAX_SUSTAINS - 1] of cl_sustain_t;
//ROGUE
var
cl_sfx_ric1, cl_sfx_ric2, cl_sfx_ric3,
cl_sfx_lashit,
cl_sfx_spark5, cl_sfx_spark6, cl_sfx_spark7,
cl_sfx_railg,
cl_sfx_rockexp, cl_sfx_grenexp, cl_sfx_watrexp,
// RAFAEL
cl_sfx_plasexp: sfx_p;
cl_sfx_footsteps: array[0..3] of sfx_p;
cl_mod_explode, cl_mod_smoke, cl_mod_flash,
cl_mod_parasite_segment,
cl_mod_grapple_cable,
cl_mod_parasite_tip,
cl_mod_explo4, cl_mod_bfg_explo,
cl_mod_powerscreen,
// RAFAEL
cl_mod_plasmaexplo: model_p;
//ROGUE
cl_sfx_lightning, cl_sfx_disrexp: sfx_p;
cl_mod_lightning, cl_mod_heatbeam,
cl_mod_monster_heatbeam,
cl_mod_explo4_big: model_p;
//ROGUE
procedure CL_RegisterTEntModels;
procedure CL_AddTEnts;
procedure CL_ClearTEnts;
procedure CL_SmokeAndFlash(Origin: vec3_t);
procedure CL_RegisterTEntSounds;
procedure CL_ParseTEnt;
implementation
uses
net_chan,
cl_fx,
cl_view,
cl_newfx,
cl_main;
{
=========
CL_RegisterTEntSounds
=========
}
procedure CL_RegisterTEntSounds;
var
i: Integer;
Name: array[0..MAX_QPATH - 1] of char;
begin
// PMM - version stuff
//Com_Printf ('%s'#10, 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 to 3 do
begin
Com_sprintf(name, sizeof(name), 'player/step%d.wav', [i + 1]);
cl_sfx_footsteps[i] := S_RegisterSound(name);
end;
//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
end;
{
=========
CL_RegisterTEntModels
=========
}
procedure CL_RegisterTEntModels;
begin
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
end;
{
=========
CL_ClearTEnts
=========
}
procedure CL_ClearTEnts;
begin
ZeroMemory(@cl_beams, sizeof(cl_beams));
ZeroMemory(@cl_explosions, sizeof(cl_explosions));
ZeroMemory(@cl_lasers, sizeof(cl_lasers));
//ROGUE
ZeroMemory(@cl_playerbeams, sizeof(cl_playerbeams));
ZeroMemory(@cl_sustains, sizeof(cl_sustains));
//ROGUE}
end;
{
=========
CL_AllocExplosion
=========
}
function CL_AllocExplosion: Explosion_p;
var
i, time, index: Integer;
begin
for i := 0 to MAX_EXPLOSIONS - 1 do
begin
if (cl_explosions[i].type_ = ex_free) then
begin
FillChar(cl_explosions[i], SizeOf(cl_explosions[i]), 0);
Result := @cl_explosions[i];
Exit;
end;
end;
// find the oldest explosion
time := cl.time;
index := 0;
for i := 0 to MAX_EXPLOSIONS - 1 do
if (cl_explosions[i].start < time) then
begin
time := Round(cl_explosions[i].start);
index := i;
end;
FillChar(cl_explosions[index], SizeOf(cl_explosions[index]), 0);
Result := @cl_explosions[index];
end;
{
=========
CL_SmokeAndFlash
=========
}
procedure CL_SmokeAndFlash(Origin: vec3_t);
var
ex: Explosion_p;
begin
ex := CL_AllocExplosion();
VectorCopy(origin, vec3_t(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, vec3_t(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;
end;
{
=========
CL_ParseParticles
=========
}
procedure CL_ParseParticles;
var
Color, Count: Integer;
Pos, Dir: vec3_t;
begin
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);
end;
{
=========
CL_ParseBeam / CL_ParseBeam2
=========
}
function CL_ParseBeam(Model: Model_p): Integer;
var
ent: Integer;
start, end_: vec3_t;
b : beam_p;
i : Integer;
begin
ent := MSG_ReadShort (net_message);
MSG_ReadPos (net_message, start);
MSG_ReadPos (net_message, end_);
// override any beam with the same entity
b := @cl_beams;
for i := 0 to MAX_BEAMS-1 do begin
if (b^.entity = ent) then begin
b^.entity := ent;
b^.model := model;
b^.endtime := cl.time + 200;
VectorCopy (start, b^.start);
VectorCopy (end_, b^.end_);
VectorClear (b^.offset);
Result := ent;
Exit;
end;
Inc(b);
end;
// find a free beam
b := @cl_beams;
for i := 0 to MAX_BEAMS-1 do begin
if (b^.model = nil) or (b^.endtime < cl.time) then begin
b^.entity := ent;
b^.model := model;
b^.endtime := cl.time + 200;
VectorCopy (start, b^.start);
VectorCopy (end_, b^.end_);
VectorClear (b^.offset);
Result := ent;
Exit;
end;
Inc(b);
end;
Com_Printf ('beam list overflow!'#10);
Result := ent;
end;
function CL_ParseBeam2(Model: Model_p): Integer;
var
ent: Integer;
start, end_, offset: vec3_t;
b : beam_p;
i : Integer;
begin
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
b := @cl_beams;
for i := 0 to MAX_BEAMS-1 do begin
if (b^.entity = ent) then begin
b^.entity := ent;
b^.model := model;
b^.endtime := cl.time + 200;
VectorCopy (start, b^.start);
VectorCopy (end_, b^.end_);
VectorCopy (offset, b^.offset);
Result := ent;
Exit;
end;
Inc(b);
end;
// find a free beam
b := @cl_beams;
for i := 0 to MAX_BEAMS-1 do begin
if (b^.model = nil) or (b^.endtime < cl.time) then begin
b^.entity := ent;
b^.model := model;
b^.endtime := cl.time + 200;
VectorCopy (start, b^.start);
VectorCopy (end_, b^.end_);
VectorCopy (offset, b^.offset);
Result := ent;
Exit;
end;
Inc(b);
end;
Com_Printf ('beam list overflow!'#10);
Result := ent;
end;
// ROGUE
{
=========
CL_ParsePlayerBeam
- adds to the cl_playerbeam array instead of the cl_beams array
=========
}
function CL_ParsePlayerBeam(Model: Model_p): Integer;
var
Ent: Integer;
Start, End_, Offset: Vec3_t;
b: Beam_p;
I: Integer;
begin
ent := MSG_ReadShort(net_message);
MSG_ReadPos(net_message, start);
MSG_ReadPos(net_message, end_);
// PMM - network optimization
if (model = cl_mod_heatbeam) then
VectorSet(offset, 2, 7, -3)
else if (model = cl_mod_monster_heatbeam) then
begin
model := cl_mod_heatbeam;
VectorSet(offset, 0, 0, 0);
end
else
MSG_ReadPos(net_message, offset);
// Com_Printf ('end- %f %f %f'#10, 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..
b := @cl_playerbeams;
for i := 0 to MAX_BEAMS - 1 do
begin
if (b^.entity = ent) then
begin
b^.entity := ent;
b^.model := model;
b^.endtime := cl.time + 200;
VectorCopy (start, b^.start);
VectorCopy (end_, b^.end_);
VectorCopy (offset, b^.offset);
Result := ent;
exit;
end;
Inc(b);
end;
// find a free beam
b := @cl_playerbeams;
for i := 0 to MAX_BEAMS - 1 do
begin
if (b^.model = nil) or (b^.endtime < cl.time) then
begin
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);
Result := ent;
exit;
end;
Inc(b);
end;
Com_Printf('beam list overflow!'#10);
result := ent;
end;
//rogue
{
=========
CL_ParseLightning
=========
}
function CL_ParseLightning(Model: Model_p): Integer;
var
srcEnt, destEnt, i: Integer;
Start, End_: vec3_t;
b: Beam_p;
begin
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
b := @cl_beams;
for i := 0 to MAX_BEAMS - 1 do
begin
if (b^.entity = srcEnt) and (b^.dest_entity = destEnt) then
begin
// Com_Printf('%d: OVERRIDE %d ^. %d'#10, 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);
result := srcEnt;
exit;
end;
Inc(b);
end;
// find a free beam
b := @cl_beams;
for i := 0 to MAX_BEAMS - 1 do
begin
if (b^.model = nil) or (b^.endtime < cl.time) then
begin
// Com_Printf('%d: NORMAL %d ^. %d'#10, 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);
result := srcEnt;
exit;
end;
Inc(b);
end;
Com_Printf('beam list overflow!'#10);
result := srcEnt;
end;
{
=========
CL_ParseLaser
=========
}
procedure CL_ParseLaser(Colors: Integer);
var
Start, End_: vec3_t;
l: laser_p;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -