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

📄 p_client.pas

📁 雷神之锤2(Quake2)Delphi源码
💻 PAS
📖 第 1 页 / 共 4 页
字号:
//This is "COMMON" file for \GAME\p_hud.pas & \CTF\p_hud.pas
{$DEFINE CTF}
{$IFDEF CTF}
{$ELSE}
{$ENDIF}

// PLEASE, don't modify this file
// 70% complete

{----------------------------------------------------------------------------}
{                                                                            }
{ 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 :                                                               }
{ Updated by :                                                               }
{                                                                            }
{----------------------------------------------------------------------------}
{ * Still dependent (to compile correctly) on:                               }
{ 1) g_local.??? (inc & pas)                                                 }
{                                                                            }
{----------------------------------------------------------------------------}
{ * TODO:                                                                    }
{ 1) Do more tests                                                           }
{                                                                            }
{----------------------------------------------------------------------------}

#include "g_local.h"
#include "m_player.h"

void ClientUserinfoChanged (edict_t *ent, char *userinfo);

void SP_misc_teleporter_dest (edict_t *ent);

//
// 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

// (GAME <> CTF)
static procedure SP_FixCoopSpots (edict_t *self);
var
	edict_t	*spot;
  d : vec3_t;
begin
  spot := NULL;

  while True do
  begin
    spot := G_Find(spot, FOFS(classname), 'info_player_start');
    if (!spot) then
      Exit;
    if (!spot.targetname) thne
      Continue;
    VectorSubtract(self.s.origin, spot.s.origin, d);
    if (VectorLength(d) < 384) then
    begin
{$IFDEF CTF}
      if ( (!self->targetname) || stricmp(self->targetname, spot->targetname) != 0)
{$ELSE}
      if ( (!self->targetname) || Q_stricmp(self->targetname, spot->targetname) != 0)
{$ENDIF}
      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;//procedure (GAME <> CTF)


// 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

// (GAME <> CTF)
static procedure SP_CreateCoopSpots (edict_t *self);
var
	edict_t	*spot;
begin
{$IFDEF CTF}
        if(stricmp(level.mapname, 'security') == 0)
{$ELSE}
	if(Q_stricmp(level.mapname, 'security') == 0)
{$ENDIF}
  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;//if
end;//procedure (GAME <> CTF)


{*QUAKED info_player_start (1 0 0) (-16 -16 -24) (16 16 32)
The normal starting point for a level.
*}
// (GAME <> CTF)
procedure SP_info_player_start(edict_t *self);
begin
  if (!coop.value) then
    Exit;
{$IFDEF CTF}
        if(stricmp(level.mapname, 'security') == 0)
{$ELSE}
	if(Q_stricmp(level.mapname, 'security') == 0)
{$ENDIF}
  begin
    // invoke one of our gross, ugly, disgusting hacks
    self.think := SP_CreateCoopSpots;
    self.nextthink := level.time + FRAMETIME;
  end;
end;//procedure (GAME <> CTF)


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


{*QUAKED info_player_coop (1 0 1) (-16 -16 -24) (16 16 32)
potential spawning position for coop games
*}
// (GAME <> CTF)
procedure SP_info_player_coop(edict_t *self);
begin
  if (!coop.value) then
  begin
    G_FreeEdict (self);
    Exit;
  end;

{$IFDEF CTF}
	if((stricmp(level.mapname, "jail2") == 0)   ||
	   (stricmp(level.mapname, "jail4") == 0)   ||
	   (stricmp(level.mapname, "mine1") == 0)   ||
	   (stricmp(level.mapname, "mine2") == 0)   ||
	   (stricmp(level.mapname, "mine3") == 0)   ||
	   (stricmp(level.mapname, "mine4") == 0)   ||
	   (stricmp(level.mapname, "lab") == 0)     ||
	   (stricmp(level.mapname, "boss1") == 0)   ||
	   (stricmp(level.mapname, "fact3") == 0)   ||
	   (stricmp(level.mapname, "biggun") == 0)  ||
	   (stricmp(level.mapname, "space") == 0)   ||
	   (stricmp(level.mapname, "command") == 0) ||
	   (stricmp(level.mapname, "power2") == 0) ||
	   (stricmp(level.mapname, "strike") == 0))

