📄 p_client.pas
字号:
//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
// 85% 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: }
{ x) }
{ }
{----------------------------------------------------------------------------}
{ * TODO: }
{ 1) Do more tests }
{ }
{----------------------------------------------------------------------------}
unit p_client;
interface
uses q_shared, game;
//...
procedure SP_info_player_start (self : edict_p); //g_spawn
procedure SP_info_player_deathmatch (self : edict_p); //g_spawn
procedure SP_info_player_coop (self : edict_p); //g_spawn
procedure SP_info_player_intermission; //g_spawn
procedure player_die (self, inflictor, attacker : edict_p; damage : integer; point : vec3_t); //a few files
procedure SaveClientData; //a few files
procedure InitBodyQue; //g_spawn
{$IFDEF CTF}
procedure PutClientInServer (ent : edict_p); //INTERFACE: only g_ctf
{$ENDIF}
procedure ClientBegin (ent : edict_p); //g_main
procedure ClientUserinfoChanged (ent : edict_p; userinfo : PChar); //g_main
function ClientConnect (ent : edict_p; userinfo : PChar) : qboolean; //g_main
procedure ClientDisconnect (ent : edict_p); //g_main
implementation
uses p_weapon, g_local;
//#include "m_player.h"
{$IFNDEF CTF}
procedure PutClientInServer (ent : edict_p); forward; //INTERFACE: only g_ctf
{$ENDIF}
(*
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);
procedure SP_FixCoopSpots (self : edict_p); cdecl;//Y: don't cdecl //only imp
var
spot : edict_p;
d : vec3_t;
begin
spot := Nil;
while True do
begin
//Y spot := G_Find(spot, FOFS(classname), 'info_player_start');
if (spot=Nil) then
Exit;
(*Y if (!spot.targetname) thne
Continue;*)
VectorSubtract(self.s.origin, spot.s.origin, d);
if (VectorLength(d) < 384) then
begin
(*Y{$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);
procedure SP_CreateCoopSpots (self : edict_p); cdecl;//Y: don't cdecl //only imp
var
spot : edict_p;
begin
(*Y{$IFDEF CTF}
if(stricmp(level.mapname, 'security') == 0)
{$ELSE}
if(Q_stricmp(level.mapname, 'security') == 0)
{$ENDIF}*)
begin
//Y 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;
//Y 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;
//Y 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 (self : edict_p); //g_spawn
begin
if (coop.value=0) then
Exit;
(*Y{$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
//Y self.think := SP_CreateCoopSpots; //Y: don't cdecl
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);
procedure SP_info_player_deathmatch (self : edict_p); //g_spawn
begin
if (deathmatch.value=0) then
begin
//Y G_FreeEdict (self);
Exit;
end;
//Y 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 (self : edict_p); //g_spawn
begin
if (coop.value=0) then
begin
//Y G_FreeEdict (self);
Exit;
end;
(*Y{$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
//Y self.think := SP_FixCoopSpots; //Y: don't cdecl
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; //g_spawn
begin
end;//procedure (GAME=CTF)
//=======================================================================
// (GAME=CTF)
//procedure player_pain (edict_t *self, edict_t *other, float kick, int damage);
procedure player_pain (self, other : edict_p; kick : float; damage : integer);
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;
function IsFemale (ent : edict_p) : qboolean; //only imp
var
info : PChar;
begin
if (ent.client=Nil) 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
if UpCase(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;
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
if (UpCase(info[0]) <> 'F') AND (UpCase(info[0]) <> 'M') then
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);
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
//Y ff := meansOfDeath AND MOD_FRIENDLY_FIRE;
mod_ := meansOfDeath AND (NOT MOD_FRIENDLY_FIRE);
message := Nil; //Nil _OR_ ''
message2 := '';
Case mod_ of
MOD_SUICIDE: message := 'suicides';
MOD_FALLING: message := 'cratered';
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -