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

📄 g_cmds.pas

📁 雷神之锤2(Quake2)Delphi源码
💻 PAS
📖 第 1 页 / 共 2 页
字号:
}
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.\n');
    Exit;
  end;

  it := @itemlist[ent.client.pers.selected_item];

  if not Assigned(it.use) then
  begin
    gi.cprintf(ent, PRINT_HIGH, 'Item is not usable.\n');
    Exit;
  end;

  it.use(ent,it);
end;

{
=================
Cmd_WeapPrev_f
=================
}
procedure Cmd_WeapPrev_f(ent :pedict_t);
var cl : pgclient_t;
    i,Index : Integer;
    it : pgitem_t;
    selected_weapon : Integer;
begin
  cl := ent.client;
  if not Assigned(cl.pers.weapon) then
    Exit;

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

  //scan for the next valid one
  for i := 1 to MAX_ITEMS do
  begin
    Index := (selected_weapon + i) mod MAX_ITEMS;
    if cl.pers.inventory[Index] = 0 then
      continue;
    it := @itemlist[Index];
    if not assigned(it.use) then
      continue;
    if it.flags and IT_WEAPON <> 0 then
      continue;

    cl.pers.weapon := it;
    Exit;  // succesfull
  end;
end;

{
=================
Cmd_WeapNext_f
=================
}
procedure Cmd_WeapNext_f (ent : pedict_t);
var cl : pgclient_t;
    i,Index : Integer;
    it : pgitem_t;
    selected_weapon : Integer;
begin
  cl := ent.client;
  if not Assigned(cl.pers.weapon) then
    Exit;

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

  //scan for the next valid one
  for i := 1 to MAX_ITEMS do
  begin
    Index := (selected_weapon - i) mod MAX_ITEMS;
    if cl.pers.inventory[Index] = 0 then
      continue;
    it := @itemlist[Index];
    if not assigned(it.use) then
      continue;
    if it.flags and IT_WEAPON <> 0 then
      continue;

    cl.pers.weapon := it;
    Exit;  // succesfull
  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 (not Assigned(cl.pers.weapon)) or (not Assigned(cl.pers.lastweapon)) then
    Exit;
  Index := ITEM_INDEX(cl.pers.lastweapon);
  if cl.pers.inventory[Index] = 0 then
    Exit;
  it := @itemlist[Index];
  if not Assigned(it.use) 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.\n');
    Exit;
  end;
  it := @itemlist[ent.client.pers.selected_item];
  if not Assigned(it.drop) then
  begin
    gi.cprintf (ent, PRINT_HIGH, 'Item is not dropable.\n');
    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;


