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

📄 p_hud.pas

📁 delphi编的不错的贪吃蛇
💻 PAS
📖 第 1 页 / 共 2 页
字号:
//99%
{----------------------------------------------------------------------------}
{                                                                            }
{ File(s): p_hud.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-04-07                                                   }
{ Updated by :  Scott price                                                  }
{                                                                            }
{----------------------------------------------------------------------------}
{ * Still dependent (to compile correctly) on:                               }
{ 1) unit g_local                                                            }
{                                                                            }
{----------------------------------------------------------------------------}
{ * TODO:                                                                    }
{ 1) Do more tests                                                           }
{ 2) Checks of the CTF Code still left                                       }
{                                                                            }
{----------------------------------------------------------------------------}

unit p_hud;

interface

uses
  q_shared,
  g_local;

procedure MoveClientToIntermission (ent : edict_p);  //for p_client

procedure DeathmatchScoreboardMessage (ent, killer : edict_p);  //for p_view
procedure G_SetStats (ent : edict_p);  //for p_view
procedure Cmd_Help_f (ent : edict_p);
procedure BeginIntermission (targ : edict_p);
procedure Cmd_Score_f (ent : edict_p);

{$IFNDEF CTF}
procedure G_CheckChaseStats (ent : edict_p);  //for p_view
procedure G_SetSpectatorStats (ent : edict_p);  //for p_view
{$ENDIF}


implementation

uses
  GameUnit,
  q_shared_add,
  game_add,
  g_main,
  g_items,
  p_client,
  CPas,
  g_utils,
  g_save;


{*
======================================================================

INTERMISSION

======================================================================
*}

procedure MoveClientToIntermission (ent : edict_p);
begin
  if (deathmatch^.value <> 0) OR (coop^.value <> 0) then
    ent^.client^.showscores := true;
  VectorCopy (level.intermission_origin, ent^.s.origin);
  ent^.client^.ps.pmove.origin[0] := trunc(level.intermission_origin[0] *8);
  ent^.client^.ps.pmove.origin[1] := trunc(level.intermission_origin[1] *8);
  ent^.client^.ps.pmove.origin[2] := trunc(level.intermission_origin[2] *8);
  VectorCopy (level.intermission_angle, ent^.client^.ps.viewangles);
  ent^.client^.ps.pmove.pm_type := PM_FREEZE;
  ent^.client^.ps.gunindex := 0;
  ent^.client^.ps.blend[3] := 0;
  ent^.client^.ps.rdflags := ent^.client^.ps.rdflags AND (NOT RDF_UNDERWATER);

  // clean up powerup info
  ent^.client^.quad_framenum := 0;
  ent^.client^.invincible_framenum := 0;
  ent^.client^.breather_framenum := 0;
  ent^.client^.enviro_framenum := 0;
  ent^.client^.grenade_blew_up := false;
  ent^.client^.grenade_time := 0;

  ent^.viewheight := 0;
  ent^.s.modelindex := 0;
  ent^.s.modelindex2 := 0;
  ent^.s.modelindex3 := 0;
  ent^.s.modelindex := 0;
  ent^.s.effects := 0;
  ent^.s.sound := 0;
  ent^.solid := SOLID_NOT;

  // add the layout

  if (deathmatch^.value <> 0) OR (coop^.value <> 0) then
  begin
    DeathmatchScoreboardMessage (ent, Nil);
    gi.unicast (ent, true);
  end;
end;


procedure BeginIntermission (targ : edict_p);
var
  i, n : integer;
  ent, client : edict_p;
begin
  if (level.intermissiontime <> 0) then
    Exit;   // already activated

