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

📄 p_client.pas

📁 delphi编的不错的贪吃蛇
💻 PAS
📖 第 1 页 / 共 4 页
字号:
//98% Reviewed
{----------------------------------------------------------------------------}
{                                                                            }
{ File(s): p_client.c                                                        }
{                                                                            }
{ Initial conversion by : YgriK (Igor Karpov) - glYgriK@hotbox.ru            }
{ Initial conversion on : 04-Feb-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-05-09                                                   }
{ Updated by :  Scott Price                                                  }
{                                                                            }
{----------------------------------------------------------------------------}
{ * Still dependent (to compile correctly) on:                               }
{ x)                                                                         }
{                                                                            }
{----------------------------------------------------------------------------}
{ * TODO:                                                                    }
{ 1) Not all CTF Sections tested or altered                                  }
{                                                                            }
{----------------------------------------------------------------------------}


unit p_client;

interface

uses
  q_shared,
  g_local_add,
  GameUnit;

procedure SP_info_player_start (self : edict_p); cdecl;
procedure SP_info_player_deathmatch (self : edict_p); cdecl;
procedure SP_info_player_coop (self : edict_p); cdecl;
procedure SP_info_player_intermission(self : edict_p); cdecl;

procedure player_die (self, inflictor, attacker : edict_p; damage : integer; const point : vec3_t); cdecl;//a few files
procedure SaveClientData; //a few files

procedure InitBodyQue; //g_spawn

procedure ClientBeginServerFrame (ent : edict_p); cdecl;
procedure ClientBegin (ent : edict_p); cdecl; //g_main
procedure ClientUserinfoChanged (ent : edict_p; userinfo : PChar); cdecl; //g_main
function  ClientConnect (ent : edict_p; userinfo : PChar) : qboolean; cdecl; //g_main
procedure ClientDisconnect (ent : edict_p); cdecl; //g_main

procedure ClientThink (ent : edict_p; ucmd : usercmd_p); cdecl;

procedure respawn (self : edict_p);

implementation

uses
  p_weapon,
  g_utils,
  g_save,
  g_main,
  g_misc,
  g_items,
  p_hud,
  p_view,
  q_shared_add,
  CPas,
  game_add,
  g_local,
  m_player,
  g_svcmds,
  SysUtils,
  g_chase,
  g_ai,
  p_trail,
  math;


{$IFNDEF CTF}
  procedure PutClientInServer (ent : edict_p); forward; //INTERFACE: only g_ctf
{$ENDIF}


//
// Gross, ugly, disgustuing hack section
//

// this function is an ugly as hell hack to fix some map flaws
//
// the coop spawn spots on some maps are SNAFU.  There are coop spots
// with the wrong targetname as well as spots with no name at all
//
// we use carnal knowledge of the maps to fix the coop spot targetnames to match
// that of the nearest named single player spot

procedure SP_FixCoopSpots (self : edict_p); cdecl;
var
  spot : edict_p;
  d : vec3_t;
begin
  spot := Nil;

  while True do
  begin
    spot := G_Find(spot, FOFS_classname, 'info_player_start');
    if (spot = Nil) then
      Exit;
    if (spot^.targetname = '') then
      Continue;
    VectorSubtract(self^.s.origin, spot^.s.origin, d);
    if (VectorLength(d) < 384) then
    begin
      if ( (Self^.targetname = nil) or (Q_stricmp(Self^.targetname, spot^.targetname) <> 0)) then
      begin
//idsoft	gi.dprintf("FixCoopSpots changed %s at %s targetname from %s to %s\n", self->classname, vtos(self->s.origin), self->targetname, spot->targetname);
        self^.targetname := spot^.targetname;
      end;
      Exit;
    end;
  end;
end;


// now if that one wasn't ugly enough for you then try this one on for size
// some maps don't have any coop spots at all, so we need to create them
// where they should have been

procedure SP_CreateCoopSpots (self : edict_p); cdecl;
var
  spot : edict_p;
