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

📄 p_weapon.pas

📁 delphi编的不错的贪吃蛇
💻 PAS
📖 第 1 页 / 共 4 页
字号:
//99%
{----------------------------------------------------------------------------}
{                                                                            }
{ File(s): p_weapon.c                                                        }
{                                                                            }
{ Initial conversion by : YgriK (Igor Karpov) - glYgriK@hotbox.ru            }
{ Initial conversion on : 24-Jan-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.                       }
{                                                                            }
{----------------------------------------------------------------------------}
{ Updated on :  2003-03-24                                                   }
{ Updated by :  Scott Price                                                  }
{                                                                            }
{----------------------------------------------------------------------------}
{ * Still dependent (to compile correctly) on:                               }
{ x)                                                                         }
{----------------------------------------------------------------------------}
{ NOTES:                                                                     }
{ 1)  Whilst mostly complete, there are certain elements of this which       }
{     relate to the CTF define that have NOT been tidied or checked.  ONLY   }
{     items relating to game have been checked/reviewed.                     }
{                                                                            }
{----------------------------------------------------------------------------}
{ * TODO:                                                                    }
{ 1) Do more tests                                                           }
{ 2) <SP>  Tried to make sections more like the original C code.             }
{    Optomisations can occur later to the code.                              }
{                                                                            }
{----------------------------------------------------------------------------}

// p_weapon.c

unit p_weapon;

interface

uses
  q_shared,
  q_shared_add,
  GameUnit,
  g_local,
  g_local_add;

{$IFDEF CTF}
procedure P_ProjectSource (client : gclient_p; var point, distance, forward_, right, result : vec3_t); //only for CTF\g_ctf.c
{$ENDIF}
procedure PlayerNoise (who : edict_p; const where : vec3_t; type_ : integer); //a few files
function Pickup_Weapon (ent, other : edict_p) : qboolean; cdecl; //for g_items
procedure ChangeWeapon (ent : edict_p); //for p_client
procedure Think_Weapon (ent : edict_p); //for p_client
procedure Use_Weapon (ent : edict_p; item : gitem_p); cdecl; //for g_items
procedure Drop_Weapon (ent : edict_p; item : gitem_p); cdecl; //for g_items

procedure Weapon_Blaster (ent: edict_p); cdecl;
procedure Weapon_Shotgun (ent: edict_p); cdecl;
procedure Weapon_SuperShotgun (ent: edict_p); cdecl;
procedure Weapon_Machinegun (ent: edict_p); cdecl;
procedure Weapon_Chaingun (ent: edict_p); cdecl;
procedure Weapon_GrenadeLauncher (ent: edict_p); cdecl;
procedure Weapon_RocketLauncher (ent: edict_p); cdecl;
procedure Weapon_Hyperblaster (ent: edict_p); cdecl;
procedure Weapon_Railgun (ent: edict_p); cdecl;
procedure Weapon_BFG(ent: edict_p); cdecl;
procedure Weapon_Grenade (ent: edict_p); cdecl;


implementation

uses g_weapon,
	 g_utils,
   g_items,
   m_player,
   g_main,
   CPas;


var
  is_quad : qboolean;
  is_silenced : byte;


procedure weapon_grenade_fire (ent : edict_p; held : qboolean); cdecl; forward;


{ (GAME <> CTF):
  GAME: static void P_ProjectSource
  CTF:  void P_ProjectSource }
//only for CTF\g_ctf.c
procedure P_ProjectSource (client : gclient_p; var point, distance, forward_, right, result : vec3_t);
var
  _distance : vec3_t;
begin
  VectorCopy (distance, _distance);
  if (client^.pers.hand = LEFT_HANDED) then
    _distance[1] := _distance[1] * -1
  else if (client^.pers.hand = CENTER_HANDED) then
    _distance[1] := 0;

  G_ProjectSource (point, _distance, forward_, right, result);
end;

{*
===============
PlayerNoise

Each player can have two noise objects associated with it:
a personal noise (jumping, pain, weapon firing), and a weapon
target noise (bullet wall impacts)

Monsters that don't directly see the player can move
to a noise in hopes of seeing the player from there.
===============
*}
// (GAME=CTF)
procedure PlayerNoise (who : edict_p; const where : vec3_t; type_ : integer); //a few files
var
  noise : edict_p;
