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

📄 p_client.pas

📁 delphi编的不错的贪吃蛇
💻 PAS
📖 第 1 页 / 共 4 页
字号:
    playerdistance := VectorLength (v);

    if (playerdistance < bestplayerdistance) then
      bestplayerdistance := playerdistance;
  end;

  Result := bestplayerdistance;
end;//procedure (GAME=CTF)


{*
================
SelectRandomDeathmatchSpawnPoint

go to a random point, but NOT the two points closest
to other players
================
*}
// (GAME=CTF)
function SelectRandomDeathmatchSpawnPoint : edict_t;
var
	edict_t	*spot, *spot1, *spot2;
	int		count = 0;
  selection             : integer;
  range, range1, range2 : float;
begin
  spot = NULL;
//  range1 = range2 = 99999;
  range2 := 99999;
  range1 := range2;
  spot1 = spot2 = NULL;

//  while ((spot = G_Find (spot, FOFS(classname), 'info_player_deathmatch')) != NULL)
  spot := G_Find (spot, FOFS(classname), 'info_player_deathmatch'));
  while (spot <> Nil) do
  begin
    Inc(count);
    range := PlayersRangeFromSpot(spot);
    if (range < range1)
    then begin
      range1 := range;
      spot1 := spot;
    end
    else
      if (range < range2) then
      begin
        range2 := range;
        spot2 := spot;
      end;
  end;

  if (!count) then
  begin
    Result := Nil;
    Exit;
  end;

  if (count <= 2)
  then begin
         spot1 = spot2 = NULL;
  end
  else
    Dec (count, 2);

//  selection = rand() % count;
  selection := random(count);

  spot = NULL;
(*  do
  {
        spot = G_Find (spot, FOFS(classname), 'info_player_deathmatch');
        if (spot = spot1) OR (spot = spot2) then
                selection++;
  } while(selection--);
*)
  repeat
    spot := G_Find (spot, FOFS(classname), 'info_player_deathmatch');
    if (spot = spot1) OR (spot = spot2) then
      Inc(selection);

    Dec(selection);
  until selection=0; //C2Pas ???

  Result := spot;
end;//procedure (GAME=CTF)


{*
================
SelectFarthestDeathmatchSpawnPoint

================
*}
// (GAME=CTF)
function SelectFarthestDeathmatchSpawnPoint : edict_t;
var
	edict_t	*bestspot;
  bestdistance,
  bestplayerdistance : float;
	edict_t	*spot;
begin
  spot = NULL;
  bestspot = NULL;
  bestdistance := 0;
//  while ((spot = G_Find (spot, FOFS(classname), 'info_player_deathmatch')) != NULL)
  spot := G_Find (spot, FOFS(classname), 'info_player_deathmatch'));
  while (spot <> NULL) do
  begin
    bestplayerdistance := PlayersRangeFromSpot (spot);

    if (bestplayerdistance > bestdistance) then
    begin
      bestspot := spot;
      bestdistance := bestplayerdistance;
    end;
  end;

  if (bestspot) then
  begin
    Result := bestspot;
    Exit;
  end;

  // if there is a player just spawned on each and every start spot
  // we have no choice to turn one into a telefrag meltdown
  spot := G_Find (NULL, FOFS(classname), 'info_player_deathmatch');

  Result := spot;
end;//procedure (GAME=CTF)

// (GAME=CTF)
function SelectDeathmatchSpawnPoint : edict_t;
begin
  if ( (int)(dmflags->value) & DF_SPAWN_FARTHEST)
  then Result := SelectFarthestDeathmatchSpawnPoint ()
  else Result := SelectRandomDeathmatchSpawnPoint ();
end;//procedure (GAME=CTF)


// (GAME=CTF)
function SelectCoopSpawnPoint (edict_t *ent) : edict_t;
var
  index : integer;
	edict_t	*spot = NULL;
	char	*target;
