⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cl_fx.pas

📁 雷神之锤2(Quake2)Delphi源码
💻 PAS
📖 第 1 页 / 共 5 页
字号:
{100%}
{----------------------------------------------------------------------------}
{                                                                            }
{ File(s): cl_fx.c                                                        }
{ Content: Quake2\Client - builds an intended movement command to send to the server }
{                                                                            }
{ Initial conversion by : Juha Hartikainen - juha@linearteam.org             }
{ Initial conversion on : 03-Jun-2002                                        }
{                                                                            }
{ This File contains part of convertion of Quake2 source to ObjectPascal.    }
{ More information about this project can be found at:                       }
{ http://www.sulaco.co.za/quake2/                                            }
{                                                                            }
{ 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.                       }
{                                                                            }
{----------------------------------------------------------------------------}
{ Updates:                                                                   }
{                                                                            }
{ 27-Jun-2002 Steve 'Sly' Williams                                           }
{ - Fix hints and warnings                                                   }
{                                                                            }
{----------------------------------------------------------------------------}
// cl_fx.c -- entity effects parsing and management

unit cl_fx;

interface

uses
  CPas,
  Common,
  Client,
  ref,
  q_shared,
  m_flash;

procedure CL_LogoutEffect(org: vec3_t; type_: Integer);
procedure CL_ItemRespawnParticles(org: vec3_t);
procedure CL_ParticleEffect(org, dir: vec3_t; color, count: Integer);
procedure CL_EntityEvent(ent: entity_state_p);
procedure CL_TeleporterParticles(ent: entity_state_p);
procedure CL_RocketTrail(start, end_: vec3_t; old: centity_p);
procedure CL_BlasterTrail(start, end_: vec3_t);
procedure CL_DiminishingTrail(start, end_: vec3_t; old: centity_p; flags: integer);
procedure CL_FlyEffect(ent: centity_p; origin: vec3_t);
procedure CL_BfgParticles(ent: entity_p);
procedure CL_TrapParticles(ent: entity_p);
procedure CL_FlagTrail(start, end_: vec3_t; color: single);
procedure CL_IonripperTrail(start, ent: vec3_t);
procedure CL_AddParticles;
procedure CL_AddDLights;
procedure CL_AddLightStyles;
procedure CL_ClearEffects;
procedure CL_RunDLights;
procedure CL_RunLightStyles;
procedure CL_ParticleEffect2 (org, dir: vec3_t; color, count: integer);
procedure CL_RailTrail (start, end_: vec3_t);
procedure CL_BubbleTrail (start, end_: vec3_t);
procedure CL_BigTeleportParticles (org: vec3_t);
procedure CL_ParticleEffect3 (org, dir: vec3_t; color, count: integer);
procedure CL_TeleportParticles (org: vec3_t);
procedure CL_BlasterParticles (org, dir: vec3_t);
procedure CL_ExplosionParticles (org: vec3_t);
procedure CL_BFGExplosionParticles (org: vec3_t);
function CL_AllocDlight (key: Integer): cdlight_p;
procedure CL_SetLightstyle(i: integer);
procedure MakeNormalVectors (forward_, right, up: vec3_t);
procedure CL_ParseMuzzleFlash;
procedure CL_ParseMuzzleFlash2;

var
  avelocities: array [0..NUMVERTEXNORMALS-1] of vec3_t;
  active_particles,
  free_particles: cparticle_p;

  particles: array[0..MAX_PARTICLES-1] of cparticle_t;
  cl_numparticles: integer = MAX_PARTICLES;

  (*
  ==============================================================

  LIGHT STYLE MANAGEMENT

  ==============================================================
  *)

type
  clightstyle_p = ^clightstyle_t;
  clightstyle_t = record
    length: integer;
    value: array[0..2] of single;
    map: array[0..MAX_QPATH - 1] of single;
  end;
  pclightstyle_t = ^clightstyle_t;

var
  cl_lightstyle: array[0..MAX_LIGHTSTYLES - 1] of clightstyle_t;
  lastofs: integer;

implementation

uses
  cl_main,
  cl_view,
  net_chan,
  cl_tent,
  snd_dma,
  g_local;

(*
================
CL_ClearLightStyles
================
*)

procedure CL_ClearLightStyles;
begin
  FillChar(cl_lightstyle, sizeof(cl_lightstyle), 0);
  lastofs := -1;
end;

(*
================
CL_RunLightStyles
================
*)

procedure CL_RunLightStyles;
var
	ofs: integer;
	i: integer;
	ls: clightstyle_p;
label
  cont;
begin
	ofs := round(cl.time / 100);
	if (ofs = lastofs) then
		exit;
	lastofs := ofs;

  ls := @cl_lightstyle;
  i := 0;
  while (i < MAX_LIGHTSTYLES) do
  begin
    if (ls.length = 0) then
    begin
      ls.value[0] := 1.0;
      ls.value[1] := 1.0;
      ls.value[2] := 1.0;
			goto cont;
    end;
    if (ls.length = 1) then
    begin
      ls.value[0] := ls.map[0];
      ls.value[1] := ls.map[0];
      ls.value[2] := ls.map[0];
    end
    else
    begin
      ls.value[0] := ls.map[ofs mod ls.length];
      ls.value[1] := ls.map[ofs mod ls.length];
      ls.value[2] := ls.map[ofs mod ls.length];
    end;
    cont:
    Inc(i);
    Inc(ls);
  end;
end;

procedure CL_SetLightstyle(i: integer);
var
  s: pchar;
  j, k: integer;
begin
  s := cl.configstrings[i + CS_LIGHTS];

  j := strlen(s);
  if (j >= MAX_QPATH) then
    Com_Error(ERR_DROP, 'svc_lightstyle length=%d', [j]);

  cl_lightstyle[i].length := j;

  for k := 0 to j - 1 do
    cl_lightstyle[i].map[k] := (byte(s[k]) - byte('a')) / (byte('m') - byte('a'));
end;

(*
================
CL_AddLightStyles
================
*)

procedure CL_AddLightStyles;
var
  i: Integer;
  ls: clightstyle_p;
begin
  ls := @cl_lightstyle;
  for i := 0 to MAX_LIGHTSTYLES - 1 do
  begin
    V_AddLightStyle(i, ls.value[0], ls.value[1], ls.value[2]);
    Inc(ls);
  end;
end;

(*
==============================================================

DLIGHT MANAGEMENT

==============================================================
*)

var
  cl_dlights: array[0..MAX_DLIGHTS - 1] of cdlight_t;

  (*
  ================
  CL_ClearDlights
  ================
  *)

procedure CL_ClearDlights;
begin
  FillChar(cl_dlights, sizeof(cl_dlights), 0);
end;

(*
===============
CL_AllocDlight

===============
*)

function CL_AllocDlight(key: Integer): cdlight_p;
var
  i: Integer;
  dl: cdlight_p;
begin
  // first look for an exact key match
  if (key <> 0) then
  begin
    dl := @cl_dlights;
    for i := 0 to MAX_DLIGHTS - 1 do
    begin
      if (dl.key = key) then
      begin
        FillChar(dl^, sizeof(cdlight_t), 0);
        dl.key := key;
        Result := dl;
        exit;
      end;
      Inc(dl);
    end;
  end;

  // then look for anything else
  dl := @cl_dlights;
  for i := 0 to MAX_DLIGHTS - 1 do
  begin
    if (dl.die < cl.time) then
    begin
      FillChar(dl^, sizeof(cdlight_t), 0);
      dl.key := key;
      Result := dl;
      exit;
    end;
    Inc(dl);
  end;

  dl := @cl_dlights[0];
  FillChar(dl^, sizeof(cdlight_t), 0);
  dl.key := key;
  Result := dl;
end;

(*
===============
CL_NewDlight
===============
*)

procedure CL_NewDlight(key: Integer; x, y, z, radius: Single; time: Single);
var
  dl: cdlight_p;
begin
  dl := CL_AllocDlight(key);
  dl.origin[0] := x;
  dl.origin[1] := y;
  dl.origin[2] := z;
  dl.radius := radius;
  dl.die := cl.time + time;
end;

(*
===============
CL_RunDLights

===============
*)

procedure CL_RunDLights;
var
  i: Integer;
  dl: cdlight_p;
label
  continue_;
begin
  dl := @cl_dlights;
  for i := 0 to MAX_DLIGHTS - 1 do
  begin
    if (dl.radius = 0) then
      goto continue_;

    if (dl.die < cl.time) then
    begin
      dl.radius := 0;
      exit;
    end;
    dl.radius := dl.radius - cls.frametime * dl.decay;
    if (dl.radius < 0) then
      dl.radius := 0;
    continue_:
    Inc(dl);
  end;
end;

(*
==============
CL_ParseMuzzleFlash
==============
*)

procedure CL_ParseMuzzleFlash;
var
  fv, rv: vec3_t;
  dl: cdlight_p;
  i, weapon: Integer;
  pl: centity_p;
  silenced: Integer;
  volume: single;
  soundname: array[0..64 - 1] of char;
begin
  i := MSG_ReadShort(net_message);
  if (i < 1) or (i >= MAX_EDICTS) then
    Com_Error(ERR_DROP, 'CL_ParseMuzzleFlash: bad entity', []);

  weapon := MSG_ReadByte(net_message);
  silenced := weapon and MZ_SILENCED;
  weapon := weapon and not MZ_SILENCED;

  pl := @cl_entities[i];

  dl := CL_AllocDlight(i);
  VectorCopy(pl.current.origin, dl.origin);
  AngleVectors(pl.current.angles, @fv, @rv, nil);
  VectorMA(dl.origin, 18, fv, dl.origin);
  VectorMA(dl.origin, 16, rv, dl.origin);
  if (silenced <> 0) then
    dl.radius := 100 + (rand() and 31)
  else
    dl.radius := 200 + (rand() and 31);
  dl.minlight := 32;
  dl.die := cl.time; // + 0.1;

  if (silenced <> 0) then
    volume := 0.2
  else
    volume := 1;

  case weapon of
    MZ_BLASTER:
      begin
        dl.color[0] := 1;
        dl.color[1] := 1;
        dl.color[2] := 0;
        S_StartSound(nil, i, CHAN_WEAPON, S_RegisterSound('weapons/blastf1a.wav'), volume, ATTN_NORM, 0);
      end;
    MZ_BLUEHYPERBLASTER:
      begin
        dl.color[0] := 0;
        dl.color[1] := 0;
        dl.color[2] := 1;
        S_StartSound(nil, i, CHAN_WEAPON, S_RegisterSound('weapons/hyprbf1a.wav'), volume, ATTN_NORM, 0);
      end;
    MZ_HYPERBLASTER:
      begin
        dl.color[0] := 1;
        dl.color[1] := 1;
        dl.color[2] := 0;
        S_StartSound(nil, i, CHAN_WEAPON, S_RegisterSound('weapons/hyprbf1a.wav'), volume, ATTN_NORM, 0);
      end;
    MZ_MACHINEGUN:
      begin
        dl.color[0] := 1;
        dl.color[1] := 1;
        dl.color[2] := 0;
        Com_sprintf(soundname, sizeof(soundname), 'weapons/machgf%db.wav', [(rand() mod 5) + 1]);
        S_StartSound(nil, i, CHAN_WEAPON, S_RegisterSound(soundname), volume, ATTN_NORM, 0);
      end;
    MZ_SHOTGUN:
      begin
        dl.color[0] := 1;
        dl.color[1] := 1;
        dl.color[2] := 0;
        S_StartSound(nil, i, CHAN_WEAPON, S_RegisterSound('weapons/shotgf1b.wav'), volume, ATTN_NORM, 0);
        S_StartSound(nil, i, CHAN_AUTO, S_RegisterSound('weapons/shotgr1b.wav'), volume, ATTN_NORM, 0.1);
      end;
    MZ_SSHOTGUN:
      begin
        dl.color[0] := 1;
        dl.color[1] := 1;
        dl.color[2] := 0;
        S_StartSound(nil, i, CHAN_WEAPON, S_RegisterSound('weapons/sshotf1b.wav'), volume, ATTN_NORM, 0);
      end;
    MZ_CHAINGUN1:
      begin
        dl.radius := 200 + (rand() and 31);
        dl.color[0] := 1;
        dl.color[1] := 0.25;
        dl.color[2] := 0;
        Com_sprintf(soundname, sizeof(soundname), 'weapons/machgf%db.wav', [(rand() mod 5) + 1]);
        S_StartSound(nil, i, CHAN_WEAPON, S_RegisterSound(soundname), volume, ATTN_NORM, 0);
      end;
    MZ_CHAINGUN2:
      begin
        dl.radius := 225 + (rand() and 31);
        dl.color[0] := 1;
        dl.color[1] := 0.5;
        dl.color[2] := 0;
        dl.die := cl.time + 0.1; // long delay
        Com_sprintf(soundname, sizeof(soundname), 'weapons/machgf%db.wav', [(rand() mod 5) + 1]);
        S_StartSound(nil, i, CHAN_WEAPON, S_RegisterSound(soundname), volume, ATTN_NORM, 0);
        Com_sprintf(soundname, sizeof(soundname), 'weapons/machgf%db.wav', [(rand() mod 5) + 1]);
        S_StartSound(nil, i, CHAN_WEAPON, S_RegisterSound(soundname), volume, ATTN_NORM, 0.05);
      end;
    MZ_CHAINGUN3:
      begin
        dl.radius := 250 + (rand() and 31);
        dl.color[0] := 1;
        dl.color[1] := 1;
        dl.color[2] := 0;
        dl.die := cl.time + 0.1; // long delay
        Com_sprintf(soundname, sizeof(soundname), 'weapons/machgf%db.wav', [(rand() mod 5) + 1]);
        S_StartSound(nil, i, CHAN_WEAPON, S_RegisterSound(soundname), volume, ATTN_NORM, 0);
        Com_sprintf(soundname, sizeof(soundname), 'weapons/machgf%db.wav', [(rand() mod 5) + 1]);
        S_StartSound(nil, i, CHAN_WEAPON, S_RegisterSound(soundname), volume, ATTN_NORM, 0.033);
        Com_sprintf(soundname, sizeof(soundname), 'weapons/machgf%db.wav', [(rand() mod 5) + 1]);
        S_StartSound(nil, i, CHAN_WEAPON, S_RegisterSound(soundname), volume, ATTN_NORM, 0.066);
      end;
    MZ_RAILGUN:
      begin
        dl.color[0] := 0.5;
        dl.color[1] := 0.5;
        dl.color[2] := 1.0;
        S_StartSound(nil, i, CHAN_WEAPON, S_RegisterSound('weapons/railgf1a.wav'), volume, ATTN_NORM, 0);
      end;
    MZ_ROCKET:
      begin
        dl.color[0] := 1;
        dl.color[1] := 0.5;
        dl.color[2] := 0.2;
        S_StartSound(nil, i, CHAN_WEAPON, S_RegisterSound('weapons/rocklf1a.wav'), volume, ATTN_NORM, 0);
        S_StartSound(nil, i, CHAN_AUTO, S_RegisterSound('weapons/rocklr1b.wav'), volume, ATTN_NORM, 0.1);
      end;
    MZ_GRENADE:
      begin
        dl.color[0] := 1;
        dl.color[1] := 0.5;
        dl.color[2] := 0;
        S_StartSound(nil, i, CHAN_WEAPON, S_RegisterSound('weapons/grenlf1a.wav'), volume, ATTN_NORM, 0);
        S_StartSound(nil, i, CHAN_AUTO, S_RegisterSound('weapons/grenlr1b.wav'), volume, ATTN_NORM, 0.1);
      end;
    MZ_BFG:
      begin
        dl.color[0] := 0;
        dl.color[1] := 1;
        dl.color[2] := 0;
        S_StartSound(nil, i, CHAN_WEAPON, S_RegisterSound('weapons/bfg__f1y.wav'), volume, ATTN_NORM, 0);
      end;

    MZ_LOGIN:
      begin
        dl.color[0] := 0;
        dl.color[1] := 1;
        dl.color[2] := 0;
        dl.die := cl.time + 1.0;
        S_StartSound(nil, i, CHAN_WEAPON, S_RegisterSound('weapons/grenlf1a.wav'), 1, ATTN_NORM, 0);
        CL_LogoutEffect(pl.current.origin, weapon);
      end;
    MZ_LOGOUT:
      begin
        dl.color[0] := 1;
        dl.color[1] := 0;
        dl.color[2] := 0;
        dl.die := cl.time + 1.0;
        S_StartSound(nil, i, CHAN_WEAPON, S_RegisterSound('weapons/grenlf1a.wav'), 1, ATTN_NORM, 0);
        CL_LogoutEffect(pl.current.origin, weapon);
      end;
    MZ_RESPAWN:
      begin
        dl.color[0] := 1;
        dl.color[1] := 1;
        dl.color[2] := 0;
        dl.die := cl.time + 1.0;
        S_StartSound(nil, i, CHAN_WEAPON, S_RegisterSound('weapons/grenlf1a.wav'), 1, ATTN_NORM, 0);
        CL_LogoutEffect(pl.current.origin, weapon);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -