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

📄 p_client.pas

📁 delphi编的不错的贪吃蛇
💻 PAS
📖 第 1 页 / 共 4 页
字号:
{$ENDIF}

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


{*
===========
PutClientInServer

Called when a player connects to a server or respawns in
a deathmatch.
============
*}
// (GAME <> CTF)
procedure PutClientInServer (edict_t *ent);
const
  mins : vec3_t = (-16, -16, -24);
  maxs : vec3_t = ( 16,  16,  32);
var
{Y}  index   : integer;
  spawn_origin,
  spawn_angles  : vec3_t;
	gclient_t      	        *client;
  i, n          : integer;
	client_persistant_t	saved;
	client_respawn_t	resp;

    char		userinfo[MAX_INFO_STRING];

begin
  // find a spawn point
  // do it before setting health back up, so farthest
  // ranging doesn't count this client
  SelectSpawnPoint (ent, spawn_origin, spawn_angles);

{Y}  index := ent-g_edicts-1;
  client := ent.client;

  // deathmatch wipes most client data every spawn
  if (deathmatch.value)
  then begin
    resp := client.resp;
    memcpy (userinfo, client->pers.userinfo, sizeof(userinfo));
    InitClientPersistant (client);
    ClientUserinfoChanged (ent, userinfo);
  end
  else
    if (coop.value)
    then begin
      resp := client.resp;
      memcpy (userinfo, client->pers.userinfo, sizeof(userinfo));

{$IFDEF CTF}
      for n:=0 to MAX_ITEMS-1 do
        if (itemlist[n].flags & IT_KEY) then
          resp.coop_respawn.inventory[n] := client.pers.inventory[n];

{$ELSE}
      // this is kind of ugly, but it's how we want to handle keys in coop
(*idsoft
//		for (n = 0; n < game.num_items; n++)
//		{
//			if (itemlist[n].flags & IT_KEY)
//				resp.coop_respawn.inventory[n] = client->pers.inventory[n];
//		}
*)
      resp.coop_respawn.game_helpchanged := client.pers.game_helpchanged;
      resp.coop_respawn.helpchanged := client.pers.helpchanged;
{$ENDIF}

      client.pers := resp.coop_respawn;
      ClientUserinfoChanged (ent, userinfo);
      if (resp.score > client.pers.score) then
        client.pers.score := resp.score;
    end
    else
      memset (&resp, 0, sizeof(resp));

  // clear everything but the persistant data
  saved := client.pers;
  memset (client, 0, sizeof( *client));
  client.pers := saved;
  if (client.pers.health <= 0) then
    InitClientPersistant(client);
  client.resp := resp;

  // copy some data from the client to the entity
  FetchClientEntData (ent);

  // clear entity values
  ent.groundentity = NULL;
  ent.client = &game.clients[index];
  ent.takedamage := DAMAGE_AIM;
  ent.movetype := MOVETYPE_WALK;
  ent.viewheight := 22;
  ent.inuse := true;
  ent.classname = 'player';
  ent.mass := 200;
  ent.solid := SOLID_BBOX;
  ent.deadflag := DEAD_NO;
  ent.air_finished := level.time + 12;
  ent.clipmask := MASK_PLAYERSOLID;
  ent.model := 'players/male/tris.md2';
  ent.pain := player_pain;
  ent.die := player_die;
  ent.waterlevel := 0;
  ent.watertype := 0;
  ent.flags := ent.flags AND (NOT FL_NO_KNOCKBACK);
  ent.svflags := ent.svflags AND (NOT SVF_DEADMONSTER);

  VectorCopy (mins, ent.mins);
  VectorCopy (maxs, ent.maxs);
  VectorClear (ent.velocity);

  // clear playerstate values
  memset (&ent->client->ps, 0, sizeof(client->ps));

  client.ps.pmove.origin[0] := spawn_origin[0]*8;
  client.ps.pmove.origin[1] := spawn_origin[1]*8;
  client.ps.pmove.origin[2] := spawn_origin[2]*8;

{$IFDEF CTF}  //onlyCTF
//ZOID
  client.ps.pmove.pm_flags := client.ps.pmove.pm_flags AND (NOT PMF_NO_PREDICTION);
//ZOID
{$ENDIF}

  if (deathmatch->value && ((int)dmflags->value & DF_FIXED_FOV))
  then client.ps.fov := 90
  else begin
    client.ps.fov := atoi(Info_ValueForKey(client.pers.userinfo, 'fov'));
    if (client.ps.fov < 1)
    then client.ps.fov := 90
    else
      if (client.ps.fov > 160) then
        client.ps.fov := 160;
  end;

  client.ps.gunindex := gi.modelindex(client.pers.weapon.view_model);

  // clear entity state values
  ent.s.effects := 0;