begin
  if (Q_stricmp(level.mapname, 'security') = 0) then
  begin
    spot := G_Spawn();
    spot^.classname := 'info_player_coop';
    spot^.s.origin[0] := 188 - 64;
    spot^.s.origin[1] := -164;
    spot^.s.origin[2] := 80;
    spot^.targetname := 'jail3';
    spot^.s.angles[1] := 90;

    spot := G_Spawn();
    spot^.classname := 'info_player_coop';
    spot^.s.origin[0] := 188 + 64;
    spot^.s.origin[1] := -164;
    spot^.s.origin[2] := 80;
    spot^.targetname := 'jail3';
    spot^.s.angles[1] := 90;

    spot := G_Spawn();
    spot^.classname := 'info_player_coop';
    spot^.s.origin[0] := 188 + 128;
    spot^.s.origin[1] := -164;
    spot^.s.origin[2] := 80;
    spot^.targetname := 'jail3';
    spot^.s.angles[1] := 90;

    Exit;
  end;
end;


{*QUAKED info_player_start (1 0 0) (-16 -16 -24) (16 16 32)
The normal starting point for a level.
*}
procedure SP_info_player_start (self : edict_p);  //g_spawn
begin
  if (coop^.value = 0) then
    Exit;
  if (Q_stricmp(level.mapname, 'security') = 0) then
  begin
    // invoke one of our gross, ugly, disgusting hacks
    self^.think := SP_CreateCoopSpots;
    self^.nextthink := level.time + FRAMETIME;
  end;
end;


{*QUAKED info_player_deathmatch (1 0 1) (-16 -16 -24) (16 16 32)
potential spawning position for deathmatch games
*}
procedure SP_info_player_deathmatch (self : edict_p);  //g_spawn
begin
  if (deathmatch^.value = 0) then
  begin
    G_FreeEdict (self);
    Exit;
  end;
  SP_misc_teleporter_dest (self);
end;


{*QUAKED info_player_coop (1 0 1) (-16 -16 -24) (16 16 32)
potential spawning position for coop games
*}

procedure SP_info_player_coop (self : edict_p);  //g_spawn
begin
  if (coop^.value = 0) then
  begin
    G_FreeEdict (self);
    Exit;
  end;

  if((Q_stricmp(level.mapname, 'jail2') = 0)   or
     (Q_stricmp(level.mapname, 'jail4') = 0)   or
     (Q_stricmp(level.mapname, 'mine1') = 0)   or
     (Q_stricmp(level.mapname, 'mine2') = 0)   or
     (Q_stricmp(level.mapname, 'mine3') = 0)   or
     (Q_stricmp(level.mapname, 'mine4') = 0)   or
     (Q_stricmp(level.mapname, 'lab') = 0)     or
     (Q_stricmp(level.mapname, 'boss1') = 0)   or
     (Q_stricmp(level.mapname, 'fact3') = 0)   or
     (Q_stricmp(level.mapname, 'biggun') = 0)  or
     (Q_stricmp(level.mapname, 'space') = 0)   or
     (Q_stricmp(level.mapname, 'command') = 0) or
     (Q_stricmp(level.mapname, 'power2') = 0) or
     (Q_stricmp(level.mapname, 'strike') = 0)) then
  begin
    // invoke one of our gross, ugly, disgusting hacks
    self^.think := SP_FixCoopSpots;
    self^.nextthink := level.time + FRAMETIME;
  end;
end;


{*QUAKED info_player_intermission (1 0 1) (-16 -16 -24) (16 16 32)
The deathmatch intermission point will be at one of these
Use 'angles' instead of 'angle', so you can set pitch or roll as well as yaw.  'pitch yaw roll'
*}
procedure SP_info_player_intermission(self : edict_p);   //g_spawn
begin
end;


//=======================================================================


procedure player_pain (self, other : edict_p; kick : single; damage : integer); cdecl;
begin
  // player pain is handled at the end of the frame in P_DamageFeedback
end;




function IsFemale (ent : edict_p) : qboolean; //only imp
var
  info : PChar;
begin
  if (ent^.client = Nil) then
  begin
    Result := false;
    Exit;
  end;

  info := Info_ValueForKey (ent^.client^.pers.userinfo, 'gender');
  if (info[0] = 'f') OR (info[0] = 'F') then
  begin
    Result := true;
    Exit;
  end;
  Result := false;
end;


