diff --git a/src/game/g_game.pas b/src/game/g_game.pas
index 0505dceb74d336c6d8a2afe83ea699fc9c13782c..0d31e221c6c5c0950e515552fe1b7ed26396620d 100644 (file)
--- a/src/game/g_game.pas
+++ b/src/game/g_game.pas
TimeLimit: Word;
GoalLimit: Word;
WarmupTime: Word;
TimeLimit: Word;
GoalLimit: Word;
WarmupTime: Word;
+ SpawnInvul: Word;
MaxLives: Byte;
Options: LongWord;
WAD: String;
MaxLives: Byte;
Options: LongWord;
WAD: String;
procedure g_Game_Restart();
procedure g_Game_RestartLevel();
procedure g_Game_RestartRound(NoMapRestart: Boolean = False);
procedure g_Game_Restart();
procedure g_Game_RestartLevel();
procedure g_Game_RestartRound(NoMapRestart: Boolean = False);
-procedure g_Game_ClientWAD(NewWAD: String; const WHash: TMD5Digest);
-procedure g_Game_SaveOptions();
-function g_Game_StartMap(Map: String; Force: Boolean = False; const oldMapPath: AnsiString=''): Boolean;
+function g_Game_ClientWAD (NewWAD: String; const WHash: TMD5Digest): AnsiString;
+function g_Game_StartMap(asMegawad: Boolean; Map: String; Force: Boolean = False; const oldMapPath: AnsiString=''): Boolean;
procedure g_Game_ChangeMap(const MapPath: String);
procedure g_Game_ExitLevel(const Map: AnsiString);
function g_Game_GetFirstMap(WAD: String): String;
procedure g_Game_ChangeMap(const MapPath: String);
procedure g_Game_ExitLevel(const Map: AnsiString);
function g_Game_GetFirstMap(WAD: String): String;
procedure g_Game_Announce_BodyKill(SpawnerUID: Word);
procedure g_Game_StartVote(Command, Initiator: string);
procedure g_Game_CheckVote;
procedure g_Game_Announce_BodyKill(SpawnerUID: Word);
procedure g_Game_StartVote(Command, Initiator: string);
procedure g_Game_CheckVote;
-procedure g_TakeScreenShot();
+procedure g_TakeScreenShot(Filename: string = '');
procedure g_FatalError(Text: String);
procedure g_SimpleError(Text: String);
function g_Game_IsTestMap(): Boolean;
procedure g_FatalError(Text: String);
procedure g_SimpleError(Text: String);
function g_Game_IsTestMap(): Boolean;
GAME_OPTION_MONSTERS = 16;
GAME_OPTION_BOTVSPLAYER = 32;
GAME_OPTION_BOTVSMONSTER = 64;
GAME_OPTION_MONSTERS = 16;
GAME_OPTION_BOTVSPLAYER = 32;
GAME_OPTION_BOTVSMONSTER = 64;
+ GAME_OPTION_DMKEYS = 128;
+ GAME_OPTION_RESPAWNITEMS = 256;
STATE_NONE = 0;
STATE_MENU = 1;
STATE_NONE = 0;
STATE_MENU = 1;
DEFAULT_PLAYERS = 1;
{$ENDIF}
DEFAULT_PLAYERS = 1;
{$ENDIF}
+ STATFILE_VERSION = $03;
+
var
gStdFont: DWORD;
gGameSettings: TGameSettings;
var
gStdFont: DWORD;
gGameSettings: TGameSettings;
gHearPoint1, gHearPoint2: THearPoint;
gSoundEffectsDF: Boolean = False;
gSoundTriggerTime: Word = 0;
gHearPoint1, gHearPoint2: THearPoint;
gSoundEffectsDF: Boolean = False;
gSoundTriggerTime: Word = 0;
- gAnnouncer: Byte = ANNOUNCE_NONE;
+ gAnnouncer: Integer = ANNOUNCE_NONE;
goodsnd: array[0..3] of TPlayableSound;
killsnd: array[0..3] of TPlayableSound;
hahasnd: array[0..2] of TPlayableSound;
goodsnd: array[0..3] of TPlayableSound;
killsnd: array[0..3] of TPlayableSound;
hahasnd: array[0..2] of TPlayableSound;
gMapToDelete: String;
gTempDelete: Boolean = False;
gLastMap: Boolean = False;
gMapToDelete: String;
gTempDelete: Boolean = False;
gLastMap: Boolean = False;
- gWinPosX, gWinPosY: Integer;
gWinSizeX, gWinSizeY: Integer;
gWinSizeX, gWinSizeY: Integer;
- gWinFrameX, gWinFrameY, gWinCaption: Integer;
- gWinActive: Boolean = True; // by default window is active, lol
gResolutionChange: Boolean = False;
gResolutionChange: Boolean = False;
- gRC_Width, gRC_Height: Word;
+ gRC_Width, gRC_Height: Integer;
gRC_FullScreen, gRC_Maximized: Boolean;
gLanguageChange: Boolean = False;
gDebugMode: Boolean = False;
gRC_FullScreen, gRC_Maximized: Boolean;
gLanguageChange: Boolean = False;
gDebugMode: Boolean = False;
{$IFDEF ENABLE_HOLMES}
g_holmes,
{$ENDIF}
{$IFDEF ENABLE_HOLMES}
g_holmes,
{$ENDIF}
- e_texture, e_res, g_textures, g_main, g_window, g_menu,
+ e_texture, e_res, g_textures, g_window, g_menu,
e_input, e_log, g_console, g_items, g_map, g_panel,
g_playermodel, g_gfx, g_options, Math,
g_triggers, g_monsters, e_sound, CONFIG,
e_input, e_log, g_console, g_items, g_map, g_panel,
g_playermodel, g_gfx, g_options, Math,
g_triggers, g_monsters, e_sound, CONFIG,
- g_language, g_net,
+ g_language, g_net, g_main,
ENet, e_msg, g_netmsg, g_netmaster,
sfs, wadreader, g_system;
ENet, e_msg, g_netmsg, g_netmaster,
sfs, wadreader, g_system;
MapList: SSArray = nil;
MapIndex: Integer = -1;
InterReadyTime: Integer = -1;
MapList: SSArray = nil;
MapIndex: Integer = -1;
InterReadyTime: Integer = -1;
+ StatShotDone: Boolean = False;
+ StatFilename: string = ''; // used by stat screenshot to save with the same name as the csv
+ StatDate: string = '';
MegaWAD: record
info: TMegaWADInfo;
endpic: String;
MegaWAD: record
info: TMegaWADInfo;
endpic: String;
end;
end;
end;
end;
+// saves a shitty CSV containing the game stats passed to it
+procedure SaveGameStat(Stat: TEndCustomGameStat; Path: string);
+var
+ s: TextFile;
+ dir, fname, map, mode, etime: String;
+ I: Integer;
+begin
+ try
+ dir := e_GetWriteableDir(StatsDirs);
+ // stats are placed in stats/yy/mm/dd/*.csv
+ fname := e_CatPath(dir, Path);
+ ForceDirectories(fname); // ensure yy/mm/dd exists within the stats dir
+ fname := e_CatPath(fname, StatFilename + '.csv');
+ AssignFile(s, fname);
+ try
+ 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 := '';
+ map := g_ExtractWadNameNoPath(gMapInfo.Map) + ':/' + g_ExtractFileName(gMapInfo.Map);
+ mode := g_Game_ModeToText(Stat.GameMode);
+ etime := Format('%d:%.2d:%.2d', [
+ Stat.GameTime div 1000 div 3600,
+ (Stat.GameTime div 1000 div 60) mod 60,
+ Stat.GameTime div 1000 mod 60
+ ]);
+ 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', [
+ STATFILE_VERSION,
+ StatDate,
+ dquoteStr(fname),
+ dquoteStr(map),
+ mode,
+ gGameSettings.TimeLimit,
+ gGameSettings.GoalLimit,
+ gGameSettings.Options,
+ etime,
+ Length(Stat.PlayerStat)
+ ]));
+ // line 2: game specific shit
+ // if it's a team game: red score, blue score
+ // 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]))
+ 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]));
+ // lines 3-...: team, player name, frags, deaths
+ WriteLn(s, 'team,name,frags,deaths');
+ for I := Low(Stat.PlayerStat) to High(Stat.PlayerStat) do
+ with Stat.PlayerStat[I] do
+ WriteLn(s, Format('%d,%s,%d,%d', [Team, dquoteStr(Name), Frags, Deaths]));
+ except
+ g_Console_Add(Format(_lc[I_CONSOLE_ERROR_WRITE], [fname]));
+ end;
+ except
+ g_Console_Add('could not create gamestats file "' + fname + '"');
+ end;
+ CloseFile(s);
+end;
+
function g_Game_ModeToText(Mode: Byte): string;
begin
Result := '';
function g_Game_ModeToText(Mode: Byte): string;
begin
Result := '';
var
a: Integer;
FileName: string;
var
a: Integer;
FileName: string;
+ t: TDateTime;
begin
if g_Game_IsNet and g_Game_IsServer then
MH_SEND_GameEvent(NET_EV_MAPEND, Byte(gMissionFailed));
begin
if g_Game_IsNet and g_Game_IsServer then
MH_SEND_GameEvent(NET_EV_MAPEND, Byte(gMissionFailed));
end;
SortGameStat(CustomStat.PlayerStat);
end;
SortGameStat(CustomStat.PlayerStat);
+
+ if (gSaveStats or gScreenshotStats) and (Length(gPlayers) > 1) then
+ begin
+ t := Now;
+ if g_Game_IsNet then StatFilename := NetServerName else StatFilename := 'local';
+ StatDate := FormatDateTime('yymmdd_hhnnss', t);
+ StatFilename := StatFilename + '_' + CustomStat.Map + '_' + g_Game_ModeToText(CustomStat.GameMode);
+ StatFilename := sanitizeFilename(StatFilename) + '_' + StatDate;
+ if gSaveStats then
+ SaveGameStat(CustomStat, FormatDateTime('yyyy"/"mm"/"dd', t));
+ end;
+
+ StatShotDone := False;
end;
g_Game_ExecuteEvent('onmapend');
end;
g_Game_ExecuteEvent('onmapend');
procedure g_Game_Init();
var
SR: TSearchRec;
procedure g_Game_Init();
var
SR: TSearchRec;
+ knownFiles: array of AnsiString = nil;
+ found: Boolean;
+ wext, s: AnsiString;
+ f: Integer;
begin
gExit := 0;
gMapToDelete := '';
begin
gExit := 0;
gMapToDelete := '';
g_Game_SetLoadingText(_lc[I_LOAD_MODELS], 0, False);
g_PlayerModel_LoadData();
g_Game_SetLoadingText(_lc[I_LOAD_MODELS], 0, False);
g_PlayerModel_LoadData();
- if e_FindFirst(ModelDirs, '*.wad', faAnyFile, SR) = 0 then
- repeat
- if not g_PlayerModel_Load(e_FindWad(ModelDirs, SR.Name)) then
- e_WriteLog(Format('Error loading model %s', [SR.Name]), TMsgType.Warning);
- until FindNext(SR) <> 0;
- FindClose(SR);
-
- if e_FindFirst(ModelDirs, '*.pk3', faAnyFile, SR) = 0 then
- repeat
- if not g_PlayerModel_Load(e_FindWad(ModelDirs, SR.Name)) then
- e_WriteLog(Format('Error loading model %s', [SR.Name]), TMsgType.Warning);
- until FindNext(SR) <> 0;
- FindClose(SR);
-
- if e_FindFirst(ModelDirs, '*.zip', faAnyFile, SR) = 0 then
- repeat
- if not g_PlayerModel_Load(e_FindWad(ModelDirs, SR.Name)) then
- e_WriteLog(Format('Error loading model %s', [SR.Name]), TMsgType.Warning);
- until FindNext(SR) <> 0;
- FindClose(SR);
+ // load models from all possible wad types, in all known directories
+ // this does a loosy job (linear search, ooph!), but meh
+ for wext in wadExtensions do
+ begin
+ for f := High(ModelDirs) downto Low(ModelDirs) do
+ begin
+ if (FindFirst(ModelDirs[f]+DirectorySeparator+'*'+wext, faAnyFile, SR) = 0) then
+ begin
+ repeat
+ found := false;
+ for s in knownFiles do
+ begin
+ if (strEquCI1251(forceFilenameExt(SR.Name, ''), forceFilenameExt(ExtractFileName(s), ''))) then
+ begin
+ found := true;
+ break;
+ end;
+ end;
+ if not found then
+ begin
+ SetLength(knownFiles, length(knownFiles)+1);
+ knownFiles[High(knownFiles)] := ModelDirs[f]+DirectorySeparator+SR.Name;
+ end;
+ until (FindNext(SR) <> 0);
+ end;
+ FindClose(SR);
+ end;
+ end;
+
+ if (length(knownFiles) = 0) then raise Exception.Create('no player models found!');
+
+ if (length(knownFiles) = 1) then e_LogWriteln('1 player model found.', TMsgType.Notify) else e_LogWritefln('%d player models found.', [Integer(length(knownFiles))], TMsgType.Notify);
+ for s in knownFiles do
+ begin
+ if not g_PlayerModel_Load(s) then e_LogWritefln('Error loading model "%s"', [s], TMsgType.Warning);
+ end;
gGameOn := false;
gPauseMain := false;
gGameOn := false;
gPauseMain := false;
and (not gJustChatted) and (not gConsoleShow) and (not gChatShow)
and (g_ActiveWindow = nil)
)
and (not gJustChatted) and (not gConsoleShow) and (not gChatShow)
and (g_ActiveWindow = nil)
)
- or (g_Game_IsNet and ((gInterTime > gInterEndTime) or (gInterReadyCount >= NetClientCount)))
+ or (g_Game_IsNet and ((gInterTime > gInterEndTime) or ((gInterReadyCount >= NetClientCount) and (NetClientCount > 0))))
)
then
begin // Íàæàëè <Enter>/<Ïðîáåë> èëè ïðîøëî äîñòàòî÷íî âðåìåíè:
)
then
begin // Íàæàëè <Enter>/<Ïðîáåë> èëè ïðîøëî äîñòàòî÷íî âðåìåíè:
_y := _y+24;
end;
end;
_y := _y+24;
end;
end;
+
+ // HACK: take stats screenshot immediately after the first frame of the stats showing
+ if gScreenshotStats and not StatShotDone then
+ begin
+ g_TakeScreenShot('stats/' + StatFilename);
+ StatShotDone := True;
+ end;
end;
procedure DrawSingleStat();
end;
procedure DrawSingleStat();
begin
g_Game_StopAllSounds(True);
gMusic.Free();
begin
g_Game_StopAllSounds(True);
gMusic.Free();
- g_Game_SaveOptions();
g_Game_FreeData();
g_PlayerModel_FreeData();
g_Texture_DeleteAll();
g_Game_FreeData();
g_PlayerModel_FreeData();
g_Texture_DeleteAll();
procedure g_Game_ChangeResolution(newWidth, newHeight: Word; nowFull, nowMax: Boolean);
begin
procedure g_Game_ChangeResolution(newWidth, newHeight: Word; nowFull, nowMax: Boolean);
begin
- sys_SetDisplayMode(newWidth, newHeight, gBPP, nowFull);
+ sys_SetDisplayMode(newWidth, newHeight, gBPP, nowFull, nowMax);
end;
procedure g_Game_AddPlayer(Team: Byte = TEAM_NONE);
end;
procedure g_Game_AddPlayer(Team: Byte = TEAM_NONE);
end;
// Çàãðóçêà è çàïóñê êàðòû:
end;
// Çàãðóçêà è çàïóñê êàðòû:
- if not g_Game_StartMap(MAP, True) then
+ if not g_Game_StartMap(false{asMegawad}, MAP, True) then
begin
if (Pos(':\', Map) > 0) or (Pos(':/', Map) > 0) then tmps := Map else tmps := gGameSettings.WAD + ':\' + MAP;
g_FatalError(Format(_lc[I_GAME_ERROR_MAP_LOAD], [tmps]));
begin
if (Pos(':\', Map) > 0) or (Pos(':/', Map) > 0) then tmps := Map else tmps := gGameSettings.WAD + ':\' + MAP;
g_FatalError(Format(_lc[I_GAME_ERROR_MAP_LOAD], [tmps]));
end;
// Çàãðóçêà è çàïóñê êàðòû:
end;
// Çàãðóçêà è çàïóñê êàðòû:
- if not g_Game_StartMap(Map, True) then
+ if not g_Game_StartMap(true{asMegawad}, Map, True) then
begin
g_FatalError(Format(_lc[I_GAME_ERROR_MAP_LOAD], [Map]));
Exit;
begin
g_FatalError(Format(_lc[I_GAME_ERROR_MAP_LOAD], [Map]));
Exit;
// Ñòàðòóåì ñåðâåð
if not g_Net_Host(IPAddr, Port, NetMaxClients) then
begin
// Ñòàðòóåì ñåðâåð
if not g_Net_Host(IPAddr, Port, NetMaxClients) then
begin
- g_FatalError(_lc[I_NET_MSG] + _lc[I_NET_ERR_HOST]);
+ g_FatalError(_lc[I_NET_MSG] + Format(_lc[I_NET_ERR_HOST], [Port]));
Exit;
end;
Exit;
end;
g_Net_Slist_ServerStarted();
// Çàãðóçêà è çàïóñê êàðòû:
g_Net_Slist_ServerStarted();
// Çàãðóçêà è çàïóñê êàðòû:
- if not g_Game_StartMap(Map, True) then
+ if not g_Game_StartMap(false{asMegawad}, Map, True) then
begin
g_Net_Slist_ServerClosed();
g_FatalError(Format(_lc[I_GAME_ERROR_MAP_LOAD], [Map]));
begin
g_Net_Slist_ServerClosed();
g_FatalError(Format(_lc[I_GAME_ERROR_MAP_LOAD], [Map]));
//if newResPath = '' then
begin
//g_Game_SetLoadingText(_lc[I_LOAD_DL_RES], 0, False);
//if newResPath = '' then
begin
//g_Game_SetLoadingText(_lc[I_LOAD_DL_RES], 0, False);
- newResPath := g_Res_DownloadMapWAD(WadName, gWADHash);
+ newResPath := g_Res_DownloadMapWAD(ExtractFileName(WadName), gWADHash);
if newResPath = '' then
begin
g_FatalError(_lc[I_NET_ERR_HASH]);
if newResPath = '' then
begin
g_FatalError(_lc[I_NET_ERR_HASH]);
e_LogWritefln('using downloaded map wad [%s] for [%s]`', [newResPath, WadName], TMsgType.Notify);
end;
//newResPath := ExtractRelativePath(MapsDir, newResPath);
e_LogWritefln('using downloaded map wad [%s] for [%s]`', [newResPath, WadName], TMsgType.Notify);
end;
//newResPath := ExtractRelativePath(MapsDir, newResPath);
-
+
gPlayer1 := g_Player_Get(g_Player_Create(gPlayer1Settings.Model,
gPlayer1Settings.Color,
gPlayer1 := g_Player_Get(g_Player_Create(gPlayer1Settings.Model,
gPlayer1Settings.Color,
gPlayer1.UID := NetPlrUID1;
gPlayer1.Reset(True);
gPlayer1.UID := NetPlrUID1;
gPlayer1.Reset(True);
- if not g_Game_StartMap(newResPath + ':\' + Map, True) then
+ if not g_Game_StartMap(false{asMegawad}, newResPath + ':\' + Map, True) then
begin
g_FatalError(Format(_lc[I_GAME_ERROR_MAP_LOAD], [WadName + ':\' + Map]));
begin
g_FatalError(Format(_lc[I_GAME_ERROR_MAP_LOAD], [WadName + ':\' + Map]));
e_WriteLog('NET: Connection successful.', TMsgType.Notify);
end;
e_WriteLog('NET: Connection successful.', TMsgType.Notify);
end;
-procedure g_Game_SaveOptions;
- var s: AnsiString;
-begin
- s := e_GetDir(ConfigDirs);
- if s <> '' then
- g_Options_Write_Video(s + '/' + CONFIG_FILENAME)
- else
- e_LogWritefln('unable to find or create directory for configs', []);
-end;
+var
+ lastAsMegaWad: Boolean = false;
procedure g_Game_ChangeMap(const MapPath: String);
var
procedure g_Game_ChangeMap(const MapPath: String);
var
Force := False;
gExitByTrigger := False;
end;
Force := False;
gExitByTrigger := False;
end;
- if not g_Game_StartMap(MapPath, Force) then
+ if not g_Game_StartMap(lastAsMegaWad, MapPath, Force) then
g_FatalError(Format(_lc[I_GAME_ERROR_MAP_LOAD], [MapPath]));
end;
g_FatalError(Format(_lc[I_GAME_ERROR_MAP_LOAD], [MapPath]));
end;
MessageTime := 0;
gGameOn := False;
g_Game_ClearLoading();
MessageTime := 0;
gGameOn := False;
g_Game_ClearLoading();
- g_Game_StartMap(Map, True, gCurrentMapFileName);
+ g_Game_StartMap(lastAsMegaWad, Map, True, gCurrentMapFileName);
end;
end;
-function g_Game_StartMap(Map: String; Force: Boolean = False; const oldMapPath: AnsiString=''): Boolean;
+function g_Game_StartMap (asMegawad: Boolean; Map: String; Force: Boolean = False; const oldMapPath: AnsiString=''): Boolean;
var
NewWAD, ResName: String;
I: Integer;
var
NewWAD, ResName: String;
I: Integer;
g_Player_ResetTeams();
g_Player_ResetTeams();
+ lastAsMegaWad := asMegawad;
if isWadPath(Map) then
begin
NewWAD := g_ExtractWadName(Map);
ResName := g_ExtractFileName(Map);
if g_Game_IsServer then
begin
if isWadPath(Map) then
begin
NewWAD := g_ExtractWadName(Map);
ResName := g_ExtractFileName(Map);
if g_Game_IsServer then
begin
-// nws := e_FindWad(MapDirs, NewWAD);
- nws := NewWAD;
+ nws := findDiskWad(NewWAD);
+ //writeln('000: Map=[', Map, ']; nws=[', nws, ']; NewWAD=[', NewWAD, ']');
+ if (asMegawad) then
+ begin
+ if (length(nws) = 0) then nws := e_FindWad(MegawadDirs, NewWAD);
+ if (length(nws) = 0) then nws := e_FindWad(MapDirs, NewWAD);
+ end
+ else
+ begin
+ if (length(nws) = 0) then nws := e_FindWad(MapDirs, NewWAD);
+ if (length(nws) = 0) then nws := e_FindWad(MegawadDirs, NewWAD);
+ end;
+ //if (length(nws) = 0) then nws := e_FindWad(MapDownloadDirs, NewWAD);
+ //writeln('001: Map=[', Map, ']; nws=[', nws, ']; NewWAD=[', NewWAD, ']');
+ //nws := NewWAD;
if (length(nws) = 0) then
begin
if (length(nws) = 0) then
begin
- ResName := '';
+ ResName := ''; // failed
end
else
begin
end
else
begin
+ NewWAD := nws;
if (g_Game_IsNet) then gWADHash := MD5File(nws);
//writeln('********: nws=', nws, ' : Map=', Map, ' : nw=', NewWAD, ' : resname=', ResName);
g_Game_LoadWAD(NewWAD);
end;
if (g_Game_IsNet) then gWADHash := MD5File(nws);
//writeln('********: nws=', nws, ' : Map=', Map, ' : nw=', NewWAD, ' : resname=', ResName);
g_Game_LoadWAD(NewWAD);
end;
- end else
+ end
+ else
+ begin
// hash received in MC_RECV_GameEvent -> NET_EV_MAPSTART
// hash received in MC_RECV_GameEvent -> NET_EV_MAPSTART
- g_Game_ClientWAD(NewWAD, gWADHash);
- end else
+ NewWAD := g_Game_ClientWAD(NewWAD, gWADHash);
+ end;
+ end
+ else
+ begin
+ NewWAD := gGameSettings.WAD;
ResName := Map;
ResName := Map;
+ end;
//writeln('********: gsw=', gGameSettings.WAD, '; rn=', ResName);
result := false;
//writeln('********: gsw=', gGameSettings.WAD, '; rn=', ResName);
result := false;
- if ResName <> '' then
- result := g_Map_Load(gGameSettings.WAD + ':\' + ResName);
+ if (ResName <> '') and (NewWAD <> '') then
+ begin
+ //result := g_Map_Load(gGameSettings.WAD + ':\' + ResName);
+ result := g_Map_Load(NewWAD+':\'+ResName);
+ end;
if Result then
begin
g_Player_ResetAll(Force or gLastMap, gGameSettings.GameType = GT_SINGLE);
if Result then
begin
g_Player_ResetAll(Force or gLastMap, gGameSettings.GameType = GT_SINGLE);
gNextMap := Map;
end;
gNextMap := Map;
end;
-procedure g_Game_ClientWAD(NewWAD: String; const WHash: TMD5Digest);
+function g_Game_ClientWAD (NewWAD: String; const WHash: TMD5Digest): AnsiString;
var
gWAD{, xwad}: String;
begin
var
gWAD{, xwad}: String;
begin
+ result := NewWAD;
if not g_Game_IsClient then Exit;
//e_LogWritefln('*** g_Game_ClientWAD: `%s`', [NewWAD]);
gWAD := g_Res_DownloadMapWAD(ExtractFileName(NewWAD), WHash);
if gWAD = '' then
begin
if not g_Game_IsClient then Exit;
//e_LogWritefln('*** g_Game_ClientWAD: `%s`', [NewWAD]);
gWAD := g_Res_DownloadMapWAD(ExtractFileName(NewWAD), WHash);
if gWAD = '' then
begin
+ result := '';
g_Game_Free();
g_FatalError(Format(_lc[I_GAME_ERROR_MAP_WAD], [ExtractFileName(NewWAD)]));
Exit;
end;
g_Game_Free();
g_FatalError(Format(_lc[I_GAME_ERROR_MAP_WAD], [ExtractFileName(NewWAD)]));
Exit;
end;
-(*
- xwad := ExtractRelativePath(MapsDir, gWAD);
- e_LogWritefln('using downloaded client map wad [%s] for [%s]`', [xwad, NewWAD], TMsgType.Notify);
- NewWAD := xwad;
- g_Game_LoadWAD(NewWAD);
-*)
+ e_LogWritefln('using downloaded client map wad [%s] for [%s]', [gWAD, NewWAD], TMsgType.Notify);
+ NewWAD := gWAD;
- e_LogWritefln('using downloaded client map wad [%s]`', [NewWAD], TMsgType.Notify);
g_Game_LoadWAD(NewWAD);
g_Game_LoadWAD(NewWAD);
+ result := NewWAD;
{
if LowerCase(NewWAD) = LowerCase(gGameSettings.WAD) then Exit;
{
if LowerCase(NewWAD) = LowerCase(gGameSettings.WAD) then Exit;
if g_Game_IsNet then MH_SEND_GameSettings;
end;
end
if g_Game_IsNet then MH_SEND_GameSettings;
end;
end
+ else if (cmd = 'g_dm_keys') and not g_Game_IsClient 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_DMKEYS
+ else
+ Options := Options and (not GAME_OPTION_DMKEYS);
+ 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;
+ end
+ else if (cmd = 'g_respawn_items') and not g_Game_IsClient 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_RESPAWNITEMS
+ else
+ Options := Options and (not GAME_OPTION_RESPAWNITEMS);
+ end;
+
+ if (LongBool(Options and GAME_OPTION_RESPAWNITEMS)) then
+ g_Console_Add(_lc[I_MSG_RESPAWNITEMS_ON])
+ else
+ g_Console_Add(_lc[I_MSG_RESPAWNITEMS_OFF]);
+
+ if g_Game_IsNet then MH_SEND_GameSettings;
+ end;
+ end
else if (cmd = 'g_warmuptime') and not g_Game_IsClient then
begin
if Length(P) > 1 then
else if (cmd = 'g_warmuptime') and not g_Game_IsClient then
begin
if Length(P) > 1 then
[gGameSettings.WarmupTime]));
g_Console_Add(_lc[I_MSG_ONMAPCHANGE]);
end
[gGameSettings.WarmupTime]));
g_Console_Add(_lc[I_MSG_ONMAPCHANGE]);
end
+ else if (cmd = 'g_spawn_invul') and not g_Game_IsClient 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);
+ end;
+
+ g_Console_Add(Format(_lc[I_MSG_SPAWNINVUL],
+ [gGameSettings.SpawnInvul]));
+ g_Console_Add(_lc[I_MSG_ONMAPCHANGE]);
+ end
else if cmd = 'net_interp' then
begin
if (Length(P) > 1) then
NetInterpLevel := StrToIntDef(P[1], NetInterpLevel);
g_Console_Add('net_interp = ' + IntToStr(NetInterpLevel));
else if cmd = 'net_interp' then
begin
if (Length(P) > 1) then
NetInterpLevel := StrToIntDef(P[1], NetInterpLevel);
g_Console_Add('net_interp = ' + IntToStr(NetInterpLevel));
- s := e_GetDir(ConfigDirs);
+ s := e_GetWriteableDir(ConfigDirs);
if s <> '' then
begin
config := TConfig.CreateFile(s + '/' + CONFIG_FILENAME);
if s <> '' then
begin
config := TConfig.CreateFile(s + '/' + CONFIG_FILENAME);
else
g_Console_Add('net_forceplayerupdate = 0');
else
g_Console_Add('net_forceplayerupdate = 0');
- s := e_GetDir(ConfigDirs);
+ s := e_GetWriteableDir(ConfigDirs);
if s <> '' then
begin
config := TConfig.CreateFile(s + '/' + CONFIG_FILENAME);
if s <> '' then
begin
config := TConfig.CreateFile(s + '/' + CONFIG_FILENAME);
else
g_Console_Add('net_predictself = 0');
else
g_Console_Add('net_predictself = 0');
- s := e_GetDir(ConfigDirs);
+ s := e_GetWriteableDir(ConfigDirs);
if s <> '' then
begin
config := TConfig.CreateFile(s + '/' + CONFIG_FILENAME);
if s <> '' then
begin
config := TConfig.CreateFile(s + '/' + CONFIG_FILENAME);
cmd := LowerCase(P[0]);
if cmd = 'd_window' then
begin
cmd := LowerCase(P[0]);
if cmd = 'd_window' then
begin
- g_Console_Add(Format('gWinPosX = %d, gWinPosY %d', [gWinPosX, gWinPosY]));
- g_Console_Add(Format('gWinRealPosX = %d, gWinRealPosY %d', [gWinRealPosX, gWinRealPosY]));
g_Console_Add(Format('gScreenWidth = %d, gScreenHeight = %d', [gScreenWidth, gScreenHeight]));
g_Console_Add(Format('gWinSizeX = %d, gWinSizeY = %d', [gWinSizeX, gWinSizeY]));
g_Console_Add(Format('gScreenWidth = %d, gScreenHeight = %d', [gScreenWidth, gScreenHeight]));
g_Console_Add(Format('gWinSizeX = %d, gWinSizeY = %d', [gWinSizeX, gWinSizeY]));
- g_Console_Add(Format('Frame X = %d, Y = %d, Caption Y = %d', [gWinFrameX, gWinFrameY, gWinCaption]));
end
else if cmd = 'd_sounds' then
begin
end
else if cmd = 'd_sounds' then
begin
if found then
begin
// no such map, found wad
if found then
begin
// no such map, found wad
+ pw := P[1];
SetLength(P, 3);
P[1] := ExpandFileName(pw);
P[2] := g_Game_GetFirstMap(P[1]);
SetLength(P, 3);
P[1] := ExpandFileName(pw);
P[2] := g_Game_GetFirstMap(P[1]);
end else
g_Console_Add(_lc[I_MSG_SERVERONLY]);
end
end else
g_Console_Add(_lc[I_MSG_SERVERONLY]);
end
+ else if cmd = 'centerprint' then
+ begin
+ if (Length(P) > 2) and (P[1] <> '') then
+ begin
+ chstr := '';
+ for a := 2 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('centerprint <timeout> <text>');
+ Exit;
+ end;
+
+ a := StrToIntDef(P[1], 100);
+ chstr := b_Text_Format(chstr);
+ g_Game_Message(chstr, a);
+ if g_Game_IsNet and g_Game_IsServer then
+ MH_SEND_GameEvent(NET_EV_BIGTEXT, a, chstr);
+ end
+ else g_Console_Add('centerprint <timeout> <text>');
+ end
else if (cmd = 'overtime') and not g_Game_IsClient then
begin
if (Length(P) = 1) or (StrToIntDef(P[1], -1) <= 0) then
else if (cmd = 'overtime') and not g_Game_IsClient then
begin
if (Length(P) = 1) or (StrToIntDef(P[1], -1) <= 0) then
end;
end;
end;
end;
-procedure g_TakeScreenShot;
- var s: TStream; t: TDateTime; date, name: String;
+procedure g_TakeScreenShot(Filename: string = '');
+ var s: TStream; t: TDateTime; dir, date, name: String;
begin
if e_NoGraphics then Exit;
begin
if e_NoGraphics then Exit;
- t := Now;
- DateTimeToString(date, 'yyyy-mm-dd-hh-nn-ss', t);
- name := 'screenshot-' + date + '.png';
try
try
- s := e_CreateResource(ScreenshotDirs, name);
- e_MakeScreenshot(s, gScreenWidth, gScreenHeight);
- g_Console_Add(Format(_lc[I_CONSOLE_SCREENSHOT], [name]))
+ dir := e_GetWriteableDir(ScreenshotDirs);
+
+ if Filename = '' then
+ begin
+ t := Now;
+ 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);
+ s.Free;
+ g_Console_Add(Format(_lc[I_CONSOLE_SCREENSHOT], [name]))
+ except
+ g_Console_Add(Format(_lc[I_CONSOLE_ERROR_WRITE], [name]));
+ s.Free;
+ DeleteFile(name)
+ end
except
g_Console_Add('oh shit, i can''t create screenshot!')
end
except
g_Console_Add('oh shit, i can''t create screenshot!')
end