{$ELSE}
	if((Q_stricmp(level.mapname, "jail2") == 0)   ||
	   (Q_stricmp(level.mapname, "jail4") == 0)   ||
	   (Q_stricmp(level.mapname, "mine1") == 0)   ||
	   (Q_stricmp(level.mapname, "mine2") == 0)   ||
	   (Q_stricmp(level.mapname, "mine3") == 0)   ||
	   (Q_stricmp(level.mapname, "mine4") == 0)   ||
	   (Q_stricmp(level.mapname, "lab") == 0)     ||
	   (Q_stricmp(level.mapname, "boss1") == 0)   ||
	   (Q_stricmp(level.mapname, "fact3") == 0)   ||
	   (Q_stricmp(level.mapname, "biggun") == 0)  ||
	   (Q_stricmp(level.mapname, "space") == 0)   ||
	   (Q_stricmp(level.mapname, "command") == 0) ||
	   (Q_stricmp(level.mapname, "power2") == 0) ||
	   (Q_stricmp(level.mapname, "strike") == 0))
{$ENDIF}
  begin
    // invoke one of our gross, ugly, disgusting hacks
    self.think := SP_FixCoopSpots;
    self.nextthink := level.time + FRAMETIME;
  end;
end;//procedure (GAME <> CTF)


{*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'
*}
// (GAME=CTF)
procedure SP_info_player_intermission;
begin
end;//procedure (GAME=CTF)


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

// (GAME=CTF)
procedure player_pain (edict_t *self, edict_t *other, float kick, int damage);
begin
  // player pain is handled at the end of the frame in P_DamageFeedback
end;//procedure (GAME=CTF)


// (GAME <> CTF)
function IsFemale (edict_t *ent) : qboolean;
var
	char		*info;
begin
  if (!ent.client) then
  begin
    Result := false;
    Exit;
  end;

{$IFDEF CTF}
  info := Info_ValueForKey (ent.client.pers.userinfo, 'skin');
{$ELSE}
  info := Info_ValueForKey (ent.client.pers.userinfo, 'gender');
{$ENDIF}
  if (info[0] = 'f' OR info[0] = 'F') then
  begin
    Result := true;
    Exit;
  end;
  Result := false;
end;//procedure (GAME <> CTF)


{$IFNDEF CTF}  //onlyGAME (none CTF)
// (GAME <> CTF)
function IsNeutral (edict_t *ent) : qboolean;
var
	char		*info;
begin
  if (!ent.lient) 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
  begin
    Result := true;
    Exit;
  end;
  Result := false;
end;//procedure (GAME <> CTF)
{$ENDIF}

// (GAME <> CTF)
procedure ClientObituary (edict_t *self, edict_t *inflictor, edict_t *attacker);
var
  mod_ : integer;
	char		*message;
	char		*message2;
  ff   : qboolean;
begin
  if (coop.value AND attacker.client) then
    meansOfDeath := meansOfDeath OR MOD_FRIENDLY_FIRE;

  if (deathmatch.value OR coop.value) then
  begin
    ff := meansOfDeath AND MOD_FRIENDLY_FIRE;
    mod_ := meansOfDeath AND (NOT MOD_FRIENDLY_FIRE);
    message := NULL;  //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;//case
    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
{$IFNDEF CTF}  //onlyGAME (none CTF)
                            if IsNeutral(self)
                            then message := 'tripped on its own grenade'
                            else
{$ENDIF}
                            if (IsFemale(self)
                            then message := 'tripped on her own grenade'
                            else message := 'tripped on his own grenade';
                          end;
        MOD_R_SPLASH:     begin
{$IFNDEF CTF}  //onlyGAME (none CTF)
                            if IsNeutral(self)
                            then message := 'blew itself up';
                            else
{$ENDIF}
                            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              begin
{$IFNDEF CTF}  //onlyGAME (none CTF)
                            if IsNeutral(self)
                            then message := 'killed itself';
                            else
{$ENDIF}
                            if IsFemale(self)
                            then message := 'killed herself'
                            else message := 'killed himself';
                          end;
      end;//case
    end;//if
    if (message) then
    begin
      gi.bprintf (PRINT_MEDIUM, '%s %s.\n', self.client.pers.netname, message);
      if (deathmatch.value) then
        self.client.resp.score--;
      self.enemy := NULL;
      Exit;
    end;

    self.enemy := attacker;
    if (attacker AND attacker.client) 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

⌨️ 快捷键说明

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