{$IFDEF CTF}  //onlyCTF
  ent.s.skinnum := ent - g_edicts - 1;
{$ENDIF}

  ent.s.modelindex := 255;		// will use the skin specified model
  ent.s.modelindex2 := 255;		// custom gun model
  // sknum is player num and weapon number
  // weapon number will be added in changeweapon
  ent.s.skinnum := ent - g_edicts - 1;

  ent.s.frame := 0;
  VectorCopy (spawn_origin, ent.s.origin);
  ent.s.origin[2] := ent.s.origin[2] +1;	// make sure off ground
  VectorCopy (ent.s.origin, ent.s.old_origin);

  // set the delta angle
  for i:=0 to 2 do
    client.ps.pmove.delta_angles[i] := ANGLE2SHORT(spawn_angles[i] - client.resp.cmd_angles[i]);

  ent.s.angles[PITCH] := 0;
  ent.s.angles[YAW] := spawn_angles[YAW];
  ent.s.angles[ROLL] := 0;
  VectorCopy (ent.s.angles, client.ps.viewangles);
  VectorCopy (ent.s.angles, client.v_angle);

{$IFDEF CTF}
//ZOID
  if (CTFStartClient(ent)) then
    Exit;
//ZOID
{$ELSE}
  // spawn a spectator
  if (client.pers.spectator)
  then begin
    client.chase_target := NULL;

    client.resp.spectator := true;

    ent.movetype := MOVETYPE_NOCLIP;
    ent.solid := SOLID_NOT;
    ent.svflags := ent.svflags OR SVF_NOCLIENT;
    ent.client.ps.gunindex := 0;
    gi.linkentity (ent);
    Exit;
  else
    client.resp.spectator := false;
{$ENDIF}

  if (!KillBox (ent))
  {	// could't spawn in?
  }

  gi.linkentity (ent);

  // force the current weapon up
  client.newweapon := client.pers.weapon;
  ChangeWeapon (ent);
end;//procedure (GAME <> CTF)


{*
=====================
ClientBeginDeathmatch

A client has just connected to the server in
deathmatch mode, so clear everything out before starting them.
=====================
*}
// (GAME=CTF)
procedure ClientBeginDeathmatch (edict_t *ent)
begin
  G_InitEdict (ent);

  InitClientResp (ent.client);

  // locate ent at a spawn point
  PutClientInServer (ent);

  // send effect
  gi.WriteByte (svc_muzzleflash);
  gi.WriteShort (ent-g_edicts);
  gi.WriteByte (MZ_LOGIN);
  gi.multicast (ent.s.origin, MULTICAST_PVS);

  gi.bprintf (PRINT_HIGH, '%s entered the game\n', ent.client.pers.netname);

  // make sure all view stuff is valid
  ClientEndServerFrame (ent);
end;//procedure (GAME=CTF)


{*
===========
ClientBegin

called when a client has finished connecting, and is ready
to be placed into the game.  This will happen every level load.
============
*}
// (GAME=CTF)
procedure ClientBegin (edict_t *ent)
var
  i : integer;
begin
  ent.client := game.clients + (ent - g_edicts - 1);

  if (deathmatch.value) then
  begin
    ClientBeginDeathmatch (ent);
    Exit;
  end;

  // if there is already a body waiting for us (a loadgame), just
  // take it, otherwise spawn one from scratch
  if (ent.inuse = true)
  then begin
    // the client has cleared the client side viewangles upon
    // connecting to the server, which is different than the
    // state when the game is saved, so we need to compensate
    // with deltaangles
    for i:=0 to 2 do
      ent.client.ps.pmove.delta_angles[i] := ANGLE2SHORT(ent.client.ps.viewangles[i]);
  end
  else begin
    // a spawn point will completely reinitialize the entity
    // except for the persistant data that was initialized at
    // ClientConnect() time
    G_InitEdict (ent);
    ent.classname := 'player';
    InitClientResp (ent.client);
    PutClientInServer (ent);
  end;

  if (level.intermissiontime)
  then MoveClientToIntermission (ent)
  else
    // send effect if in a multiplayer game
    if (game.maxclients > 1) then
    begin
      gi.WriteByte (svc_muzzleflash);
      gi.WriteShort (ent-g_edicts);
      gi.WriteByte (MZ_LOGIN);
      gi.multicast (ent.s.origin, MULTICAST_PVS);

      gi.bprintf (PRINT_HIGH, '%s entered the game\n', ent.client.pers.netname);
    end;

  // make sure all view stuff is valid
  ClientEndServerFrame (ent);
