📄 g_cmds.pas
字号:
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 + -