diff --git a/src/game/g_game.pas b/src/game/g_game.pas
index 2cf72c1bcc17dc8ceb2cb1b7f2ef140a2500a803..824595b850be4297c8199295f4f1d7b8c9f73cc0 100644 (file)
--- a/src/game/g_game.pas
+++ b/src/game/g_game.pas
g_touch, g_weapons;
type
+ TGameOption = (
+ //RESERVED = 0, // FIXME: reuse for something
+ TEAM_DAMAGE = 1,
+ ALLOW_EXIT,
+ WEAPONS_STAY,
+ MONSTERS,
+ BOTS_VS_PLAYERS,
+ BOTS_VS_MONSTERS,
+ DM_KEYS,
+ TEAM_HIT_TRACE,
+ TEAM_HIT_PROJECTILE,
+ TEAM_ABSORB_DAMAGE,
+ ALLOW_DROP_FLAG,
+ THROW_FLAG,
+ POWERUP_RANDOM,
+ ITEM_ALL_RANDOM,
+ ITEM_LIFE_RANDOM,
+ ITEM_AMMO_RANDOM,
+ ITEM_WEAPON_RANDOM
+ );
+ TGameOptions = set of TGameOption;
+
TGameSettings = record
GameType: Byte;
GameMode: Byte;
TimeLimit: Word;
- GoalLimit: Word;
+ ScoreLimit: Word;
WarmupTime: Word;
SpawnInvul: Word;
ItemRespawnTime: Word;
+ ItemRespawnRandom: Word;
+ PowerupRespawnTime: Word;
+ PowerupRespawnRandom: Word;
MaxLives: Byte;
- Options: LongWord;
+ Options: TGameOptions;
WAD: String;
end;
Model: String;
Color: TRGB;
Team: Byte;
+ // ones below are sent only to the server
+ WeaponSwitch: Byte;
+ WeaponPreferences: Array[WP_FIRST..WP_LAST+1] of Byte;
+ SwitchToEmpty: Byte;
+ SkipIronFist: Byte;
end;
TMegaWADInfo = record
procedure g_Game_Spectate();
procedure g_Game_SpectateCenterView();
procedure g_Game_StartSingle(Map: String; TwoPlayers: Boolean; nPlayers: Byte);
-procedure g_Game_StartCustom(Map: String; GameMode: Byte; TimeLimit, GoalLimit: Word; MaxLives: Byte; Options: LongWord; nPlayers: Byte);
-procedure g_Game_StartServer(Map: String; GameMode: Byte; TimeLimit, GoalLimit: Word; MaxLives: Byte; Options: LongWord; nPlayers: Byte; IPAddr: LongWord; Port: Word);
+procedure g_Game_StartCustom(Map: String; GameMode: Byte; TimeLimit, ScoreLimit: Word; MaxLives: Byte; Options: TGameOptions; nPlayers: Byte);
+procedure g_Game_StartServer(Map: String; GameMode: Byte; TimeLimit, ScoreLimit: Word; MaxLives: Byte; Options: TGameOptions; nPlayers: Byte; IPAddr: LongWord; Port: Word);
procedure g_Game_StartClient(Addr: String; Port: Word; PW: String);
procedure g_Game_Restart();
procedure g_Game_RestartLevel();
procedure g_Game_Announce_GoodShot(SpawnerUID: Word);
procedure g_Game_Announce_KillCombo(Param: Integer);
procedure g_Game_Announce_BodyKill(SpawnerUID: Word);
+procedure g_Game_Effect_Bubbles(fX, fY: Integer; count: Word; devX, devY: Byte; Silent: Boolean = False);
procedure g_Game_StartVote(Command, Initiator: string);
procedure g_Game_CheckVote;
procedure g_TakeScreenShot(Filename: string = '');
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_TEAMHITTRACE = 256;
- GAME_OPTION_TEAMHITPROJECTILE = 512;
-
STATE_NONE = 0;
STATE_MENU = 1;
STATE_FOLD = 2;
gPauseHolmes: Boolean = false;
gShowTime: Boolean = False;
gShowFPS: Boolean = False;
- gShowGoals: Boolean = True;
+ gShowScore: Boolean = True;
gShowStat: Boolean = True;
gShowPIDs: Boolean = False;
gShowKillMsg: Boolean = True;
gDelayedEvents: Array of TDelayedEvent;
gUseChatSounds: Boolean = True;
gChatSounds: Array of TChatSound;
+ gWeaponAction: Array [0..1, WP_FACT..WP_LACT] of Boolean; // [player, weapon_action]
gSelectWeapon: Array [0..1, WP_FIRST..WP_LAST] of Boolean; // [player, weapon]
gInterReadyCount: Integer = 0;
+ gMaxBots: Integer = 127;
g_dbg_ignore_bounds: Boolean = false;
r_smallmap_h: Integer = 0; // 0: left; 1: center; 2: right
// saves a shitty CSV containing the game stats passed to it
procedure SaveGameStat(Stat: TEndCustomGameStat; Path: string);
-var
+var
s: TextFile;
- dir, fname, map, mode, etime: String;
+ dir, fname, map, mode, etime, flags, strf: String;
+ flag: TGameOption;
I: Integer;
begin
try
fname := e_CatPath(fname, StatFilename + '.csv');
AssignFile(s, fname);
try
+ SetTextCodePage(s, CP_UTF8);
Rewrite(s);
// line 1: stats ver, datetime, server name, map name, game mode, time limit, score limit, dmflags, game time, num players
if g_Game_IsNet then fname := NetServerName else fname := '';
(Stat.GameTime div 1000 div 60) mod 60,
Stat.GameTime div 1000 mod 60
]);
+ flags := '';
+ strf := '';
+ for flag in gGameSettings.Options do
+ begin
+ flags += strf;
+ System.WriteStr(strf, flag); // FIXME: rename our utils.WriteStr()
+ flags += strf;
+ strf := ', ';
+ end;
WriteLn(s, 'stats_ver,datetime,server,map,mode,timelimit,scorelimit,dmflags,time,num_players');
- WriteLn(s, Format('%d,%s,%s,%s,%s,%u,%u,%u,%s,%d', [
+ WriteLn(s, Format('%d,%s,%s,%s,%s,%u,%u,"%s",%s,%d', [
STATFILE_VERSION,
StatDate,
dquoteStr(fname),
dquoteStr(map),
mode,
gGameSettings.TimeLimit,
- gGameSettings.GoalLimit,
- gGameSettings.Options,
+ gGameSettings.ScoreLimit,
+ flags,
etime,
Length(Stat.PlayerStat)
]));
// if it's a coop game: monsters killed, monsters total, secrets found, secrets total
// otherwise nothing
if Stat.GameMode in [GM_TDM, GM_CTF] then
- WriteLn(s,
- Format('red_score,blue_score' + LineEnding + '%d,%d', [Stat.TeamStat[TEAM_RED].Goals, Stat.TeamStat[TEAM_BLUE].Goals]))
+ WriteLn(s,
+ Format('red_score,blue_score' + LineEnding + '%d,%d', [Stat.TeamStat[TEAM_RED].Score, Stat.TeamStat[TEAM_BLUE].Score]))
else if Stat.GameMode in [GM_COOP, GM_SINGLE] then
WriteLn(s,
Format('mon_killed,mon_total,secrets_found,secrets_total' + LineEnding + '%d,%d,%d,%d',[gCoopMonstersKilled, gTotalMonsters, gCoopSecretsFound, gSecretsCount]));
CloseFile(s);
end;
+procedure ClearDebugCvars();
+begin
+ g_debug_Sounds := False;
+ g_debug_Frames := False;
+ g_debug_WinMsgs := False;
+ g_debug_MonsterOff := False;
+ g_debug_BotAIOff := 0;
+ g_debug_HealthBar := False;
+ g_Debug_Player := False;
+end;
+
function g_Game_ModeToText(Mode: Byte): string;
begin
Result := '';
s1 := _lc[I_GAME_DM]
else
s1 := _lc[I_GAME_LMS];
- s2 := Format(_lc[I_GAME_FRAG_LIMIT], [gGameSettings.GoalLimit]);
+ s2 := Format(_lc[I_GAME_FRAG_LIMIT], [gGameSettings.ScoreLimit]);
s3 := Format(_lc[I_GAME_TIME_LIMIT], [gGameSettings.TimeLimit div 3600, (gGameSettings.TimeLimit div 60) mod 60, gGameSettings.TimeLimit mod 60]);
end;
s1 := _lc[I_GAME_TDM]
else
s1 := _lc[I_GAME_TLMS];
- s2 := Format(_lc[I_GAME_FRAG_LIMIT], [gGameSettings.GoalLimit]);
+ s2 := Format(_lc[I_GAME_FRAG_LIMIT], [gGameSettings.ScoreLimit]);
s3 := Format(_lc[I_GAME_TIME_LIMIT], [gGameSettings.TimeLimit div 3600, (gGameSettings.TimeLimit div 60) mod 60, gGameSettings.TimeLimit mod 60]);
end;
GM_CTF:
begin
s1 := _lc[I_GAME_CTF];
- s2 := Format(_lc[I_GAME_SCORE_LIMIT], [gGameSettings.GoalLimit]);
+ s2 := Format(_lc[I_GAME_SCORE_LIMIT], [gGameSettings.ScoreLimit]);
s3 := Format(_lc[I_GAME_TIME_LIMIT], [gGameSettings.TimeLimit div 3600, (gGameSettings.TimeLimit div 60) mod 60, gGameSettings.TimeLimit mod 60]);
end;
end;
e_TextureFontPrintEx(x+16, _y, s1, gStdFont, r, g, b, 1);
- e_TextureFontPrintEx(x+w1+16, _y, IntToStr(gTeamStat[a].Goals),
+ e_TextureFontPrintEx(x+w1+16, _y, IntToStr(gTeamStat[a].Score),
gStdFont, r, g, b, 1);
_y := _y+ch+(ch div 4);
if gPlayerAction[p, ACTION_LOOKUP] then plr.PressKey(KEY_UP, time);
if gPlayerAction[p, ACTION_LOOKDOWN] then plr.PressKey(KEY_DOWN, time);
if gPlayerAction[p, ACTION_ATTACK] then plr.PressKey(KEY_FIRE);
- if gPlayerAction[p, ACTION_WEAPNEXT] then plr.PressKey(KEY_NEXTWEAPON);
- if gPlayerAction[p, ACTION_WEAPPREV] then plr.PressKey(KEY_PREVWEAPON);
if gPlayerAction[p, ACTION_ACTIVATE] then plr.PressKey(KEY_OPEN);
- gPlayerAction[p, ACTION_WEAPNEXT] := False; // HACK, remove after readyweaon&pendinweapon implementation
- gPlayerAction[p, ACTION_WEAPPREV] := False; // HACK, remove after readyweaon&pendinweapon implementation
+ for i := WP_FACT to WP_LACT do
+ begin
+ if gWeaponAction[p, i] then
+ begin
+ plr.ProcessWeaponAction(i);
+ gWeaponAction[p, i] := False
+ end
+ end;
for i := WP_FIRST to WP_LAST do
begin
if mon.gncNeedSend then MH_SEND_MonsterPos(mon.UID);
end;
+ function sendItemPos (it: PItem): Boolean;
+ begin
+ result := false; // don't stop
+ if it.needSend then
+ begin
+ MH_SEND_ItemPos(it.myId);
+ it.needSend := False;
+ end;
+ end;
+
var
reliableUpdate: Boolean;
begin
// Çàêîí÷èëñÿ óðîâåíü â Ñâîåé èãðå:
if gGameSettings.GameType in [GT_CUSTOM, GT_SERVER, GT_CLIENT] then
begin
+ gState := STATE_INTERCUSTOM;
InterReadyTime := -1;
if gLastMap and (gGameSettings.GameMode = GM_COOP) then
begin
end
else
gMusic.SetByName('MUSIC_ROUNDMUS');
-
gMusic.Play();
- gState := STATE_INTERCUSTOM;
e_UnpressAllKeys();
end
else // Çàêîí÷èëàñü ïîñëåäíÿÿ êàðòà â Îäèíî÷íîé èãðå
gFlags[FLAG_BLUE].CaptureTime := gFlags[FLAG_BLUE].CaptureTime + GAME_TICK;
// Áûë çàäàí ëèìèò ïîáåä:
- if (gGameSettings.GoalLimit > 0) then
+ if (gGameSettings.ScoreLimit > 0) then
begin
b := 0;
else
if gGameSettings.GameMode in [GM_TDM, GM_CTF] then
begin //  CTF/TDM âûáèðàåì êîìàíäó ñ íàèáîëüøèì ñ÷åòîì
- b := Max(gTeamStat[TEAM_RED].Goals, gTeamStat[TEAM_BLUE].Goals);
+ b := Max(gTeamStat[TEAM_RED].Score, gTeamStat[TEAM_BLUE].Score);
end;
// Ëèìèò ïîáåä íàáðàí => êîíåö óðîâíÿ:
- if b >= gGameSettings.GoalLimit then
+ if b >= gGameSettings.ScoreLimit then
begin
g_Game_NextLevel();
Exit;
gSpectY := Max(gSpectY - gSpectStep, 0);
if gPlayerAction[0, ACTION_LOOKDOWN] then
gSpectY := Min(gSpectY + gSpectStep, gMapInfo.Height - gScreenHeight);
- if gPlayerAction[0, ACTION_WEAPPREV] then
+ if gWeaponAction[0, WP_PREV] then
begin
// decrease step
if gSpectStep > 4 then gSpectStep := gSpectStep shr 1;
- gSpectKeyPress := True;
+ gWeaponAction[0, WP_PREV] := False;
end;
- if gPlayerAction[0, ACTION_WEAPNEXT] then
+ if gWeaponAction[0, WP_NEXT] then
begin
// increase step
if gSpectStep < 64 then gSpectStep := gSpectStep shl 1;
- gSpectKeyPress := True;
+ gWeaponAction[0, WP_NEXT] := False;
end;
end;
if (gSpectMode = SPECT_PLAYERS)
gSpectPID1 := GetActivePlayerID_Next(gSpectPID1);
gSpectKeyPress := True;
end;
- if gPlayerAction[0, ACTION_WEAPPREV] then
+ if gWeaponAction[0, WP_PREV] then
begin
// prev player (view 2)
gSpectPID2 := GetActivePlayerID_Prev(gSpectPID2);
- gSpectKeyPress := True;
+ gWeaponAction[0, WP_PREV] := False;
end;
- if gPlayerAction[0, ACTION_WEAPNEXT] then
+ if gWeaponAction[0, WP_NEXT] then
begin
// next player (view 2)
gSpectPID2 := GetActivePlayerID_Next(gSpectPID2);
- gSpectKeyPress := True;
+ gWeaponAction[0, WP_NEXT] := False;
end;
end;
if gPlayerAction[0, ACTION_ATTACK] then
(not gPlayerAction[0, ACTION_MOVELEFT]) and
(not gPlayerAction[0, ACTION_MOVERIGHT]) and
(not gPlayerAction[0, ACTION_LOOKUP]) and
- (not gPlayerAction[0, ACTION_LOOKDOWN]) and
- (not gPlayerAction[0, ACTION_WEAPPREV]) and
- (not gPlayerAction[0, ACTION_WEAPNEXT]) then
+ (not gPlayerAction[0, ACTION_LOOKDOWN]) then
gSpectKeyPress := False;
if gSpectAuto then
g_Mons_ForEach(sendMonsPos);
+ // update flags that aren't stationary
+ if gGameSettings.GameMode = GM_CTF then
+ for I := FLAG_RED to FLAG_BLUE do
+ if gFlags[I].NeedSend then
+ begin
+ gFlags[I].NeedSend := False;
+ MH_SEND_FlagPos(I);
+ end;
+
+ // update items that aren't stationary
+ g_Items_ForEachAlive(sendItemPos);
+
if reliableUpdate then
begin
NetTimeToReliable := 0;
_y := _y+16+16;
with CustomStat do
- if TeamStat[TEAM_RED].Goals > TeamStat[TEAM_BLUE].Goals then s1 := _lc[I_GAME_WIN_RED]
- else if TeamStat[TEAM_BLUE].Goals > TeamStat[TEAM_RED].Goals then s1 := _lc[I_GAME_WIN_BLUE]
+ if TeamStat[TEAM_RED].Score > TeamStat[TEAM_BLUE].Score then s1 := _lc[I_GAME_WIN_RED]
+ else if TeamStat[TEAM_BLUE].Score > TeamStat[TEAM_RED].Score then s1 := _lc[I_GAME_WIN_BLUE]
else s1 := _lc[I_GAME_WIN_DRAW];
e_TextureFontPrintEx(x+8+(w div 2)-(Length(s1)*ww2 div 2), _y, s1, gStdFont, 255, 255, 255, 1);
begin
e_TextureFontPrintEx(x+8, _y, _lc[I_GAME_TEAM_RED],
gStdFont, 255, 0, 0, 1);
- e_TextureFontPrintEx(x+w1+8, _y, IntToStr(CustomStat.TeamStat[TEAM_RED].Goals),
+ e_TextureFontPrintEx(x+w1+8, _y, IntToStr(CustomStat.TeamStat[TEAM_RED].Score),
gStdFont, 255, 0, 0, 1);
r := 255;
g := 0;
begin
e_TextureFontPrintEx(x+8, _y, _lc[I_GAME_TEAM_BLUE],
gStdFont, 0, 0, 255, 1);
- e_TextureFontPrintEx(x+w1+8, _y, IntToStr(CustomStat.TeamStat[TEAM_BLUE].Goals),
+ e_TextureFontPrintEx(x+w1+8, _y, IntToStr(CustomStat.TeamStat[TEAM_BLUE].Score),
gStdFont, 0, 0, 255, 1);
r := 0;
g := 0;
p.DrawPain();
p.DrawPickup();
- p.DrawRulez();
+ p.DrawOverlay();
if gShowMap then DrawMinimap(p, _TRect(0, 0, 128, 128));
if g_Debug_Player then
g_Player_DrawDebug(p);
px: Integer = -1;
py: Integer = -1;
begin
- if g_profile_frame_draw and (profileFrameDraw <> nil) then px := px-drawProfiles(px, py, profileFrameDraw);
- if g_profile_collision and (profMapCollision <> nil) then begin px := px-drawProfiles(px, py, profMapCollision); py -= calcProfilesHeight(profMonsLOS); end;
- if g_profile_los and (profMonsLOS <> nil) then begin px := px-drawProfiles(px, py, profMonsLOS); py -= calcProfilesHeight(profMonsLOS); end;
+ if g_profile_frame_draw and (profileFrameDraw <> nil) then
+ px -= drawProfiles(px, py, profileFrameDraw);
+
+ if g_profile_collision and (profMapCollision <> nil) then
+ begin
+ px -= drawProfiles(px, py, profMapCollision);
+ py -= calcProfilesHeight(profMonsLOS);
+ end;
+
+ if g_profile_los and (profMonsLOS <> nil) then
+ begin
+ px -= drawProfiles(px, py, profMonsLOS);
+ py -= calcProfilesHeight(profMonsLOS);
+ end;
end;
procedure g_Game_Draw();
else
begin
gPlayer1.Name := gPlayer1Settings.Name;
+ gPlayer1.WeapSwitchMode := gPlayer1Settings.WeaponSwitch;
+ gPlayer1.setWeaponPrefs(gPlayer1Settings.WeaponPreferences);
+ gPlayer1.SwitchToEmpty := gPlayer1Settings.SwitchToEmpty;
+ gPlayer1.SkipIronFist := gPlayer1Settings.SkipIronFist;
g_Console_Add(Format(_lc[I_PLAYER_JOIN], [gPlayer1.Name]), True);
if g_Game_IsServer and g_Game_IsNet then
MH_SEND_PlayerCreate(gPlayer1.UID);
else
begin
gPlayer2.Name := gPlayer2Settings.Name;
+ gPlayer2.WeapSwitchMode := gPlayer2Settings.WeaponSwitch;
+ gPlayer2.setWeaponPrefs(gPlayer2Settings.WeaponPreferences);
+ gPlayer2.SwitchToEmpty := gPlayer2Settings.SwitchToEmpty;
+ gPlayer2.SkipIronFist := gPlayer2Settings.SkipIronFist;
g_Console_Add(Format(_lc[I_PLAYER_JOIN], [gPlayer2.Name]), True);
if g_Game_IsServer and g_Game_IsNet then
MH_SEND_PlayerCreate(gPlayer2.UID);
g_Game_ClearLoading();
// Íàñòðîéêè èãðû:
- FillByte(gGameSettings, SizeOf(TGameSettings), 0);
+ gGameSettings := Default(TGameSettings);
gAimLine := False;
gShowMap := False;
gGameSettings.GameType := GT_SINGLE;
gGameSettings.MaxLives := 0;
- gGameSettings.Options := gGameSettings.Options + GAME_OPTION_ALLOWEXIT;
- gGameSettings.Options := gGameSettings.Options + GAME_OPTION_MONSTERS;
- gGameSettings.Options := gGameSettings.Options + GAME_OPTION_BOTVSMONSTER;
+ gGameSettings.Options := [TGameOption.ALLOW_EXIT, TGameOption.MONSTERS,
+ TGameOption.BOTS_VS_MONSTERS, TGameOption.TEAM_HIT_PROJECTILE, TGameOption.TEAM_HIT_TRACE,
+ TGameOption.POWERUP_RANDOM, TGameOption.ITEM_ALL_RANDOM, TGameOption.ITEM_LIFE_RANDOM,
+ TGameOption.ITEM_AMMO_RANDOM, TGameOption.ITEM_WEAPON_RANDOM];
gSwitchGameMode := GM_SINGLE;
gLMSRespawn := LMS_RESPAWN_NONE;
end;
gPlayer1.Name := gPlayer1Settings.Name;
+ gPlayer1.WeapSwitchMode := gPlayer1Settings.WeaponSwitch;
+ gPlayer1.setWeaponPrefs(gPlayer1Settings.WeaponPreferences);
+ gPlayer1.SwitchToEmpty := gPlayer1Settings.SwitchToEmpty;
+ gPlayer1.SkipIronFist := gPlayer1Settings.SkipIronFist;
nPl := 1;
// Ñîçäàíèå âòîðîãî èãðîêà, åñëè åñòü:
end;
gPlayer2.Name := gPlayer2Settings.Name;
+ gPlayer2.WeapSwitchMode := gPlayer2Settings.WeaponSwitch;
+ gPlayer2.setWeaponPrefs(gPlayer2Settings.WeaponPreferences);
+ gPlayer2.SwitchToEmpty := gPlayer2Settings.SwitchToEmpty;
+ gPlayer2.SkipIronFist := gPlayer2Settings.SkipIronFist;
Inc(nPl);
end;
end;
procedure g_Game_StartCustom(Map: String; GameMode: Byte;
- TimeLimit, GoalLimit: Word;
+ TimeLimit, ScoreLimit: Word;
MaxLives: Byte;
- Options: LongWord; nPlayers: Byte);
+ Options: TGameOptions; nPlayers: Byte);
var
i, nPl: Integer;
begin
gGameSettings.GameMode := GameMode;
gSwitchGameMode := GameMode;
gGameSettings.TimeLimit := TimeLimit;
- gGameSettings.GoalLimit := GoalLimit;
+ gGameSettings.ScoreLimit := ScoreLimit;
gGameSettings.MaxLives := IfThen(GameMode = GM_CTF, 0, MaxLives);
gGameSettings.Options := Options;
end;
gPlayer1.Name := gPlayer1Settings.Name;
+ gPlayer1.WeapSwitchMode := gPlayer1Settings.WeaponSwitch;
+ gPlayer1.setWeaponPrefs(gPlayer1Settings.WeaponPreferences);
+ gPlayer1.SwitchToEmpty := gPlayer1Settings.SwitchToEmpty;
+ gPlayer1.SkipIronFist := gPlayer1Settings.SkipIronFist;
Inc(nPl);
end;
end;
gPlayer2.Name := gPlayer2Settings.Name;
+ gPlayer2.WeapSwitchMode := gPlayer2Settings.WeaponSwitch;
+ gPlayer2.setWeaponPrefs(gPlayer2Settings.WeaponPreferences);
+ gPlayer2.SwitchToEmpty := gPlayer2Settings.SwitchToEmpty;
+ gPlayer2.SkipIronFist := gPlayer2Settings.SkipIronFist;
Inc(nPl);
end;
end;
procedure g_Game_StartServer(Map: String; GameMode: Byte;
- TimeLimit, GoalLimit: Word; MaxLives: Byte;
- Options: LongWord; nPlayers: Byte;
+ TimeLimit, ScoreLimit: Word; MaxLives: Byte;
+ Options: TGameOptions; nPlayers: Byte;
IPAddr: LongWord; Port: Word);
begin
g_Game_Free();
g_Game_ClearLoading();
+ ClearDebugCvars();
+
// Íàñòðîéêè èãðû:
gGameSettings.GameType := GT_SERVER;
gGameSettings.GameMode := GameMode;
gSwitchGameMode := GameMode;
gGameSettings.TimeLimit := TimeLimit;
- gGameSettings.GoalLimit := GoalLimit;
+ gGameSettings.ScoreLimit := ScoreLimit;
gGameSettings.MaxLives := IfThen(GameMode = GM_CTF, 0, MaxLives);
gGameSettings.Options := Options;
end;
gPlayer1.Name := gPlayer1Settings.Name;
+ gPlayer1.WeapSwitchMode := gPlayer1Settings.WeaponSwitch;
+ gPlayer1.setWeaponPrefs(gPlayer1Settings.WeaponPreferences);
+ gPlayer1.SwitchToEmpty := gPlayer1Settings.SwitchToEmpty;
+ gPlayer1.SkipIronFist := gPlayer1Settings.SkipIronFist;
end;
if nPlayers >= 2 then
end;
gPlayer2.Name := gPlayer2Settings.Name;
+ gPlayer2.WeapSwitchMode := gPlayer2Settings.WeaponSwitch;
+ gPlayer2.setWeaponPrefs(gPlayer2Settings.WeaponPreferences);
+ gPlayer2.SwitchToEmpty := gPlayer2Settings.SwitchToEmpty;
+ gPlayer2.SkipIronFist := gPlayer2Settings.SkipIronFist;
end;
g_Game_SetLoadingText(_lc[I_LOAD_HOST], 0, False);
g_Game_ClearLoading();
+ ClearDebugCvars();
+
// Íàñòðîéêè èãðû:
gGameSettings.GameType := GT_CLIENT;
begin
if (NetEvent.kind = ENET_EVENT_TYPE_RECEIVE) then
begin
- if (NetEvent.channelID = NET_CHAN_DOWNLOAD_EX) then
- begin
- // ignore all download packets, they're processed by separate code
- enet_packet_destroy(NetEvent.packet);
- continue;
- end;
Ptr := NetEvent.packet^.data;
if not InMsg.Init(Ptr, NetEvent.packet^.dataLength, True) then
begin
gGameSettings.GameMode := InMsg.ReadByte();
gSwitchGameMode := gGameSettings.GameMode;
- gGameSettings.GoalLimit := InMsg.ReadWord();
+ gGameSettings.ScoreLimit := InMsg.ReadWord();
gGameSettings.TimeLimit := InMsg.ReadWord();
gGameSettings.MaxLives := InMsg.ReadByte();
- gGameSettings.Options := InMsg.ReadLongWord();
+ gGameSettings.Options := TGameOptions(InMsg.ReadLongWord());
T := InMsg.ReadLongWord();
//newResPath := g_Res_SearchSameWAD(MapsDir, WadName, gWADHash);
end;
gPlayer1.Name := gPlayer1Settings.Name;
+ gPlayer1.WeapSwitchMode := gPlayer1Settings.WeaponSwitch;
+ gPlayer1.setWeaponPrefs(gPlayer1Settings.WeaponPreferences);
+ gPlayer1.SwitchToEmpty := gPlayer1Settings.SwitchToEmpty;
+ gPlayer1.SkipIronFist := gPlayer1Settings.SkipIronFist;
gPlayer1.UID := NetPlrUID1;
gPlayer1.Reset(True);
end;
end;
- ProcessLoading(true);
-
+ ProcessLoading(True);
if g_Net_UserRequestExit() then
begin
State := 0;
if NetMode = NET_SERVER then
begin
+ // reset full state flags
+ if NetClients <> nil then
+ for I := 0 to High(NetClients) do
+ NetClients[I].FullUpdateSent := False;
+
MH_SEND_GameEvent(NET_EV_MAPSTART, gGameSettings.GameMode, Map);
// Ìàñòåðñåðâåð
end;
end;
- g_Net_UnbanNonPermHosts();
+ g_Net_UnbanNonPerm();
end;
if gLastMap then
if gGameSettings.GameMode = GM_COOP then
begin
gPlayers[i].Frags := 0;
- gPlayers[i].RecallState;
+ gPlayers[i].RestoreState;
end;
if (gPlayer1 = nil) and (gSpectLatchPID1 > 0) then
gPlayer1 := g_Player_Get(gSpectLatchPID1);
a, b: Integer;
stat: TPlayerStatArray;
cmd: string;
+ it: PItem;
- procedure ParseGameFlag(Flag: LongWord; OffMsg, OnMsg: TStrings_Locale; OnMapChange: Boolean = False);
+ procedure ParseGameFlag(Flag: TGameOption; OffMsg, OnMsg: TStrings_Locale; OnMapChange: Boolean = False);
var
x: Boolean;
begin
- if Length(P) > 1 then
+ if Length(P) <= 1 then
+ x := Flag in gsGameFlags
+ else
begin
x := P[1] = '1';
- if x then
- gsGameFlags := gsGameFlags or Flag
- else
- gsGameFlags := gsGameFlags and (not Flag);
+ if x
+ then gsGameFlags += [Flag]
+ else gsGameFlags -= [Flag];
if g_Game_IsServer then
begin
- if x then
- gGameSettings.Options := gGameSettings.Options or Flag
- else
- gGameSettings.Options := gGameSettings.Options and (not Flag);
+ if x
+ then gGameSettings.Options += [Flag]
+ else gGameSettings.Options -= [Flag];
if g_Game_IsNet then MH_SEND_GameSettings;
end;
end;
- if LongBool(gsGameFlags and Flag) then
- g_Console_Add(_lc[OnMsg])
- else
- g_Console_Add(_lc[OffMsg]);
+ if x
+ then g_Console_Add(_lc[OnMsg])
+ else g_Console_Add(_lc[OffMsg]);
if OnMapChange and g_Game_IsServer then
g_Console_Add(_lc[I_MSG_ONMAPCHANGE]);
stat := nil;
cmd := LowerCase(P[0]);
- if cmd = 'g_gamemode' then
- begin
- if (Length(P) > 1) then
- begin
- a := g_Game_TextToMode(P[1]);
- if a = GM_SINGLE then a := GM_COOP;
- gsGameMode := g_Game_ModeToText(a);
- if g_Game_IsServer then
+ case cmd of
+ 'g_gamemode': begin
+ if (Length(P) > 1) then
begin
- gSwitchGameMode := a;
- if (gGameOn and (gGameSettings.GameMode = GM_SINGLE)) or
- (gState = STATE_INTERSINGLE) then
- gSwitchGameMode := GM_SINGLE;
- if not gGameOn then
- gGameSettings.GameMode := gSwitchGameMode;
+ a := g_Game_TextToMode(P[1]);
+ if a = GM_SINGLE then a := GM_COOP;
+ gsGameMode := g_Game_ModeToText(a);
+ if g_Game_IsServer then
+ begin
+ gSwitchGameMode := a;
+ if (gGameOn and (gGameSettings.GameMode = GM_SINGLE)) or
+ (gState = STATE_INTERSINGLE) then
+ gSwitchGameMode := GM_SINGLE;
+ if not gGameOn then
+ gGameSettings.GameMode := gSwitchGameMode;
+ end;
end;
+
+ if gSwitchGameMode = gGameSettings.GameMode then
+ g_Console_Add(Format(_lc[I_MSG_GAMEMODE_CURRENT],
+ [g_Game_ModeToText(gGameSettings.GameMode)]))
+ else
+ g_Console_Add(Format(_lc[I_MSG_GAMEMODE_CHANGE],
+ [g_Game_ModeToText(gGameSettings.GameMode),
+ g_Game_ModeToText(gSwitchGameMode)]));
end;
- if gSwitchGameMode = gGameSettings.GameMode then
- g_Console_Add(Format(_lc[I_MSG_GAMEMODE_CURRENT],
- [g_Game_ModeToText(gGameSettings.GameMode)]))
- else
- g_Console_Add(Format(_lc[I_MSG_GAMEMODE_CHANGE],
- [g_Game_ModeToText(gGameSettings.GameMode),
- g_Game_ModeToText(gSwitchGameMode)]));
- end
- else if cmd = 'g_friendlyfire' then
- begin
- ParseGameFlag(GAME_OPTION_TEAMDAMAGE, 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);
- end
- else if cmd = 'g_allow_exit' then
- begin
- ParseGameFlag(GAME_OPTION_ALLOWEXIT, I_MSG_ALLOWEXIT_OFF, I_MSG_ALLOWEXIT_ON, True);
- end
- else if cmd = 'g_allow_monsters' then
- begin
- ParseGameFlag(GAME_OPTION_MONSTERS, I_MSG_ALLOWMON_OFF, I_MSG_ALLOWMON_ON, True);
- end
- else if cmd = 'g_bot_vsplayers' then
- begin
- ParseGameFlag(GAME_OPTION_BOTVSPLAYER, I_MSG_BOTSVSPLAYERS_OFF, I_MSG_BOTSVSPLAYERS_ON);
- end
- else if cmd = 'g_bot_vsmonsters' then
- begin
- ParseGameFlag(GAME_OPTION_BOTVSMONSTER, I_MSG_BOTSVSMONSTERS_OFF, I_MSG_BOTSVSMONSTERS_ON);
- end
- else if cmd = 'g_dm_keys' then
- begin
- ParseGameFlag(GAME_OPTION_DMKEYS, I_MSG_DMKEYS_OFF, I_MSG_DMKEYS_ON, True);
- end
- else if cmd = 'g_gameflags' then
- begin
- if Length(P) > 1 then
- begin
- gsGameFlags := StrToDWordDef(P[1], gsGameFlags);
- if g_Game_IsServer then
+ 'g_friendlyfire':
+ ParseGameFlag(TGameOption.TEAM_DAMAGE, I_MSG_FRIENDLY_FIRE_OFF, I_MSG_FRIENDLY_FIRE_ON);
+ 'g_friendly_absorb_damage':
+ ParseGameFlag(TGameOption.TEAM_ABSORB_DAMAGE, I_MSG_FRIENDLY_ABSORB_DAMAGE_OFF, I_MSG_FRIENDLY_ABSORB_DAMAGE_ON);
+ 'g_friendly_hit_trace':
+ ParseGameFlag(TGameOption.TEAM_HIT_TRACE, I_MSG_FRIENDLY_HIT_TRACE_OFF, I_MSG_FRIENDLY_HIT_TRACE_ON);
+ 'g_friendly_hit_projectile':
+ ParseGameFlag(TGameOption.TEAM_HIT_PROJECTILE, I_MSG_FRIENDLY_PROJECT_TRACE_OFF, I_MSG_FRIENDLY_PROJECT_TRACE_ON);
+ 'g_items_all_respawn_random':
+ ParseGameFlag(TGameOption.ITEM_ALL_RANDOM, I_MSG_ITEM_ALL_RANDOM_OFF, I_MSG_ITEM_ALL_RANDOM_ON, False);
+ 'g_items_help_respawn_random':
+ ParseGameFlag(TGameOption.ITEM_LIFE_RANDOM, I_MSG_ITEM_LIFE_RANDOM_OFF, I_MSG_ITEM_LIFE_RANDOM_ON, False);
+ 'g_items_ammo_respawn_random':
+ ParseGameFlag(TGameOption.ITEM_AMMO_RANDOM, I_MSG_ITEM_AMMO_RANDOM_OFF, I_MSG_ITEM_AMMO_RANDOM_ON, False);
+ 'g_items_weapon_respawn_random':
+ ParseGameFlag(TGameOption.ITEM_WEAPON_RANDOM, I_MSG_ITEM_WEAPON_RANDOM_OFF, I_MSG_ITEM_WEAPON_RANDOM_ON);
+ 'g_powerup_randomize_respawn':
+ ParseGameFlag(TGameOption.POWERUP_RANDOM, I_MSG_POWERUP_RANDOM_OFF, I_MSG_POWERUP_RANDOM_ON, False);
+ 'g_weaponstay':
+ ParseGameFlag(TGameOption.WEAPONS_STAY, I_MSG_WEAPONSTAY_OFF, I_MSG_WEAPONSTAY_ON);
+ 'g_allow_exit':
+ ParseGameFlag(TGameOption.ALLOW_EXIT, I_MSG_ALLOWEXIT_OFF, I_MSG_ALLOWEXIT_ON, True);
+ 'g_allow_monsters':
+ ParseGameFlag(TGameOption.MONSTERS, I_MSG_ALLOWMON_OFF, I_MSG_ALLOWMON_ON, True);
+ 'g_allow_dropflag':
+ ParseGameFlag(TGameOption.ALLOW_DROP_FLAG, I_MSG_ALLOWDROPFLAG_OFF, I_MSG_ALLOWDROPFLAG_ON);
+ 'g_throw_flag':
+ ParseGameFlag(TGameOption.THROW_FLAG, I_MSG_THROWFLAG_OFF, I_MSG_THROWFLAG_ON);
+ 'g_bot_vsplayers':
+ ParseGameFlag(TGameOption.BOTS_VS_PLAYERS, I_MSG_BOTSVSPLAYERS_OFF, I_MSG_BOTSVSPLAYERS_ON);
+ 'g_bot_vsmonsters':
+ ParseGameFlag(TGameOption.BOTS_VS_MONSTERS, I_MSG_BOTSVSMONSTERS_OFF, I_MSG_BOTSVSMONSTERS_ON);
+ 'g_dm_keys':
+ ParseGameFlag(TGameOption.DM_KEYS, I_MSG_DMKEYS_OFF, I_MSG_DMKEYS_ON, True);
+
+ 'g_gameflags': begin
+ if Length(P) > 1 then
begin
- gGameSettings.Options := gsGameFlags;
- if g_Game_IsNet then MH_SEND_GameSettings;
+ gsGameFlags := TGameOptions(StrToDWordDef(P[1], LongWord(gsGameFlags)));
+ if g_Game_IsServer then
+ begin
+ gGameSettings.Options := gsGameFlags;
+ if g_Game_IsNet then MH_SEND_GameSettings;
+ end;
end;
+
+ g_Console_Add(Format('%s %u', [cmd, LongWord(gsGameFlags)]));
end;
- g_Console_Add(Format('%s %u', [cmd, gsGameFlags]));
- end
- else if cmd = 'g_warmup_time' then
- begin
- if Length(P) > 1 then
- begin
- gsWarmupTime := nclamp(StrToIntDef(P[1], gsWarmupTime), 0, $FFFF);
- if g_Game_IsServer then
+ 'g_warmup_time': begin
+ if Length(P) > 1 then
begin
- gGameSettings.WarmupTime := gsWarmupTime;
- // extend warmup if it's already going
- if gLMSRespawn = LMS_RESPAWN_WARMUP then
+ gsWarmupTime := nclamp(StrToIntDef(P[1], gsWarmupTime), 0, $FFFF);
+ if g_Game_IsServer then
begin
- gLMSRespawnTime := gTime + gsWarmupTime * 1000;
- if g_Game_IsNet then MH_SEND_GameEvent(NET_EV_LMS_WARMUP, gLMSRespawnTime - gTime);
+ gGameSettings.WarmupTime := gsWarmupTime;
+ // extend warmup if it's already going
+ if gLMSRespawn = LMS_RESPAWN_WARMUP then
+ begin
+ gLMSRespawnTime := gTime + gsWarmupTime * 1000;
+ if g_Game_IsNet then MH_SEND_GameEvent(NET_EV_LMS_WARMUP, gLMSRespawnTime - gTime);
+ end;
+ if g_Game_IsNet then MH_SEND_GameSettings;
end;
- if g_Game_IsNet then MH_SEND_GameSettings;
end;
+
+ g_Console_Add(Format(_lc[I_MSG_WARMUP], [Integer(gsWarmupTime)]));
+ if g_Game_IsServer then g_Console_Add(_lc[I_MSG_ONMAPCHANGE]);
end;
- g_Console_Add(Format(_lc[I_MSG_WARMUP], [Integer(gsWarmupTime)]));
- if g_Game_IsServer then g_Console_Add(_lc[I_MSG_ONMAPCHANGE]);
- end
- else if cmd = 'g_spawn_invul' then
- begin
- if Length(P) > 1 then
- begin
- gsSpawnInvul := nclamp(StrToIntDef(P[1], gsSpawnInvul), 0, $FFFF);
- if g_Game_IsServer then
+ 'g_spawn_invul': begin
+ if Length(P) > 1 then
begin
- gGameSettings.SpawnInvul := gsSpawnInvul;
- if g_Game_IsNet then MH_SEND_GameSettings;
+ gsSpawnInvul := nclamp(StrToIntDef(P[1], gsSpawnInvul), 0, $FFFF);
+ if g_Game_IsServer then
+ begin
+ gGameSettings.SpawnInvul := gsSpawnInvul;
+ if g_Game_IsNet then MH_SEND_GameSettings;
+ end;
end;
+
+ g_Console_Add(Format('%s %d', [cmd, Integer(gsSpawnInvul)]));
end;
- g_Console_Add(Format('%s %d', [cmd, Integer(gsSpawnInvul)]));
- end
- else if cmd = 'g_item_respawn_time' then
- begin
- if Length(P) > 1 then
- begin
- gsItemRespawnTime := nclamp(StrToIntDef(P[1], gsItemRespawnTime), 0, $FFFF);
- if g_Game_IsServer then
+ 'g_item_respawn_time': begin
+ if Length(P) > 1 then
begin
- gGameSettings.ItemRespawnTime := gsItemRespawnTime;
- if g_Game_IsNet then MH_SEND_GameSettings;
+ gsItemRespawnTime := nclamp(StrToIntDef(P[1], gsItemRespawnTime), 0, $FFFF);
+ if g_Game_IsServer then
+ begin
+ gGameSettings.ItemRespawnTime := gsItemRespawnTime;
+ if g_Game_IsNet then MH_SEND_GameSettings;
+ end;
end;
+
+ g_Console_Add(Format('%s %d', [cmd, Integer(gsItemRespawnTime)]));
+ if g_Game_IsServer then g_Console_Add(_lc[I_MSG_ONMAPCHANGE]);
end;
- g_Console_Add(Format('%s %d', [cmd, Integer(gsItemRespawnTime)]));
- if g_Game_IsServer then g_Console_Add(_lc[I_MSG_ONMAPCHANGE]);
- end
- else if cmd = 'sv_intertime' then
- begin
- if (Length(P) > 1) then
- gDefInterTime := Min(Max(StrToIntDef(P[1], gDefInterTime), -1), 120);
+ 'g_item_time_random': begin
+ if Length(P) > 1 then
+ begin
+ gsItemRespawnRandom := nclamp(StrToIntDef(P[1], gsItemRespawnRandom), 0, $FFFF);
+ if g_Game_IsServer then
+ begin
+ gGameSettings.ItemRespawnRandom := gsItemRespawnRandom;
+ if g_Game_IsNet then MH_SEND_GameSettings;
+ end;
+ end;
- g_Console_Add(cmd + ' = ' + IntToStr(gDefInterTime));
- end
- else if cmd = 'g_max_particles' then
- begin
- if Length(p) = 2 then
- begin
- a := Max(0, StrToInt(p[1]));
- g_GFX_SetMax(a)
- end
- else if Length(p) = 1 then
- begin
- e_LogWritefln('%s', [g_GFX_GetMax()])
- end
- else
- begin
- e_LogWritefln('usage: %s <n>', [cmd])
- end
- end
- else if cmd = 'g_max_shells' then
- begin
- if Length(p) = 2 then
- begin
- a := Max(0, StrToInt(p[1]));
- g_Shells_SetMax(a)
- end
- else if Length(p) = 1 then
- begin
- e_LogWritefln('%s', [g_Shells_GetMax()])
- end
- else
- begin
- e_LogWritefln('usage: %s <n>', [cmd])
- end
- end
- else if cmd = 'g_max_gibs' then
- begin
- if Length(p) = 2 then
- begin
- a := Max(0, StrToInt(p[1]));
- g_Gibs_SetMax(a)
- end
- else if Length(p) = 1 then
- begin
- e_LogWritefln('%s', [g_Gibs_GetMax()])
- end
- else
- begin
- e_LogWritefln('usage: %s <n>', [cmd])
- end
- end
- else if cmd = 'g_max_corpses' then
- begin
- if Length(p) = 2 then
- begin
- a := Max(0, StrToInt(p[1]));
- g_Corpses_SetMax(a)
- end
- else if Length(p) = 1 then
- begin
- e_LogWritefln('%s', [g_Corpses_GetMax()])
- end
- else
- begin
- e_LogWritefln('usage: %s <n>', [cmd])
- end
- end
- else if cmd = 'g_scorelimit' then
- begin
- if Length(P) > 1 then
- begin
- gsGoalLimit := nclamp(StrToIntDef(P[1], gsGoalLimit), 0, $FFFF);
+ g_Console_Add(Format('%s %d', [cmd, Integer(gsItemRespawnRandom)]));
+ if g_Game_IsServer then g_Console_Add(_lc[I_MSG_ONMAPCHANGE]);
+ end;
- if g_Game_IsServer then
+ 'g_powerup_respawn_time': begin
+ if Length(P) > 1 then
begin
- b := 0;
- if gGameSettings.GameMode = GM_DM then
- begin // DM
- stat := g_Player_GetStats();
- if stat <> nil then
- for a := 0 to High(stat) do
- if stat[a].Frags > b then
- b := stat[a].Frags;
- end
- else // TDM/CTF
- b := Max(gTeamStat[TEAM_RED].Goals, gTeamStat[TEAM_BLUE].Goals);
+ gsPowerupRespawnTime := nclamp(StrToIntDef(P[1], gsPowerupRespawnTime), 0, $FFFF);
+ if g_Game_IsServer then
+ begin
+ gGameSettings.PowerupRespawnTime := gsPowerupRespawnTime;
+ if g_Game_IsNet then MH_SEND_GameSettings;
+ end;
+ end;
- // if someone has a higher score, set it to that instead
- gsGoalLimit := max(gsGoalLimit, b);
- gGameSettings.GoalLimit := gsGoalLimit;
-
- if g_Game_IsNet then MH_SEND_GameSettings;
+ g_Console_Add(Format('%s %d', [cmd, Integer(gsPowerupRespawnTime)]));
+ if g_Game_IsServer then g_Console_Add(_lc[I_MSG_ONMAPCHANGE]);
+ end;
+
+ 'g_powerup_time_random': begin
+ if Length(P) > 1 then
+ begin
+ gsPowerupRespawnRandom := nclamp(StrToIntDef(P[1], gsPowerupRespawnRandom), 0, $FFFF);
+ if g_Game_IsServer then
+ begin
+ gGameSettings.PowerupRespawnRandom := gsPowerupRespawnRandom;
+ if g_Game_IsNet then MH_SEND_GameSettings;
+ end;
end;
+
+ g_Console_Add(Format('%s %d', [cmd, Integer(gsPowerupRespawnRandom)]));
+ if g_Game_IsServer then g_Console_Add(_lc[I_MSG_ONMAPCHANGE]);
end;
- g_Console_Add(Format(_lc[I_MSG_SCORE_LIMIT], [Integer(gsGoalLimit)]));
- end
- else if cmd = 'g_timelimit' then
- begin
- if Length(P) > 1 then
- begin
- gsTimeLimit := nclamp(StrToIntDef(P[1], gsTimeLimit), 0, $FFFF);
- if g_Game_IsServer then
+ 'sv_intertime': begin
+ if (Length(P) > 1) then
+ gDefInterTime := Min(Max(StrToIntDef(P[1], gDefInterTime), -1), 120);
+
+ g_Console_Add(cmd + ' = ' + IntToStr(gDefInterTime));
+ end;
+
+ 'g_max_particles': begin
+ if Length(p) = 2 then
begin
- gGameSettings.TimeLimit := gsTimeLimit;
- if g_Game_IsNet then MH_SEND_GameSettings;
+ a := Max(0, StrToIntDef(p[1], 0));
+ g_GFX_SetMax(a)
+ end
+ else if Length(p) = 1 then
+ begin
+ e_LogWritefln('%s', [g_GFX_GetMax()])
+ end
+ else
+ begin
+ e_LogWritefln('usage: %s <n>', [cmd])
+ end
+ end;
+
+ 'g_max_shells': begin
+ if Length(p) = 2 then
+ begin
+ a := Max(0, StrToIntDef(p[1], 0));
+ g_Shells_SetMax(a)
+ end
+ else if Length(p) = 1 then
+ begin
+ e_LogWritefln('%s', [g_Shells_GetMax()])
+ end
+ else
+ begin
+ e_LogWritefln('usage: %s <n>', [cmd])
+ end
+ end;
+
+ 'g_max_gibs': begin
+ if Length(p) = 2 then
+ begin
+ a := Max(0, StrToIntDef(p[1], 0));
+ g_Gibs_SetMax(a)
+ end
+ else if Length(p) = 1 then
+ begin
+ e_LogWritefln('%s', [g_Gibs_GetMax()])
+ end
+ else
+ begin
+ e_LogWritefln('usage: %s <n>', [cmd])
+ end
+ end;
+
+ 'g_max_corpses': begin
+ if Length(p) = 2 then
+ begin
+ a := Max(0, StrToIntDef(p[1], 0));
+ g_Corpses_SetMax(a)
+ end
+ else if Length(p) = 1 then
+ begin
+ e_LogWritefln('%s', [g_Corpses_GetMax()])
+ end
+ else
+ begin
+ e_LogWritefln('usage: %s <n>', [cmd])
+ end
+ end;
+
+ 'g_force_model': begin
+ if Length(p) = 2 then
+ begin
+ a := StrToIntDef(p[1], 0);
+ g_Force_Model_Set(a);
+ if (g_Force_Model_Get() <> 0) and (gPlayers <> nil) then
+ begin
+ for a := Low(gPlayers) to High(gPlayers) do
+ begin
+ if (gPlayers[a] <> nil) then
+ begin
+ if (gPlayers[a].UID = gPlayer1.UID) then
+ continue
+ else if (gPlayer2 <> nil) and (gPlayers[a].UID = gPlayer2.UID) then
+ continue;
+ gPlayers[a].setModel(g_Forced_Model_GetName());
+ end;
+ end
+ end
+ else if (g_Force_Model_Get() = 0) and (gPlayers <> nil) then
+ begin
+ for a := Low(gPlayers) to High(gPlayers) do
+ begin
+ if (gPlayers[a] <> nil) then
+ begin
+ if (gPlayers[a].UID = gPlayer1.UID) then
+ continue
+ else if (gPlayer2 <> nil) and (gPlayers[a].UID = gPlayer2.UID) then
+ continue;
+ gPlayers[a].setModel(gPlayers[a].FActualModelName);
+ end;
+ end
+ end
+ end
+ end;
+
+ 'g_force_model_name': begin
+ if (Length(P) > 1) then
+ begin
+ cmd := b_Text_Unformat(P[1]);
+ g_Forced_Model_SetName(cmd);
+ if (g_Force_Model_Get() <> 0) and (gPlayers <> nil) then
+ begin
+ for a := Low(gPlayers) to High(gPlayers) do
+ begin
+ if (gPlayers[a] <> nil) then
+ begin
+ if (gPlayers[a].UID = gPlayer1.UID) then
+ continue
+ else if (gPlayer2 <> nil) and (gPlayers[a].UID = gPlayer2.UID) then
+ continue;
+ gPlayers[a].setModel(g_Forced_Model_GetName());
+ end;
+ end
+ end
+ end
+ end;
+
+ 'g_scorelimit': begin
+ if Length(P) > 1 then
+ begin
+ gsScoreLimit := nclamp(StrToIntDef(P[1], gsScoreLimit), 0, $FFFF);
+
+ if g_Game_IsServer then
+ begin
+ b := 0;
+ if gGameSettings.GameMode = GM_DM then
+ begin // DM
+ stat := g_Player_GetStats();
+ if stat <> nil then
+ for a := 0 to High(stat) do
+ if stat[a].Frags > b then
+ b := stat[a].Frags;
+ end
+ else // TDM/CTF
+ b := Max(gTeamStat[TEAM_RED].Score, gTeamStat[TEAM_BLUE].Score);
+
+ // if someone has a higher score, set it to that instead
+ gsScoreLimit := max(gsScoreLimit, b);
+ gGameSettings.ScoreLimit := gsScoreLimit;
+
+ if g_Game_IsNet then MH_SEND_GameSettings;
+ end;
end;
+
+ g_Console_Add(Format(_lc[I_MSG_SCORE_LIMIT], [Integer(gsScoreLimit)]));
end;
- g_Console_Add(Format(_lc[I_MSG_TIME_LIMIT],
- [gsTimeLimit div 3600,
- (gsTimeLimit div 60) mod 60,
- gsTimeLimit mod 60]));
- end
- else if cmd = 'g_maxlives' then
- begin
- if Length(P) > 1 then
- begin
- gsMaxLives := nclamp(StrToIntDef(P[1], gsMaxLives), 0, $FFFF);
- if g_Game_IsServer then
+
+ 'g_timelimit': begin
+ if Length(P) > 1 then
begin
- gGameSettings.MaxLives := gsMaxLives;
- if g_Game_IsNet then MH_SEND_GameSettings;
+ gsTimeLimit := nclamp(StrToIntDef(P[1], gsTimeLimit), 0, $FFFF);
+ if g_Game_IsServer then
+ begin
+ gGameSettings.TimeLimit := gsTimeLimit;
+ if g_Game_IsNet then MH_SEND_GameSettings;
+ end;
end;
+ g_Console_Add(Format(_lc[I_MSG_TIME_LIMIT],
+ [gsTimeLimit div 3600,
+ (gsTimeLimit div 60) mod 60,
+ gsTimeLimit mod 60]));
end;
- g_Console_Add(Format(_lc[I_MSG_LIVES], [Integer(gsMaxLives)]));
+ 'g_max_bots': begin
+ if Length(P) > 1 then
+ gMaxBots := nclamp(StrToIntDef(P[1], gMaxBots), 0, 127);
+ g_Console_Add('g_max_bots = ' + IntToStr(gMaxBots));
+ end;
+
+ 'g_maxlives': begin
+ if Length(P) > 1 then
+ begin
+ gsMaxLives := nclamp(StrToIntDef(P[1], gsMaxLives), 0, $FFFF);
+ if g_Game_IsServer then
+ begin
+ gGameSettings.MaxLives := gsMaxLives;
+ if g_Game_IsNet then MH_SEND_GameSettings;
+ end;
+ end;
+
+ g_Console_Add(Format(_lc[I_MSG_LIVES], [Integer(gsMaxLives)]));
+ end;
end;
end;
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
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;
+ 'p1_autoswitch':
+ begin
+ if (Length(P) = 2) then
+ gPlayer1Settings.WeaponSwitch := EnsureRange(StrTointDef(P[1], 0), 0, 2);
+ end;
+ 'p2_autoswitch':
+ begin
+ if (Length(P) = 2) then
+ gPlayer2Settings.WeaponSwitch := EnsureRange(StrTointDef(P[1], 0), 0, 2);
+ end;
+ 'p1_switch_empty':
+ begin
+ if (Length(P) = 2) then
+ gPlayer1Settings.SwitchToEmpty := EnsureRange(StrTointDef(P[1], 0), 0, 1);
+ end;
+ 'p2_switch_empty':
+ begin
+ if (Length(P) = 2) then
+ gPlayer2Settings.SwitchToEmpty := EnsureRange(StrTointDef(P[1], 0), 0, 1);
+ end;
+ 'p1_skip_ironfist':
+ begin
+ if (Length(P) = 2) then
+ gPlayer1Settings.SkipIronFist := EnsureRange(StrTointDef(P[1], 0), 0, 1);
+ end;
+ 'p2_skip_ironfist':
+ begin
+ if (Length(P) = 2) then
+ gPlayer2Settings.SkipIronFist := EnsureRange(StrTointDef(P[1], 0), 0, 1);
+ end;
+ 'p1_priority_ironfist':
+ begin
+ if (Length(P) = 2) then
+ gPlayer1Settings.WeaponPreferences[WEAPON_IRONFIST] := EnsureRange(StrToIntDef(P[1], WP_FIRST), WP_FIRST, WP_LAST+1);
+ end;
+ 'p2_priority_ironfist':
+ begin
+ if (Length(P) = 2) then
+ gPlayer2Settings.WeaponPreferences[WEAPON_IRONFIST] := EnsureRange(StrToIntDef(P[1], WP_FIRST), WP_FIRST, WP_LAST+1);
+ end;
+ 'p1_priority_saw':
+ begin
+ if (Length(P) = 2) then
+ gPlayer1Settings.WeaponPreferences[WEAPON_SAW] := EnsureRange(StrToIntDef(P[1], WP_FIRST), WP_FIRST, WP_LAST+1);
+ end;
+ 'p2_priority_saw':
+ begin
+ if (Length(P) = 2) then
+ gPlayer2Settings.WeaponPreferences[WEAPON_SAW] := EnsureRange(StrToIntDef(P[1], WP_FIRST), WP_FIRST, WP_LAST+1);
+ end;
+ 'p1_priority_pistol':
+ begin
+ if (Length(P) = 2) then
+ gPlayer1Settings.WeaponPreferences[WEAPON_PISTOL] := EnsureRange(StrToIntDef(P[1], WP_FIRST), WP_FIRST, WP_LAST+1);
+ end;
+ 'p2_priority_pistol':
+ begin
+ if (Length(P) = 2) then
+ gPlayer2Settings.WeaponPreferences[WEAPON_PISTOL] := EnsureRange(StrToIntDef(P[1], WP_FIRST), WP_FIRST, WP_LAST+1);
+ end;
+ 'p1_priority_shotgun1':
+ begin
+ if (Length(P) = 2) then
+ gPlayer1Settings.WeaponPreferences[WEAPON_SHOTGUN1] := EnsureRange(StrToIntDef(P[1], WP_FIRST), WP_FIRST, WP_LAST+1);
+ end;
+ 'p2_priority_shotgun1':
+ begin
+ if (Length(P) = 2) then
+ gPlayer2Settings.WeaponPreferences[WEAPON_SHOTGUN1] := EnsureRange(StrToIntDef(P[1], WP_FIRST), WP_FIRST, WP_LAST+1);
+ end;
+ 'p1_priority_shotgun2':
+ begin
+ if (Length(P) = 2) then
+ gPlayer1Settings.WeaponPreferences[WEAPON_SHOTGUN2] := EnsureRange(StrToIntDef(P[1], WP_FIRST), WP_FIRST, WP_LAST+1);
+ end;
+ 'p2_priority_shotgun2':
+ begin
+ if (Length(P) = 2) then
+ gPlayer2Settings.WeaponPreferences[WEAPON_SHOTGUN2] := EnsureRange(StrToIntDef(P[1], WP_FIRST), WP_FIRST, WP_LAST+1);
+ end;
+ 'p1_priority_chaingun':
+ begin
+ if (Length(P) = 2) then
+ gPlayer1Settings.WeaponPreferences[WEAPON_CHAINGUN] := EnsureRange(StrToIntDef(P[1], WP_FIRST), WP_FIRST, WP_LAST+1);
+ end;
+ 'p2_priority_chaingun':
+ begin
+ if (Length(P) = 2) then
+ gPlayer2Settings.WeaponPreferences[WEAPON_CHAINGUN] := EnsureRange(StrToIntDef(P[1], WP_FIRST), WP_FIRST, WP_LAST+1);
+ end;
+ 'p1_priority_rocketlauncher':
+ begin
+ if (Length(P) = 2) then
+ gPlayer1Settings.WeaponPreferences[WEAPON_ROCKETLAUNCHER] := EnsureRange(StrToIntDef(P[1], WP_FIRST), WP_FIRST, WP_LAST+1);
+ end;
+ 'p2_priority_rocketlauncher':
+ begin
+ if (Length(P) = 2) then
+ gPlayer2Settings.WeaponPreferences[WEAPON_ROCKETLAUNCHER] := EnsureRange(StrToIntDef(P[1], WP_FIRST), WP_FIRST, WP_LAST+1);
+ end;
+ 'p1_priority_plasma':
+ begin
+ if (Length(P) = 2) then
+ gPlayer1Settings.WeaponPreferences[WEAPON_PLASMA] := EnsureRange(StrToIntDef(P[1], WP_FIRST), WP_FIRST, WP_LAST+1);
+ end;
+ 'p2_priority_plasma':
+ begin
+ if (Length(P) = 2) then
+ gPlayer2Settings.WeaponPreferences[WEAPON_PLASMA] := EnsureRange(StrToIntDef(P[1], WP_FIRST), WP_FIRST, WP_LAST+1);
+ end;
+ 'p1_priority_bfg':
+ begin
+ if (Length(P) = 2) then
+ gPlayer1Settings.WeaponPreferences[WEAPON_BFG] := EnsureRange(StrToIntDef(P[1], WP_FIRST), WP_FIRST, WP_LAST+1);
+ end;
+ 'p2_priority_bfg':
+ begin
+ if (Length(P) = 2) then
+ gPlayer2Settings.WeaponPreferences[WEAPON_BFG] := EnsureRange(StrToIntDef(P[1], WP_FIRST), WP_FIRST, WP_LAST+1);
+ end;
+ 'p1_priority_superchaingun':
+ begin
+ if (Length(P) = 2) then
+ gPlayer1Settings.WeaponPreferences[WEAPON_SUPERCHAINGUN] := EnsureRange(StrToIntDef(P[1], WP_FIRST), WP_FIRST, WP_LAST+1);
+ end;
+ 'p2_priority_superchaingun':
+ begin
+ if (Length(P) = 2) then
+ gPlayer2Settings.WeaponPreferences[WEAPON_SUPERCHAINGUN] := EnsureRange(StrToIntDef(P[1], WP_FIRST), WP_FIRST, WP_LAST+1);
+ end;
+ 'p1_priority_flamethrower':
+ begin
+ if (Length(P) = 2) then
+ gPlayer1Settings.WeaponPreferences[WEAPON_FLAMETHROWER] := EnsureRange(StrToIntDef(P[1], WP_FIRST), WP_FIRST, WP_LAST+1);
+ end;
+ 'p2_priority_flamethrower':
+ begin
+ if (Length(P) = 2) then
+ gPlayer2Settings.WeaponPreferences[WEAPON_FLAMETHROWER] := EnsureRange(StrToIntDef(P[1], WP_FIRST), WP_FIRST, WP_LAST+1);
+ end;
+ 'p1_priority_berserk':
+ begin
+ if (Length(P) = 2) then
+ gPlayer1Settings.WeaponPreferences[WP_LAST+1] := EnsureRange(StrToIntDef(P[1], WP_FIRST), WP_FIRST, WP_LAST+1);
+ end;
+ 'p2_priority_berserk':
+ begin
+ if (Length(P) = 2) then
+ gPlayer2Settings.WeaponPreferences[WP_LAST+1] := EnsureRange(StrToIntDef(P[1], WP_FIRST), WP_FIRST, WP_LAST+1);
+ end;
end;
end;
if cmd = 'd_window' then
begin
g_Console_Add(Format('gScreenWidth = %d, gScreenHeight = %d', [gScreenWidth, gScreenHeight]));
- g_Console_Add(Format('gScreenWidth = %d, gScreenHeight = %d', [gScreenWidth, gScreenHeight]));
+ g_Console_Add(Format('gWinSizeX = %d, gWinSizeY = %d', [gWinSizeX, gWinSizeY]));
end
else if cmd = 'd_sounds' then
begin
begin
cmd := LowerCase(P[f]);
if cmd = 'health' then begin plr.RestoreHealthArmor(); g_Console_Add('player feels himself better'); continue; end;
- if (cmd = 'all') {or (cmd = 'weapons')} then begin plr.AllRulez(False); g_Console_Add('player got the gifts'); continue; end;
+ if (cmd = 'all') {or (cmd = 'weapons')} then begin plr.TankRamboCheats(False); g_Console_Add('player got the gifts'); continue; end;
if cmd = 'exit' then
begin
if gTriggers <> nil then
if cmd = 'greenarmor' then begin plr.GiveItem(ITEM_ARMOR_GREEN); g_Console_Add('player got a security armor'); continue; end;
if cmd = 'bluearmor' then begin plr.GiveItem(ITEM_ARMOR_BLUE); g_Console_Add('player got a combat armor'); continue; end;
- if (cmd = 'megasphere') or (cmd = 'mega') then begin plr.GiveItem(ITEM_SPHERE_BLUE); g_Console_Add('player got a megasphere'); continue; end;
- if (cmd = 'soulsphere') or (cmd = 'soul')then begin plr.GiveItem(ITEM_SPHERE_WHITE); g_Console_Add('player got a soul sphere'); continue; end;
+ if (cmd = 'soulsphere') or (cmd = 'soul') then begin plr.GiveItem(ITEM_SPHERE_BLUE); g_Console_Add('player got a soul sphere'); continue; end;
+ if (cmd = 'megasphere') or (cmd = 'mega') then begin plr.GiveItem(ITEM_SPHERE_WHITE); g_Console_Add('player got a megasphere'); continue; end;
if (cmd = 'invul') or (cmd = 'invulnerability') then begin plr.GiveItem(ITEM_INVUL); g_Console_Add('player got invulnerability'); continue; end;
if (cmd = 'invis') or (cmd = 'invisibility') then begin plr.GiveItem(ITEM_INVIS); g_Console_Add('player got invisibility'); continue; end;
if cmd = 'plasmagunzz' then begin plr.GiveItem(ITEM_WEAPON_PLASMA); plr.GiveItem(ITEM_AMMO_CELL_BIG); g_Console_Add('player got a plasma gun'); continue; end;
if cmd = 'bfgzz' then begin plr.GiveItem(ITEM_WEAPON_BFG); plr.GiveItem(ITEM_AMMO_CELL_BIG); g_Console_Add('player got a BFG-9000'); continue; end;
- if cmd = 'superchaingun' then begin plr.GiveItem(ITEM_WEAPON_SUPERPULEMET); g_Console_Add('player got a superchaingun'); continue; end;
- if cmd = 'superchaingunzz' then begin plr.GiveItem(ITEM_WEAPON_SUPERPULEMET); plr.GiveItem(ITEM_AMMO_BULLETS_BOX); g_Console_Add('player got a superchaingun'); continue; end;
+ if cmd = 'superchaingun' then begin plr.GiveItem(ITEM_WEAPON_SUPERCHAINGUN); g_Console_Add('player got a superchaingun'); continue; end;
+ if cmd = 'superchaingunzz' then begin plr.GiveItem(ITEM_WEAPON_SUPERCHAINGUN); plr.GiveItem(ITEM_AMMO_BULLETS_BOX); g_Console_Add('player got a superchaingun'); continue; end;
if (cmd = 'flamer') or (cmd = 'flamethrower') or (cmd = 'ft') then begin plr.GiveItem(ITEM_WEAPON_FLAMETHROWER); g_Console_Add('player got a flame thrower'); continue; end;
if (cmd = 'flamerzz') or (cmd = 'flamethrowerzz') or (cmd = 'ftzz') then begin plr.GiveItem(ITEM_WEAPON_FLAMETHROWER); plr.GiveItem(ITEM_AMMO_FUELCAN); g_Console_Add('player got a flame thrower'); continue; end;
nm: Boolean;
listen: LongWord;
found: Boolean;
+ t: Byte;
begin
// Îáùèå êîìàíäû:
cmd := LowerCase(P[0]);
if (pl <> nil) then
begin
s := g_Net_ClientName_ByID(pl^.ID);
- enet_peer_disconnect(pl^.Peer, NET_DISC_KICK);
+ g_Net_Host_Kick(pl^.ID, 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();
if NetClients[a].Used and (NetClients[a].Peer <> nil) then
begin
s := g_Net_ClientName_ByID(NetClients[a].ID);
- enet_peer_disconnect(NetClients[a].Peer, NET_DISC_KICK);
+ g_Net_Host_Kick(NetClients[a].ID, 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();
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_Net_Host_Kick(pl^.ID, 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();
pl := g_Net_Client_ByName(P[1]);
if (pl <> 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 else
+ g_Net_Host_Ban(pl, False)
+ else
g_Console_Add(Format(_lc[I_NET_ERR_NAME404], [P[1]]));
end else
g_Console_Add(_lc[I_MSG_SERVERONLY]);
a := StrToIntDef(P[1], 0);
if (NetClients <> nil) and (a <= High(NetClients)) then
if NetClients[a].Used and (NetClients[a].Peer <> nil) then
- begin
- s := g_Net_ClientName_ByID(NetClients[a].ID);
- g_Net_BanHost(NetClients[a].Peer^.address.host, False);
- enet_peer_disconnect(NetClients[a].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;
+ g_Net_Host_Ban(pl, False);
end else
g_Console_Add(_lc[I_MSG_SERVERONLY]);
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;
+ g_Net_Host_Ban(pl, False);
end else
g_Console_Add(_lc[I_MSG_SERVERONLY]);
end
pl := g_Net_Client_ByName(P[1]);
if (pl <> 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 else
+ g_Net_Host_Ban(pl, True)
+ else
g_Console_Add(Format(_lc[I_NET_ERR_NAME404], [P[1]]));
end else
g_Console_Add(_lc[I_MSG_SERVERONLY]);
a := StrToIntDef(P[1], 0);
if (NetClients <> nil) and (a <= High(NetClients)) then
if NetClients[a].Used and (NetClients[a].Peer <> nil) then
- begin
- s := g_Net_ClientName_ByID(NetClients[a].ID);
- g_Net_BanHost(NetClients[a].Peer^.address.host);
- enet_peer_disconnect(NetClients[a].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;
+ g_Net_Host_Ban(@NetClients[a], True);
end else
g_Console_Add(_lc[I_MSG_SERVERONLY]);
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;
+ g_Net_Host_Ban(pl, True);
end else
g_Console_Add(_lc[I_MSG_SERVERONLY]);
end
Exit;
end;
- g_Net_BanHost(P[1]);
+ g_Net_BanAddress(P[1]);
g_Net_SaveBanList();
g_Console_Add(Format(_lc[I_PLAYER_BAN], [P[1]]));
end else
Exit;
end;
- if g_Net_UnbanHost(P[1]) then
+ if g_Net_UnbanAddress(P[1]) then
begin
g_Console_Add(Format(_lc[I_MSG_UNBAN_OK], [P[1]]));
g_Net_SaveBanList();
else if (cmd = 'addbot') or
(cmd = 'bot_add') then
begin
- if Length(P) > 2 then
- g_Bot_Add(TEAM_NONE, StrToIntDef(P[1], 2), StrToIntDef(P[2], 100))
- else if Length(P) > 1 then
- g_Bot_Add(TEAM_NONE, StrToIntDef(P[1], 2))
+ case Length(P) of
+ 1: g_Bot_Add(TEAM_NONE, 2);
+ 2: g_Bot_Add(TEAM_NONE, StrToIntDef(P[1], 2));
else
- g_Bot_Add(TEAM_NONE, 2);
+ g_Bot_Add(TEAM_NONE, StrToIntDef(P[1], 2), StrToIntDef(P[2], 100));
+ end;
end
else if cmd = 'bot_addlist' then
begin
- if Length(P) > 1 then
- begin
- if Length(P) = 2 then
- g_Bot_AddList(TEAM_NONE, P[1], StrToIntDef(P[1], -1))
- else if Length(P) = 3 then
- g_Bot_AddList(TEAM_NONE, P[1], StrToIntDef(P[1], -1), StrToIntDef(P[2], 100))
+ case Length(P) of
+ 1: g_Bot_AddList(TEAM_NONE, '');
+ 2: g_Bot_AddList(TEAM_NONE, P[1], StrToIntDef(P[1], -1));
+ else
+ if P[2] = 'red' then
+ t := TEAM_RED
+ else if P[2] = 'blue' then
+ t := TEAM_BLUE
else
- g_Bot_AddList(IfThen(P[2] = 'red', TEAM_RED, TEAM_BLUE), P[1], StrToIntDef(P[1], -1));
+ t := TEAM_NONE;
+
+ if Length(P) = 3
+ then g_Bot_AddList(t, P[1], StrToIntDef(P[1], -1))
+ else g_Bot_AddList(t, P[1], StrToIntDef(P[1], -1), StrToIntDef(P[3], 100));
end;
end
else if cmd = 'bot_removeall' then
end else
g_Console_Add(_lc[I_MSG_GM_UNAVAIL]);
end
+ else if (cmd = 'an') or (cmd = 'announce') then
+ begin
+ if g_Game_IsNet then
+ begin
+ if Length(P) > 1 then
+ begin
+ for a := 1 to High(P) do
+ chstr := chstr + P[a] + ' ';
+
+ if Length(chstr) > 200 then SetLength(chstr, 200);
+
+ if Length(chstr) < 1 then
+ begin
+ g_Console_Add('announce <text>');
+ Exit;
+ end;
+
+ chstr := 'centerprint 100 ' + b_Text_Format(chstr);
+ if g_Game_IsClient then
+ MC_SEND_RCONCommand(chstr)
+ else
+ g_Console_Process(chstr, True);
+ end
+ else
+ g_Console_Add('announce <text>');
+ end else
+ g_Console_Add(_lc[I_MSG_GM_UNAVAIL]);
+ end
else if cmd = 'game' then
begin
if gGameSettings.GameType <> GT_NONE then
g_Console_Add(cmd + ' <WAD> [MAP] [# players]');
Exit;
end;
- // game not started yet, load fist map from some wad
+ // game not started yet, load first map from some wad
found := false;
s := addWadExtension(P[1]);
found := e_FindResource(AllMapDirs, s);
if Length(P) >= 4 then
b := StrToIntDef(P[3], 1);
g_Game_StartCustom(s, GameMode, TimeLimit,
- GoalLimit, MaxLives, Options, b);
+ ScoreLimit, MaxLives, Options, b);
end;
end
else
b := 0;
if Length(P) >= 6 then
b := StrToIntDef(P[5], 0);
- g_Game_StartServer(s, GameMode, TimeLimit, GoalLimit, MaxLives, Options, b, listen, prt)
+ g_Game_StartServer(s, GameMode, TimeLimit, ScoreLimit, MaxLives, Options, b, listen, prt)
end
end
else
g_Console_Add(_lc[I_MSG_GM_UNAVAIL])
end
end
+ else if not e_IsValidResourceName(P[1]) then
+ begin
+ g_Console_Add('wad name must not be absolute or relative');
+ end
else
begin
if g_Game_IsServer and (gGameSettings.GameType <> GT_SINGLE) then
g_Console_Add(_lc[I_MSG_GM_UNAVAIL]);
end;
end
+ else if not e_IsValidResourceName(P[1]) then
+ begin
+ g_Console_Add('wad name must not be absolute or relative');
+ end
else
begin
nm := False;
begin
g_TakeScreenShot()
end
+ else if (cmd = 'weapnext') or (cmd = 'weapprev') then
+ begin
+ a := 1 - (ord(cmd[5]) - ord('n'));
+ if a = -1 then
+ gWeaponAction[0, WP_PREV] := True;
+ if a = 1 then
+ gWeaponAction[0, WP_NEXT] := True;
+ end
else if cmd = 'weapon' then
begin
if Length(p) = 2 then
begin
- a := WP_FIRST + StrToInt(p[1]) - 1;
+ a := WP_FIRST + StrToIntDef(p[1], 0) - 1;
if (a >= WP_FIRST) and (a <= WP_LAST) then
gSelectWeapon[0, a] := True
end
end
+ else if (cmd = 'p1_weapnext') or (cmd = 'p1_weapprev')
+ or (cmd = 'p2_weapnext') or (cmd = 'p2_weapprev') then
+ begin
+ a := 1 - (ord(cmd[8]) - ord('n'));
+ b := ord(cmd[2]) - ord('1');
+ if a = -1 then
+ gWeaponAction[b, WP_PREV] := True;
+ if a = 1 then
+ gWeaponAction[b, WP_NEXT] := True;
+ end
else if (cmd = 'p1_weapon') or (cmd = 'p2_weapon') then
begin
if Length(p) = 2 then
begin
- a := WP_FIRST + StrToInt(p[1]) - 1;
+ a := WP_FIRST + StrToIntDef(p[1], 0) - 1;
b := ord(cmd[2]) - ord('1');
if (a >= WP_FIRST) and (a <= WP_LAST) then
gSelectWeapon[b, a] := True
end
end
+ else if (cmd = 'p1_weapbest') or (cmd = 'p2_weapbest') then
+ begin
+ b := ord(cmd[2]) - ord('1');
+ if b = 0 then
+ gSelectWeapon[b, gPlayer1.GetMorePrefered()] := True
+ else
+ gSelectWeapon[b, gPlayer2.GetMorePrefered()] := True;
+ end
+ else if (cmd = 'dropflag') then
+ begin
+ if g_Game_IsServer then
+ begin
+ if gPlayer2 <> nil then gPlayer2.TryDropFlag();
+ if gPlayer1 <> nil then gPlayer1.TryDropFlag();
+ end
+ else
+ MC_SEND_CheatRequest(NET_CHEAT_DROPFLAG);
+ end
+ else if (cmd = 'p1_dropflag') or (cmd = 'p2_dropflag') then
+ begin
+ b := ord(cmd[2]) - ord('1');
+ if g_Game_IsServer then
+ begin
+ if (b = 1) and (gPlayer2 <> nil) then gPlayer2.TryDropFlag()
+ else if (b = 0) and (gPlayer1 <> nil) then gPlayer1.TryDropFlag();
+ end
+ else
+ MC_SEND_CheatRequest(NET_CHEAT_DROPFLAG);
+ end
// Êîìàíäû Ñâîåé èãðû:
else if gGameSettings.GameType in [GT_CUSTOM, GT_SERVER, GT_CLIENT] then
begin
DateTimeToString(date, 'yyyy-mm-dd-hh-nn-ss', t);
Filename := 'screenshot-' + date;
end;
-
+
name := e_CatPath(dir, Filename + '.png');
s := createDiskFile(name);
try
- e_MakeScreenshot(s, gScreenWidth, gScreenHeight);
+ e_MakeScreenshot(s, gWinSizeX, gWinSizeY);
s.Free;
g_Console_Add(Format(_lc[I_CONSOLE_SCREENSHOT], [name]))
except
hahasnd[Random(3)].Play();
end;
+procedure g_Game_Effect_Bubbles (fX, fY: Integer; count: Word; devX, devY: Byte; Silent: Boolean);
+begin
+ g_GFX_Bubbles(fX, fY, count, devX, devY);
+ if not Silent then if Random(2) = 0
+ then g_Sound_PlayExAt('SOUND_GAME_BUBBLE1', fX, fY)
+ else g_Sound_PlayExAt('SOUND_GAME_BUBBLE2', fX, fY);
+end;
+
procedure g_Game_StartVote(Command, Initiator: string);
var
Need: Integer;
end;
g_ActiveWindow := nil;
-
- ProcessLoading(true);
+ ProcessLoading(True);
end;
procedure g_Game_StepLoading(Value: Integer = -1);
end
else
CurValue := Value;
+
if (ShowCount > LOADING_SHOW_STEP) or (Value > -1) then
begin
ShowCount := 0;
- ProcessLoading();
+ ProcessLoading(False);
end;
end;
end;
while i <= ParamCount do
begin
s := ParamStr(i);
- if (s[1] = '-') and (Length(s) > 1) then
+ if (Length(s) > 1) and (s[1] = '-') then
begin
- if (s[2] = '-') and (Length(s) > 2) then
+ if (Length(s) > 2) and (s[2] = '-') then
begin // Îäèíî÷íûé ïàðàìåòð
SetLength(pars, Length(pars) + 1);
with pars[High(pars)] do
map: String;
GMode, n: Byte;
LimT, LimS: Integer;
- Opt: LongWord;
+ Opt: TGameOptions;
Lives: Integer;
s: String;
Port: Integer;
if LimT < 0 then
LimT := 0;
- // Goal limit:
+ // Score limit:
s := Find_Param_Value(pars, '-lims');
if (s = '') or (not TryStrToInt(s, LimS)) then
LimS := 0;
// Options:
s := Find_Param_Value(pars, '-opt');
- if (s = '') then
- Opt := gsGameFlags
- else
- Opt := StrToIntDef(s, 0);
+ if (s = '')
+ then Opt := gsGameFlags
+ else Opt := TGameOptions(StrToIntDef(s, 0));
// Close after map:
s := Find_Param_Value(pars, '--close');
// Start:
s := Find_Param_Value(pars, '-port');
- if (s = '') or not TryStrToInt(s, Port) then
- g_Game_StartCustom(map, GMode, LimT, LimS, Lives, Opt, n)
- else
- g_Game_StartServer(map, GMode, LimT, LimS, Lives, Opt, n, 0, Port);
+ if (s = '') or not TryStrToInt(s, Port)
+ then g_Game_StartCustom(map, GMode, LimT, LimS, Lives, Opt, n)
+ else g_Game_StartServer(map, GMode, LimT, LimS, Lives, Opt, n, 0, Port);
end;
// Execute script when game loads:
conRegVar('r_showfps', @gShowFPS, 'draw fps counter', 'draw fps counter');
conRegVar('r_showtime', @gShowTime, 'show game time', 'show game time');
conRegVar('r_showping', @gShowPing, 'show ping', 'show ping');
- conRegVar('r_showscore', @gShowGoals, 'show score', 'show score');
+ conRegVar('r_showscore', @gShowScore, 'show score', 'show score');
conRegVar('r_showkillmsg', @gShowKillMsg, 'show kill log', 'show kill log');
conRegVar('r_showlives', @gShowLives, 'show lives', 'show lives');
conRegVar('r_showspect', @gSpectHUD, 'show spectator hud', 'show spectator hud');