diff --git a/src/game/g_netmsg.pas b/src/game/g_netmsg.pas
index aec47c7ff524d3c16de2bc4da6f2e9ea350f2172..5e95a6a57dd97b42a4d31178c153e94589092816 100644 (file)
--- a/src/game/g_netmsg.pas
+++ b/src/game/g_netmsg.pas
NET_EV_PLAYER_TOUCH = 18;
NET_EV_SECRET = 19;
NET_EV_INTER_READY = 20;
+ NET_EV_LMS_NOSPAWN = 21;
NET_VE_STARTED = 1;
NET_VE_PASSED = 2;
Name := PName;
FClientID := C^.ID;
// round in progress, don't spawn
- if (gGameSettings.MaxLives > 0) and (gLMSRespawn = LMS_RESPAWN_NONE) then
- begin
- Lives := 0;
- FNoRespawn := True;
- Spectate;
- FWantsInGame := True; // TODO: look into this later
- C^.WaitForFirstSpawn := true;
- end
- else
- begin
- e_LogWritefln('*** client #%u (cid #%u) authenticated...', [C.ID, C.Player]);
- //e_LogWritefln('spawning player with pid #%u...', [PID]);
- //Respawn(gGameSettings.GameType = GT_SINGLE);
- //k8: no, do not spawn a player yet, wait for "request full state" packet
- Lives := 0;
- Spectate;
- FNoRespawn := True;
- // `FWantsInGame` seems to mean "spawn the player on the next occasion".
- // that is, if we'll set it to `true`, the player can be spawned after
- // warmup time ran out, for example, regardless of the real player state.
- // also, this seems to work only for the initial connection. further
- // map changes could initiate resource downloading, but the player will
- // be spawned immediately.
- // the proper solution will require another player state, "ephemeral".
- // the player should start any map in "ephemeral" state, and turned into
- // real mobj only when they sent a special "i am ready" packet. this packet
- // must be sent after receiving the full state, so the player will get a full
- // map view before going into game.
- FWantsInGame := false;
- C^.WaitForFirstSpawn := true;
- end;
+ e_LogWritefln('*** client #%u (cid #%u) authenticated...', [C.ID, C.Player]);
+ //e_LogWritefln('spawning player with pid #%u...', [PID]);
+ //Respawn(gGameSettings.GameType = GT_SINGLE);
+ //k8: no, do not spawn a player yet, wait for "request full state" packet
+ Lives := 0;
+ Spectate;
+ FNoRespawn := True;
+ // `FWantsInGame` seems to mean "spawn the player on the next occasion".
+ // that is, if we'll set it to `true`, the player can be spawned after
+ // warmup time ran out, for example, regardless of the real player state.
+ // also, this seems to work only for the initial connection. further
+ // map changes could initiate resource downloading, but the player will
+ // be spawned immediately.
+ // the proper solution will require another player state, "ephemeral".
+ // the player should start any map in "ephemeral" state, and turned into
+ // real mobj only when they sent a special "i am ready" packet. this packet
+ // must be sent after receiving the full state, so the player will get a full
+ // map view before going into game.
+ FWantsInGame := false;
+ C^.WaitForFirstSpawn := true;
end;
//if not C^.WaitForFirstSpawn then
C.WaitForFirstSpawn := false;
plr.FNoRespawn := false;
plr.FWantsInGame := true; // TODO: look into this later
- plr.Respawn(False);
+
+ if (gGameSettings.MaxLives > 0) and (gLMSRespawn = LMS_RESPAWN_NONE) then
+ begin
+ plr.Spectate;
+ MH_SEND_GameEvent(NET_EV_LMS_NOSPAWN, 0, 'N', C.ID);
+ end
+ else
+ begin
+ plr.Respawn(False);
+ if gLMSRespawn > LMS_RESPAWN_NONE then
+ MH_SEND_GameEvent(NET_EV_LMS_WARMUP, gLMSRespawnTime - gTime, 'N', C.ID);
+ end;
end;
NET_CHEAT_SPECTATE:
begin
if Pl.FSpectator then
- Pl.Respawn(False)
+ begin
+ if (gGameSettings.MaxLives = 0) or (gLMSRespawn > LMS_RESPAWN_NONE) then
+ Pl.Respawn(False)
+ else
+ MH_SEND_GameEvent(NET_EV_LMS_NOSPAWN, Pl.UID);
+ end
else
Pl.Spectate;
end;
if CreatePlayers and (ID >= 0) then NetClients[ID].State := NET_STATE_GAME;
- if gLMSRespawn > LMS_RESPAWN_NONE then
- begin
- e_LogWritefln('*** client #%u (cid #%u) WARMUP', [ID, NetClients[ID].Player]);
- MH_SEND_GameEvent(NET_EV_LMS_WARMUP, (gLMSRespawnTime - gTime) div 1000, 'N', ID);
- end;
-
g_Net_Flush();
end;
procedure MH_SEND_Info(ID: Byte);
-var
- Map: string;
begin
- Map := g_ExtractFileName(gMapInfo.Map);
-
NetOut.Clear();
NetOut.Write(Byte(NET_MSG_INFO));
NetOut.Write(ID);
NetOut.Write(NetClients[ID].Player);
- NetOut.Write(gGameSettings.WAD);
- NetOut.Write(Map);
+ NetOut.Write(ExtractFileName(gGameSettings.WAD));
+ NetOut.Write(g_ExtractFileName(gMapInfo.Map));
NetOut.Write(gWADHash);
NetOut.Write(gGameSettings.GameMode);
NetOut.Write(gGameSettings.GoalLimit);
NetOut.Write(Byte(FJetpack));
NetOut.Write(FFireTime);
NetOut.Write(Byte(FFlaming));
+ NetOut.Write(FSpawnInvul);
end;
g_Net_Host_Send(ID, True, NET_CHAN_PLAYER);
NET_EV_MAPEND: goodCmd := true;
NET_EV_PLAYER_KICK: goodCmd := true;
NET_EV_PLAYER_BAN: goodCmd := true;
+ NET_EV_LMS_WARMUP: goodCmd := true;
end;
if not goodCmd then exit;
end;
gGameSettings.GameMode := gSwitchGameMode;
gWADHash := EvHash;
- if not g_Game_StartMap(EvStr, True) then
+ if not g_Game_StartMap(false{asMegawad}, EvStr, True) then
begin
if not isWadPath(EvStr) then
g_FatalError(Format(_lc[I_GAME_ERROR_MAP_LOAD], [gGameSettings.WAD + ':\' + EvStr]))
NET_EV_MAPEND:
begin
+ gLMSRespawn := LMS_RESPAWN_NONE;
+ gLMSRespawnTime := 0;
if (g_Res_received_map_start <> 0) then
begin
g_Res_received_map_start := -1;
end;
NET_EV_LMS_WARMUP:
- g_Console_Add(Format(_lc[I_MSG_WARMUP_START], [EvNum]), True);
+ begin
+ if EvNum > 0 then
+ begin
+ gLMSRespawn := LMS_RESPAWN_WARMUP;
+ gLMSRespawnTime := gTime + EvNum;
+ g_Console_Add(Format(_lc[I_MSG_WARMUP_START], [EvNum div 1000]), True);
+ end
+ else if gPlayer1 = nil then
+ begin
+ g_Console_Add(_lc[I_PLAYER_SPECT4], True);
+ end;
+ end;
NET_EV_LMS_SURVIVOR:
g_Console_Add('*** ' + _lc[I_MESSAGE_LMS_SURVIVOR] + ' ***', True);
NET_EV_LMS_START:
begin
g_Player_RemoveAllCorpses;
+ gLMSRespawn := LMS_RESPAWN_NONE;
g_Game_Message(_lc[I_MESSAGE_LMS_START], 144);
end;
NET_EV_LMS_DRAW:
g_Game_Message(_lc[I_GAME_WIN_DRAW], 144);
+ NET_EV_LMS_NOSPAWN:
+ g_Console_Add(_lc[I_PLAYER_SPECT4], True);
+
NET_EV_KILLCOMBO:
g_Game_Announce_KillCombo(EvNum);
FSpectator := M.ReadByte() <> 0;
if FSpectator then
begin
- if Pl = gPlayer1 then
+ if UID = NetPlrUID1 then
begin
- gLMSPID1 := UID;
+ gSpectLatchPID1 := UID;
gPlayer1 := nil;
end;
- if Pl = gPlayer2 then
+ if UID = NetPlrUID2 then
begin
- gLMSPID2 := UID;
+ gSpectLatchPID2 := UID;
gPlayer2 := nil;
end;
end
else
begin
- if (gPlayer1 = nil) and (gLMSPID1 > 0) then
- gPlayer1 := g_Player_Get(gLMSPID1);
- if (gPlayer2 = nil) and (gLMSPID2 > 0) then
- gPlayer2 := g_Player_Get(gLMSPID2);
+ if (gPlayer1 = nil) and (gSpectLatchPID1 > 0) and (UID = gSpectLatchPID1) then
+ begin
+ gPlayer1 := Pl;
+ gSpectLatchPID1 := 0;
+ end;
+ if (gPlayer2 = nil) and (gSpectLatchPID2 > 0) and (UID = gSpectLatchPID2) then
+ begin
+ gPlayer2 := Pl;
+ gSpectLatchPID2 := 0;
+ end;
end;
FGhost := M.ReadByte() <> 0;
FPhysics := M.ReadByte() <> 0;
if (OldFire <= 0) and (FFireTime > 0) then
g_Sound_PlayExAt('SOUND_IGNITE', Obj.X, Obj.Y);
Flam := M.ReadByte() <> 0;
+ FSpawnInvul := M.ReadLongInt();
if OldJet and not FJetpack then
JetpackOff
else if not OldJet and FJetpack then