begin
  index := ent.client - game.clients;

  // player 0 starts in normal player spawn point
  if (!index) then
  begin
    Result := NULL;
    Exit;
  end; 

  spot = NULL;

  // assume there are four coop spots at each spawnpoint
  while (1)
  begin
    spot := G_Find (spot, FOFS(classname), 'info_player_coop');
    if (!spot) then
    begin
      Result := NULL;  // we didn't have enough...
      Exit;
    end;  

    target := spot.targetname;
    if (!target) then
      target := '';
    if (Q_stricmp(game.spawnpoint, target) = 0) then
    begin
      // this is a coop spawn point for one of the clients here
      Dec(index);
      if (!index) then
      begin
        Result := spot;	 // this is it
        Exit;
      end;  
    end;
  end;

  Result := spot;
end;//procedure (GAME=CTF)


{*
===========
SelectSpawnPoint

Chooses a player start, deathmatch start, coop start, etc
============
*}
// (GAME <> CTF)
procedure SelectSpawnPoint (edict_t *ent, vec3_t origin, vec3_t angles);
begin
  edict_t	*spot = NULL;

  if (deathmatch.value)
{$IFDEF CTF}
//ZOID
  then
    if (ctf.value)
    then spot := SelectCTFSpawnPoint(ent)
    else spot := SelectDeathmatchSpawnPoint ();
//ZOID
{$ELSE}
  then spot := SelectDeathmatchSpawnPoint ()
{$ENDIF}
  else
    if (coop.value) then
      spot := SelectCoopSpawnPoint (ent);

  // find a single player start spot
  if (!spot) then
  begin
//      while ((spot = G_Find (spot, FOFS(classname), 'info_player_start')) != NULL)
      spot := G_Find (spot, FOFS(classname), 'info_player_start');
      while (spot <> Nil) do
      begin
        if (!game.spawnpoint[0]) AND (!spot.targetname) then
          Break;

        if (!game.spawnpoint[0]) OR (!spot.targetname) then
          Continue;

        if (Q_stricmp(game.spawnpoint, spot.targetname) = 0) then
          Break;
      end;

      if (!spot) then
      begin
        if (!game.spawnpoint[0]) then
          // there wasn't a spawnpoint without a target, so use any
          spot := G_Find (spot, FOFS(classname), 'info_player_start');
        if (!spot) then
          gi.error ('Couldn"t find spawn point %s\n', game.spawnpoint);
      end;
  end;

  VectorCopy (spot.s.origin, origin);
  origin[2] := origin[2] +9;
  VectorCopy (spot.s.angles, angles);
end;//procedure (GAME <> CTF)


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


// (GAME=CTF)
procedure InitBodyQue;
var
  i : integer;
	edict_t	*ent;
begin
  level.body_que = 0;
  for i:=0 to BODY_QUEUE_SIZE-1 do
  begin
    ent := G_Spawn();
    ent.classname := 'bodyque';
  end;
end;//procedure (GAME=CTF)

// (GAME=CTF)
procedure body_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point);
var
  n : integer;
begin
  if (self.health < -40) then
  begin
    gi.sound (self, CHAN_BODY, gi.soundindex ('misc/udeath.wav'), 1, ATTN_NORM, 0);
    for n:=0 to 3 do
      ThrowGib (self, 'models/objects/gibs/sm_meat/tris.md2', damage, GIB_ORGANIC);
    self.s.origin[2] := self.s.origin[2] -48;
    ThrowClientHead (self, damage);
    self.takedamage := DAMAGE_NO;
  end;
end;//procedure (GAME=CTF)

// (GAME=CTF)
procedure CopyToBodyQue (edict_t *ent);
var
	edict_t		*body;
begin
  // grab a body que and cycle to the next one
  body = &g_edicts[(int)maxclients->value + level.body_que + 1];
  level.body_que := (level.body_que + 1) MOD BODY_QUEUE_SIZE;

  // FIXME: send an effect on the removed body

  gi.unlinkentity (ent);

  gi.unlinkentity (body);
  body.s := ent.s;
  body.s.number := body - g_edicts;

  body.svflags := ent.svflags;
  VectorCopy (ent.mins, body.mins);
  VectorCopy (ent.maxs, body.maxs);
  VectorCopy (ent.absmin, body.absmin);
  VectorCopy (ent.absmax, body.absmax);
  VectorCopy (ent.size, body.size);
  body.solid := ent.solid;
  body.clipmask := ent.clipmask;
  body.owner := ent.owner;
  body.movetype := ent.movetype;

  body.die := body_die;
  body.takedamage := DAMAGE_YES;

  gi.linkentity (body);