{$IFNDEF CTF}  //onlyGAME (none CTF)
function IsNeutral (ent : edict_p) : qboolean; //only imp
var
  info : PChar;
begin
  if (ent^.client = Nil) then
  begin
    Result := false;
    Exit;
  end;

  info := Info_ValueForKey (ent^.client^.pers.userinfo, 'gender');
  if (info[0] <> 'f') and (info[0] <> 'F') and (info[0] <> 'm') and (info[0] <> 'M') then
  begin
    Result := true;
    Exit;
  end;
  Result := false;
end;
{$ENDIF}


procedure ClientObituary (self, inflictor, attacker : edict_p); //only imp
var
  mod_ : integer;
  _message,
  message2 : PChar;
  ff   : qboolean;
begin
  if (coop^.value <> 0) AND (attacker^.client <> Nil) then
    meansOfDeath := meansOfDeath OR MOD_FRIENDLY_FIRE;

  if (deathmatch^.value <> 0) OR (coop^.value <> 0) then
  begin
    ff := (meansOfDeath AND MOD_FRIENDLY_FIRE) <> 0;
    mod_ := meansOfDeath AND (NOT MOD_FRIENDLY_FIRE);
    _message := Nil;  //Nil _OR_ ''
    message2 := '';

    Case mod_ of
      MOD_SUICIDE:       _message := 'suicides';
      MOD_FALLING:       _message := 'cratered';
      MOD_CRUSH:         _message := 'was squished';
      MOD_WATER:         _message := 'sank like a rock';
      MOD_SLIME:         _message := 'melted';
      MOD_LAVA:          _message := 'does a back flip into the lava';
      MOD_EXPLOSIVE,
      MOD_BARREL:        _message := 'blew up';
      MOD_EXIT:          _message := 'found a way out';
      MOD_TARGET_LASER:  _message := 'saw the light';
      MOD_TARGET_BLASTER:_message := 'got blasted';
      MOD_BOMB,
      MOD_SPLASH,
      MOD_TRIGGER_HURT:  _message := 'was in the wrong place';
    end;
    if (attacker = self) then
    begin
      Case mod_ of
        MOD_HELD_GRENADE: _message := 'tried to put the pin back in';
        MOD_HG_SPLASH,
        MOD_G_SPLASH:     begin
                            if IsNeutral(Self) then
                              _message := 'tripped on its own grenade'
                            else if IsFemale(Self) then
                              _message := 'tripped on her own grenade'
                            else
                              _message := 'tripped on his own grenade';
                          end;
        MOD_R_SPLASH:     begin
                            if IsNeutral(Self) then
                              _message := 'blew itself up'
                            else if IsFemale(Self) then
                              _message := 'blew herself up'
                            else
                              _message := 'blew himself up';
                          end;

        MOD_BFG_BLAST:    _message := 'should have used a smaller gun';
      else
        if IsNeutral(Self) then
          _message := 'killed itself'
        else if IsFemale(Self) then
          _message := 'killed herself'
        else
          _message := 'killed himself';
      end;
    end;
    if (_message <> nil) then
    begin
      gi.bprintf (PRINT_MEDIUM, '%s %s.'#10, self^.client^.pers.netname, _message);
      if (deathmatch^.value <> 0) then
        Dec(self^.client^.resp.score);
      self^.enemy := Nil;
      Exit;
    end;

    self^.enemy := attacker;
    if (attacker <> Nil) AND (attacker^.client <> Nil) then
    begin
      Case mod_ of
        MOD_BLASTER:    _message := 'was blasted by';
        MOD_SHOTGUN:    _message := 'was gunned down by';
        MOD_SSHOTGUN:   begin
                          _message := 'was blown away by';
                          message2 := '''s super shotgun';
                        end;
        MOD_MACHINEGUN: _message := 'was machinegunned by';
        MOD_CHAINGUN:   begin
                          _message := 'was cut in half by';
                          message2 := '''s chaingun';
                        end;
        MOD_GRENADE:    begin
                          _message := 'was popped by';
                          message2 := '''s grenade';
                        end;
        MOD_G_SPLASH:   begin
                          _message := 'was shredded by';
                          message2 := '''s shrapnel';
                        end;
        MOD_ROCKET:     begin
                          _message := 'ate';
                          message2 := '''s rocket';
                        end;
        MOD_R_SPLASH:   begin
                          _message := 'almost dodged';
                          message2 := '''s rocket';
                        end;
        MOD_HYPERBLASTER:begin
                           _message := 'was melted by';
                           message2 := '''s hyperblaster';
                         end;
        MOD_RAILGUN:    _message := 'was railed by';
        MOD_BFG_LASER:  begin
                          _message := 'saw the pretty lights from';
                          message2 := '''s BFG';
                        end;
        MOD_BFG_BLAST:  begin
                          _message := 'was disintegrated by';
                          message2 := '''s BFG blast';
                        end;
        MOD_BFG_EFFECT: begin
                          _message := 'couldn''t hide from';
                          message2 := '''s BFG';
                        end;
        MOD_HANDGRENADE:begin
                          _message := 'caught';
                          message2 := '''s handgrenade';
                        end;
        MOD_HG_SPLASH:  begin
                          _message := 'didn''t see';
                          message2 := '''s handgrenade';
                        end;
        MOD_HELD_GRENADE:begin
                           _message := 'feels';
                           message2 := '''s pain';
                         end;
        MOD_TELEFRAG:   begin
                          _message := 'tried to invade';
                          message2 := '''s personal space';
                        end;
      end;

      if (_message <> nil) then
      begin
        gi.bprintf (PRINT_MEDIUM, '%s %s %s%s'#10, self^.client^.pers.netname, _message, attacker^.client^.pers.netname, message2);
        if (deathmatch^.value <> 0) then
          if (ff) then
            Dec(attacker^.client^.resp.score)
          else
            Inc(attacker^.client^.resp.score);
        Exit;
      end;
    end;
  end;

  gi.bprintf (PRINT_MEDIUM, '%s died.'#10, self^.client^.pers.netname);
  if (deathmatch^.value <> 0) then
    Dec(self^.client^.resp.score);
end;

procedure TossClientWeapon (self : edict_p); //only imp
var
  item   : gitem_p;
  drop   : edict_p;
  quad   : qboolean;
  spread : Single;
begin
  if (deathmatch^.value = 0) then
    Exit;

  item := self^.client^.pers.weapon;
  if (self^.client^.pers.inventory[self^.client^.ammo_index] = 0) then
    item := nil;
  if (item <> nil) and (strcmp (item^.pickup_name, 'Blaster') = 0) then
    item := nil;

  if (trunc(dmflags^.Value) and DF_QUAD_DROP) = 0 then
    quad := false
  else
    quad := (self^.client^.quad_framenum > (level.framenum + 10));

  if (item <> nil) AND (quad) then
    spread := 22.5
  else
    spread := 0.0;

  if (item <> Nil) then
  begin
    self^.client^.v_angle[YAW] := self^.client^.v_angle[YAW] - spread;
    drop := Drop_Item(self, item);
    self^.client^.v_angle[YAW] := self^.client^.v_angle[YAW] + spread;
    drop^.spawnflags := DROPPED_PLAYER_ITEM;
  end;

  if (quad) then
  begin
    self^.client^.v_angle[YAW] := self^.client^.v_angle[YAW] + spread;
    drop := Drop_Item (self, FindItemByClassname ('item_quad'));
    self^.client^.v_angle[YAW] := self^.client^.v_angle[YAW] - spread;
    drop^.spawnflags := drop^.spawnflags OR DROPPED_PLAYER_ITEM;

    drop^.touch := Touch_Item;
    drop^.nextthink := level.time + (self^.client^.quad_framenum - level.framenum) * FRAMETIME;
    drop^.think := G_FreeEdict;
  end;
end;


{*
==================
LookAtKiller
==================
*}
procedure LookAtKiller (self, inflictor, attacker : edict_p); //only imp
var
  dir : vec3_t;
begin
  if (attacker <> Nil) AND (attacker <> world) AND (attacker <> Self) then
  begin
    VectorSubtract (attacker^.s.origin, self^.s.origin, dir);
  end
  else if (inflictor <> Nil) AND (inflictor <> world) AND (inflictor <> Self) then
    VectorSubtract (inflictor^.s.origin, self^.s.origin, dir)
  else
  begin

⌨️ 快捷键说明

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