end;//procedure (GAME=CTF)


{*
===========
ClientUserInfoChanged

called whenever the player updates a userinfo variable.

The game can override any of the settings in place
(forcing skins or names, etc) before copying it off.
============
*}
// (GAME <> CTF)
procedure ClientUserinfoChanged (edict_t *ent, char *userinfo);
var
	char	*s;
{Y}  playernum : integer;
begin
  // check for malformed or illegal info strings
  if (!Info_Validate(userinfo)) then
          strcpy (userinfo, '\\name\\badinfo\\skin\\male/grunt');

  // set name
  s := Info_ValueForKey (userinfo, 'name');
  strncpy (ent->client->pers.netname, s, sizeof(ent->client->pers.netname)-1);

{$IFNDEF CTF}  //onlyGAME (noneCTF)
  // set spectator
  s := Info_ValueForKey (userinfo, 'spectator');
  // spectators are only supported in deathmatch
  if (deathmatch->value && *s && strcmp(s, '0'))
  then ent.client.pers.spectator := true;
  else ent.client.pers.spectator := false;
{$ENDIF}

  // set skin
  s := Info_ValueForKey (userinfo, 'skin');

{Y}  playernum := ent-g_edicts-1;

  // combine name and skin into a configstring
{$IFDEF CTF}  //onlyCTF
//ZOID
  if (ctf.value)
  then CTFAssignSkin(ent, s)
  else
//ZOID
{$ENDIF}
    gi.configstring (CS_PLAYERSKINS+playernum, va('%s\\%s', ent.client.pers.netname, s));

  // fov
  if (deathmatch->value && ((int)dmflags->value & DF_FIXED_FOV))
  then ent.client.ps.fov := 90
  else begin
    ent.client.ps.fov := atoi(Info_ValueForKey(userinfo, 'fov'));
    if (ent.client.ps.fov < 1)
    then ent.client.ps.fov := 90;
    else
      if (ent.client.ps.fov > 160) then
       ent.client.ps.fov := 160;
  end;

  // handedness
  s := Info_ValueForKey (userinfo, 'hand');
  if (strlen(s)) then
    ent.client.pers.hand := atoi(s);

  // save off the userinfo in case we want to check something later
  strncpy (ent->client->pers.userinfo, userinfo, sizeof(ent->client->pers.userinfo)-1);
end;//procedure (GAME <> CTF)


{*
===========
ClientConnect

Called when a player begins connecting to the server.
The game can refuse entrance to a client by returning false.
If the client is allowed, the connection process will continue
and eventually get to ClientBegin()
Changing levels will NOT cause this to be called again, but
loadgames will.
============
*}
// (GAME <> CTF)
function ClientConnect (edict_t *ent, char *userinfo) : qboolean;
var
	char	*value;
          int i, numspec;
begin
  // check to see if they are on the banned IP list
  value := Info_ValueForKey (userinfo, 'ip');

{$IF褼EF CTF}  //onlyGAME (noneCTF)
  if (SV_FilterPacket(value))
  then begin
    Info_SetValueForKey (userinfo, 'rejmsg', 'Banned.');
    Result := false;
    Exit;
  end;

  // check for a spectator
  value := Info_ValueForKey (userinfo, 'spectator');
  if (deathmatch->value && *value && strcmp(value, '0'))
  then begin
    if ( *spectator_password.string AND
         strcmp(spectator_password.string, 'none') AND
         strcmp(spectator_password.string, value))
    then begin
      Info_SetValueForKey(userinfo, 'rejmsg', 'Spectator password required or incorrect.');
      Result := false;
      Exit;
    end;

    // count spectators
//    for (i = numspec = 0; i < maxclients->value; i++)
    numspec := 0;
    for i:=0 to maxclients.value-1 do
      if (g_edicts[i+1].inuse) AND (g_edicts[i+1].client.pers.spectator) then
        Inc(numspec);

    if (numspec >= maxspectators.value) then
    begin
      Info_SetValueForKey(userinfo, 'rejmsg', 'Server spectator limit is full.');
      Result := false;
      Exit;
    end;
  end
  else begin
{$ENDIF}
    // check for a password
    value := Info_ValueForKey (userinfo, 'password');
    if ( *password.string AND
         strcmp(password.string, 'none') AND
         strcmp(password.string, value))
    then begin
      Info_SetValueForKey(userinfo, 'rejmsg', 'Password required or incorrect.');
      Result := false;
      Exit;
    end;
//耢铗痂 篑腩忤

⌨️ 快捷键说明

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