{$IFDEF CTF}  //only CTF
(*Y//ZOID
  if (deathmatch.value AND ctf.value) then
    CTFCalcScores();
//ZOID*)
{$ENDIF}

  game.autosaved := false;

  // respawn any dead clients
  for i := 0 to Trunc(maxclients^.value)-1 do
  begin
    client := @g_edicts^[1 + i];
    if (NOT client^.inuse) then
      Continue;
    if (client^.health <= 0) then
      respawn (client);
  end;

  level.intermissiontime := level.time;
  level.changemap := targ^.map;

  if (strstr(level.changemap, '*') <> nil) then
  begin
    if (coop^.value <> 0) then
      for i := 0 to Trunc(maxclients^.value)-1 do
      begin
        client := @g_edicts^[1 + i];
        if (NOT client^.inuse) then
          Continue;
        // strip players of all keys between units
        for n := 0 to MAX_ITEMS-1 do
          if (itemlist[n].flags AND IT_KEY) <> 0 then
            client^.client^.pers.inventory[n] := 0;
      end;
  end
  else
  begin
    if (deathmatch^.value = 0) then
    begin
      level.exitintermission := 1;	 // go immediately to the next level
      Exit;
    end;
  end;

  level.exitintermission := 0;

  // find an intermission spot
  ent := G_Find (NULL, FOFS_classname, 'info_player_intermission');
  if (ent = Nil) then
  begin
    // the map creator forgot to put in an intermission point...
    ent := G_Find (NULL, FOFS_classname, 'info_player_start');
    if (ent = Nil) then
      ent := G_Find (NULL, FOFS_classname, 'info_player_deathmatch');
  end
  else
  begin
    // chose one of four spots
    i := rand() mod 3;
    while (i <> 0) do
    begin
      Dec(i);  { SP:  Operation really should occur immediately after evaluator }
      ent := G_Find (ent, FOFS_classname, 'info_player_intermission');
      if (ent = Nil) then // wrap around the list
        ent := G_Find (ent, FOFS_classname, 'info_player_intermission');
    end;
  end;

  VectorCopy (ent^.s.origin, level.intermission_origin);
  VectorCopy (ent^.s.angles, level.intermission_angle);

  // move all clients to the intermission point
  for i := 0 to Trunc(maxclients^.value)-1 do
  begin
    client := @g_edicts^[1 + i];
    if (NOT client^.inuse) then
      Continue;
    MoveClientToIntermission (client);
  end;
end;


{*
==================
DeathmatchScoreboardMessage
==================
*}
procedure DeathmatchScoreboardMessage (ent, killer : edict_p);
var
  entry : array[0..1024-1] of char;
  string_ : array[0..1400-1] of char;

  stringlength,
  i, j, k,
  score, total,
  x, y,
  picnum        : integer;

  sorted,
  sortedscores  : array [0..MAX_CLIENTS-1] of integer;

  cl : gclient_p;
  cl_ent : edict_p;
  tag : PChar;
begin
{$IFDEF CTF}  //only CTF
(*Y//ZOID
  if (ctf.value) then
  begin
    CTFScoreboardMessage (ent, killer);
    Exit;
  end;
//ZOID*)
{$ENDIF}

  // sort the clients by score
  total := 0;
  for i := 0 to game.maxclients-1 do
  begin
    cl_ent := @g_edicts^[1 + i];

{$IFDEF CTF}
    if (NOT cl_ent^.inuse) then
      Continue;
{$ELSE}
    if (not cl_ent^.inuse) OR (gclient_a(game.clients)[i].resp.spectator) then
      Continue;
{$ENDIF}

    score := gclient_a(game.clients)[i].resp.score;
    j := 0;
    while j < total do
    begin
      if (score > sortedscores[j]) then
        Break;

      Inc(j);
    end;

    k := total;
    while k > j do
    begin
      sorted[k] := sorted[k-1];
      sortedscores[k] := sortedscores[k-1];
      Dec(k);
    end;

    sorted[j] := i;
    sortedscores[j] := score;
    Inc(total);
  end;

  // print level name and exit rules
  string_[0] := #0;

  stringlength := strlen(string_);

  // add the clients in sorted order
  if (total > 12) then
    total := 12;

  for i := 0 to total-1 do
  begin
    cl := @gclient_a(game.clients)[sorted[i]];
    cl_ent := @g_edicts^[1 + sorted[i]];

    picnum := gi.imageindex ('i_fixme');

    if (i >= 6) then
      x := 160
    else
      x := 0;

    y := 32 + 32 * (i MOD 6);

    // add a dogtag
    if (cl_ent = ent) then
      tag := 'tag1'
    else if (cl_ent = killer) then
      tag := 'tag2'
    else
      tag := nil;
    if (tag <> nil) then
    begin
      Com_sprintf (entry, SizeOf(entry), 'xv %i yv %i picn %s ',[x+32, y, Tag]);
      j := strlen(entry);
      if (stringlength + j > 1024) then
        Break;
      strcpy (string_ + stringlength, entry);
      stringlength := stringlength + j;
    end;

    // send the layout
    Com_sprintf (entry, SizeOf(entry),
                 'client %i %i %i %i %i %i ',
                 [x, y, sorted[i], cl^.resp.score, cl^.ping, (level.framenum - cl^.resp.enterframe) div 600]);
    j := strlen(entry);
    if (stringlength + j > 1024) then
      Break;
    strcpy (string_ + stringlength, entry);
    Inc(stringlength, j);
  end;

  gi.WriteByte (svc_layout);
  gi.WriteString (string_);
end;


{*
==================
DeathmatchScoreboard

Draw instead of help message.
Note that it isn't that hard to overflow the 1400 byte message limit!
==================
*}
procedure DeathmatchScoreboard (ent : edict_p);

⌨️ 快捷键说明

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