diff --git a/src/game/g_game.pas b/src/game/g_game.pas
index 35f667bf432ce2678561f40920e28d44ac93df0f..963496aab5b49eddfb4779dda2ef1f7e9d14674b 100644 (file)
--- a/src/game/g_game.pas
+++ b/src/game/g_game.pas
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
+ * the Free Software Foundation, version 3 of the License ONLY.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
procedure g_Game_Restart();
procedure g_Game_RestartLevel();
procedure g_Game_RestartRound(NoMapRestart: Boolean = False);
-procedure g_Game_ClientWAD(NewWAD: String; WHash: TMD5Digest);
+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;
procedure g_Game_ChangeMap(const MapPath: String);
ANNOUNCE_ALL = 3;
CONFIG_FILENAME = 'Doom2DF.cfg';
- LOG_FILENAME = 'Doom2DF.log';
TEST_MAP_NAME = '$$$_TEST_$$$';
begin
s := g_ExtractWadName(MegaWAD.endpic);
if s = '' then s := MapsDir+WAD else s := GameDir+'/wads/';
+ TEXTUREFILTER := GL_LINEAR;
g_Texture_CreateWADEx('TEXTURE_endpic', s+MegaWAD.endpic);
+ TEXTUREFILTER := GL_NEAREST;
end;
MegaWAD.endmus := cfg.ReadStr('megawad', 'endmus', 'Standart.wad:D2DMUS\ÊÎÍÅÖ');
if MegaWAD.endmus <> '' then
g_Sound_CreateWADEx('MUSIC_ROUNDMUS', GameWAD+':MUSIC\ROUNDMUS', True, True);
g_Sound_CreateWADEx('MUSIC_STDENDMUS', GameWAD+':MUSIC\ENDMUS', True);
+{$IFNDEF HEADLESS}
g_Game_SetLoadingText(_lc[I_LOAD_MENUS], 0, False);
g_Menu_Init();
+{$ENDIF}
gMusic := TMusic.Create();
gMusic.SetByName('MUSIC_MENU');
if NetUseMaster then
begin
- if gTime >= NetTimeToMaster then
+ if (gTime >= NetTimeToMaster) or g_Net_Slist_IsConnectionInProgress then
begin
- if (NetMHost = nil) or (NetMPeer = nil) then
- begin
- if not g_Net_Slist_Connect then g_Console_Add(_lc[I_NET_MSG_ERROR] + _lc[I_NET_SLIST_ERROR]);
- end;
-
+ if (not g_Net_Slist_IsConnectionActive) then g_Net_Slist_Connect(false); // non-blocking connection to the master
g_Net_Slist_Update;
NetTimeToMaster := gTime + NetMasterRate;
end;
//e_WriteLog('Read language file', MSG_NOTIFY);
//g_Language_Load(DataDir + gLanguage + '.txt');
g_Language_Set(gLanguage);
+{$IFNDEF HEADLESS}
g_Menu_Reset();
+{$ENDIF}
gLanguageChange := False;
end;
end;
procedure DrawPlayer(p: TPlayer);
var
- px, py, a, b, c, d: Integer;
+ px, py, a, b, c, d, i: Integer;
//R: TRect;
begin
if (p = nil) or (p.FDummy) then
renderMapInternal(-c, -d, true);
- if (gGameSettings.GameMode <> GM_SINGLE) and gPlayerIndicator then
- p.DrawIndicator();
+ if (gGameSettings.GameMode <> GM_SINGLE) and (gPlayerIndicator > 0) then
+ case gPlayerIndicator of
+ 1:
+ p.DrawIndicator(_RGB(255, 255, 255));
+
+ 2:
+ for i := 0 to High(gPlayers) do
+ if gPlayers[i] <> nil then
+ if gPlayers[i] = p then p.DrawIndicator(_RGB(255, 255, 255))
+ else if (gPlayers[i].Team = p.Team) and (gPlayers[i].Team <> TEAM_NONE) then
+ if gPlayerIndicatorStyle = 1 then
+ gPlayers[i].DrawIndicator(_RGB(192, 192, 192))
+ else gPlayers[i].DrawIndicator(gPlayers[i].GetColor);
+ end;
+
if p.FSpectator then
e_TextureFontPrintEx(p.GameX + PLAYER_RECT_CX - 4,
p.GameY + PLAYER_RECT_CY - 4,
if plView1 <> nil then
begin
gHearPoint1.Active := True;
- gHearPoint1.Coords.X := plView1.GameX;
- gHearPoint1.Coords.Y := plView1.GameY;
+ gHearPoint1.Coords.X := plView1.GameX + PLAYER_RECT.Width;
+ gHearPoint1.Coords.Y := plView1.GameY + PLAYER_RECT.Height DIV 2;
end else
gHearPoint1.Active := False;
if plView2 <> nil then
begin
gHearPoint2.Active := True;
- gHearPoint2.Coords.X := plView2.GameX;
- gHearPoint2.Coords.Y := plView2.GameY;
+ gHearPoint2.Coords.X := plView2.GameX + PLAYER_RECT.Width;
+ gHearPoint2.Coords.Y := plView2.GameY + PLAYER_RECT.Height DIV 2;
end else
gHearPoint2.Active := False;
if gState = STATE_ENDPIC then
begin
ID := DWORD(-1);
- if not g_Texture_Get('TEXTURE_endpic', ID) then
- g_Texture_Get(_lc[I_TEXTURE_ENDPIC], ID);
-
- if ID <> DWORD(-1) then
- e_DrawSize(ID, 0, 0, 0, False, False, gScreenWidth, gScreenHeight)
- else
- e_Clear(GL_COLOR_BUFFER_BIT, 0, 0, 0);
+ if g_Texture_Get('TEXTURE_endpic', ID) then DrawMenuBackground('TEXTURE_endpic')
+ else DrawMenuBackground(_lc[I_TEXTURE_ENDPIC]);
if g_ActiveWindow <> nil then
begin
g_ActiveWindow.Draw();
end;
+{$IFNDEF HEADLESS}
g_Console_Draw();
+{$ENDIF}
if g_debug_Sounds and gGameOn then
begin
g_PlayerModel_FreeData();
g_Texture_DeleteAll();
g_Frames_DeleteAll();
+{$IFNDEF HEADLESS}
//g_Menu_Free(); //k8: this segfaults after resolution change; who cares?
+{$ENDIF}
if NetInitDone then g_Net_Free;
NetState := NET_STATE_AUTH;
g_Game_SetLoadingText(_lc[I_LOAD_CONNECT], 0, False);
+
+ // create (or update) map/resource databases
+ g_Res_CreateDatabases(true);
+
// Ñòàðòóåì êëèåíò
if not g_Net_Connect(Addr, Port) then
begin
OuterLoop := True;
while OuterLoop do
begin
- while (enet_host_service(NetHost, @NetEvent, 0) > 0) do
+ while (enet_host_service(NetHost, @NetEvent, 50) > 0) do
begin
if (NetEvent.kind = ENET_EVENT_TYPE_RECEIVE) then
begin
+ if (NetEvent.channelID = NET_CHAN_DOWNLOAD_EX) then
+ begin
+ // ignore all download packets, they're processed by separate code
+ enet_packet_destroy(NetEvent.packet);
+ continue;
+ end;
Ptr := NetEvent.packet^.data;
if not InMsg.Init(Ptr, NetEvent.packet^.dataLength, True) then
+ begin
+ enet_packet_destroy(NetEvent.packet);
continue;
+ end;
+ InMsg.ReadLongWord(); // skip size
MID := InMsg.ReadByte();
if (MID = NET_MSG_INFO) and (State = 0) then
gGameSettings.Options := InMsg.ReadLongWord();
T := InMsg.ReadLongWord();
- newResPath := g_Res_SearchSameWAD(MapsDir, WadName, gWADHash);
- if newResPath = '' then
+ //newResPath := g_Res_SearchSameWAD(MapsDir, WadName, gWADHash);
+ //if newResPath = '' then
begin
- g_Game_SetLoadingText(_lc[I_LOAD_DL_RES], 0, False);
- newResPath := g_Res_DownloadWAD(WadName);
+ //g_Game_SetLoadingText(_lc[I_LOAD_DL_RES], 0, False);
+ newResPath := g_Res_DownloadMapWAD(WadName, gWADHash);
if newResPath = '' then
begin
g_FatalError(_lc[I_NET_ERR_HASH]);
NetState := NET_STATE_NONE;
Exit;
end;
+ e_LogWritefln('using downloaded map wad [%s] for [%s]`', [newResPath, WadName], TMsgType.Notify);
end;
newResPath := ExtractRelativePath(MapsDir, newResPath);
ProcessLoading(true);
- if e_KeyPressed(IK_SPACE) or e_KeyPressed(IK_ESCAPE) or e_KeyPressed(VK_ESCAPE) or
- e_KeyPressed(JOY0_JUMP) or e_KeyPressed(JOY1_JUMP) or e_KeyPressed(JOY2_JUMP) or e_KeyPressed(JOY3_JUMP) then
+ if g_Net_UserRequestExit() then
begin
State := 0;
break;
@@ -4768,6 +4794,7 @@ function g_Game_StartMap(Map: String; Force: Boolean = False; const oldMapPath:
var
NewWAD, ResName: String;
I: Integer;
+ nws: AnsiString;
begin
g_Map_Free((Map <> gCurrentMapFileName) and (oldMapPath <> gCurrentMapFileName));
g_Player_RemoveAllCorpses();
ResName := g_ExtractFileName(Map);
if g_Game_IsServer then
begin
- gWADHash := MD5File(MapsDir + NewWAD);
- g_Game_LoadWAD(NewWAD);
+ nws := findDiskWad(MapsDir+NewWAD);
+ if (length(nws) = 0) then
+ begin
+ ResName := '';
+ end
+ else
+ begin
+ if (g_Game_IsNet) then gWADHash := MD5File(nws);
+ //writeln('********: nws=', nws, ' : Map=', Map, ' : nw=', NewWAD, ' : resname=', ResName);
+ g_Game_LoadWAD(NewWAD);
+ end;
end else
// hash received in MC_RECV_GameEvent -> NET_EV_MAPSTART
g_Game_ClientWAD(NewWAD, gWADHash);
end else
ResName := Map;
- Result := g_Map_Load(MapsDir + gGameSettings.WAD + ':\' + ResName);
+ //writeln('********: gsw=', gGameSettings.WAD, '; rn=', ResName);
+ Result := (ResName <> '') and g_Map_Load(MapsDir + gGameSettings.WAD + ':\' + ResName);
if Result then
begin
g_Player_ResetAll(Force or gLastMap, gGameSettings.GameType = GT_SINGLE);
// Ìàñòåðñåðâåð
if NetUseMaster then
begin
- if (NetMHost = nil) or (NetMPeer = nil) then
- if not g_Net_Slist_Connect then
- g_Console_Add(_lc[I_NET_MSG_ERROR] + _lc[I_NET_SLIST_ERROR]);
-
+ if (not g_Net_Slist_IsConnectionActive) then g_Net_Slist_Connect(false); // non-blocking connection to the master
g_Net_Slist_Update;
end;
gNextMap := Map;
end;
-procedure g_Game_ClientWAD(NewWAD: String; WHash: TMD5Digest);
+procedure g_Game_ClientWAD(NewWAD: String; const WHash: TMD5Digest);
var
- gWAD: String;
+ gWAD, xwad: String;
begin
- if LowerCase(NewWAD) = LowerCase(gGameSettings.WAD) then
- Exit;
- if not g_Game_IsClient then
+ 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
+ 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);
+
+ {
+ if LowerCase(NewWAD) = LowerCase(gGameSettings.WAD) then Exit;
gWAD := g_Res_SearchSameWAD(MapsDir, ExtractFileName(NewWAD), WHash);
if gWAD = '' then
begin
g_Game_SetLoadingText(_lc[I_LOAD_DL_RES], 0, False);
- gWAD := g_Res_DownloadWAD(ExtractFileName(NewWAD));
+ gWAD := g_Res_DownloadMapWAD(ExtractFileName(NewWAD), WHash);
if gWAD = '' then
begin
g_Game_Free();
end;
NewWAD := ExtractRelativePath(MapsDir, gWAD);
g_Game_LoadWAD(NewWAD);
+ }
end;
procedure g_Game_RestartRound(NoMapRestart: Boolean = False);
begin
NetUseMaster := StrToIntDef(P[1], Byte(NetUseMaster)) > 0;
if g_Game_IsServer and g_Game_IsNet then
+ begin
if NetUseMaster then
begin
- if NetMPeer = nil then
- if not g_Net_Slist_Connect() then
- g_Console_Add(_lc[I_NET_MSG_ERROR] + _lc[I_NET_SLIST_ERROR]);
+ if (not g_Net_Slist_IsConnectionActive) then g_Net_Slist_Connect(false); // non-blocking connection to the master
g_Net_Slist_Update();
end
else
- if NetMPeer <> nil then
- g_Net_Slist_Disconnect();
+ begin
+ if (not g_Net_Slist_IsConnectionActive) then g_Net_Slist_Disconnect();
+ end;
+ end;
end;
g_Console_Add(cmd + ' = ' + IntToStr(Byte(NetUseMaster)));
e_StopChannels();
end;
-procedure g_Game_UpdateTriggerSounds();
-var
- i: Integer;
+procedure g_Game_UpdateTriggerSounds;
+ var i: Integer;
begin
if gTriggers <> nil then
for i := 0 to High(gTriggers) do
with gTriggers[i] do
- if (TriggerType = TRIGGER_SOUND) and
- (Sound <> nil) and
- (tgcLocal) and
- Sound.IsPlaying() then
- begin
- if ((gPlayer1 <> nil) and g_CollidePoint(gPlayer1.GameX, gPlayer1.GameY, X, Y, Width, Height)) or
- ((gPlayer2 <> nil) and g_CollidePoint(gPlayer2.GameX, gPlayer2.GameY, X, Y, Width, Height)) then
- begin
- Sound.SetPan(0.5 - tgcPan/255.0);
- Sound.SetVolume(tgcVolume/255.0);
- end
- else
- Sound.SetCoords(X+(Width div 2), Y+(Height div 2), tgcVolume/255.0);
- end;
+ if (TriggerType = TRIGGER_SOUND) and (Sound <> nil) and tgcLocal and Sound.IsPlaying() then
+ Sound.SetCoordsRect(X, Y, Width, Height, tgcVolume / 255.0)
end;
function g_Game_IsWatchedPlayer(UID: Word): Boolean;