📄 cl_newfx.pas
字号:
(*
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_newfx.c -- MORE entity effects parsing and management
unit cl_newfx;
interface
uses
q_shared,
ref,
Client;
procedure CL_Flashlight(ent: Integer; const pos: vec3_t);
procedure CL_ColorFlash(const pos: vec3_t; ent, intensity: Integer; r, g, b: Single);
procedure CL_DebugTrail(const start, end_: vec3_t);
procedure CL_SmokeTrail(const start, end_: vec3_t; colorStart, colorRun, spacing: Integer);
procedure CL_ForceWall(const start, end_: vec3_t; color: Integer);
procedure CL_FlameEffects(ent: centity_p; const origin: vec3_t);
procedure CL_GenericParticleEffect(const org, dir: vec3_t; color, count, numcolors, dirspread: Integer; alphavel: Single);
procedure CL_BubbleTrail2(const start, end_: vec3_t; dist: Integer);
procedure CL_Heatbeam(const start, forward_: vec3_t);
procedure CL_ParticleSteamEffect(var org, dir: vec3_t; color, count, magnitude: Integer);
procedure CL_ParticleSteamEffect2(self: cl_sustain_p); cdecl;
procedure CL_TrackerTrail(const start, end_: vec3_t; particleColor: Integer);
procedure CL_Tracker_Shell(const origin: vec3_t);
procedure CL_MonsterPlasma_Shell(const origin: vec3_t);
procedure CL_Widowbeamout(self: cl_sustain_p); cdecl;
procedure CL_Nukeblast(self: cl_sustain_p); cdecl;
procedure CL_WidowSplash(const org: vec3_t);
procedure CL_Tracker_Explode(const origin: vec3_t);
procedure CL_TagTrail(const start, end_: vec3_t; color: Single);
procedure CL_ColorExplosionParticles(const org: vec3_t; color, run: Integer);
procedure CL_ParticleSmokeEffect(var org, dir: vec3_t; color, count, magnitude: Integer);
procedure CL_BlasterParticles2(const org, dir: vec3_t; color: Cardinal);
procedure CL_BlasterTrail2(const start, end_: vec3_t);
implementation
uses
cl_fx,
cl_main,
Common,
Math;
function fmod(a, b: single): single;
begin
result := a - (b * int(a / b));
end;
(*
======
vectoangles2 - this is duplicated in the game DLL, but I need it here.
======
*)
procedure vectoangles2(var value1, angles: vec3_t);
var
forward_: Single;
yaw_, pitch_: Single;
begin
if (value1[1] = 0.0) and (value1[0] = 0.0) then
begin
yaw_ := 0.0;
if (value1[2] > 0.0) then
pitch_ := 90.0
else
pitch_ := 270.0;
end
else
begin
// PMM - fixed to correct for pitch of 0
if (value1[0] <> 0.0) then
yaw_ := (ArcTan2(value1[1], value1[0]) * 180.0 / M_PI)
else if (value1[1] > 0.0) then
yaw_ := 90
else
yaw_ := 270;
if (yaw_ < 0.0) then
yaw_ := yaw_ + 360.0;
forward_ := Sqrt(value1[0] * value1[0] + value1[1] * value1[1]);
pitch_ := (ArcTan2(value1[2], forward_) * 180.0 / M_PI);
if (pitch_ < 0.0) then
pitch_ := pitch_ + 360;
end;
angles[PITCH] := -pitch_;
angles[YAW] := yaw_;
angles[ROLL] := 0.0;
end;
//=============
//=============
procedure CL_Flashlight(ent: Integer; const pos: vec3_t);
var
dl: cdlight_p;
begin
dl := CL_AllocDlight(ent);
VectorCopy(pos, dl^.origin);
dl^.radius := 400;
dl^.minlight := 250;
dl^.die := cl.time + 100;
dl^.color[0] := 1;
dl^.color[1] := 1;
dl^.color[2] := 1;
end;
(*
======
CL_ColorFlash - flash of light
======
*)
procedure CL_ColorFlash(const pos: vec3_t; ent, intensity: Integer; r, g, b: Single);
var
dl: cdlight_p;
begin
if ((vidref_val = VIDREF_SOFT) and ((r < 0) or (g < 0) or (b < 0))) then
begin
intensity := -intensity;
r := -r;
g := -g;
b := -b;
end;
dl := CL_AllocDlight(ent);
VectorCopy(pos, dl^.origin);
dl^.radius := intensity;
dl^.minlight := 250;
dl^.die := cl.time + 100;
dl^.color[0] := r;
dl^.color[1] := g;
dl^.color[2] := b;
end;
(*
======
CL_DebugTrail
======
*)
procedure CL_DebugTrail(const start, end_: vec3_t);
var
move, vec: vec3_t;
len: Single;
// j: Integer;
p: cparticle_p;
dec: Single;
right, up: vec3_t;
begin
VectorCopy(start, move);
VectorSubtract(end_, start, vec);
len := VectorNormalize(vec);
MakeNormalVectors(vec, right, up);
// VectorScale(vec, RT2_SKIP, vec);
// dec = 1.0;
// dec = 0.75;
dec := 3;
VectorScale(vec, dec, vec);
VectorCopy(start, move);
while (len > 0) do
begin
len := len - dec;
if (free_particles = nil) then
Exit;
p := free_particles;
free_particles := p^.next;
p^.next := active_particles;
active_particles := p;
p^.time := cl.time;
VectorClear(p^.accel);
VectorClear(p^.vel);
p^.alpha := 1.0;
p^.alphavel := -0.1;
// p^.alphavel := 0;
p^.color := $74 + (rand() and 7);
VectorCopy(move, p^.org);
{
for j := 0 to 2 do
begin
p^.org[j] := move[j] + crand()*2;
p^.vel[j] := crand()*3;
p^.accel[j] := 0;
end;
}
VectorAdd(move, vec, move);
end;
end;
(*
===============
CL_SmokeTrail
===============
*)
procedure CL_SmokeTrail(const start, end_: vec3_t; colorStart, colorRun, spacing: Integer);
var
move, vec: vec3_t;
len: Single;
j: Integer;
p: cparticle_p;
begin
VectorCopy(start, move);
VectorSubtract(end_, start, vec);
len := VectorNormalize(vec);
VectorScale(vec, spacing, vec);
// FIXME: this is a really silly way to have a loop
while (len > 0) do
begin
len := len - spacing;
if (free_particles = nil) then
Exit;
p := free_particles;
free_particles := p^.next;
p^.next := active_particles;
active_particles := p;
VectorClear(p^.accel);
p^.time := cl.time;
p^.alpha := 1.0;
p^.alphavel := -1.0 / (1 + frand() * 0.5);
p^.color := colorStart + (rand() mod colorRun);
for j := 0 to 2 do
begin
p^.org[j] := move[j] + crand() * 3;
p^.accel[j] := 0;
end;
p^.vel[2] := 20 + crand() * 5;
VectorAdd(move, vec, move);
end;
end;
procedure CL_ForceWall(const start, end_: vec3_t; color: Integer);
var
move, vec: vec3_t;
len: Single;
j: Integer;
p: cparticle_p;
begin
VectorCopy(start, move);
VectorSubtract(end_, start, vec);
len := VectorNormalize(vec);
VectorScale(vec, 4, vec);
// FIXME: this is a really silly way to have a loop
while (len > 0) do
begin
len := len - 4;
if (free_particles = nil) then
Exit;
if (frand() > 0.3) then
begin
p := free_particles;
free_particles := p^.next;
p^.next := active_particles;
active_particles := p;
VectorClear(p^.accel);
p^.time := cl.time;
p^.alpha := 1.0;
p^.alphavel := -1.0 / (3.0 + frand() * 0.5);
p^.color := color;
for j := 0 to 2 do
begin
p^.org[j] := move[j] + crand() * 3;
p^.accel[j] := 0;
end;
p^.vel[0] := 0;
p^.vel[1] := 0;
p^.vel[2] := -40 - (crand() * 10);
end;
VectorAdd(move, vec, move);
end;
end;
procedure CL_FlameEffects(ent: centity_p; const origin: vec3_t);
var
n, count, j: Integer;
p: cparticle_p;
begin
count := rand() and $F;
for n := 0 to count - 1 do
begin
if (free_particles = nil) then
Exit;
p := free_particles;
free_particles := p^.next;
p^.next := active_particles;
active_particles := p;
VectorClear(p^.accel);
p^.time := cl.time;
p^.alpha := 1.0;
p^.alphavel := -1.0 / (1 + frand() * 0.2);
p^.color := 226 + (rand() mod 4);
for j := 0 to 2 do
begin
p^.org[j] := origin[j] + crand() * 5;
p^.vel[j] := crand() * 5;
end;
p^.vel[2] := crand() * -10;
p^.accel[2] := -PARTICLE_GRAVITY;
end;
count := rand() and $7;
for n := 0 to count - 1 do
begin
if (free_particles = nil) then
Exit;
p := free_particles;
free_particles := p^.next;
p^.next := active_particles;
active_particles := p;
VectorClear(p^.accel);
p^.time := cl.time;
p^.alpha := 1.0;
p^.alphavel := -1.0 / (1 + frand() * 0.5);
p^.color := 0 + (rand() mod 4);
for j := 0 to 2 do
begin
p^.org[j] := origin[j] + crand() * 3;
end;
p^.vel[2] := 20 + crand() * 5;
end;
end;
(*
===============
CL_GenericParticleEffect
===============
*)
procedure CL_GenericParticleEffect(const org, dir: vec3_t; color, count, numcolors, dirspread: Integer; alphavel: Single);
var
i, j: Integer;
p: cparticle_p;
d: Single;
begin
for i := 0 to count - 1 do
begin
if (free_particles = nil) then
Exit;
p := free_particles;
free_particles := p^.next;
p^.next := active_particles;
active_particles := p;
p^.time := cl.time;
if (numcolors > 1) then
p^.color := color + (rand() and numcolors)
else
p^.color := color;
d := rand() and dirspread;
for j := 0 to 2 do
begin
p^.org[j] := org[j] + ((rand() and 7) - 4) + d * dir[j];
p^.vel[j] := crand() * 20;
end;
p^.accel[0] := 0.0;
p^.accel[1] := 0.0;
p^.accel[2] := -PARTICLE_GRAVITY;
// VectorCopy (accel, p^.accel);
p^.alpha := 1.0;
p^.alphavel := -1.0 / (0.5 + frand() * alphavel);
// p^.alphavel := alphavel;
end;
end;
(*
===============
CL_BubbleTrail2 (lets you control the # of bubbles by setting the distance between the spawns)
===============
*)
procedure CL_BubbleTrail2(const start, end_: vec3_t; dist: Integer);
var
move, vec: vec3_t;
len: Single;
i: Single;
j: Integer;
p: cparticle_p;
dec: Single;
begin
VectorCopy(start, move);
VectorSubtract(end_, start, vec);
len := VectorNormalize(vec);
dec := dist;
VectorScale(vec, dec, vec);
i := 0;
while (i < len) do
begin
if (free_particles = nil) then
Exit;
p := free_particles;
free_particles := p^.next;
p^.next := active_particles;
active_particles := p;
VectorClear(p^.accel);
p^.time := cl.time;
p^.alpha := 1.0;
p^.alphavel := -1.0 / (1 + frand() * 0.1);
p^.color := 4 + (rand() and 7);
for j := 0 to 2 do
begin
p^.org[j] := move[j] + crand() * 2;
p^.vel[j] := crand() * 10;
end;
p^.org[2] := p^.org[2] - 4;
// p^.vel[2] := p^.vel[2] + 6;
p^.vel[2] := p^.vel[2] + 20;
VectorAdd(move, vec, move);
i := i + dec;
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -