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