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

📄 g_cmds.pas

📁 雷神之锤2(Quake2)Delphi源码
💻 PAS
📖 第 1 页 / 共 2 页
字号:
  cl := ent^.client;

  cl^.showscores := false;
  cl^.showhelp := false;

  if (cl^.showinventory = True) then
  begin
    cl^.showinventory := False;
    Exit;
  end;

  cl^.showinventory := True;

  gi.WriteByte(svc_inventory);
  for i := 0 to (MAX_ITEMS - 1) do
    gi.WriteShort(cl^.pers.inventory[i]);

  gi.unicast(ent, True);
end;

(* =================
Cmd_InvUse_f
================= *)
procedure Cmd_InvUse_f(ent: Pedict_t);
var
  it: Pgitem_t;
begin
  ValidateSelectedItem(ent);

  if (ent^.client^.pers.selected_item = -1) then
  begin
    gi.cprintf(ent, PRINT_HIGH, 'No item to use.'#10);
    Exit;
  end;

  it := @itemlist[ent^.client^.pers.selected_item];
  if (it^.use = 0) then
  begin
    gi.cprintf(ent, PRINT_HIGH, 'Item is not usable.'#10);
    Exit;
  end;
  it^.use(ent, it);
end;

(* =================
Cmd_WeapPrev_f
================= *)
procedure Cmd_WeapPrev_f(ent: Pedict_t);
var
  cl: gclient_t;
  i, index, selected_weapon: Integer;
  it: Pgitem_t;
begin
  cl := ent^.client;

  if (cl^.pers.weapon = 0) then
    Exit;

  selected_weapon := ITEM_INDEX(cl^.pers.weapon);

  // scan  for the next valid one
  for i := 1 to (MAX_ITEMS - 1) do
  begin
    index := (selected_weapon + i) mod MAX_ITEMS;
    if (cl^.pers.inventory[index] = Nil) then
      Continue;

    it := @itemlist[index];
    if (it^.use = 0)
      Continue;

    if ((it^.flags AND IT_WEAPON) = 0)
      Continue;

    it^.use(ent, it);
    if (cl^.pers.weapon = it) then
      Exit;	// successful
  end;
end;

(* =================
Cmd_WeapNext_f
================= *)
procedure Cmd_WeapNext_f(ent: Pedict_t);
var
  cl: Pgclient_t;
  i, index, selected_weapon: Integer;
  it: Pgitem_t;
begin
  cl := ent^.client;

  if (cl^.pers.weapon = 0) then
    Exit;

  selected_weapon := ITEM_INDEX(cl^.pers.weapon);

  // scan  for the next valid one
  for i := 1 to (MAX_ITEMS - 1) do
  begin
    index := (selected_weapon + MAX_ITEMS - i) mod MAX_ITEMS;
    if (cl^.pers.inventory[index] = 0) then
      Continue;

    it := @itemlist[index];
    if (it^.use = 0) then
      Continue;

    if ((it^.flags AND IT_WEAPON) = 0) then
      Continue;

    it^.use(ent, it);
    if (cl^.pers.weapon = it) then
      Exit;	// successful
  end;
end;

(* =================
Cmd_WeapLast_f
================= *)
procedure Cmd_WeapLast_f(ent: Pedict_t);
var
  cl: Pgclient_t;
  index: Integer;
  it: Pgitem_t;
begin
  cl := ent^.client;

  if (cl^.pers.weapon = 0) OR (cl^.pers.lastweapon = 0) then // ???:  Should these be Nil?
    Exit;

  index := ITEM_INDEX(cl^.pers.lastweapon);
  if (cl^.pers.inventory[index] = 0) then
    Exit;

  it := @itemlist[index];

  if (it^.use = 0) then
    Exit;
  if ((it^.flags AND IT_WEAPON) = 0) then
    Exit;

  it^.use(ent, it);
end;

(* =================
Cmd_InvDrop_f
================= *)
procedure Cmd_InvDrop_f(ent: Pedict_t);
var
  it: Pgitem_t;
begin
  ValidateSelectedItem(ent);

  if (ent^.client^.pers.selected_item = -1) then
  begin
    gi.cprintf(ent, PRINT_HIGH, 'No item to drop.'#10);
    Exit;
  end;

  it := @itemlist[ent^.client^.pers.selected_item];
  if (it^.drop = 0) then
  begin
    gi.cprintf(ent, PRINT_HIGH, 'Item is not dropable.'#10);
    Exit;
  end;
  it^.drop(ent, it);
end;

(* =================
Cmd_Kill_f
================= *)
procedure Cmd_Kill_f(ent: Pedict_t);
begin
  if ((level.time - ent^.client^.respawn_time) < 5) then
    Exit;

  ent^.flags := ent^.flags AND (NOT FL_GODMODE);
  ent^.health := 0;
  meansOfDeath := MOD_SUICIDE;
  player_die(ent, ent, ent, 100000, vec3_origin);
end;

(* =================
Cmd_PutAway_f
================= *)
procedure Cmd_PutAway_f(ent: Pedict_t);
begin
  ent^.client^.showscores := False;
  ent^.client^.showhelp := False;
  ent^.client^.showinventory := False;
end;

{ TODO: Convert  -  int PlayerSort (void const *a, void const *b) }
function PlayerSort(const a, b: Pointer): Integer;  { ???  Not sure about this one at all... }
var
  anum, bnum: Integer;
begin
  anum := PInteger(a)^;
  bnum = PInteger(b)^;

  anum := game.clients[anum].ps.stats[STAT_FRAGS];
  bnum := game.clients[bnum].ps.stats[STAT_FRAGS];

  if (anum < bnum) then
  begin
    Result := -1;
    Exit;
  end;
  if (anum > bnum) then
  begin
    Result := 1;
    Exit;
  end;
  Result := 0;
end;

(* =================
Cmd_Players_f
================= *)
procedure Cmd_Players_f(ent: Pedict_t);
var
  i, count: Integer;
  small: array[0..64-1] of char;
  large: array[0..1280-1] of char;
  index: array[0..256-1] of Integer;
begin
  count := 0;
  for i := 0 to (maxclients^.value - 1) do
    if (game.clients[i].pers.connected <> 0) then
    begin
      index[count] := i;
      Inc(count);
    end;

  // sort by frags
  qsort(index, count, SizeOf(index[0]), PlayerSort);

  // print information
  large[0] := 0;

  for i := 0 to (count - 1) do
  begin
    Com_sprintf(small, sizeof(small), '%3i %s'#10,  { TODO:  What does '%3i' translate to? }
            game.clients[index[i]].ps.stats[STAT_FRAGS],
            game.clients[index[i]].pers.netname);
    if (strlen(small) + strlen(large)) > (sizeof(large) - 100) then
    begin
      // can't print all of them in one packet
      strcat (large, '...'#10);
      Break;
    end;
    strcat(large, small);
  end;

  gi.cprintf(ent, PRINT_HIGH, PChar('%s'#10 + '%i players'#10), large, count);
end;

(* =================
Cmd_Wave_f
================= *)
procedure Cmd_Wave_f(ent: Pedict_t);
var
  i: Integer;
begin
  i := atoi(gi.argv(1));

  // can't wave when ducked
  if (ent^.client^.ps.pmove.pm_flags AND PMF_DUCKED) <> 0 then
    Exit;

  if (ent^.client^.anim_priority > ANIM_WAVE) then
    Exit;

  ent^.client^.anim_priority := ANIM_WAVE;

  case i of
    0:  begin
      gi.cprintf(ent, PRINT_HIGH, 'flipoff'#10);
      ent^.s.frame := FRAME_flip01 - 1;
      ent^.client^.anim_end := FRAME_flip12;
      //Break;
    end;
    1:  begin
      gi.cprintf(ent, PRINT_HIGH, 'salute'#10);
      ent^.s.frame := FRAME_salute01 - 1;
      ent^.client^.anim_end := FRAME_salute11;
      //Break;
    end;
    2:  begin
      gi.cprintf(ent, PRINT_HIGH, 'taunt'#10);
      ent^.s.frame := FRAME_taunt01 - 1;
      ent^.client^.anim_end := FRAME_taunt17;
      //Break;
    end;
    3:  begin
      gi.cprintf(ent, PRINT_HIGH, 'wave'#10);
      ent^.s.frame := FRAME_wave01 - 1;
      ent^.client^.anim_end := FRAME_wave11;
      //Break;
    end;
  else
    gi.cprintf(ent, PRINT_HIGH, 'point'#10);
    ent^.s.frame := FRAME_point01-1;
    ent^.client^.anim_end := FRAME_point12;
    //Break;
  end;
end;

(* ==================
Cmd_Say_f
================== *)
procedure Cmd_Say_f(ent: Pedict_t; team, arg0: qboolean);
var
  i, j: Integer;
  other: Pedict_t;
  p: PChar;
  text: array[0..2048-1] of Char;
  cl: Pgclient_t;
begin
  if (gi.argc < 2) AND (NOT arg0) then
    Exit;

  if ((integer(dmflags^.value) AND (DF_MODELTEAMS OR DF_SKINTEAMS)) = 0) then
    team := False;

  if team then
    Com_sprintf(text, sizeof(text), '(%s): ', ent^.client^.pers.netname)
  else
    Com_sprintf(text, sizeof(text), '%s: ', ent^.client^.pers.netname);

  if (arg0) then
  begin
    strcat(text, gi.argv(0));
    strcat(text, ' ');
    strcat(text, gi.args());
  end
  else
  begin
    p := gi.args();

    if (p^ = '"') then
    begin
      Inc(p);
      p[strlen(p)-1] := 0;
    end;
    strcat(text, p);
  end;

  // don't let text be too long for malicious reasons
  if (strlen(text) > 150) then
    text[150] := 0;

  strcat(text, '\n');

  if (flood_msgs^.value) then
  begin
    cl := ent^.client;

    if (level.time < cl^.flood_locktill) then
    begin
        gi.cprintf(ent, PRINT_HIGH, 'You can''t talk for %d more seconds'#10,
          Integer(cl^.flood_locktill - level.time));
        Exit;
    end;
    i := cl^.flood_whenhead - flood_msgs^.value + 1;
    if (i < 0) then
        i := (SizeOf(cl^.flood_when) div SizeOf(cl^.flood_when[0])) + i;

    if (cl^.flood_when[i] <> 0) AND
    (level.time - cl^.flood_when[i] < flood_persecond^.value) then
    begin
      cl^.flood_locktill := level.time + flood_waitdelay^.value;
      gi.cprintf(ent, PRINT_CHAT, 'Flood protection:  You can''t talk for %d seconds.'#10,
        Integer(flood_waitdelay^.value));
      Exit;
    end;
    cl^.flood_whenhead := (cl^.flood_whenhead + 1) mod
            (SizeOf(cl^.flood_when) div sizeof(cl^.flood_when[0]));
    cl^.flood_when[cl^.flood_whenhead] := level.time;
  end;

  if (dedicated^.value <> 0) then
    gi.cprintf(Nil, PRINT_CHAT, '%s', text);

  for j := 1 to game.maxclients do
  begin
    other := @g_edicts[j];
    if (other^.inuse = 0) then
      Continue;
    if (other^.client = Nil)
      Continue;
    if (team) then
    begin
      if (NOT OnSameTeam(ent, other)) then
        Continue;
    end;
    gi.cprintf(other, PRINT_CHAT, '%s', text);
  end;
end;

procedure Cmd_PlayerList_f(ent: Pedict_t);
{ TODO:  Check this conversion! }
var
  i: Integer;
  st: array[0..80-1] of Char;
  text: array[0..1400-1] of Char;
  e2: Pedict_t;
  pcSpectator: PChar;
begin
  { TODO:  Check this conversion! }
  // connect time, ping, score, name
  { TODO:  Don't think this line will compile in Delphi }
  text^ := 0;

  { TODO:  Don't think this line will compile in Delphi }
  e2 := g_edicts + 1;  { Try converting to:  Pedict_t(Integer(@g_edicts) + 1) }
  for i := 0 to (maxclients^.value - 1) do begin
    TRY
      if (e2^.inuse = 0) then
        Continue;

      { This is an addition to resolve the following line:
          e2^.client^.resp.spectator ? ' (spectator)' : '');
      }
      if e2^.client^.resp.spectator <> 0 then
        pcSpectator := ' (spectator)'
      else
        pcSpectator := '';

      Com_sprintf(st, SizeOf(st), '%02d:%02d %4d %3d %s%s'#10,
              (level.framenum - e2^.client^.resp.enterframe) / 600,
              ((level.framenum - e2^.client^.resp.enterframe) mod 600) / 10,
              e2^.client^.ping,
              e2^.client^.resp.score,
              e2^.client^.pers.netname,
              { TODO:  Convert the following Line >>>> }
              //e2^.client^.resp.spectator ? ' (spectator)' : '');
              pcSpectator);

      if (strlen(text) + strlen(st)) > (sizeof(text) - 50) then
      begin
        sprintf(text + strlen(text), 'And more...'#10);
        gi.cprintf(ent, PRINT_HIGH, '%s', text);
        Exit;
      end;
      strcat(text, st);
    FINALLY
      Inc(e2);
    END;
  end;

  gi.cprintf(ent, PRINT_HIGH, '%s', text);
end;

(* =================
ClientCommand
================= *)
procedure ClientCommand(ent: Pedict_t);
var
  cmd: PChar;
begin
  if (ent^.client = Nil) then
    Exit;		// not fully in game yet

  cmd := gi.argv(0);  { TODO:  Replace with??:  ParamStr(0) or Application.ExeName }

  if (Q_stricmp(cmd, 'players') = 0) then
  begin
    Cmd_Players_f(ent);
    Exit;
  end;
  if (Q_stricmp(cmd, 'say') = 0) then
  begin
    Cmd_Say_f(ent, False, False);
    Exit;
  end;
  if (Q_stricmp(cmd, 'say_team') = 0) then
  begin
    Cmd_Say_f(ent, True, False);
    Exit;
  end;
  if (Q_stricmp(cmd, 'score') = 0) then
  begin
    Cmd_Score_f(ent);
    Exit;
  end;
  if (Q_stricmp(cmd, 'help') = 0) then
  begin
    Cmd_Help_f(ent);
    Exit;
  end;

  if (level.intermissiontime <> 0) then
    Exit;

  if (Q_stricmp(cmd, 'use') = 0) then
    Cmd_Use_f(ent)
  else if (Q_stricmp(cmd, 'drop') = 0) then
    Cmd_Drop_f(ent)
  else if (Q_stricmp(cmd, 'give') = 0) then
    Cmd_Give_f(ent)
  else if (Q_stricmp(cmd, 'god') = 0) then
    Cmd_God_f(ent)
  else if (Q_stricmp(cmd, 'notarget') = 0) then
    Cmd_Notarget_f(ent)
  else if (Q_stricmp(cmd, 'noclip') = 0) then
    Cmd_Noclip_f(ent)
  else if (Q_stricmp(cmd, 'inven') = 0) then
    Cmd_Inven_f(ent)
  else if (Q_stricmp(cmd, 'invnext') = 0) then
    SelectNextItem(ent, -1)
  else if (Q_stricmp(cmd, 'invprev') = 0) then
    SelectPrevItem(ent, -1)
  else if (Q_stricmp(cmd, 'invnextw') = 0) then
    SelectNextItem(ent, IT_WEAPON)
  else if (Q_stricmp(cmd, 'invprevw') = 0) then
    SelectPrevItem(ent, IT_WEAPON)
  else if (Q_stricmp(cmd, 'invnextp') = 0) then
    SelectNextItem(ent, IT_POWERUP)
  else if (Q_stricmp(cmd, 'invprevp') = 0) then
    SelectPrevItem(ent, IT_POWERUP)
  else if (Q_stricmp(cmd, 'invuse') = 0) then
    Cmd_InvUse_f(ent)
  else if (Q_stricmp(cmd, 'invdrop') = 0) then
    Cmd_InvDrop_f(ent)
  else if (Q_stricmp(cmd, 'weapprev') = 0) then
    Cmd_WeapPrev_f(ent)
  else if (Q_stricmp(cmd, 'weapnext') = 0) then
    Cmd_WeapNext_f(ent)
  else if (Q_stricmp(cmd, 'weaplast') = 0) then
    Cmd_WeapLast_f(ent)
  else if (Q_stricmp(cmd, 'kill') = 0) then
    Cmd_Kill_f(ent)
  else if (Q_stricmp(cmd, 'putaway') = 0) then
    Cmd_PutAway_f(ent)
  else if (Q_stricmp(cmd, 'wave') = 0) then
    Cmd_Wave_f(ent)
  else if (Q_stricmp(cmd, 'playerlist') = 0) then
    Cmd_PlayerList_f(ent)
  else
    // anything that doesn't match a command will be a chat
    Cmd_Say_f(ent, False, True);
end;

end.

⌨️ 快捷键说明

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