From be2ad7bf5e09b4ee91a0c5ee741503ace8c7887c Mon Sep 17 00:00:00 2001 From: fgsfds Date: Tue, 25 Feb 2020 00:12:38 +0300 Subject: [PATCH] nuke doom2df.cfg; refactor some cvar-related stuff --- src/game/g_console.pas | 178 +++++++++++-- src/game/g_game.pas | 524 +++++++++++++++++++------------------ src/game/g_items.pas | 5 +- src/game/g_language.pas | 13 +- src/game/g_main.pas | 9 +- src/game/g_menu.pas | 260 ++++++++----------- src/game/g_net.pas | 36 ++- src/game/g_netmaster.pas | 11 +- src/game/g_options.pas | 547 +++------------------------------------ 9 files changed, 606 insertions(+), 977 deletions(-) diff --git a/src/game/g_console.pas b/src/game/g_console.pas index cbfcf5f..806c73f 100644 --- a/src/game/g_console.pas +++ b/src/game/g_console.pas @@ -64,6 +64,8 @@ procedure conwritefln (const s: AnsiString; args: array of const; show: Boolean= procedure conRegVar (const conname: AnsiString; pvar: PBoolean; const ahelp: AnsiString; const amsg: AnsiString; acheat: Boolean=false; ahidden: Boolean=false); overload; procedure conRegVar (const conname: AnsiString; pvar: PSingle; amin, amax: Single; const ahelp: AnsiString; const amsg: AnsiString; acheat: Boolean=false; ahidden: Boolean=false); overload; procedure conRegVar (const conname: AnsiString; pvar: PInteger; const ahelp: AnsiString; const amsg: AnsiString; acheat: Boolean=false; ahidden: Boolean=false); overload; +procedure conRegVar (const conname: AnsiString; pvar: PWord; const ahelp: AnsiString; const amsg: AnsiString; acheat: Boolean=false; ahidden: Boolean=false); overload; +procedure conRegVar (const conname: AnsiString; pvar: PCardinal; const ahelp: AnsiString; const amsg: AnsiString; acheat: Boolean=false; ahidden: Boolean=false); overload; procedure conRegVar (const conname: AnsiString; pvar: PAnsiString; const ahelp: AnsiString; const amsg: AnsiString; acheat: Boolean=false; ahidden: Boolean=false); overload; // <0: no arg; 0/1: true/false @@ -72,6 +74,8 @@ function conGetBoolArg (p: SSArray; idx: Integer): Integer; // poor man's floating literal parser; i'm sorry, but `StrToFloat()` sux cocks function conParseFloat (var res: Single; const s: AnsiString): Boolean; +const + defaultConfigScript = 'dfconfig.cfg'; var gConsoleShow: Boolean = false; // True - êîíñîëü îòêðûòà èëè îòêðûâàåòñÿ @@ -81,6 +85,7 @@ var gJustChatted: Boolean = false; // ÷òîáû àäìèí â èíòåðå ÷àòÿñü íå ïðîìàòûâàë ñòàòèñòèêó gParsingBinds: Boolean = true; // íå ïåðåñîõðàíÿòü êîíôèã âî âðåìÿ ïàðñèíãà gPlayerAction: Array [0..1, 0..LAST_ACTION] of Boolean; // [player, action] + gConfigScript: string = defaultConfigScript; implementation @@ -90,7 +95,6 @@ uses g_menu, g_gui, g_language, g_net, g_netmsg, e_log, conbuf; const - configScript = 'dfconfig.cfg'; autoexecScript = 'autoexec.cfg'; configComment = 'generated by doom2d, do not modify'; @@ -287,6 +291,50 @@ begin end; +procedure wordVarHandler (me: PCommand; p: SSArray); +var + old: Integer; +begin + if (Length(p) <> 2) then + begin + conwritefln('%s %d', [me.cmd, PInteger(me.ptr)^]); + end + else + begin + try + old := PWord(me.ptr)^; + PWord(me.ptr)^ := min($FFFF, StrToDWord(p[1])); + if PWord(me.ptr)^ <> old then + g_Console_WriteGameConfig(); + except + conwritefln('invalid word value: "%s"', [p[1]]); + end; + end; +end; + + +procedure dwordVarHandler (me: PCommand; p: SSArray); +var + old: Integer; +begin + if (Length(p) <> 2) then + begin + conwritefln('%s %d', [me.cmd, PInteger(me.ptr)^]); + end + else + begin + try + old := PCardinal(me.ptr)^; + PCardinal(me.ptr)^ := StrToDWord(p[1]); + if PCardinal(me.ptr)^ <> old then + g_Console_WriteGameConfig(); + except + conwritefln('invalid dword value: "%s"', [p[1]]); + end; + end; +end; + + procedure strVarHandler (me: PCommand; p: SSArray); var old: AnsiString; @@ -347,6 +395,48 @@ begin end; +procedure conRegVar (const conname: AnsiString; pvar: PWord; const ahelp: AnsiString; const amsg: AnsiString; acheat: Boolean=false; ahidden: Boolean=false); overload; +var + f: Integer; + cp: PCommand; +begin + f := Length(commands); + SetLength(commands, f+1); + cp := @commands[f]; + cp.cmd := LowerCase(conname); + cp.proc := nil; + cp.procEx := wordVarHandler; + cp.help := ahelp; + cp.hidden := ahidden; + cp.ptr := pvar; + cp.msg := amsg; + cp.cheat := acheat; + cp.action := -1; + cp.player := -1; +end; + + +procedure conRegVar (const conname: AnsiString; pvar: PCardinal; const ahelp: AnsiString; const amsg: AnsiString; acheat: Boolean=false; ahidden: Boolean=false); overload; +var + f: Integer; + cp: PCommand; +begin + f := Length(commands); + SetLength(commands, f+1); + cp := @commands[f]; + cp.cmd := LowerCase(conname); + cp.proc := nil; + cp.procEx := dwordVarHandler; + cp.help := ahelp; + cp.hidden := ahidden; + cp.ptr := pvar; + cp.msg := amsg; + cp.cheat := acheat; + cp.action := -1; + cp.player := -1; +end; + + procedure conRegVar (const conname: AnsiString; pvar: PAnsiString; const ahelp: AnsiString; const amsg: AnsiString; acheat: Boolean=false; ahidden: Boolean=false); overload; var f: Integer; @@ -860,13 +950,10 @@ begin AddCommand('segfault', segfault, 'make segfault'); - AddCommand('r_reset', g_Options_Commands); - AddCommand('g_language', g_Options_Commands); - AddCommand('g_max_particles', g_Options_Commands); - AddCommand('g_max_shells', g_Options_Commands); - AddCommand('g_max_gibs', g_Options_Commands); - AddCommand('g_max_corpses', g_Options_Commands); - AddCommand('g_item_respawn_time', g_Options_Commands); + AddCommand('quit', SystemCommands); + AddCommand('exit', SystemCommands); + AddCommand('r_reset', SystemCommands); + AddCommand('g_language', SystemCommands); AddCommand('bind', BindCommands); AddCommand('bindlist', BindCommands); @@ -913,12 +1000,10 @@ begin AddCommand('p1_model', PlayerSettingsCVars); AddCommand('p2_model', PlayerSettingsCVars); - AddCommand('r_showscore', GameCVars); - AddCommand('r_showlives', GameCVars); - AddCommand('r_showstat', GameCVars); - AddCommand('r_showkillmsg', GameCVars); - AddCommand('r_showspect', GameCVars); - AddCommand('r_showping', GameCVars); + AddCommand('g_max_particles', GameCVars); + AddCommand('g_max_shells', GameCVars); + AddCommand('g_max_gibs', GameCVars); + AddCommand('g_max_corpses', GameCVars); AddCommand('g_gamemode', GameCVars); AddCommand('g_friendlyfire', GameCVars); AddCommand('g_weaponstay', GameCVars); @@ -930,17 +1015,17 @@ begin AddCommand('g_scorelimit', GameCVars); AddCommand('g_timelimit', GameCVars); AddCommand('g_maxlives', GameCVars); - AddCommand('g_warmuptime', GameCVars); + AddCommand('g_warmup_time', GameCVars); AddCommand('g_spawn_invul', GameCVars); + AddCommand('g_item_respawn_time', GameCVars); AddCommand('sv_intertime', GameCVars); AddCommand('sv_name', NetServerCVars); AddCommand('sv_passwd', NetServerCVars); AddCommand('sv_maxplrs', NetServerCVars); AddCommand('sv_public', NetServerCVars); + AddCommand('sv_port', NetServerCVars); - AddCommand('quit', GameCommands); - AddCommand('exit', GameCommands); AddCommand('pause', GameCommands); AddCommand('endgame', GameCommands); AddCommand('restart', GameCommands); @@ -1037,10 +1122,11 @@ begin WhitelistCommand('g_timelimit'); WhitelistCommand('g_dm_keys'); WhitelistCommand('g_spawn_invul'); - WhitelistCommand('g_warmuptime'); + WhitelistCommand('g_item_respawn_time'); + WhitelistCommand('g_warmup_time'); g_Console_ResetBinds; - g_Console_ReadConfig(configScript); + g_Console_ReadConfig(gConfigScript); g_Console_ReadConfig(autoexecScript); gParsingBinds := False; end; @@ -1932,10 +2018,18 @@ end; procedure g_Console_WriteConfig (filename: String); var f: TextFile; i, j: Integer; + + procedure WriteFlag(name: string; flag: LongWord); + begin + WriteLn(f, name, IfThen(LongBool(gsGameFlags and flag), 1, 0)); + end; + begin AssignFile(f, filename); Rewrite(f); WriteLn(f, '// ' + configComment); + + // binds WriteLn(f, 'unbindall'); for i := 0 to e_MaxInputKeys - 1 do if (Length(gInputBinds[i].down) > 0) or (Length(gInputBinds[i].up) > 0) then @@ -1947,25 +2041,58 @@ begin Write(f, ' ', QuoteStr(GetCommandString(gInputBinds[i].up))); WriteLn(f, ''); end; + + // lang if gAskLanguage then WriteLn(f, 'g_language ask') else WriteLn(f, 'g_language ', gLanguage); + + // net server + WriteLn(f, 'sv_name ', QuoteStr(NetServerName)); + WriteLn(f, 'sv_passwd ', QuoteStr(NetPassword)); + WriteLn(f, 'sv_maxplrs ', NetMaxClients); + WriteLn(f, 'sv_port ', NetPort); + + // game settings WriteLn(f, 'g_max_particles ', g_GFX_GetMax()); WriteLn(f, 'g_max_shells ', g_Shells_GetMax()); WriteLn(f, 'g_max_gibs ', g_Gibs_GetMax()); WriteLn(f, 'g_max_corpses ', g_Corpses_GetMax()); - WriteLn(f, 'g_item_respawn_time ', ITEM_RESPAWNTIME div 36); + WriteLn(f, 'sv_intertime ', gDefInterTime); + + // gameplay settings + WriteLn(f, 'g_gamemode ', gsGameMode); + WriteLn(f, 'g_scorelimit ', gsGoalLimit); + WriteLn(f, 'g_timelimit ', gsTimeLimit); + WriteLn(f, 'g_maxlives ', gsMaxLives); + WriteLn(f, 'g_item_respawn_time ', gsItemRespawnTime); + WriteLn(f, 'g_spawn_invul ', gsSpawnInvul); + WriteLn(f, 'g_warmup_time ', gsWarmupTime); + + WriteFlag('g_friendlyfire ', GAME_OPTION_TEAMDAMAGE); + WriteFlag('g_allow_exit ', GAME_OPTION_ALLOWEXIT); + WriteFlag('g_allow_monsters ', GAME_OPTION_MONSTERS); + WriteFlag('g_dm_keys ', GAME_OPTION_DMKEYS); + WriteFlag('g_weaponstay ', GAME_OPTION_WEAPONSTAY); + WriteFlag('g_bot_vsmonsters ', GAME_OPTION_BOTVSMONSTER); + WriteFlag('g_bot_vsplayers ', GAME_OPTION_BOTVSPLAYER); + + // players with gPlayer1Settings do begin WriteLn(f, 'p1_name ', QuoteStr(Name)); WriteLn(f, 'p1_color ', Color.R, ' ', Color.G, ' ', Color.B); + WriteLn(f, 'p1_model ', QuoteStr(Model)); end; with gPlayer2Settings do begin WriteLn(f, 'p2_name ', QuoteStr(Name)); WriteLn(f, 'p2_color ', Color.R, ' ', Color.G, ' ', Color.B); + WriteLn(f, 'p2_model ', QuoteStr(Model)); end; + + // all cvars for i := 0 to High(commands) do begin if not commands[i].cheat then @@ -1979,6 +2106,14 @@ begin begin WriteLn(f, commands[i].cmd, ' ', PInteger(commands[i].ptr)^) end + else if @commands[i].procEx = @wordVarHandler then + begin + WriteLn(f, commands[i].cmd, ' ', PWord(commands[i].ptr)^) + end + else if @commands[i].procEx = @dwordVarHandler then + begin + WriteLn(f, commands[i].cmd, ' ', PCardinal(commands[i].ptr)^) + end else if @commands[i].procEx = @singleVarHandler then begin WriteLn(f, commands[i].cmd, ' ', PVarSingle(commands[i].ptr).val^:0:6) @@ -1992,6 +2127,7 @@ begin end end end; + WriteLn(f, 'r_reset'); CloseFile(f) end; @@ -2002,7 +2138,7 @@ begin if gParsingBinds = false then begin s := e_GetWriteableDir(ConfigDirs); - g_Console_WriteConfig(e_CatPath(s, configScript)) + g_Console_WriteConfig(e_CatPath(s, gConfigScript)) end end; diff --git a/src/game/g_game.pas b/src/game/g_game.pas index 61fed94..4a79f98 100644 --- a/src/game/g_game.pas +++ b/src/game/g_game.pas @@ -32,6 +32,7 @@ type GoalLimit: Word; WarmupTime: Word; SpawnInvul: Word; + ItemRespawnTime: Word; MaxLives: Byte; Options: LongWord; WAD: String; @@ -133,6 +134,7 @@ function g_Game_IsTestMap(): Boolean; procedure g_Game_DeleteTestMap(); procedure GameCVars(P: SSArray); procedure PlayerSettingsCVars(P: SSArray); +procedure SystemCommands(P: SSArray); procedure GameCommands(P: SSArray); procedure GameCheats(P: SSArray); procedure DebugCommands(P: SSArray); @@ -4625,7 +4627,7 @@ begin Exit; end; - g_Net_Slist_Set(NetSlistIP, NetSlistPort, NetSlistList); + g_Net_Slist_Set(NetMasterList); g_Net_Slist_ServerStarted(); @@ -5383,64 +5385,61 @@ var a, b: Integer; stat: TPlayerStatArray; cmd: string; -begin - stat := nil; - cmd := LowerCase(P[0]); - if (cmd = 'g_friendlyfire') and not g_Game_IsClient then + + procedure ParseGameFlag(Flag: LongWord; OffMsg, OnMsg: TStrings_Locale; OnMapChange: Boolean = False); + var + x: Boolean; begin - with gGameSettings do + if Length(P) > 1 then begin - if (Length(P) > 1) and - ((P[1] = '1') or (P[1] = '0')) then - begin - if (P[1][1] = '1') then - Options := Options or GAME_OPTION_TEAMDAMAGE - else - Options := Options and (not GAME_OPTION_TEAMDAMAGE); - end; + x := P[1] = '1'; - if (LongBool(Options and GAME_OPTION_TEAMDAMAGE)) then - g_Console_Add(_lc[I_MSG_FRIENDLY_FIRE_ON]) + if x then + gsGameFlags := gsGameFlags or Flag else - g_Console_Add(_lc[I_MSG_FRIENDLY_FIRE_OFF]); + gsGameFlags := gsGameFlags and (not Flag); - if g_Game_IsNet then MH_SEND_GameSettings; - end; - end - else if (cmd = 'g_weaponstay') and not g_Game_IsClient then - begin - with gGameSettings do - begin - if (Length(P) > 1) and - ((P[1] = '1') or (P[1] = '0')) then + if g_Game_IsServer then begin - if (P[1][1] = '1') then - Options := Options or GAME_OPTION_WEAPONSTAY + if x then + gGameSettings.Options := gGameSettings.Options or Flag else - Options := Options and (not GAME_OPTION_WEAPONSTAY); + gGameSettings.Options := gGameSettings.Options and (not Flag); + if g_Game_IsNet then MH_SEND_GameSettings; end; + end; - if (LongBool(Options and GAME_OPTION_WEAPONSTAY)) then - g_Console_Add(_lc[I_MSG_WEAPONSTAY_ON]) - else - g_Console_Add(_lc[I_MSG_WEAPONSTAY_OFF]); + if LongBool(gsGameFlags and Flag) then + g_Console_Add(_lc[OnMsg]) + else + g_Console_Add(_lc[OffMsg]); - if g_Game_IsNet then MH_SEND_GameSettings; - end; - end - else if cmd = 'g_gamemode' then + if OnMapChange and g_Game_IsServer then + g_Console_Add(_lc[I_MSG_ONMAPCHANGE]); + end; + +begin + stat := nil; + cmd := LowerCase(P[0]); + + if cmd = 'g_gamemode' then begin - a := g_Game_TextToMode(P[1]); - if a = GM_SINGLE then a := GM_COOP; - if (Length(P) > 1) and (a <> GM_NONE) and (not g_Game_IsClient) then + 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)])) @@ -5449,140 +5448,91 @@ begin [g_Game_ModeToText(gGameSettings.GameMode), g_Game_ModeToText(gSwitchGameMode)])); end - else if (cmd = 'g_allow_exit') and not g_Game_IsClient then + else if cmd = 'g_friendlyfire' then begin - with gGameSettings do - begin - if (Length(P) > 1) and - ((P[1] = '1') or (P[1] = '0')) then - begin - if (P[1][1] = '1') then - Options := Options or GAME_OPTION_ALLOWEXIT - else - Options := Options and (not GAME_OPTION_ALLOWEXIT); - end; - - if (LongBool(Options and GAME_OPTION_ALLOWEXIT)) then - g_Console_Add(_lc[I_MSG_ALLOWEXIT_ON]) - else - g_Console_Add(_lc[I_MSG_ALLOWEXIT_OFF]); - g_Console_Add(_lc[I_MSG_ONMAPCHANGE]); - - if g_Game_IsNet then MH_SEND_GameSettings; - end; + ParseGameFlag(GAME_OPTION_TEAMDAMAGE, I_MSG_FRIENDLY_FIRE_OFF, I_MSG_FRIENDLY_FIRE_ON); end - else if (cmd = 'g_allow_monsters') and not g_Game_IsClient then + else if cmd = 'g_weaponstay' then begin - with gGameSettings do - begin - if (Length(P) > 1) and - ((P[1] = '1') or (P[1] = '0')) then - begin - if (P[1][1] = '1') then - Options := Options or GAME_OPTION_MONSTERS - else - Options := Options and (not GAME_OPTION_MONSTERS); - end; - - if (LongBool(Options and GAME_OPTION_MONSTERS)) then - g_Console_Add(_lc[I_MSG_ALLOWMON_ON]) - else - g_Console_Add(_lc[I_MSG_ALLOWMON_OFF]); - g_Console_Add(_lc[I_MSG_ONMAPCHANGE]); - - if g_Game_IsNet then MH_SEND_GameSettings; - end; + ParseGameFlag(GAME_OPTION_WEAPONSTAY, I_MSG_WEAPONSTAY_OFF, I_MSG_WEAPONSTAY_ON); end - else if (cmd = 'g_bot_vsplayers') and not g_Game_IsClient then + else if cmd = 'g_allow_exit' then begin - with gGameSettings do - begin - if (Length(P) > 1) and - ((P[1] = '1') or (P[1] = '0')) then - begin - if (P[1][1] = '1') then - Options := Options or GAME_OPTION_BOTVSPLAYER - else - Options := Options and (not GAME_OPTION_BOTVSPLAYER); - end; - - if (LongBool(Options and GAME_OPTION_BOTVSPLAYER)) then - g_Console_Add(_lc[I_MSG_BOTSVSPLAYERS_ON]) - else - g_Console_Add(_lc[I_MSG_BOTSVSPLAYERS_OFF]); - - if g_Game_IsNet then MH_SEND_GameSettings; - end; + 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_vsmonsters') and not g_Game_IsClient then + else if cmd = 'g_bot_vsplayers' then begin - with gGameSettings do + 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 - if (Length(P) > 1) and - ((P[1] = '1') or (P[1] = '0')) then + gsGameFlags := StrToDWordDef(P[1], gsGameFlags); + if g_Game_IsServer then begin - if (P[1][1] = '1') then - Options := Options or GAME_OPTION_BOTVSMONSTER - else - Options := Options and (not GAME_OPTION_BOTVSMONSTER); + gGameSettings.Options := gsGameFlags; + if g_Game_IsNet then MH_SEND_GameSettings; end; - - if (LongBool(Options and GAME_OPTION_BOTVSMONSTER)) then - g_Console_Add(_lc[I_MSG_BOTSVSMONSTERS_ON]) - else - g_Console_Add(_lc[I_MSG_BOTSVSMONSTERS_OFF]); - - if g_Game_IsNet then MH_SEND_GameSettings; end; + + g_Console_Add(Format('%s %u', [cmd, gsGameFlags])); end - else if (cmd = 'g_dm_keys') and not g_Game_IsClient then + else if cmd = 'g_warmup_time' then begin - with gGameSettings do + if Length(P) > 1 then begin - if (Length(P) > 1) and - ((P[1] = '1') or (P[1] = '0')) then + gsWarmupTime := nclamp(StrToIntDef(P[1], gsWarmupTime), 0, $FFFF); + if g_Game_IsServer then begin - if (P[1][1] = '1') then - Options := Options or GAME_OPTION_DMKEYS - else - Options := Options and (not GAME_OPTION_DMKEYS); + gGameSettings.WarmupTime := gsWarmupTime; + if g_Game_IsNet then MH_SEND_GameSettings; end; - - if (LongBool(Options and GAME_OPTION_DMKEYS)) then - g_Console_Add(_lc[I_MSG_DMKEYS_ON]) - else - g_Console_Add(_lc[I_MSG_DMKEYS_OFF]); - - 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 - else if (cmd = 'g_warmuptime') and not g_Game_IsClient then + else if cmd = 'g_spawn_invul' then begin if Length(P) > 1 then begin - if StrToIntDef(P[1], gGameSettings.WarmupTime) = 0 then - gGameSettings.WarmupTime := 30 - else - gGameSettings.WarmupTime := StrToIntDef(P[1], gGameSettings.WarmupTime); + 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(_lc[I_MSG_WARMUP], - [gGameSettings.WarmupTime])); - g_Console_Add(_lc[I_MSG_ONMAPCHANGE]); + g_Console_Add(Format('%s %d', [cmd, Integer(gsSpawnInvul)])); end - else if (cmd = 'g_spawn_invul') and not g_Game_IsClient then + else if cmd = 'g_item_respawn_time' then begin if Length(P) > 1 then begin - if StrToIntDef(P[1], gGameSettings.SpawnInvul) = 0 then - gGameSettings.SpawnInvul := 0 - else - gGameSettings.SpawnInvul := StrToIntDef(P[1], gGameSettings.SpawnInvul); + 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(_lc[I_MSG_SPAWNINVUL], - [gGameSettings.SpawnInvul])); - g_Console_Add(_lc[I_MSG_ONMAPCHANGE]); + 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 @@ -5591,134 +5541,129 @@ begin g_Console_Add(cmd + ' = ' + IntToStr(gDefInterTime)); end - else if cmd = 'r_showscore' then - begin - if (Length(P) > 1) and - ((P[1] = '1') or (P[1] = '0')) then - gShowGoals := (P[1][1] = '1'); - - if gShowGoals then - g_Console_Add(_lc[I_MSG_SCORE_ON]) - else - g_Console_Add(_lc[I_MSG_SCORE_OFF]); - end - else if cmd = 'r_showstat' then - begin - if (Length(P) > 1) and - ((P[1] = '1') or (P[1] = '0')) then - gShowStat := (P[1][1] = '1'); - - if gShowStat then - g_Console_Add(_lc[I_MSG_STATS_ON]) - else - g_Console_Add(_lc[I_MSG_STATS_OFF]); - end - else if cmd = 'r_showkillmsg' then + else if cmd = 'g_max_particles' then begin - if (Length(P) > 1) and - ((P[1] = '1') or (P[1] = '0')) then - gShowKillMsg := (P[1][1] = '1'); - - if gShowKillMsg then - g_Console_Add(_lc[I_MSG_KILL_MSGS_ON]) + 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 - g_Console_Add(_lc[I_MSG_KILL_MSGS_OFF]); + begin + e_LogWritefln('usage: %s ', [cmd]) + end end - else if cmd = 'r_showlives' then + else if cmd = 'g_max_shells' then begin - if (Length(P) > 1) and - ((P[1] = '1') or (P[1] = '0')) then - gShowLives := (P[1][1] = '1'); - - if gShowLives then - g_Console_Add(_lc[I_MSG_LIVES_ON]) + 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 - g_Console_Add(_lc[I_MSG_LIVES_OFF]); + begin + e_LogWritefln('usage: %s ', [cmd]) + end end - else if cmd = 'r_showspect' then + else if cmd = 'g_max_gibs' then begin - if (Length(P) > 1) and - ((P[1] = '1') or (P[1] = '0')) then - gSpectHUD := (P[1][1] = '1'); - - if gSpectHUD then - g_Console_Add(_lc[I_MSG_SPECT_HUD_ON]) + 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 - g_Console_Add(_lc[I_MSG_SPECT_HUD_OFF]); + begin + e_LogWritefln('usage: %s ', [cmd]) + end end - else if cmd = 'r_showping' then + else if cmd = 'g_max_corpses' then begin - if (Length(P) > 1) and - ((P[1] = '1') or (P[1] = '0')) then - gShowPing := (P[1][1] = '1'); - - if gShowPing then - g_Console_Add(_lc[I_MSG_PING_ON]) + 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 - g_Console_Add(_lc[I_MSG_PING_OFF]); + begin + e_LogWritefln('usage: %s ', [cmd]) + end end - else if (cmd = 'g_scorelimit') and not g_Game_IsClient then + else if cmd = 'g_scorelimit' then begin if Length(P) > 1 then begin - if StrToIntDef(P[1], gGameSettings.GoalLimit) = 0 then - gGameSettings.GoalLimit := 0 - else - 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); + gsGoalLimit := nclamp(StrToIntDef(P[1], gsGoalLimit), 0, $FFFF); - gGameSettings.GoalLimit := Max(StrToIntDef(P[1], gGameSettings.GoalLimit), b); - end; - - if g_Game_IsNet then MH_SEND_GameSettings; + 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].Goals, gTeamStat[TEAM_BLUE].Goals); + + // 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; + end; end; - g_Console_Add(Format(_lc[I_MSG_SCORE_LIMIT], [gGameSettings.GoalLimit])); + g_Console_Add(Format(_lc[I_MSG_SCORE_LIMIT], [Integer(gsGoalLimit)])); end - else if (cmd = 'g_timelimit') and not g_Game_IsClient then + else if cmd = 'g_timelimit' then begin - if (Length(P) > 1) and (StrToIntDef(P[1], -1) >= 0) then - gGameSettings.TimeLimit := StrToIntDef(P[1], -1); - + if Length(P) > 1 then + begin + 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], - [gGameSettings.TimeLimit div 3600, - (gGameSettings.TimeLimit div 60) mod 60, - gGameSettings.TimeLimit mod 60])); - if g_Game_IsNet then MH_SEND_GameSettings; + [gsTimeLimit div 3600, + (gsTimeLimit div 60) mod 60, + gsTimeLimit mod 60])); end - else if (cmd = 'g_maxlives') and not g_Game_IsClient then + else if cmd = 'g_maxlives' then begin if Length(P) > 1 then begin - if StrToIntDef(P[1], gGameSettings.MaxLives) = 0 then - gGameSettings.MaxLives := 0 - else + gsMaxLives := nclamp(StrToIntDef(P[1], gsMaxLives), 0, $FFFF); + if g_Game_IsServer then begin - b := 0; - stat := g_Player_GetStats(); - if stat <> nil then - for a := 0 to High(stat) do - if stat[a].Lives > b then - b := stat[a].Lives; - gGameSettings.MaxLives := - Max(StrToIntDef(P[1], gGameSettings.MaxLives), b); + gGameSettings.MaxLives := gsMaxLives; + if g_Game_IsNet then MH_SEND_GameSettings; end; end; - g_Console_Add(Format(_lc[I_MSG_LIVES], - [gGameSettings.MaxLives])); - if g_Game_IsNet then MH_SEND_GameSettings; + g_Console_Add(Format(_lc[I_MSG_LIVES], [Integer(gsMaxLives)])); end; end; @@ -6194,14 +6139,7 @@ begin // Îáùèå êîìàíäû: cmd := LowerCase(P[0]); chstr := ''; - if (cmd = 'quit') or - (cmd = 'exit') then - begin - g_Game_Free(); - g_Game_Quit(); - Exit; - end - else if cmd = 'pause' then + if cmd = 'pause' then begin if (g_ActiveWindow = nil) then g_Game_Pause(not gPauseMain); @@ -6620,7 +6558,7 @@ begin g_Game_Free(); with gGameSettings do begin - GameMode := g_Game_TextToMode(gcGameMode); + GameMode := g_Game_TextToMode(gsGameMode); if gSwitchGameMode <> GM_NONE then GameMode := gSwitchGameMode; if GameMode = GM_NONE then GameMode := GM_DM; @@ -6674,7 +6612,7 @@ begin g_Game_Free(); with gGameSettings do begin - GameMode := g_Game_TextToMode(gcGameMode); + GameMode := g_Game_TextToMode(gsGameMode); if gSwitchGameMode <> GM_NONE then GameMode := gSwitchGameMode; if GameMode = GM_NONE then GameMode := GM_DM; if GameMode = GM_SINGLE then GameMode := GM_COOP; @@ -7251,6 +7189,61 @@ begin end; end; +procedure SystemCommands(P: SSArray); +var + cmd: string; +begin + cmd := LowerCase(P[0]); + case cmd of + 'exit', 'quit': + begin + g_Game_Free(); + g_Game_Quit(); + end; + 'r_reset': + begin + sys_EnableVSync(gVSync); + gRC_Width := Max(1, gRC_Width); + gRC_Height := Max(1, gRC_Height); + gBPP := Max(1, gBPP); + if sys_SetDisplayMode(gRC_Width, gRC_Height, gBPP, gRC_FullScreen, gRC_Maximized) = True then + e_LogWriteln('resolution changed') + else + e_LogWriteln('resolution not changed'); + end; + 'g_language': + begin + if Length(p) = 2 then + begin + gAskLanguage := true; + gLanguage := LANGUAGE_ENGLISH; + case LowerCase(p[1]) of + 'english': + begin + gAskLanguage := false; + gLanguage := LANGUAGE_ENGLISH; + end; + 'russian': + begin + gAskLanguage := false; + gLanguage := LANGUAGE_RUSSIAN; + end; + 'ask': + begin + gAskLanguage := true; + gLanguage := LANGUAGE_ENGLISH; + end; + end; + g_Language_Set(gLanguage); + end + else + begin + e_LogWritefln('usage: %s ', [cmd]); + end + end; + end; +end; + procedure g_TakeScreenShot(Filename: string = ''); var s: TStream; t: TDateTime; dir, date, name: String; begin @@ -7941,11 +7934,10 @@ begin // Options: s := Find_Param_Value(pars, '-opt'); if (s = '') then - Opt := GAME_OPTION_ALLOWEXIT or GAME_OPTION_BOTVSPLAYER or GAME_OPTION_BOTVSMONSTER + Opt := GAME_OPTION_ALLOWEXIT or GAME_OPTION_BOTVSPLAYER or + GAME_OPTION_BOTVSMONSTER or GAME_OPTION_DMKEYS else Opt := StrToIntDef(s, 0); - if Opt = 0 then - Opt := GAME_OPTION_ALLOWEXIT or GAME_OPTION_BOTVSPLAYER or GAME_OPTION_BOTVSMONSTER; // Close after map: s := Find_Param_Value(pars, '--close'); @@ -8068,4 +8060,10 @@ begin 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_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'); + conRegVar('r_showstat', @gShowStat, 'show stats', 'show stats'); end. diff --git a/src/game/g_items.pas b/src/game/g_items.pas index 9693ad0..200ebdd 100644 --- a/src/game/g_items.pas +++ b/src/game/g_items.pas @@ -83,7 +83,6 @@ function g_Items_ForEachAlive (cb: TItemEachAliveCB; backwards: Boolean=false): var gItemsTexturesID: Array [1..ITEM_MAX] of DWORD; gMaxDist: Integer = 1; // for sounds - ITEM_RESPAWNTIME: Integer = 60 * 36; implementation @@ -576,7 +575,7 @@ begin // Íàäî óáðàòü ñ êàðòû, åñëè ýòî íå êëþ÷, êîòîðûì íóæíî ïîäåëèòüñÿ ñ äðóãèì èãðîêîì if r then begin - if not (Respawnable and (ITEM_RESPAWNTIME > 0)) then + if not (Respawnable and (gGameSettings.ItemRespawnTime > 0)) then g_Items_Remove(i) else g_Items_Pick(i); @@ -692,7 +691,7 @@ begin if (ID < Length(ggItems)) then begin ggItems[ID].alive := false; - ggItems[ID].RespawnTime := ITEM_RESPAWNTIME; + ggItems[ID].RespawnTime := gGameSettings.ItemRespawnTime * 36; end; end; diff --git a/src/game/g_language.pas b/src/game/g_language.pas index 8d5ea09..e17b4c2 100644 --- a/src/game/g_language.pas +++ b/src/game/g_language.pas @@ -611,6 +611,7 @@ type I_MSG_NOT_DEBUG, I_MSG_GM_UNAVAIL, I_MSG_SERVERONLY, + I_MSG_NOT_NETGAME, I_MSG_NOCLIENTS, I_MSG_UNBAN_OK, I_MSG_UNBAN_FAIL, @@ -1773,14 +1774,16 @@ const 'Ñëåäóþùàÿ êàðòà íå çàäàíà.'), ('MSG ONMAPCHANGE', '* Changes to this variable will be applied upon next map change', '* Èçìåíåíèÿ âñòóïÿò â ñèëó ïîñëå ñëåäóþùåé ñìåíû êàðòû'), - ('MSG NOT GAME', 'Command can be accepted in a game only.', + ('MSG NOT GAME', 'This command is only available in-game.', 'Êîìàíäà ïðèìåíèìà òîëüêî â èãðå.'), - ('MSG NOT DEBUG', 'Command can be accepted in debug mode only.', + ('MSG NOT DEBUG', 'This command is only available in debug mode.', 'Êîìàíäà ïðèìåíèìà òîëüêî â ðåæèìå îòëàäêè.'), ('MSG GM UNAVAIL', 'This command is unavailable in the current game mode.', - 'Ýòà êîìàíäà íåäîñòóïíà â òåêóùåì ðåæèìå èãðû.'), - ('MSG SERVERONLY', 'This command is for server only.', - 'Ýòà êîìàíäà äîñòóïíà òîëüêî â ðåæèìå ñåðâåðà.'), + 'Êîìàíäà íåäîñòóïíà â òåêóùåì ðåæèìå èãðû.'), + ('MSG SERVERONLY', 'This command is only available to servers.', + 'Êîìàíäà äîñòóïíà òîëüêî â ðåæèìå ñåðâåðà.'), + ('MSG NOT NETGAME', 'This command is unavailable during a net game.', + 'Êîìàíäà íåäîñòóïíà âî âðåìÿ ñåòåâîé èãðû.'), ('MSG NOCLIENTS', 'No clients connected.', 'Íåò ïîäêëþ÷¸ííûõ êëèåíòîâ.'), ('MSG UNBAN OK', 'Client %s was unbanned.', diff --git a/src/game/g_main.pas b/src/game/g_main.pas index ab6e1d8..20419ec 100644 --- a/src/game/g_main.pas +++ b/src/game/g_main.pas @@ -372,6 +372,11 @@ begin Inc(i); GameWADName := ParamStr(i); end; + '--config': + begin + Inc(i); + gConfigScript := ParamStr(i); + end; end; Inc(i) end; @@ -502,7 +507,6 @@ procedure Main(); {$IFDEF ENABLE_HOLMES} var flexloaded: Boolean; {$ENDIF} - var s: AnsiString; begin InitPath; InitPrep; @@ -511,9 +515,6 @@ begin g_Options_SetDefault; g_Options_SetDefaultVideo; - s := CONFIG_FILENAME; - if e_FindResource(ConfigDirs, s) = true then - g_Options_Read(s); g_Console_SysInit; if sys_SetDisplayMode(gRC_Width, gRC_Height, gBPP, gRC_FullScreen, gRC_Maximized) = False then raise Exception.Create('Failed to set videomode on startup.'); diff --git a/src/game/g_menu.pas b/src/game/g_menu.pas index 9f7aaaa..b29a513 100644 --- a/src/game/g_menu.pas +++ b/src/game/g_menu.pas @@ -109,7 +109,6 @@ var menu: TGUIMenu; i: Integer; ovs: Boolean; - s: AnsiString; begin menu := TGUIMenu(g_GUI_GetWindow('OptionsVideoMenu').GetControl('mOptionsVideoMenu')); @@ -376,9 +375,6 @@ begin if g_Game_IsClient then MC_SEND_PlayerSettings; - s := e_GetWriteableDir(ConfigDirs); - if s <> '' then - g_Options_Write(s + '/' + CONFIG_FILENAME); g_Console_WriteGameConfig; end; @@ -646,14 +642,13 @@ begin } end; -procedure ProcStartCustomGame(); +function LatchGameOptions(const MenuName: string): Byte; var - Map: String; - GameMode: Byte; - Options: LongWord; - s: AnsiString; + Map: string; begin - with TGUIMenu(g_ActiveWindow.GetControl('mCustomGameMenu')) do + Result := GM_NONE; + + with TGUIMenu(g_ActiveWindow.GetControl(MenuName)) do begin Map := TGUILabel(GetControl('lbMap')).Text; if Map = '' then @@ -661,113 +656,60 @@ begin if not isWadPath(Map) then Exit; - GameMode := TGUISwitch(GetControl('swGameMode')).ItemIndex+1; - gcGameMode := TGUISwitch(GetControl('swGameMode')).GetText; - gcTimeLimit := StrToIntDef(TGUIEdit(GetControl('edTimeLimit')).Text, 0); - gcGoalLimit := StrToIntDef(TGUIEdit(GetControl('edGoalLimit')).Text, 0); - gcMaxLives := StrToIntDef(TGUIEdit(GetControl('edMaxLives')).Text, 0); - - gcTeamDamage := TGUISwitch(GetControl('swTeamDamage')).ItemIndex = 0; - gcDeathmatchKeys := TGUISwitch(GetControl('swDeathmatchKeys')).ItemIndex = 0; - gcAllowExit := TGUISwitch(GetControl('swEnableExits')).ItemIndex = 0; - gcWeaponStay := TGUISwitch(GetControl('swWeaponStay')).ItemIndex = 0; - gcMonsters := TGUISwitch(GetControl('swMonsters')).ItemIndex = 0; - Options := 0; - if gcTeamDamage then - Options := Options or GAME_OPTION_TEAMDAMAGE; - if gcDeathmatchKeys then - Options := Options or GAME_OPTION_DMKEYS; - if gcAllowExit then - Options := Options or GAME_OPTION_ALLOWEXIT; - if gcWeaponStay then - Options := Options or GAME_OPTION_WEAPONSTAY; - if gcMonsters then - Options := Options or GAME_OPTION_MONSTERS; - gcPlayers := TGUISwitch(GetControl('swPlayers')).ItemIndex; + Result := TGUISwitch(GetControl('swGameMode')).ItemIndex+1; + gsGameMode := TGUISwitch(GetControl('swGameMode')).GetText; + gsTimeLimit := StrToIntDef(TGUIEdit(GetControl('edTimeLimit')).Text, 0); + gsGoalLimit := StrToIntDef(TGUIEdit(GetControl('edGoalLimit')).Text, 0); + gsMaxLives := StrToIntDef(TGUIEdit(GetControl('edMaxLives')).Text, 0); + gsItemRespawnTime := StrToIntDef(TGUIEdit(GetControl('edItemRespawnTime')).Text, 0); + gsPlayers := TGUISwitch(GetControl('swPlayers')).ItemIndex; + gsMap := Map; + + gsGameFlags := 0; + if TGUISwitch(GetControl('swTeamDamage')).ItemIndex = 0 then + gsGameFlags := gsGameFlags or GAME_OPTION_TEAMDAMAGE; + if TGUISwitch(GetControl('swDeathmatchKeys')).ItemIndex = 0 then + gsGameFlags := gsGameFlags or GAME_OPTION_DMKEYS; + if TGUISwitch(GetControl('swEnableExits')).ItemIndex = 0 then + gsGameFlags := gsGameFlags or GAME_OPTION_ALLOWEXIT; + if TGUISwitch(GetControl('swWeaponStay')).ItemIndex = 0 then + gsGameFlags := gsGameFlags or GAME_OPTION_WEAPONSTAY; + if TGUISwitch(GetControl('swMonsters')).ItemIndex = 0 then + gsGameFlags := gsGameFlags or GAME_OPTION_MONSTERS; case TGUISwitch(GetControl('swBotsVS')).ItemIndex of - 1: begin - Options := Options or GAME_OPTION_BOTVSMONSTER; - gcBotsVS := 'Monsters'; - end; - 2: begin - Options := Options or GAME_OPTION_BOTVSPLAYER or GAME_OPTION_BOTVSMONSTER; - gcBotsVS := 'Everybody'; - end; - else begin - Options := Options or GAME_OPTION_BOTVSPLAYER; - gcBotsVS := 'Players'; - end; + 1: gsGameFlags := gsGameFlags or GAME_OPTION_BOTVSMONSTER; + 2: gsGameFlags := gsGameFlags or GAME_OPTION_BOTVSPLAYER or GAME_OPTION_BOTVSMONSTER; + else gsGameFlags := gsGameFlags or GAME_OPTION_BOTVSPLAYER; end; - gcMap := Map; + gGameSettings.ItemRespawnTime := gsItemRespawnTime; // TODO: get this crap out of here end; +end; - s := e_GetWriteableDir(ConfigDirs); - if s <> '' then - g_Options_Write_Gameplay_Custom(s + '/' + CONFIG_FILENAME); +procedure ProcStartCustomGame(); +var + GameMode: Byte; +begin + GameMode := LatchGameOptions('mCustomGameMenu'); + if GameMode = GM_NONE then Exit; - g_Game_StartCustom(Map, GameMode, gcTimeLimit, gcGoalLimit, - gcMaxLives, Options, gcPlayers); + g_Console_WriteGameConfig; + g_Game_StartCustom(gsMap, GameMode, gsTimeLimit, gsGoalLimit, + gsMaxLives, gsGameFlags, gsPlayers); end; procedure ProcStartNetGame(); var - Map: String; GameMode: Byte; - Options: LongWord; - s: AnsiString; begin + GameMode := LatchGameOptions('mNetServerMenu'); + if GameMode = GM_NONE then Exit; + with TGUIMenu(g_ActiveWindow.GetControl('mNetServerMenu')) do begin - Map := TGUILabel(GetControl('lbMap')).Text; - if Map = '' then - Exit; - if not isWadPath(Map) then - Exit; - - GameMode := TGUISwitch(GetControl('swGameMode')).ItemIndex+1; - gnGameMode := TGUISwitch(GetControl('swGameMode')).GetText; - gnTimeLimit := StrToIntDef(TGUIEdit(GetControl('edTimeLimit')).Text, 0); - gnGoalLimit := StrToIntDef(TGUIEdit(GetControl('edGoalLimit')).Text, 0); - gnMaxLives := StrToIntDef(TGUIEdit(GetControl('edMaxLives')).Text, 0); NetPort := StrToIntDef(TGUIEdit(GetControl('edPort')).Text, 0); - - gnTeamDamage := TGUISwitch(GetControl('swTeamDamage')).ItemIndex = 0; - gnDeathmatchKeys := TGUISwitch(GetControl('swDeathmatchKeys')).ItemIndex = 0; - gnAllowExit := TGUISwitch(GetControl('swEnableExits')).ItemIndex = 0; - gnWeaponStay := TGUISwitch(GetControl('swWeaponStay')).ItemIndex = 0; - gnMonsters := TGUISwitch(GetControl('swMonsters')).ItemIndex = 0; - Options := 0; - if gnTeamDamage then - Options := Options or GAME_OPTION_TEAMDAMAGE; - if gnDeathmatchKeys then - Options := Options or GAME_OPTION_DMKEYS; - if gnAllowExit then - Options := Options or GAME_OPTION_ALLOWEXIT; - if gnWeaponStay then - Options := Options or GAME_OPTION_WEAPONSTAY; - if gnMonsters then - Options := Options or GAME_OPTION_MONSTERS; - gnPlayers := TGUISwitch(GetControl('swPlayers')).ItemIndex; - - case TGUISwitch(GetControl('swBotsVS')).ItemIndex of - 1: begin - Options := Options or GAME_OPTION_BOTVSMONSTER; - gnBotsVS := 'Monsters'; - end; - 2: begin - Options := Options or GAME_OPTION_BOTVSPLAYER or GAME_OPTION_BOTVSMONSTER; - gnBotsVS := 'Everybody'; - end; - else begin - Options := Options or GAME_OPTION_BOTVSPLAYER; - gnBotsVS := 'Players'; - end; - end; - - gnMap := Map; NetServerName := TGUIEdit(GetControl('edSrvName')).Text; NetMaxClients := Max(1, StrToIntDef(TGUIEdit(GetControl('edMaxPlayers')).Text, 1)); NetMaxClients := Min(NET_MAXCLIENTS, NetMaxClients); @@ -775,21 +717,14 @@ begin NetUseMaster := TGUISwitch(GetControl('swUseMaster')).ItemIndex = 0; end; - s := e_GetWriteableDir(ConfigDirs); - if s <> '' then - begin - g_Options_Write_Net_Server(s + '/' + CONFIG_FILENAME); - g_Options_Write_Gameplay_Net(s + '/' + CONFIG_FILENAME) - end; - - g_Game_StartServer(Map, GameMode, gnTimeLimit, gnGoalLimit, gnMaxLives, - Options, gnPlayers, 0, NetPort); + g_Console_WriteGameConfig; + g_Game_StartServer(gsMap, GameMode, gsTimeLimit, gsGoalLimit, gsMaxLives, + gsGameFlags, gsPlayers, 0, NetPort); end; procedure ProcConnectNetGame(); var PW: String; - s: AnsiString; begin with TGUIMenu(g_ActiveWindow.GetControl('mNetClientMenu')) do begin @@ -798,16 +733,13 @@ begin PW := TGUIEdit(GetControl('edPW')).Text; end; - s := e_GetWriteableDir(ConfigDirs); - if s <> '' then - g_Options_Write_Net_Client(s + '/' + CONFIG_FILENAME); + g_Console_WriteGameConfig; g_Game_StartClient(NetClientIP, NetClientPort, PW); end; procedure ProcEnterPassword(); var PW: string; - s: AnsiString; begin with TGUIMenu(g_ActiveWindow.GetControl('mClientPasswordMenu')) do begin @@ -816,9 +748,7 @@ begin PW := TGUIEdit(GetControl('edPW')).Text; end; - s := e_GetWriteableDir(ConfigDirs); - if s <> '' then - g_Options_Write_Net_Client(s + '/' + CONFIG_FILENAME); + g_Console_WriteGameConfig; g_Game_StartClient(NetClientIP, NetClientPort, PW); end; @@ -835,7 +765,7 @@ begin NetInitDone := True; end; - g_Net_Slist_Set(NetSlistIP, NetSlistPort, NetSlistList); + g_Net_Slist_Set(NetMasterList); gState := STATE_SLIST; g_ActiveWindow := nil; @@ -1873,6 +1803,12 @@ begin end; end; end; + + // don't forget to latch this shit + gsGameFlags := Options; + gsMaxLives := MaxLives; + gsGoalLimit := GoalLimit; + gsTimeLimit := TimeLimit; end; if g_Game_IsNet then MH_SEND_GameSettings; @@ -2174,7 +2110,7 @@ begin begin Name := 'lbMap'; FixedLength := 16; - Text := gnMap; + Text := gsMap; OnClick := @ProcSelectMapMenu; end; with AddSwitch(_lc[I_MENU_GAME_TYPE]) do @@ -2184,7 +2120,7 @@ begin AddItem(_lc[I_MENU_GAME_TYPE_TDM]); AddItem(_lc[I_MENU_GAME_TYPE_CTF]); AddItem(_lc[I_MENU_GAME_TYPE_COOP]); - case g_Game_TextToMode(gnGameMode) of + case g_Game_TextToMode(gsGameMode) of GM_NONE, GM_DM: ItemIndex := 0; GM_TDM: ItemIndex := 1; @@ -2192,7 +2128,7 @@ begin GM_SINGLE, GM_COOP: ItemIndex := 3; end; - OnChange := ProcSwitchMonstersNet; + OnChange := ProcSwitchMonstersCustom; end; with AddEdit(_lc[I_MENU_TIME_LIMIT]) do begin @@ -2200,8 +2136,8 @@ begin OnlyDigits := True; Width := 4; MaxLength := 5; - if gnTimeLimit > 0 then - Text := IntToStr(gnTimeLimit); + if gsTimeLimit > 0 then + Text := IntToStr(gsTimeLimit); end; with AddEdit(_lc[I_MENU_GOAL_LIMIT]) do begin @@ -2209,32 +2145,41 @@ begin OnlyDigits := True; Width := 4; MaxLength := 5; - if gnGoalLimit > 0 then - Text := IntToStr(gnGoalLimit); + if gsGoalLimit > 0 then + Text := IntToStr(gsGoalLimit); end; with AddEdit(_lc[I_MENU_MAX_LIVES]) do begin Name := 'edMaxLives'; OnlyDigits := True; Width := 4; - MaxLength := 3; - if gnMaxLives > 0 then - Text := IntToStr(gnMaxLives); + MaxLength := 5; + if gsMaxLives > 0 then + Text := IntToStr(gsMaxLives); + end; + with AddEdit(_lc[I_MENU_ITEM_RESPAWN_TIME]) do + begin + Name := 'edItemRespawnTime'; + OnlyDigits := True; + Width := 4; + MaxLength := 5; + if gsItemRespawnTime > 0 then + Text := IntToStr(gsItemRespawnTime); end; - with AddSwitch(_lc[I_MENU_SERVER_PLAYERS]) do + with AddSwitch(_lc[I_MENU_PLAYERS]) do begin Name := 'swPlayers'; AddItem(_lc[I_MENU_COUNT_NONE]); AddItem(_lc[I_MENU_PLAYERS_ONE]); AddItem(_lc[I_MENU_PLAYERS_TWO]); - ItemIndex := gnPlayers; + ItemIndex := gsPlayers; end; with AddSwitch(_lc[I_MENU_TEAM_DAMAGE]) do begin Name := 'swTeamDamage'; AddItem(_lc[I_MENU_YES]); AddItem(_lc[I_MENU_NO]); - if gnTeamDamage then + if LongBool(gsGameFlags and GAME_OPTION_TEAMDAMAGE) then ItemIndex := 0 else ItemIndex := 1; @@ -2244,7 +2189,7 @@ begin Name := 'swDeathmatchKeys'; AddItem(_lc[I_MENU_YES]); AddItem(_lc[I_MENU_NO]); - if gnDeathmatchKeys then + if LongBool(gsGameFlags and GAME_OPTION_DMKEYS) then ItemIndex := 0 else ItemIndex := 1; @@ -2254,7 +2199,7 @@ begin Name := 'swEnableExits'; AddItem(_lc[I_MENU_YES]); AddItem(_lc[I_MENU_NO]); - if gnAllowExit then + if LongBool(gsGameFlags and GAME_OPTION_ALLOWEXIT) then ItemIndex := 0 else ItemIndex := 1; @@ -2264,7 +2209,7 @@ begin Name := 'swWeaponStay'; AddItem(_lc[I_MENU_YES]); AddItem(_lc[I_MENU_NO]); - if gnWeaponStay then + if LongBool(gsGameFlags and GAME_OPTION_WEAPONSTAY) then ItemIndex := 0 else ItemIndex := 1; @@ -2274,7 +2219,7 @@ begin Name := 'swMonsters'; AddItem(_lc[I_MENU_YES]); AddItem(_lc[I_MENU_NO]); - if gnMonsters then + if LongBool(gsGameFlags and GAME_OPTION_MONSTERS) then ItemIndex := 0 else ItemIndex := 1; @@ -2286,9 +2231,9 @@ begin AddItem(_lc[I_MENU_BOTS_VS_MONSTERS]); AddItem(_lc[I_MENU_BOTS_VS_ALL]); ItemIndex := 2; - if gnBotsVS = 'Players' then + if not LongBool(gsGameFlags and GAME_OPTION_BOTVSMONSTER) then ItemIndex := 0; - if gnBotsVS = 'Monsters' then + if not LongBool(gsGameFlags and GAME_OPTION_BOTVSPLAYER) then ItemIndex := 1; end; AddSpace(); @@ -2384,7 +2329,7 @@ begin begin Name := 'lbMap'; FixedLength := 16; - Text := gcMap; + Text := gsMap; OnClick := @ProcSelectMapMenu; end; with AddSwitch(_lc[I_MENU_GAME_TYPE]) do @@ -2394,7 +2339,7 @@ begin AddItem(_lc[I_MENU_GAME_TYPE_TDM]); AddItem(_lc[I_MENU_GAME_TYPE_CTF]); AddItem(_lc[I_MENU_GAME_TYPE_COOP]); - case g_Game_TextToMode(gcGameMode) of + case g_Game_TextToMode(gsGameMode) of GM_NONE, GM_DM: ItemIndex := 0; GM_TDM: ItemIndex := 1; @@ -2410,8 +2355,8 @@ begin OnlyDigits := True; Width := 4; MaxLength := 5; - if gcTimeLimit > 0 then - Text := IntToStr(gcTimeLimit); + if gsTimeLimit > 0 then + Text := IntToStr(gsTimeLimit); end; with AddEdit(_lc[I_MENU_GOAL_LIMIT]) do begin @@ -2419,8 +2364,8 @@ begin OnlyDigits := True; Width := 4; MaxLength := 5; - if gcGoalLimit > 0 then - Text := IntToStr(gcGoalLimit); + if gsGoalLimit > 0 then + Text := IntToStr(gsGoalLimit); end; with AddEdit(_lc[I_MENU_MAX_LIVES]) do begin @@ -2428,8 +2373,17 @@ begin OnlyDigits := True; Width := 4; MaxLength := 5; - if gcMaxLives > 0 then - Text := IntToStr(gcMaxLives); + if gsMaxLives > 0 then + Text := IntToStr(gsMaxLives); + end; + with AddEdit(_lc[I_MENU_ITEM_RESPAWN_TIME]) do + begin + Name := 'edItemRespawnTime'; + OnlyDigits := True; + Width := 4; + MaxLength := 5; + if gsItemRespawnTime > 0 then + Text := IntToStr(gsItemRespawnTime); end; with AddSwitch(_lc[I_MENU_PLAYERS]) do begin @@ -2437,14 +2391,14 @@ begin AddItem(_lc[I_MENU_COUNT_NONE]); AddItem(_lc[I_MENU_PLAYERS_ONE]); AddItem(_lc[I_MENU_PLAYERS_TWO]); - ItemIndex := gcPlayers; + ItemIndex := gsPlayers; end; with AddSwitch(_lc[I_MENU_TEAM_DAMAGE]) do begin Name := 'swTeamDamage'; AddItem(_lc[I_MENU_YES]); AddItem(_lc[I_MENU_NO]); - if gcTeamDamage then + if LongBool(gsGameFlags and GAME_OPTION_TEAMDAMAGE) then ItemIndex := 0 else ItemIndex := 1; @@ -2454,7 +2408,7 @@ begin Name := 'swDeathmatchKeys'; AddItem(_lc[I_MENU_YES]); AddItem(_lc[I_MENU_NO]); - if gcDeathmatchKeys then + if LongBool(gsGameFlags and GAME_OPTION_DMKEYS) then ItemIndex := 0 else ItemIndex := 1; @@ -2464,7 +2418,7 @@ begin Name := 'swEnableExits'; AddItem(_lc[I_MENU_YES]); AddItem(_lc[I_MENU_NO]); - if gcAllowExit then + if LongBool(gsGameFlags and GAME_OPTION_ALLOWEXIT) then ItemIndex := 0 else ItemIndex := 1; @@ -2474,7 +2428,7 @@ begin Name := 'swWeaponStay'; AddItem(_lc[I_MENU_YES]); AddItem(_lc[I_MENU_NO]); - if gcWeaponStay then + if LongBool(gsGameFlags and GAME_OPTION_WEAPONSTAY) then ItemIndex := 0 else ItemIndex := 1; @@ -2484,7 +2438,7 @@ begin Name := 'swMonsters'; AddItem(_lc[I_MENU_YES]); AddItem(_lc[I_MENU_NO]); - if gcMonsters then + if LongBool(gsGameFlags and GAME_OPTION_MONSTERS) then ItemIndex := 0 else ItemIndex := 1; @@ -2496,9 +2450,9 @@ begin AddItem(_lc[I_MENU_BOTS_VS_MONSTERS]); AddItem(_lc[I_MENU_BOTS_VS_ALL]); ItemIndex := 2; - if gcBotsVS = 'Players' then + if not LongBool(gsGameFlags and GAME_OPTION_BOTVSMONSTER) then ItemIndex := 0; - if gcBotsVS = 'Monsters' then + if not LongBool(gsGameFlags and GAME_OPTION_BOTVSPLAYER) then ItemIndex := 1; end; AddSpace(); diff --git a/src/game/g_net.pas b/src/game/g_net.pas index 0c01dd9..d2bc5a2 100644 --- a/src/game/g_net.pas +++ b/src/game/g_net.pas @@ -147,9 +147,7 @@ var NetPongSock: ENetSocket = ENET_SOCKET_NULL; NetUseMaster: Boolean = True; - NetSlistIP: string = 'mpms.doom2d.org'; - NetSlistPort: Word = 25665; - NetSlistList: string = 'deadsoftware.ru:25665'; + NetMasterList: string = 'mpms.doom2d.org:25665,deadsoftware.ru:25665'; NetClientIP: string = '127.0.0.1'; NetClientPort: Word = 25666; @@ -2374,7 +2372,7 @@ begin SetLength(NetServerName, 64); g_Net_Slist_ServerRenamed(); end; - g_Console_Add(cmd + ' = "' + NetServerName + '"'); + g_Console_Add(cmd + ' "' + NetServerName + '"'); end; 'sv_passwd': begin @@ -2385,7 +2383,7 @@ begin SetLength(NetPassword, 24); g_Net_Slist_ServerRenamed(); end; - g_Console_Add(cmd + ' = "' + AnsiLowerCase(NetPassword) + '"'); + g_Console_Add(cmd + ' "' + AnsiLowerCase(NetPassword) + '"'); end; 'sv_maxplrs': begin @@ -2412,16 +2410,27 @@ begin g_Net_Slist_ServerRenamed(); end; end; - g_Console_Add(cmd + ' = ' + IntToStr(NetMaxClients)); + g_Console_Add(cmd + ' ' + IntToStr(NetMaxClients)); end; 'sv_public': begin if (Length(P) > 1) then begin - NetUseMaster := StrToIntDef(P[1], Byte(NetUseMaster)) > 0; + NetUseMaster := StrToIntDef(P[1], Byte(NetUseMaster)) <> 0; if NetUseMaster then g_Net_Slist_Public() else g_Net_Slist_Private(); end; - g_Console_Add(cmd + ' = ' + IntToStr(Byte(NetUseMaster))); + g_Console_Add(cmd + ' ' + IntToStr(Byte(NetUseMaster))); + end; + 'sv_port': + begin + if (Length(P) > 1) then + begin + if not g_Game_IsNet then + NetPort := nclamp(StrToIntDef(P[1], NetPort), 0, $FFFF) + else + g_Console_Add(_lc[I_MSG_NOT_NETGAME]); + end; + g_Console_Add(cmd + ' ' + IntToStr(Ord(NetUseMaster))); end; end; end; @@ -2431,7 +2440,18 @@ initialization conRegVar('cl_predictself', @NetPredictSelf, '', 'predict local player'); conRegVar('cl_forceplayerupdate', @NetForcePlayerUpdate, '', 'update net players on NET_MSG_PLRPOS'); conRegVar('cl_interp', @NetInterpLevel, '', 'net player interpolation steps'); + conRegVar('cl_last_ip', @NetClientIP, '', 'address of the last you have connected to'); + conRegVar('cl_last_port', @NetClientPort, '', 'port of the last server you have connected to'); + conRegVar('sv_forwardports', @NetForwardPorts, '', 'forward server port using miniupnpc (requires server restart)'); + conRegVar('sv_rcon', @NetAllowRCON, '', 'enable remote console'); + conRegVar('sv_rcon_password', @NetRCONPassword, '', 'remote console password'); + conRegVar('sv_update_interval', @NetUpdateRate, '', 'unreliable update interval'); + conRegVar('sv_reliable_interval', @NetRelupdRate, '', 'reliable update interval'); + conRegVar('sv_master_interval', @NetMasterRate, '', 'master server update interval'); + + conRegVar('net_master_list', @NetMasterList, '', 'list of master servers'); + SetLength(NetClients, 0); g_Net_DownloadTimeout := 60; NetIn.Alloc(NET_BUFSIZE); diff --git a/src/game/g_netmaster.pas b/src/game/g_netmaster.pas index 6774759..fa3d190 100644 --- a/src/game/g_netmaster.pas +++ b/src/game/g_netmaster.pas @@ -133,7 +133,7 @@ var NMASTER_FORCE_UPDATE_TIMEOUT: Integer = 0; // fuck you, fpc, and your idiotic "diagnostics" -procedure g_Net_Slist_Set (IP: AnsiString; Port: Word; list: AnsiString=''); +procedure g_Net_Slist_Set (list: AnsiString); function g_Net_Slist_Fetch (var SL: TNetServerList): Boolean; // make this server private @@ -1053,7 +1053,7 @@ end; // g_Net_Slist_Set // //========================================================================== -procedure g_Net_Slist_Set (IP: AnsiString; Port: Word; list: AnsiString=''); +procedure g_Net_Slist_Set (list: AnsiString); var f, dest: Integer; sa: AnsiString; @@ -1064,13 +1064,6 @@ begin for f := 0 to High(mlist) do mlist[f].justAdded := false; - IP := Trim(IP); - if (length(IP) > 0) and (Port > 0) then - begin - sa := IP+':'+IntToStr(Port); - if parseAddressPort(ea, sa) then addMasterRecord(ea, sa); - end; - list := Trim(list); //writeln('list=[', list, ']'); while (length(list) > 0) do diff --git a/src/game/g_options.pas b/src/game/g_options.pas index 23ddc36..091935c 100644 --- a/src/game/g_options.pas +++ b/src/game/g_options.pas @@ -24,13 +24,7 @@ function GenPlayerName (n: Integer): String; procedure g_Options_SetDefault; procedure g_Options_SetDefaultVideo; -procedure g_Options_Read(FileName: String); -procedure g_Options_Write(FileName: String); -procedure g_Options_Write_Gameplay_Custom(FileName: String); -procedure g_Options_Write_Gameplay_Net(FileName: String); -procedure g_Options_Write_Net_Server(FileName: String); -procedure g_Options_Write_Net_Client(FileName: String); -procedure g_Options_Commands (p: SSArray); +procedure g_Options_ApplyGameSettings; const DF_Default_Megawad_Start = 'megawads/DOOM2D.WAD:\MAP01'; @@ -62,38 +56,24 @@ var gAskLanguage: Boolean; gSaveStats: Boolean = False; gScreenshotStats: Boolean = False; - gcMap: String; - gcGameMode: String; - gcTimeLimit: Word; - gcGoalLimit: Word; - gcMaxLives: Byte; - gcPlayers: Byte; - gcTeamDamage: Boolean; - gcAllowExit: Boolean; - gcWeaponStay: Boolean; - gcMonsters: Boolean; - gcBotsVS: String; - gcDeathmatchKeys: Boolean = True; - gcSpawnInvul: Integer = 0; - gnMap: String; - gnGameMode: String; - gnTimeLimit: Word; - gnGoalLimit: Word; - gnMaxLives: Byte; - gnPlayers: Byte; - gnTeamDamage: Boolean; - gnAllowExit: Boolean; - gnWeaponStay: Boolean; - gnMonsters: Boolean; - gnBotsVS: String; - gnDeathmatchKeys: Boolean = True; - gnSpawnInvul: Integer = 0; gsSDLSampleRate: Integer; gsSDLBufferSize: Integer; gDefaultMegawadStart: AnsiString; gBerserkAutoswitch: Boolean; glNPOTOverride: Boolean = false; + (* Latched game settings *) + gsMap: String; + gsGameMode: String; + gsTimeLimit: Word; + gsGoalLimit: Word; + gsMaxLives: Byte; + gsPlayers: Byte; + gsGameFlags: LongWord; + gsSpawnInvul: Integer = 0; + gsItemRespawnTime: Word = 60; + gsWarmupTime: Word = 30; + implementation uses @@ -258,7 +238,6 @@ begin g_Gibs_SetMax(150); g_Corpses_SetMax(20); gGibsCount := 32; - ITEM_RESPAWNTIME := 60 * 36; gBloodCount := 4; gAdvBlood := True; gAdvCorpses := True; @@ -279,40 +258,21 @@ begin gAskLanguage := True; gLanguage := LANGUAGE_ENGLISH; - (* section GameplayCustom *) - gcMap := ''; - gcGameMode := _lc[I_MENU_GAME_TYPE_DM]; - gcTimeLimit := 0; - gcGoalLimit := 0; - gcMaxLives := 0; - gcPlayers := 1; - gcTeamDamage := False; - gcAllowExit := True; - gcWeaponStay := False; - gcMonsters := False; - gcBotsVS := 'Everybody'; - gcDeathmatchKeys := True; - gcSpawnInvul := 0; - - (* section GameplayNetwork *) - gnMap := ''; - gnGameMode := _lc[I_MENU_GAME_TYPE_DM]; - gnTimeLimit := 0; - gnGoalLimit := 0; - gnMaxLives := 0; - gnPlayers := 1; - gnTeamDamage := False; - gnAllowExit := True; - gnWeaponStay := False; - gnMonsters := False; - gnBotsVS := 'Everybody'; - gnDeathmatchKeys := True; - gnSpawnInvul := 0; + gsMap := ''; + gsGameMode := _lc[I_MENU_GAME_TYPE_DM]; + gsTimeLimit := 0; + gsGoalLimit := 0; + gsMaxLives := 0; + gsPlayers := 1; + gsSpawnInvul := 0; + gsItemRespawnTime := 60; + gsGameFlags := GAME_OPTION_ALLOWEXIT or GAME_OPTION_DMKEYS or + GAME_OPTION_BOTVSPLAYER or GAME_OPTION_BOTVSMONSTER; + gsPlayers := 1; (* section MasterServer *) - NetSlistIP := 'mpms.doom2d.org'; - NetSlistPort := 25665; - g_Net_Slist_Set(NetSlistIP, NetSlistPort, NetSlistList); + NetMasterList := 'mpms.doom2d.org:25665,deadsoftware.ru:25665'; + g_Net_Slist_Set(NetMasterList); (* section Server *) NetServerName := 'Unnamed Server'; @@ -335,458 +295,22 @@ begin NetClientPort := NetPort; end; -procedure g_Options_Read(FileName: String); -var - config: TConfig; - section: String; - - procedure ReadInteger (VAR v: Integer; param: String; minv: Integer = Low(Integer); maxv: Integer = High(Integer)); - begin - v := Max(Min(config.ReadInt(section, param, v), maxv), minv) - end; - - procedure ReadInteger (VAR v: LongWord; param: String; minv: LongWord = Low(LongWord); maxv: LongWord = High(LongWord)); overload; - begin - v := Max(Min(config.ReadInt(section, param, v), maxv), minv) - end; - - procedure ReadInteger (VAR v: Word; param: String; minv: Word = Low(Word); maxv: Word = High(Word)); overload; - begin - v := Max(Min(config.ReadInt(section, param, v), maxv), minv) - end; - - procedure ReadInteger (VAR v: Byte; param: String; minv: Byte = Low(Byte); maxv: Byte = High(Byte)); overload; - begin - v := Max(Min(config.ReadInt(section, param, v), maxv), minv) - end; - - procedure ReadBoolean (VAR v: Boolean; param: String); - begin - v := config.ReadBool(section, param, v) - end; - - procedure ReadString (VAR v: String; param: String); - begin - v := config.ReadStr(section, param, v) - end; - +procedure g_Options_ApplyGameSettings; begin - gAskLanguage := True; - e_WriteLog('Reading config', TMsgType.Notify); - g_Options_SetDefault; - - if FileExists(FileName) = False then - begin - e_WriteLog('Config file '+FileName+' not found', TMsgType.Warning); - g_Options_SetDefaultVideo; - Exit - end; - - config := TConfig.CreateFile(FileName); - - section := 'Player1'; - with gPlayer1Settings do - begin - ReadString(Name, 'name'); - ReadString(Model, 'model'); - ReadInteger(Color.R, 'red', 0, 255); - ReadInteger(Color.G, 'green', 0, 255); - ReadInteger(Color.B, 'blue', 0, 255); - ReadInteger(Team, 'team'); - if (Team < TEAM_RED) or (Team > TEAM_BLUE) then - Team := TEAM_RED; - end; - - section := 'Player2'; - with gPlayer2Settings do - begin - ReadString(Name, 'name'); - ReadString(Model, 'model'); - ReadInteger(Color.R, 'red', 0, 255); - ReadInteger(Color.G, 'green', 0, 255); - ReadInteger(Color.B, 'blue', 0, 255); - ReadInteger(Team, 'team'); - if (Team < TEAM_RED) or (Team > TEAM_BLUE) then - Team := TEAM_RED; - end; - - section := 'GameplayCustom'; - ReadString(gcMap, 'Map'); - ReadString(gcGameMode, 'GameMode'); - ReadInteger(gcTimeLimit, 'TimeLimit', 0, 65535); - ReadInteger(gcGoalLimit, 'GoalLimit', 0, 65535); - ReadInteger(gcMaxLives, 'MaxLives', 0, 255); - ReadInteger(gcPlayers, 'Players', 0, 2); - ReadBoolean(gcTeamDamage, 'TeamDamage'); - ReadBoolean(gcAllowExit, 'AllowExit'); - ReadBoolean(gcWeaponStay, 'WeaponStay'); - ReadBoolean(gcMonsters, 'Monsters'); - ReadString(gcBotsVS, 'BotsVS'); - ReadBoolean(gcDeathmatchKeys, 'DeathmatchKeys'); - ReadInteger(gcSpawnInvul, 'SpawnInvul'); - with gGameSettings do begin - GameMode := g_Game_TextToMode(gcGameMode); + GameMode := g_Game_TextToMode(gsGameMode); if GameMode = GM_NONE then GameMode := GM_DM; if GameMode = GM_SINGLE then GameMode := GM_COOP; - TimeLimit := gcTimeLimit; - GoalLimit := gcGoalLimit; - MaxLives := gcMaxLives; - - Options := 0; - if gcTeamDamage then - Options := Options or GAME_OPTION_TEAMDAMAGE; - if gcAllowExit then - Options := Options or GAME_OPTION_ALLOWEXIT; - if gcWeaponStay then - Options := Options or GAME_OPTION_WEAPONSTAY; - if gcMonsters then - Options := Options or GAME_OPTION_MONSTERS; - if gcBotsVS = 'Everybody' then - Options := Options or GAME_OPTION_BOTVSPLAYER or GAME_OPTION_BOTVSMONSTER; - if gcBotsVS = 'Players' then - Options := Options or GAME_OPTION_BOTVSPLAYER; - if gcBotsVS = 'Monsters' then - Options := Options or GAME_OPTION_BOTVSMONSTER; - if gcDeathmatchKeys then - Options := Options or GAME_OPTION_DMKEYS; - end; - - section := 'GameplayNetwork'; - ReadString(gnMap, 'Map'); - ReadString(gnGameMode, 'GameMode'); - ReadInteger(gnTimeLimit, 'TimeLimit', 0, 65535); - ReadInteger(gnGoalLimit, 'GoalLimit', 0, 65535); - ReadInteger(gnMaxLives, 'MaxLives', 0, 255); - ReadInteger(gnPlayers, 'Players', 0, 2); - ReadBoolean(gnTeamDamage, 'TeamDamage'); - ReadBoolean(gnAllowExit, 'AllowExit'); - ReadBoolean(gnWeaponStay, 'WeaponStay'); - ReadBoolean(gnMonsters, 'Monsters'); - ReadString(gnBotsVS, 'BotsVS'); - ReadBoolean(gnDeathmatchKeys, 'DeathmatchKeys'); - ReadInteger(gnSpawnInvul, 'SpawnInvul'); - - section := 'MasterServer'; - ReadString(NetSlistIP, 'IP'); - ReadInteger(NetSlistPort, 'Port', 0, 65535); - ReadString(NetSlistList, 'List'); - g_Net_Slist_Set(NetSlistIP, NetSlistPort, NetSlistList); - - section := 'Server'; - ReadString(NetServerName, 'Name'); - ReadString(NetPassword, 'Password'); - ReadInteger(NetPort, 'Port', 0, 65535); - ReadInteger(NetMaxClients, 'MaxClients', 0, NET_MAXCLIENTS); - ReadBoolean(NetAllowRCON, 'RCON'); - ReadString(NetRCONPassword, 'RCONPassword'); - ReadBoolean(NetUseMaster, 'SyncWithMaster'); - ReadInteger(NetUpdateRate, 'UpdateInterval', 0); - ReadInteger(NetRelupdRate, 'ReliableUpdateInterval', 0); - ReadInteger(NetMasterRate, 'MasterSyncInterval', 1); - ReadBoolean(NetForwardPorts, 'ForwardPorts'); - - section := 'Client'; - ReadInteger(NetInterpLevel, 'InterpolationSteps', 0); - ReadBoolean(NetForcePlayerUpdate, 'ForcePlayerUpdate'); - ReadBoolean(NetPredictSelf, 'PredictSelf'); - ReadString(NetClientIP, 'LastIP'); - ReadInteger(NetClientPort, 'LastPort', 0, 65535); - - config.Free(); - - //if gTextureFilter then TEXTUREFILTER := GL_LINEAR else TEXTUREFILTER := GL_NEAREST; -end; - -procedure g_Options_Write(FileName: String); - var config: TConfig; -begin - e_WriteLog('Writing config', TMsgType.Notify); - - config := TConfig.CreateFile(FileName); - - with config, gPlayer1Settings do - begin - WriteStr('Player1', 'Name', Name); - WriteStr('Player1', 'model', Model); - WriteInt('Player1', 'red', Color.R); - WriteInt('Player1', 'green', Color.G); - WriteInt('Player1', 'blue', Color.B); - WriteInt('Player1', 'team', Team); - end; - - with config, gPlayer2Settings do - begin - WriteStr('Player2', 'Name', Name); - WriteStr('Player2', 'model', Model); - WriteInt('Player2', 'red', Color.R); - WriteInt('Player2', 'green', Color.G); - WriteInt('Player2', 'blue', Color.B); - WriteInt('Player2', 'team', Team); - end; - - config.WriteStr ('GameplayCustom', 'Map', gcMap); - config.WriteStr ('GameplayCustom', 'GameMode', gcGameMode); - config.WriteInt ('GameplayCustom', 'TimeLimit', gcTimeLimit); - config.WriteInt ('GameplayCustom', 'GoalLimit', gcGoalLimit); - config.WriteInt ('GameplayCustom', 'MaxLives', gcMaxLives); - config.WriteInt ('GameplayCustom', 'Players', gcPlayers); - config.WriteBool('GameplayCustom', 'TeamDamage', gcTeamDamage); - config.WriteBool('GameplayCustom', 'AllowExit', gcAllowExit); - config.WriteBool('GameplayCustom', 'WeaponStay', gcWeaponStay); - config.WriteBool('GameplayCustom', 'Monsters', gcMonsters); - config.WriteStr ('GameplayCustom', 'BotsVS', gcBotsVS); - config.WriteBool('GameplayCustom', 'DeathmatchKeys', gcDeathmatchKeys); - config.WriteInt ('GameplayCustom', 'SpawnInvul', gcSpawnInvul); - - config.WriteStr ('GameplayNetwork', 'Map', gnMap); - config.WriteStr ('GameplayNetwork', 'GameMode', gnGameMode); - config.WriteInt ('GameplayNetwork', 'TimeLimit', gnTimeLimit); - config.WriteInt ('GameplayNetwork', 'GoalLimit', gnGoalLimit); - config.WriteInt ('GameplayNetwork', 'MaxLives', gnMaxLives); - config.WriteInt ('GameplayNetwork', 'Players', gnPlayers); - config.WriteBool('GameplayNetwork', 'TeamDamage', gnTeamDamage); - config.WriteBool('GameplayNetwork', 'AllowExit', gnAllowExit); - config.WriteBool('GameplayNetwork', 'WeaponStay', gnWeaponStay); - config.WriteBool('GameplayNetwork', 'Monsters', gnMonsters); - config.WriteStr ('GameplayNetwork', 'BotsVS', gnBotsVS); - config.WriteBool('GameplayNetwork', 'DeathmatchKeys', gnDeathmatchKeys); - config.WriteInt ('GameplayNetwork', 'SpawnInvul', gnSpawnInvul); - - config.WriteStr('MasterServer', 'IP', NetSlistIP); - config.WriteInt('MasterServer', 'Port', NetSlistPort); - config.WriteStr('MasterServer', 'List', NetSlistList); - - config.WriteStr ('Server', 'Name', NetServerName); - config.WriteStr ('Server', 'Password', NetPassword); - config.WriteInt ('Server', 'Port', NetPort); - config.WriteInt ('Server', 'MaxClients', NetMaxClients); - config.WriteBool('Server', 'RCON', NetAllowRCON); - config.WriteStr ('Server', 'RCONPassword', NetRCONPassword); - config.WriteBool('Server', 'SyncWithMaster', NetUseMaster); - config.WriteBool('Server', 'ForwardPorts', NetForwardPorts); - config.WriteInt ('Server', 'UpdateInterval', NetUpdateRate); - config.WriteInt ('Server', 'ReliableUpdateInterval', NetRelupdRate); - config.WriteInt ('Server', 'MasterSyncInterval', NetMasterRate); - - config.WriteInt ('Client', 'InterpolationSteps', NetInterpLevel); - config.WriteBool ('Client', 'ForcePlayerUpdate', NetForcePlayerUpdate); - config.WriteBool ('Client', 'PredictSelf', NetPredictSelf); - config.WriteStr ('Client', 'LastIP', NetClientIP); - config.WriteInt ('Client', 'LastPort', NetClientPort); - - config.SaveFile(FileName); - config.Free(); -end; - -procedure g_Options_Write_Gameplay_Custom(FileName: String); -var - config: TConfig; -begin - e_WriteLog('Writing custom gameplay config', TMsgType.Notify); - - config := TConfig.CreateFile(FileName); - - config.WriteStr ('GameplayCustom', 'Map', gcMap); - config.WriteStr ('GameplayCustom', 'GameMode', gcGameMode); - config.WriteInt ('GameplayCustom', 'TimeLimit', gcTimeLimit); - config.WriteInt ('GameplayCustom', 'GoalLimit', gcGoalLimit); - config.WriteInt ('GameplayCustom', 'MaxLives', gcMaxLives); - config.WriteInt ('GameplayCustom', 'Players', gcPlayers); - config.WriteBool('GameplayCustom', 'TeamDamage', gcTeamDamage); - config.WriteBool('GameplayCustom', 'AllowExit', gcAllowExit); - config.WriteBool('GameplayCustom', 'WeaponStay', gcWeaponStay); - config.WriteBool('GameplayCustom', 'Monsters', gcMonsters); - config.WriteStr ('GameplayCustom', 'BotsVS', gcBotsVS); - config.WriteBool('GameplayCustom', 'DeathmatchKeys', gcDeathmatchKeys); - config.WriteInt ('GameplayCustom', 'SpawnInvul', gcSpawnInvul); - - config.SaveFile(FileName); - config.Free(); -end; - -procedure g_Options_Write_Gameplay_Net(FileName: String); -var - config: TConfig; -begin - e_WriteLog('Writing network gameplay config', TMsgType.Notify); - - config := TConfig.CreateFile(FileName); - - config.WriteStr ('GameplayNetwork', 'Map', gnMap); - config.WriteStr ('GameplayNetwork', 'GameMode', gnGameMode); - config.WriteInt ('GameplayNetwork', 'TimeLimit', gnTimeLimit); - config.WriteInt ('GameplayNetwork', 'GoalLimit', gnGoalLimit); - config.WriteInt ('GameplayNetwork', 'MaxLives', gnMaxLives); - config.WriteInt ('GameplayNetwork', 'Players', gnPlayers); - config.WriteBool('GameplayNetwork', 'TeamDamage', gnTeamDamage); - config.WriteBool('GameplayNetwork', 'AllowExit', gnAllowExit); - config.WriteBool('GameplayNetwork', 'WeaponStay', gnWeaponStay); - config.WriteBool('GameplayNetwork', 'Monsters', gnMonsters); - config.WriteStr ('GameplayNetwork', 'BotsVS', gnBotsVS); - config.WriteBool('GameplayNetwork', 'DeathmatchKeys', gnDeathmatchKeys); - config.WriteInt ('GameplayNetwork', 'SpawnInvul', gnSpawnInvul); - - config.SaveFile(FileName); - config.Free(); -end; - -procedure g_Options_Write_Net_Server(FileName: String); -var - config: TConfig; -begin - e_WriteLog('Writing server config', TMsgType.Notify); - - config := TConfig.CreateFile(FileName); - - config.WriteStr ('Server', 'Name', NetServerName); - config.WriteStr ('Server', 'Password', NetPassword); - config.WriteInt ('Server', 'Port', NetPort); - config.WriteInt ('Server', 'MaxClients', NetMaxClients); - config.WriteBool('Server', 'SyncWithMaster', NetUseMaster); - config.WriteBool('Server', 'ForwardPorts', NetForwardPorts); - - config.SaveFile(FileName); - config.Free(); -end; - -procedure g_Options_Write_Net_Client(FileName: String); -var - config: TConfig; -begin - e_WriteLog('Writing client config', TMsgType.Notify); - - config := TConfig.CreateFile(FileName); - - config.WriteStr('Client', 'LastIP', NetClientIP); - config.WriteInt('Client', 'LastPort', NetClientPort); - - config.SaveFile(FileName); - config.Free(); -end; - -procedure g_Options_Commands (p: SSArray); - var cmd: AnsiString; i: Integer; -begin - cmd := LowerCase(p[0]); - case cmd of - 'r_reset': - begin - sys_EnableVSync(gVSync); - gRC_Width := Max(1, gRC_Width); - gRC_Height := Max(1, gRC_Height); - gBPP := Max(1, gBPP); - if sys_SetDisplayMode(gRC_Width, gRC_Height, gBPP, gRC_FullScreen, gRC_Maximized) = True then - e_LogWriteln('resolution changed') - else - e_LogWriteln('resolution not changed') - end; - 'g_language': - begin - if Length(p) = 2 then - begin - gAskLanguage := true; - gLanguage := LANGUAGE_ENGLISH; - case LowerCase(p[1]) of - 'english': - begin - gAskLanguage := false; - gLanguage := LANGUAGE_ENGLISH; - end; - 'russian': - begin - gAskLanguage := false; - gLanguage := LANGUAGE_RUSSIAN; - end; - 'ask': - begin - gAskLanguage := true; - gLanguage := LANGUAGE_ENGLISH; - end; - end; - g_Language_Set(gLanguage) - end - else - begin - e_LogWritefln('usage: %s ', [cmd]) - end - end; - 'g_max_particles': - begin - if Length(p) = 2 then - begin - i := Max(0, StrToInt(p[1])); - g_GFX_SetMax(i) - end - else if Length(p) = 1 then - begin - e_LogWritefln('%s', [g_GFX_GetMax()]) - end - else - begin - e_LogWritefln('usage: %s ', [cmd]) - end - end; - 'g_max_shells': - begin - if Length(p) = 2 then - begin - i := Max(0, StrToInt(p[1])); - g_Shells_SetMax(i) - end - else if Length(p) = 1 then - begin - e_LogWritefln('%s', [g_Shells_GetMax()]) - end - else - begin - e_LogWritefln('usage: %s ', [cmd]) - end - end; - 'g_max_gibs': - begin - if Length(p) = 2 then - begin - i := Max(0, StrToInt(p[1])); - g_Gibs_SetMax(i) - end - else if Length(p) = 1 then - begin - e_LogWritefln('%s', [g_Gibs_GetMax()]) - end - else - begin - e_LogWritefln('usage: %s ', [cmd]) - end - end; - 'g_max_corpses': - begin - if Length(p) = 2 then - begin - i := Max(0, StrToInt(p[1])); - g_Corpses_SetMax(i) - end - else if Length(p) = 1 then - begin - e_LogWritefln('%s', [g_Corpses_GetMax()]) - end - else - begin - e_LogWritefln('usage: %s ', [cmd]) - end - end; - 'g_item_respawn_time': - begin - if Length(p) = 2 then - ITEM_RESPAWNTIME := Max(0, StrToInt(p[1])) * 36 - else if Length(p) = 1 then - e_LogWritefln('%s', [ITEM_RESPAWNTIME div 36]) - else - e_LogWritefln('usage: %s ', [cmd]) - end; + TimeLimit := gsTimeLimit; + GoalLimit := gsGoalLimit; + MaxLives := gsMaxLives; + SpawnInvul := gsSpawnInvul; + ItemRespawnTime := gsItemRespawnTime; + WarmupTime := gsWarmupTime; + Options := gsGameFlags; end; end; @@ -835,4 +359,5 @@ initialization conRegVar('g_default_megawad', @gDefaultMegawadStart, '', ''); conRegVar('g_save_stats', @gSaveStats, '', ''); conRegVar('g_screenshot_stats', @gScreenshotStats, '', ''); + conRegVar('g_lastmap', @gsMap, '', ''); end. -- 2.29.2