function PlayerSort (const a, b : Pointer) : integer;
var anum,bnum :Integer;
begin
  anum := PInteger(a)^;
  bnum := pinteger(b)^;
  anum := gclient_a(game.clients)[anum].ps.stats[STAT_FRAGS];
  bnum := gclient_a(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;

// Delphi Specific : QSort
procedure qsort_int(base: Pointer; width: Integer; compare: QSortCB;  Left, Right: Integer; TempBuffer, TempBuffer2: Pointer);
var  Lo, Hi: Integer;  P: Pointer;
begin
  Lo := Left;
  Hi := Right;
  P := Pointer(Integer(base) + ((Lo + Hi) div 2)*width);
  Move(P^, TempBuffer2^, width);
  repeat
    while compare(Pointer(Integer(base) + Lo*width), TempBuffer2) < 0 do Inc(Lo);
    while compare(Pointer(Integer(base) + Hi*width), TempBuffer2) > 0 do Dec(Hi);
    if Lo <= Hi then
    begin
      Move(Pointer(Integer(base) + Lo*width)^, TempBuffer^,width);
      Move(Pointer(Integer(base) + Hi*width)^, Pointer(Integer(base) + Lo*width)^, width);
      Move(TempBuffer^,Pointer(Integer(base) + Hi*width)^, width);
      Inc(Lo);
      Dec(Hi);
    end;
  until Lo > Hi;
  if Hi > Left then qsort_int(base, width, compare, Left, Hi, TempBuffer, TempBuffer2);
  if Lo < Right then qsort_int(base, width, compare, Lo, Right, TempBuffer, TempBuffer2);
end;

procedure QSort(base: Pointer; num: Size_t; width: Size_t; compare: QSortCB);
var  p, p1: Pointer;
begin
  GetMem(p, width);
  GetMem(p1, width);
  {$IFDEF SUPPORTS_EXCEPTIONS}
  try
  {$ENDIF}
    qsort_int(base, width, compare, 0, num - 1, p, p1);
  {$IFDEF SUPPORTS_EXCEPTIONS}
  finally
  {$ENDIF}
    FreeMem(p1, width);
    FreeMem(p, width);
  {$IFDEF SUPPORTS_EXCEPTIONS}
  end;
  {$ENDIF}
end;
{
=================
Cmd_Players_f
=================
}
procedure Cmd_Players_f(ent : pedict_t);
var i : Integer;
    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 round(MaxClients.Value) do
  begin
    if gclient_a(game.clients)[i].pers.connected then
    begin
      Index[Count] := 1;
      Inc(Count);
    end;
  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\n',
    		[gclient_a(game.clients)[index[i]].ps.stats[STAT_FRAGS],
  		 gclient_a(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,'...\n');
      break;
    end;
    strcat(large,small);
  end;
  gi.cprintf(ent,PRINT_HIGH,'%s\n%i players\n'{,[large,Count]});
end;


{
=================
Cmd_Wave_f
=================
}
procedure Cmd_Wave_f(ent : pedict_t);
var i : Integer;
begin
  i := StrToInt(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\n');
      ent.s.frame := FRAME_flip01-1;
      ent.client.anim_end := FRAME_flip12;
    end;
    1 :
    begin
      gi.cprintf(ent,PRINT_HIGH,'salute\n');
      ent.s.frame := FRAME_salute01-1;
      ent.client.anim_end := FRAME_salute11;
    end;
    2 :
    begin
      gi.cprintf(ent,PRINT_HIGH,'taunt\n');
      ent.s.frame := FRAME_taunt01-1;
      ent.client.anim_end := FRAME_taunt17;
    end;
    3 :
    begin
      gi.cprintf(ent,PRINT_HIGH,'wave\n');
      ent.s.frame := FRAME_wave01-1;
      ent.client.anim_end := FRAME_wave11;
    end;
    4 :
    begin
      gi.cprintf(ent,PRINT_HIGH,'point\n');
      ent.s.frame := FRAME_point01-1;
      ent.client.anim_end := FRAME_point12;
    end;
  end;
end;

{
==================
Cmd_Say_f
==================
}
procedure Cmd_Say_f(ent : pedict_t;team : qboolean;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 round(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 <> 0 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\n'{,round((cl->flood_locktill - level.time)});
      Exit;
    end;
    i := round(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.\n'{,(int)flood_waitdelay->Value});
      Exit;
    end;
    cl.flood_whenhead := (cl.flood_whenhead + 1) mod round(sizeof(cl.flood_when)/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 not other.inuse then
      continue;
    if not Assigned(other.client) then
      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);
var i   : Integer;
    st  : array[0..80-1] of char;
    Text : array[0..1400-1] of char;
    e2   : pedict_t;
    Spec : string; //delphi specific
begin
  // connect time, ping, score, name
  Text[0] := #0;
  e2 := @g_edicts[1];
  for i := 0 to round(maxclients.Value) - 1 do
  begin
    if not e2.inuse then
    begin
      Inc(e2);
      continue;
    end;
    if e2.client.resp.spectator then
      Spec := ' (spectator)'
    else
      Spec := '';
    Com_sprintf(st, sizeof(st), '%02d:%02d %4d %3d %s%s\n',
			[(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,
			Spec]);
    if strlen(Text) + strlen(st) > SizeOf(Text) - 50 then
    begin
      // Format? was sprintf
      Format(Text+strlen(Text), ['And more...\']);
      gi.cprintf(ent,PRINT_HIGH,'%s'{, Text});
      Exit;
    end;
    Inc(e2);
  end;
  gi.cprintf(ent, PRINT_HIGH, '%s'{, Text});
end;

{
=================
ClientCommand
=================
}
procedure ClientCommand(ent : pedict_t);
var cmd : PChar;
begin
  if not Assigned(ent.client) then
    Exit;  // not fully in the game yet
  cmd := gi.argv(0);
  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 + -