end;//procedure (GAME=CTF)


// (GAME <> CTF)
procedure respawn (edict_t *self);
begin
  if (deathmatch.value OR coop.value) then
  begin
{$IFDEF CTF}
//Y: none comments
{$ELSE}
    // spectator's don't leave bodies
{$ENDIF}
    if (self.movetype <> MOVETYPE_NOCLIP) then
      CopyToBodyQue (self);
    self.svflags := self.svflags AND (NOT SVF_NOCLIENT);
    PutClientInServer (self);

    // add a teleportation effect
    self.s.event := EV_PLAYER_TELEPORT;

    // hold in place briefly
    self.client.ps.pmove.pm_flags := PMF_TIME_TELEPORT;
    self.client.ps.pmove.pm_time := 14;

    self.client.respawn_time := level.time;

    Exit;
  end;

  // restart the entire server
  gi.AddCommandString ('menu_loadgame\n');
end;//procedure (GAME <> CTF)


{$IFNDEF CTF}  //onlyGAME (noneCTF)
{*
 * only called when pers.spectator changes
 * note that resp.spectator should be the opposite of pers.spectator here
 *}
// (GAME <> CTF)
procedure spectator_respawn (edict_t *ent);
var
  i, numspec : integer;
begin
  // if the user wants to become a spectator, make sure he doesn't
  // exceed max_spectators

  if (ent.client.pers.spectator)
  then begin
    char *value := Info_ValueForKey (ent.client.pers.userinfo, 'spectator');
    if ( *spectator_password.string AND
         strcmp(spectator_password.string, 'none') AND
         strcmp(spectator_password.string, value) ) then
    begin
      gi.cprintf(ent, PRINT_HIGH, 'Spectator password incorrect.\n');
      ent.client.pers.spectator := false;
      gi.WriteByte (svc_stufftext);
      gi.WriteString ('spectator 0\n');
      gi.unicast(ent, true);
      Exit;
    end;

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

    if (numspec >= maxspectators.value) then
    begin
      gi.cprintf(ent, PRINT_HIGH, 'Server spectator limit is full.');
      ent.client.pers.spectator := false;
      // reset his spectator var
      gi.WriteByte (svc_stufftext);
      gi.WriteString ('spectator 0\n');
      gi.unicast(ent, true);
      Exit;
    end;
  end
  else begin
    // he was a spectator and wants to join the game
    // he must have the right password
    char *value := Info_ValueForKey (ent->client->pers.userinfo, "password");
    if ( *password.string AND
         strcmp(password.string, 'none') AND
         strcmp(password.string, value) ) then
    begin
      gi.cprintf(ent, PRINT_HIGH, 'Password incorrect.\n');
      ent.client.pers.spectator := true;
      gi.WriteByte (svc_stufftext);
      gi.WriteString ('spectator 1\n');
      gi.unicast(ent, true);
      Exit;
    end;
  end;

  // clear score on respawn
//  ent->client->pers.score = ent->client->resp.score = 0;
  ent.client.resp.score := 0;
  ent.client.pers.score := ent.client.resp.score;

  ent.svflags := ent.svflags AND (NOT SVF_NOCLIENT);
  PutClientInServer (ent);

  // add a teleportation effect
  if (!ent.client.pers.spectator) then
  begin
    // send effect
    gi.WriteByte (svc_muzzleflash);
    gi.WriteShort (ent-g_edicts);
    gi.WriteByte (MZ_LOGIN);
    gi.multicast (ent.s.origin, MULTICAST_PVS);

    // hold in place briefly
    ent.client.ps.pmove.pm_flags := PMF_TIME_TELEPORT;
    ent.client.ps.pmove.pm_time := 14;
  end;

  ent.client.respawn_time := level.time;

  if (ent.client.pers.spectator)
  then gi.bprintf (PRINT_HIGH, '%s has moved to the sidelines\n', ent.client.pers.netname)
  else gi.bprintf (PRINT_HIGH, '%s joined the game\n', ent.client.pers.netname);
end;//procedure (GAME <> CTF)

⌨️ 快捷键说明

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