begin
  if (type_ = PNOISE_WEAPON) then
    if (who^.client^.silencer_shots <> 0) then
      begin
        Dec(who^.client^.silencer_shots);
        Exit;
      end;

  if (deathmatch^.value <> 0) then
    Exit;

  if (who^.flags AND FL_NOTARGET) <> 0 then
    Exit;

  if (who^.mynoise = Nil) then
  begin
    noise := G_Spawn();
    noise^.classname := 'player_noise';
    VectorSet (noise^.mins, -8, -8, -8);
    VectorSet (noise^.maxs, 8, 8, 8);
    noise^.owner := who;
    noise^.svflags := SVF_NOCLIENT;
    who^.mynoise := noise;

    noise := G_Spawn();  // by FAB
    noise^.classname := 'player_noise';
    VectorSet (noise^.mins, -8, -8, -8);
    VectorSet (noise^.maxs, 8, 8, 8);
    noise^.owner := who;
    noise^.svflags := SVF_NOCLIENT;
    who^.mynoise2 := noise;
  end;

  if (type_ = PNOISE_SELF) OR (type_ = PNOISE_WEAPON) then
  begin
    noise := who^.mynoise;
    level.sound_entity := noise;
    level.sound_entity_framenum := level.framenum;
  end
  else // type == PNOISE_IMPACT
  begin
    noise := who^.mynoise2;
    level.sound2_entity := noise;
    level.sound2_entity_framenum := level.framenum;
  end;

  VectorCopy (where, noise^.s.origin);
  VectorSubtract (where, noise^.maxs, noise^.absmin);
  VectorAdd (where, noise^.maxs, noise^.absmax);
  noise^.teleport_time := level.time;
  gi.linkentity (noise);
end;

// (GAME=CTF)
function Pickup_Weapon (ent, other : edict_p) : qboolean; //for g_items
var
  index : integer;
  ammo  : gitem_p;
begin
  index := ITEM_INDEX(ent^.item); // by FAB

  if ( ( ((Trunc(dmflags^.value) AND DF_WEAPONS_STAY) <> 0) OR (coop^.value <> 0) ) AND
       (other^.client^.pers.inventory[index] <> 0) ) then
    if (ent^.spawnflags AND (DROPPED_ITEM OR DROPPED_PLAYER_ITEM) = 0) then
    begin
      Result := false;   // leave the weapon for others to pickup
      Exit;
    end;

  Inc(other^.client^.pers.inventory[index]);

  if ((ent^.spawnflags AND DROPPED_ITEM) = 0) then
  begin
    // give them some ammo with it
    ammo := FindItem (ent^.item^.ammo); // by FAB
	
    if ((Trunc(dmflags^.value ) AND DF_INFINITE_AMMO) <> 0) then
      Add_Ammo (other, ammo, 1000)
    else
      Add_Ammo (other, ammo, ammo^.quantity);

    if ((ent^.spawnflags AND DROPPED_PLAYER_ITEM) = 0) then
    begin
      if (deathmatch^.value <> 0) then
      begin
        if ((Trunc(dmflags^.value) AND DF_WEAPONS_STAY) <> 0) then
          ent^.flags := ent^.flags OR FL_RESPAWN
        else
          SetRespawn (ent, 30); // by FAB
      end;

      if (coop^.value <> 0) then
        ent^.flags := ent^.flags OR FL_RESPAWN;
    end;
  end;

  { 2003-03-14-SP:  The Deathmatch and next boolean result were supposed to have
                    an additional set of brackets around them.  Added. }
  if (other^.client^.pers.weapon <> ent^.item) AND (other^.client^.pers.inventory[index] = 1)
  AND ((deathmatch^.value = 0) OR (other^.client^.pers.weapon = FindItem('blaster')) ) then
    other^.client^.newweapon := ent^.item;

  Result := true;
end;


{*
===============
ChangeWeapon

The old weapon has been dropped all the way, so make the new one
current
===============
*}
// (GAME=CTF)
procedure ChangeWeapon (ent : edict_p);
var
  i : integer;
begin
  if (ent^.client^.grenade_time <> 0) then
  begin
    ent^.client^.grenade_time := level.time;
    ent^.client^.weapon_sound := 0;
    weapon_grenade_fire (ent, false);
    ent^.client^.grenade_time := 0;
  end;

  ent^.client^.pers.lastweapon  := ent^.client^.pers.weapon;
  ent^.client^.pers.weapon := ent^.client^.newweapon;
  ent^.client^.newweapon := Nil;
  ent^.client^.machinegun_shots := 0;

  // set visible model
  if (ent^.s.modelindex = 255) then
  begin
    if (ent^.client^.pers.weapon <> Nil) then
      i := ((ent^.client^.pers.weapon^.weapmodel AND $FF) SHL 8)
    else
      i := 0;

    ent^.s.skinnum := (Cardinal(ent) - Cardinal(g_edicts) - 1 * SizeOf(edict_t)) OR i;
  end;

  if (ent^.client^.pers.weapon <> Nil) AND (ent^.client^.pers.weapon^.ammo <> '') then
    ent^.client^.ammo_index := ITEM_INDEX(FindItem(ent^.client^.pers.weapon^.ammo))
  else
    ent^.client^.ammo_index := 0;

  if (ent^.client^.pers.weapon = Nil) then
  begin
    // dead
    ent^.client^.ps.gunindex := 0;
    Exit;
  end;

  ent^.client^.weaponstate := WEAPON_ACTIVATING;
  ent^.client^.ps.gunframe := 0;
  ent^.client^.ps.gunindex := gi.modelindex(ent^.client^.pers.weapon^.view_model);

  ent^.client^.anim_priority := ANIM_PAIN;
  if (ent^.client^.ps.pmove.pm_flags AND PMF_DUCKED) <> 0 then
  begin
    ent^.s.frame := FRAME_crpain1;       // by FAB
    ent^.client^.anim_end := FRAME_crpain4;  // by FAB
  end
  else begin
    ent^.s.frame := FRAME_pain301;  // by FAB
    ent^.client^.anim_end := FRAME_pain304; // by FAB
  end;
