diff --git a/src/game/g_game.pas b/src/game/g_game.pas
index e3d9b7bb2bed0c13288230a0e9be989c17656068..6f70992fef7a5f5a48e3bad1e50d77e9722b1f86 100644 (file)
--- a/src/game/g_game.pas
+++ b/src/game/g_game.pas
procedure g_Game_LoadData();
procedure g_Game_FreeData();
procedure g_Game_Update();
procedure g_Game_LoadData();
procedure g_Game_FreeData();
procedure g_Game_Update();
+procedure g_Game_PreUpdate();
procedure g_Game_Draw();
procedure g_Game_Quit();
procedure g_Game_SetupScreenSize();
procedure g_Game_Draw();
procedure g_Game_Quit();
procedure g_Game_SetupScreenSize();
EXIT_ENDLEVELSINGLE = 4;
EXIT_ENDLEVELCUSTOM = 5;
EXIT_ENDLEVELSINGLE = 4;
EXIT_ENDLEVELCUSTOM = 5;
- GAME_OPTION_RESERVED = 1;
- GAME_OPTION_TEAMDAMAGE = 2;
- GAME_OPTION_ALLOWEXIT = 4;
- GAME_OPTION_WEAPONSTAY = 8;
- GAME_OPTION_MONSTERS = 16;
- GAME_OPTION_BOTVSPLAYER = 32;
- GAME_OPTION_BOTVSMONSTER = 64;
- GAME_OPTION_DMKEYS = 128;
+ GAME_OPTION_RESERVED = 1;
+ GAME_OPTION_TEAMDAMAGE = 2;
+ GAME_OPTION_ALLOWEXIT = 4;
+ GAME_OPTION_WEAPONSTAY = 8;
+ GAME_OPTION_MONSTERS = 16;
+ GAME_OPTION_BOTVSPLAYER = 32;
+ GAME_OPTION_BOTVSMONSTER = 64;
+ GAME_OPTION_DMKEYS = 128;
+ GAME_OPTION_TEAMHITTRACE = 256;
+ GAME_OPTION_TEAMHITPROJECTILE = 512;
+ GAME_OPTION_TEAMABSORBDAMAGE = 1024;
STATE_NONE = 0;
STATE_MENU = 1;
STATE_NONE = 0;
STATE_MENU = 1;
gShowFPS: Boolean = False;
gShowGoals: Boolean = True;
gShowStat: Boolean = True;
gShowFPS: Boolean = False;
gShowGoals: Boolean = True;
gShowStat: Boolean = True;
+ gShowPIDs: Boolean = False;
gShowKillMsg: Boolean = True;
gShowLives: Boolean = True;
gShowPing: Boolean = False;
gShowKillMsg: Boolean = True;
gShowLives: Boolean = True;
gShowPing: Boolean = False;
g_holmes,
{$ENDIF}
e_texture, e_res, g_textures, g_window, g_menu,
g_holmes,
{$ENDIF}
e_texture, e_res, g_textures, g_window, g_menu,
- e_input, e_log, g_console, g_items, g_map, g_panel,
+ e_input, e_log, g_console, r_console, g_items, g_map, g_panel,
g_playermodel, g_gfx, g_options, Math,
g_triggers, g_monsters, e_sound, CONFIG,
g_playermodel, g_gfx, g_options, Math,
g_triggers, g_monsters, e_sound, CONFIG,
- g_language, g_net, g_main,
+ g_language, g_net, g_main, g_phys,
ENet, e_msg, g_netmsg, g_netmaster,
sfs, wadreader, g_system;
ENet, e_msg, g_netmsg, g_netmaster,
sfs, wadreader, g_system;
stat: TPlayerStatArray;
wad, map: string;
mapstr: string;
stat: TPlayerStatArray;
wad, map: string;
mapstr: string;
+ namestr: string;
begin
s1 := '';
s2 := '';
begin
s1 := '';
s2 := '';
gg := g;
bb := b;
end;
gg := g;
bb := b;
end;
+ if gShowPIDs then
+ namestr := Format('[%5d] %s', [UID, Name])
+ else
+ namestr := Name;
// Èìÿ
// Èìÿ
- e_TextureFontPrintEx(x+16, _y, Name, gStdFont, rr, gg, bb, 1);
+ e_TextureFontPrintEx(x+16, _y, namestr, gStdFont, rr, gg, bb, 1);
// Ïèíã/ïîòåðè
e_TextureFontPrintEx(x+w1+16, _y, Format(_lc[I_GAME_PING_MS], [Ping, Loss]), gStdFont, rr, gg, bb, 1);
// Ôðàãè
// Ïèíã/ïîòåðè
e_TextureFontPrintEx(x+w1+16, _y, Format(_lc[I_GAME_PING_MS], [Ping, Loss]), gStdFont, rr, gg, bb, 1);
// Ôðàãè
r := 255;
g := 127;
end;
r := 255;
g := 127;
end;
+ if gShowPIDs then
+ namestr := Format('[%5d] %s', [UID, Name])
+ else
+ namestr := Name;
// Öâåò èãðîêà
e_DrawFillQuad(x+16, _y+4, x+32-1, _y+16+4-1, Color.R, Color.G, Color.B, 0);
e_DrawQuad(x+16, _y+4, x+32-1, _y+16+4-1, 192, 192, 192);
// Èìÿ
// Öâåò èãðîêà
e_DrawFillQuad(x+16, _y+4, x+32-1, _y+16+4-1, Color.R, Color.G, Color.B, 0);
e_DrawQuad(x+16, _y+4, x+32-1, _y+16+4-1, 192, 192, 192);
// Èìÿ
- e_TextureFontPrintEx(x+16+16+8, _y+4, Name, gStdFont, r, g, 0, 1);
+ e_TextureFontPrintEx(x+16+16+8, _y+4, namestr, gStdFont, r, g, 0, 1);
// Ïèíã/ïîòåðè
e_TextureFontPrintEx(x+w1+16, _y+4, Format(_lc[I_GAME_PING_MS], [Ping, Loss]), gStdFont, r, g, 0, 1);
// Ôðàãè
// Ïèíã/ïîòåðè
e_TextureFontPrintEx(x+w1+16, _y+4, Format(_lc[I_GAME_PING_MS], [Ping, Loss]), gStdFont, r, g, 0, 1);
// Ôðàãè
g_Game_SetLoadingText('', 0, False);
g_Game_SetLoadingText(_lc[I_LOAD_CONSOLE], 0, False);
g_Game_SetLoadingText('', 0, False);
g_Game_SetLoadingText(_lc[I_LOAD_CONSOLE], 0, False);
+ r_Console_Init;
g_Console_Init();
g_Game_SetLoadingText(_lc[I_LOAD_MODELS], 0, False);
g_Console_Init();
g_Game_SetLoadingText(_lc[I_LOAD_MODELS], 0, False);
MC_SEND_CheatRequest(NET_CHEAT_READY);
end;
MC_SEND_CheatRequest(NET_CHEAT_READY);
end;
+procedure g_Game_PreUpdate();
+begin
+ // these are in separate PreUpdate functions because they can interact during Update()
+ // and are synced over the net
+ // we don't care that much about corpses and gibs
+ g_Player_PreUpdate();
+ g_Monsters_PreUpdate();
+ g_Items_PreUpdate();
+ g_Weapon_PreUpdate();
+end;
+
procedure g_Game_Update();
var
Msg: g_gui.TMessage;
procedure g_Game_Update();
var
Msg: g_gui.TMessage;
// no need to, as we'll do it in event handler
// Îáíîâëÿåì êîíñîëü (äâèæåíèå è ñîîáùåíèÿ):
// no need to, as we'll do it in event handler
// Îáíîâëÿåì êîíñîëü (äâèæåíèå è ñîîáùåíèÿ):
+ r_Console_Update;
g_Console_Update();
if (NetMode = NET_NONE) and (g_Game_IsNet) and (gGameOn or (gState in [STATE_FOLD, STATE_INTERCUSTOM])) then
g_Console_Update();
if (NetMode = NET_NONE) and (g_Game_IsNet) and (gGameOn or (gState in [STATE_FOLD, STATE_INTERCUSTOM])) then
end;
end;
end;
end;
- // these are in separate PreUpdate functions because they can interact during Update()
- // we don't care that much about corpses and gibs
- g_Player_PreUpdate();
- g_Monsters_PreUpdate();
- g_Items_PreUpdate();
- g_Weapon_PreUpdate();
-
// Îáíîâëÿåì âñå îñòàëüíîå:
g_Map_Update();
g_Items_Update();
// Îáíîâëÿåì âñå îñòàëüíîå:
g_Map_Update();
g_Items_Update();
procedure DrawPlayer(p: TPlayer);
var
px, py, a, b, c, d, i, fX, fY: Integer;
procedure DrawPlayer(p: TPlayer);
var
px, py, a, b, c, d, i, fX, fY: Integer;
+ camObj: TObj;
//R: TRect;
begin
if (p = nil) or (p.FDummy) then
//R: TRect;
begin
if (p = nil) or (p.FDummy) then
glPushMatrix();
glPushMatrix();
- p.Obj.lerp(gLerpFactor, fX, fY);
+ camObj := p.getCameraObj();
+ camObj.lerp(gLerpFactor, fX, fY);
px := fX + PLAYER_RECT_CX;
px := fX + PLAYER_RECT_CX;
- py := fY + PLAYER_RECT_CY+nlerp(p.SlopeOld, p.Obj.slopeUpLeft, gLerpFactor);
+ py := fY + PLAYER_RECT_CY+nlerp(p.SlopeOld, camObj.slopeUpLeft, gLerpFactor);
if (g_dbg_scale = 1.0) and (not g_dbg_ignore_bounds) then
begin
if (g_dbg_scale = 1.0) and (not g_dbg_ignore_bounds) then
begin
Round(gScreenHeight / 2.75)-(h div 2), MessageText);
end;
Round(gScreenHeight / 2.75)-(h div 2), MessageText);
end;
- if IsDrawStat or (gSpectMode = 1) then DrawStat();
+ if IsDrawStat or (gSpectMode = SPECT_STATS) then
+ DrawStat();
if gSpectHUD and (not gChatShow) and (gSpectMode <> SPECT_NONE) and (not gSpectAuto) then
begin
if gSpectHUD and (not gChatShow) and (gSpectMode <> SPECT_NONE) and (not gSpectAuto) then
begin
end;
{$IFNDEF HEADLESS}
end;
{$IFNDEF HEADLESS}
- g_Console_Draw();
+ r_Console_Draw();
{$ENDIF}
if g_debug_Sounds and gGameOn then
{$ENDIF}
if g_debug_Sounds and gGameOn then
e_WriteLog(Format(_lc[I_FATAL_ERROR], [Text]), TMsgType.Warning);
gExit := EXIT_SIMPLE;
e_WriteLog(Format(_lc[I_FATAL_ERROR], [Text]), TMsgType.Warning);
gExit := EXIT_SIMPLE;
+ if gGameOn then EndGame;
end;
procedure g_SimpleError(Text: String);
end;
procedure g_SimpleError(Text: String);
gGameSettings.Options := gGameSettings.Options + GAME_OPTION_ALLOWEXIT;
gGameSettings.Options := gGameSettings.Options + GAME_OPTION_MONSTERS;
gGameSettings.Options := gGameSettings.Options + GAME_OPTION_BOTVSMONSTER;
gGameSettings.Options := gGameSettings.Options + GAME_OPTION_ALLOWEXIT;
gGameSettings.Options := gGameSettings.Options + GAME_OPTION_MONSTERS;
gGameSettings.Options := gGameSettings.Options + GAME_OPTION_BOTVSMONSTER;
+ gGameSettings.Options := gGameSettings.Options + GAME_OPTION_TEAMHITPROJECTILE;
+ gGameSettings.Options := gGameSettings.Options + GAME_OPTION_TEAMHITTRACE;
gSwitchGameMode := GM_SINGLE;
gLMSRespawn := LMS_RESPAWN_NONE;
gSwitchGameMode := GM_SINGLE;
gLMSRespawn := LMS_RESPAWN_NONE;
begin
ParseGameFlag(GAME_OPTION_TEAMDAMAGE, I_MSG_FRIENDLY_FIRE_OFF, I_MSG_FRIENDLY_FIRE_ON);
end
begin
ParseGameFlag(GAME_OPTION_TEAMDAMAGE, I_MSG_FRIENDLY_FIRE_OFF, I_MSG_FRIENDLY_FIRE_ON);
end
+ else if cmd = 'g_friendly_absorb_damage' then
+ begin
+ ParseGameFlag(GAME_OPTION_TEAMABSORBDAMAGE, I_MSG_FRIENDLY_FIRE_OFF, I_MSG_FRIENDLY_FIRE_ON);
+ end
+ else if cmd = 'g_friendly_hit_trace' then
+ begin
+ ParseGameFlag(GAME_OPTION_TEAMHITTRACE, I_MSG_FRIENDLY_FIRE_OFF, I_MSG_FRIENDLY_FIRE_ON);
+ end
+ else if cmd = 'g_friendly_hit_projectile' then
+ begin
+ ParseGameFlag(GAME_OPTION_TEAMHITPROJECTILE, I_MSG_FRIENDLY_FIRE_OFF, I_MSG_FRIENDLY_FIRE_ON);
+ end
else if cmd = 'g_weaponstay' then
begin
ParseGameFlag(GAME_OPTION_WEAPONSTAY, I_MSG_WEAPONSTAY_OFF, I_MSG_WEAPONSTAY_ON);
else if cmd = 'g_weaponstay' then
begin
ParseGameFlag(GAME_OPTION_WEAPONSTAY, I_MSG_WEAPONSTAY_OFF, I_MSG_WEAPONSTAY_ON);
procedure PlayerSettingsCVars(P: SSArray);
var
cmd: string;
procedure PlayerSettingsCVars(P: SSArray);
var
cmd: string;
+ team: Byte;
+
+ function ParseTeam(s: string): Byte;
+ begin
+ result := 0;
+ case s of
+ 'red', '1': result := TEAM_RED;
+ 'blue', '2': result := TEAM_BLUE;
+ else result := TEAM_NONE;
+ end;
+ end;
begin
cmd := LowerCase(P[0]);
case cmd of
begin
cmd := LowerCase(P[0]);
case cmd of
end;
end;
end;
end;
end;
end;
+ 'p1_team':
+ begin
+ // TODO: switch teams if in game or store this separately
+ if (Length(P) > 1) then
+ begin
+ team := ParseTeam(P[1]);
+ if team = TEAM_NONE then
+ g_Console_Add('expected ''red'', ''blue'', 1 or 2')
+ else if not gGameOn and not g_Game_IsNet then
+ gPlayer1Settings.Team := team
+ else
+ g_Console_Add(_lc[I_MSG_ONMAPCHANGE]);
+ end;
+ end;
+ 'p2_team':
+ begin
+ // TODO: switch teams if in game or store this separately
+ if (Length(P) > 1) then
+ begin
+ team := ParseTeam(P[1]);
+ if team = TEAM_NONE then
+ g_Console_Add('expected ''red'', ''blue'', 1 or 2')
+ else if not gGameOn and not g_Game_IsNet then
+ gPlayer2Settings.Team := team
+ else
+ g_Console_Add(_lc[I_MSG_ONMAPCHANGE]);
+ end;
+ end;
end;
end;
end;
end;
end else
g_Console_Add(_lc[I_MSG_SERVERONLY]);
end
end else
g_Console_Add(_lc[I_MSG_SERVERONLY]);
end
+ else if cmd = 'kick_pid' then
+ begin
+ if g_Game_IsServer and g_Game_IsNet then
+ begin
+ if Length(P) < 2 then
+ begin
+ g_Console_Add('kick_pid <player ID>');
+ Exit;
+ end;
+ if P[1] = '' then
+ begin
+ g_Console_Add('kick_pid <player ID>');
+ Exit;
+ end;
+
+ a := StrToIntDef(P[1], 0);
+ pl := g_Net_Client_ByPlayer(a);
+ if (pl <> nil) and pl^.Used and (pl^.Peer <> nil) then
+ begin
+ s := g_Net_ClientName_ByID(pl^.ID);
+ enet_peer_disconnect(pl^.Peer, NET_DISC_KICK);
+ g_Console_Add(Format(_lc[I_PLAYER_KICK], [s]));
+ MH_SEND_GameEvent(NET_EV_PLAYER_KICK, 0, s);
+ g_Net_Slist_ServerPlayerLeaves();
+ end;
+ end else
+ g_Console_Add(_lc[I_MSG_SERVERONLY]);
+ end
else if cmd = 'ban' then
begin
if g_Game_IsServer and g_Game_IsNet then
else if cmd = 'ban' then
begin
if g_Game_IsServer and g_Game_IsNet then
end else
g_Console_Add(_lc[I_MSG_SERVERONLY]);
end
end else
g_Console_Add(_lc[I_MSG_SERVERONLY]);
end
+ else if cmd = 'ban_pid' then
+ begin
+ if g_Game_IsServer and g_Game_IsNet then
+ begin
+ if Length(P) < 2 then
+ begin
+ g_Console_Add('ban_pid <player ID>');
+ Exit;
+ end;
+ if P[1] = '' then
+ begin
+ g_Console_Add('ban_pid <player ID>');
+ Exit;
+ end;
+
+ a := StrToIntDef(P[1], 0);
+ pl := g_Net_Client_ByPlayer(a);
+ if (pl <> nil) and pl^.Used and (pl^.Peer <> nil) then
+ begin
+ s := g_Net_ClientName_ByID(pl^.ID);
+ g_Net_BanHost(pl^.Peer^.address.host, False);
+ enet_peer_disconnect(pl^.Peer, NET_DISC_TEMPBAN);
+ g_Console_Add(Format(_lc[I_PLAYER_BAN], [s]));
+ MH_SEND_GameEvent(NET_EV_PLAYER_BAN, 0, s);
+ g_Net_Slist_ServerPlayerLeaves();
+ end;
+ end else
+ g_Console_Add(_lc[I_MSG_SERVERONLY]);
+ end
else if cmd = 'permban' then
begin
if g_Game_IsServer and g_Game_IsNet then
else if cmd = 'permban' then
begin
if g_Game_IsServer and g_Game_IsNet then
end else
g_Console_Add(_lc[I_MSG_SERVERONLY]);
end
end else
g_Console_Add(_lc[I_MSG_SERVERONLY]);
end
+ else if cmd = 'permban_pid' then
+ begin
+ if g_Game_IsServer and g_Game_IsNet then
+ begin
+ if Length(P) < 2 then
+ begin
+ g_Console_Add('permban_pid <player ID>');
+ Exit;
+ end;
+ if P[1] = '' then
+ begin
+ g_Console_Add('permban_pid <player ID>');
+ Exit;
+ end;
+
+ a := StrToIntDef(P[1], 0);
+ pl := g_Net_Client_ByPlayer(a);
+ if (pl <> nil) and pl^.Used and (pl^.Peer <> nil) then
+ begin
+ s := g_Net_ClientName_ByID(pl^.ID);
+ g_Net_BanHost(pl^.Peer^.address.host);
+ enet_peer_disconnect(pl^.Peer, NET_DISC_BAN);
+ g_Net_SaveBanList();
+ g_Console_Add(Format(_lc[I_PLAYER_BAN], [s]));
+ MH_SEND_GameEvent(NET_EV_PLAYER_BAN, 0, s);
+ g_Net_Slist_ServerPlayerLeaves();
+ end;
+ end else
+ g_Console_Add(_lc[I_MSG_SERVERONLY]);
+ end
+ else if cmd = 'permban_ip' then
+ begin
+ if g_Game_IsServer and g_Game_IsNet then
+ begin
+ if Length(P) < 2 then
+ begin
+ g_Console_Add('permban_ip <IP address>');
+ Exit;
+ end;
+ if P[1] = '' then
+ begin
+ g_Console_Add('permban_ip <IP address>');
+ Exit;
+ end;
+
+ g_Net_BanHost(P[1]);
+ g_Net_SaveBanList();
+ g_Console_Add(Format(_lc[I_PLAYER_BAN], [P[1]]));
+ end else
+ g_Console_Add(_lc[I_MSG_SERVERONLY]);
+ end
else if cmd = 'unban' then
begin
if g_Game_IsServer and g_Game_IsNet then
else if cmd = 'unban' then
begin
if g_Game_IsServer and g_Game_IsNet then
g_Game_Free();
with gGameSettings do
begin
g_Game_Free();
with gGameSettings do
begin
+ Options := gsGameFlags;
GameMode := g_Game_TextToMode(gsGameMode);
if gSwitchGameMode <> GM_NONE then
GameMode := gSwitchGameMode;
GameMode := g_Game_TextToMode(gsGameMode);
if gSwitchGameMode <> GM_NONE then
GameMode := gSwitchGameMode;
g_Game_Free();
with gGameSettings do
begin
g_Game_Free();
with gGameSettings do
begin
+ Options := gsGameFlags;
GameMode := g_Game_TextToMode(gsGameMode);
if gSwitchGameMode <> GM_NONE then GameMode := gSwitchGameMode;
if GameMode = GM_NONE then GameMode := GM_DM;
GameMode := g_Game_TextToMode(gsGameMode);
if gSwitchGameMode <> GM_NONE then GameMode := gSwitchGameMode;
if GameMode = GM_NONE then GameMode := GM_DM;
case gAnnouncer of
ANNOUNCE_NONE:
Exit;
case gAnnouncer of
ANNOUNCE_NONE:
Exit;
- ANNOUNCE_ME,
- ANNOUNCE_MEPLUS:
+ ANNOUNCE_ME:
if not g_Game_IsWatchedPlayer(SpawnerUID) then
Exit;
end;
if not g_Game_IsWatchedPlayer(SpawnerUID) then
Exit;
end;
// Options:
s := Find_Param_Value(pars, '-opt');
if (s = '') then
// Options:
s := Find_Param_Value(pars, '-opt');
if (s = '') then
- Opt := GAME_OPTION_ALLOWEXIT or GAME_OPTION_BOTVSPLAYER or
- GAME_OPTION_BOTVSMONSTER or GAME_OPTION_DMKEYS
+ Opt := gsGameFlags
else
Opt := StrToIntDef(s, 0);
else
Opt := StrToIntDef(s, 0);
conRegVar('r_showlives', @gShowLives, 'show lives', 'show lives');
conRegVar('r_showspect', @gSpectHUD, 'show spectator hud', 'show spectator hud');
conRegVar('r_showstat', @gShowStat, 'show stats', 'show stats');
conRegVar('r_showlives', @gShowLives, 'show lives', 'show lives');
conRegVar('r_showspect', @gSpectHUD, 'show spectator hud', 'show spectator hud');
conRegVar('r_showstat', @gShowStat, 'show stats', 'show stats');
+ conRegVar('r_showpids', @gShowPIDs, 'show PIDs', 'show PIDs');
end.
end.