end;

{*
=================
NoAmmoWeaponChange
=================
*}
// (GAME=CTF)
procedure NoAmmoWeaponChange (ent : edict_p); //???only imp
begin
  if (ent^.client^.pers.inventory[ITEM_INDEX(FindItem('slugs'))] AND
  ent^.client^.pers.inventory[ITEM_INDEX(FindItem('railgun'))]) <> 0 then  // check this ..by FAB
  begin
    ent^.client^.newweapon := FindItem ('railgun');
    Exit;
  end;

  if (ent^.client^.pers.inventory[ITEM_INDEX(FindItem('cells'))] AND
  ent^.client^.pers.inventory[ITEM_INDEX(FindItem('hyperblaster'))]) <> 0 then  // check this ..by FAB
  begin
    ent^.client^.newweapon := FindItem ('hyperblaster');
    Exit;
  end;

  if (ent^.client^.pers.inventory[ITEM_INDEX(FindItem('bullets'))] AND
  ent^.client^.pers.inventory[ITEM_INDEX(FindItem('chaingun'))]) <> 0 then   // check this ..by FAB
  begin
    ent^.client^.newweapon := FindItem ('chaingun');
    Exit;
  end;

  if (ent^.client^.pers.inventory[ITEM_INDEX(FindItem('bullets'))] AND
  ent^.client^.pers.inventory[ITEM_INDEX(FindItem('machinegun'))]) <> 0 then  // check this ..by FAB
  begin
    ent^.client^.newweapon := FindItem ('machinegun');
    Exit;
  end;

  if (ent^.client^.pers.inventory[ITEM_INDEX(FindItem('shells'))] AND
  ent^.client^.pers.inventory[ITEM_INDEX(FindItem('super shotgun'))]) <> 0 then  // check this ..by FAB
  begin
    ent^.client^.newweapon := FindItem ('super shotgun');
    Exit;
  end;

  if (ent^.client^.pers.inventory[ITEM_INDEX(FindItem('shells'))] AND
  ent^.client^.pers.inventory[ITEM_INDEX(FindItem('shotgun'))]) <> 0 then     // check this ..by FAB
  begin
    ent^.client^.newweapon := FindItem ('shotgun');
    Exit;
  end;

  ent^.client^.newweapon := FindItem ('blaster');
end;

{*
=================
Think_Weapon

Called by ClientBeginServerFrame and ClientThink
=================
*}
// (GAME=CTF)
procedure Think_Weapon (ent : edict_p);
begin
  // if just died, put the weapon away
  if (ent^.health < 1) then
  begin
    ent^.client^.newweapon := Nil;
    ChangeWeapon (ent);
  end;

  // call active weapon think routine
  if (ent^.client^.pers.weapon <> Nil) AND Assigned(ent^.client^.pers.weapon^.weaponthink) then
  begin
    is_quad := (ent^.client^.quad_framenum > level.framenum);
    if (ent^.client^.silencer_shots <> 0) then
      is_silenced := MZ_SILENCED
    else
      is_silenced := 0;
    ent^.client^.pers.weapon^.weaponthink (ent);
  end;
end;


{*
================
Use_Weapon

Make the weapon ready if there is ammo
================
*}
// (GAME=CTF)
procedure Use_Weapon (ent : edict_p; item : gitem_p);
var
  ammo_index : integer;
  ammo_item  : gitem_p;
begin
  // see if we're already using it
  if (item = ent^.client^.pers.weapon) then
    Exit;

  if ( (item^.ammo <> nil) AND (g_select_empty^.Value = 0) AND ((item^.flags AND IT_AMMO) = 0) ) then
  begin
    ammo_item  := FindItem(item^.ammo);
    ammo_index := ITEM_INDEX(ammo_item);

    if (ent^.client^.pers.inventory[ammo_index]) = 0 then
    begin
      gi.cprintf (ent, PRINT_HIGH, 'No %s for %s.'#10 , ammo_item^.pickup_name, item^.pickup_name  );
      Exit;
    end;

    if (ent^.client^.pers.inventory[ammo_index] < item^.quantity) then
    begin
      gi.cprintf (ent, PRINT_HIGH, 'Not enough %s for %s.'#10 , ammo_item^.pickup_name, item^.pickup_name );
      Exit;
    end;
  end;

  // change to this weapon when down
  ent^.client^.newweapon := item;
end;


{*
================
Drop_Weapon
================
*}
// (GAME=CTF)
procedure Drop_Weapon (ent : edict_p; item : gitem_p);
var
  index : integer;
begin
  if ((Trunc(dmflags^.value) AND DF_WEAPONS_STAY) <> 0) then
    Exit;

  index := ITEM_INDEX(item); 
  // see if we're already using it
  if ( ((item = ent^.client^.pers.weapon) OR (item = ent^.client^.newweapon)) AND

⌨️ 快捷键说明

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