diff --git a/src/game/g_netmsg.pas b/src/game/g_netmsg.pas
index 33d16522865e7e122b6bdbe9e7f9c76c90c43b74..0ad3894b0e0af831c28d1178f79b748d8fa7e852 100644 (file)
--- a/src/game/g_netmsg.pas
+++ b/src/game/g_netmsg.pas
-(* Copyright (C) DooM 2D:Forever Developers
+(* Copyright (C) Doom 2D: Forever Developers
*
* 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
NET_EV_LMS_DRAW = 16;
NET_EV_KILLCOMBO = 17;
NET_EV_PLAYER_TOUCH = 18;
+ NET_EV_SECRET = 19;
+ NET_EV_INTER_READY = 20;
NET_VE_STARTED = 1;
NET_VE_PASSED = 2;
NET_CHEAT_SUICIDE = 1;
NET_CHEAT_SPECTATE = 2;
+ NET_CHEAT_READY = 3;
NET_MAX_DIFFTIME = 5000 div 36;
@@ -168,8 +171,8 @@ procedure MH_SEND_PlayerSettings(PID: Word; Mdl: string = ''; ID: Integer = NET_
procedure MH_SEND_ItemSpawn(Quiet: Boolean; IID: Word; ID: Integer = NET_EVERYONE);
procedure MH_SEND_ItemDestroy(Quiet: Boolean; IID: Word; ID: Integer = NET_EVERYONE);
// PANEL
-procedure MH_SEND_PanelTexture(PType: Word; PGUID: Integer; AnimLoop: Byte; ID: Integer = NET_EVERYONE);
-procedure MH_SEND_PanelState(PType: Word; PGUID: Integer; ID: Integer = NET_EVERYONE);
+procedure MH_SEND_PanelTexture(PGUID: Integer; AnimLoop: Byte; ID: Integer = NET_EVERYONE);
+procedure MH_SEND_PanelState(PGUID: Integer; ID: Integer = NET_EVERYONE);
// MONSTER
procedure MH_SEND_MonsterSpawn(UID: Word; ID: Integer = NET_EVERYONE);
procedure MH_SEND_MonsterPos(UID: Word; ID: Integer = NET_EVERYONE);
g_Console_Add(Format(_lc[I_PLAYER_JOIN], [PName]), True);
e_WriteLog('NET: Client ' + PName + ' [' + IntToStr(C^.ID) +
- '] connected. Assigned player #' + IntToStr(PID) + '.', MSG_NOTIFY);
+ '] connected. Assigned player #' + IntToStr(PID) + '.', TMsgType.Notify);
MH_SEND_Info(C^.ID);
else
Pl.Spectate;
end;
+ NET_CHEAT_READY:
+ begin
+ if gState <> STATE_INTERCUSTOM then Exit;
+ Pl.FReady := not Pl.FReady;
+ if Pl.FReady then
+ begin
+ MH_SEND_GameEvent(NET_EV_INTER_READY, Pl.UID, 'Y');
+ Inc(gInterReadyCount);
+ end
+ else
+ begin
+ MH_SEND_GameEvent(NET_EV_INTER_READY, Pl.UID, 'N');
+ Dec(gInterReadyCount);
+ end;
+ end;
end;
end;
@@ -640,6 +658,13 @@ procedure MH_SEND_Everything(CreatePlayers: Boolean = False; ID: Integer = NET_E
MH_SEND_MonsterSpawn(mon.UID, ID);
end;
+ function sendPanelState (pan: TPanel): Boolean;
+ begin
+ result := false; // don't stop
+ MH_SEND_PanelState(pan.guid, ID); // anyway, to sync mplats
+ if (pan.CanChangeTexture) then MH_SEND_PanelTexture(pan.guid, pan.LastAnimLoop, ID);
+ end;
+
var
I: Integer;
begin
MH_SEND_PlayerStats(gPlayers[I].UID, ID);
if (gPlayers[I].Flag <> FLAG_NONE) and (gGameSettings.GameMode = GM_CTF) then
+ begin
MH_SEND_FlagEvent(FLAG_STATE_CAPTURED, gPlayers[I].Flag, gPlayers[I].UID, True, ID);
+ end;
end;
end;
end;
g_Items_ForEachAlive(sendItemRespawn, true); // backwards
g_Mons_ForEach(sendMonSpawn);
-
- if gWalls <> nil then
- for I := Low(gWalls) to High(gWalls) do
- if gWalls[I] <> nil then
- with gWalls[I] do
- begin
- if Door then
- MH_SEND_PanelState(PanelType, I, ID);
-
- if GetTextureCount > 1 then
- MH_SEND_PanelTexture(PanelType, I, LastAnimLoop, ID);
- end;
-
- if gLifts <> nil then
- for I := Low(gLifts) to High(gLifts) do
- if gLifts[I] <> nil then
- with gLifts[I] do
- MH_SEND_PanelState(PanelType, I, ID);
-
- if gRenderForegrounds <> nil then
- for I := Low(gRenderForegrounds) to High(gRenderForegrounds) do
- if gRenderForegrounds[I] <> nil then
- with gRenderForegrounds[I] do
- begin
- if (GetTextureCount > 1) then
- MH_SEND_PanelTexture(PanelType, I, LastAnimLoop, ID);
- if Moved then
- MH_SEND_PanelState(PanelType, I, ID);
- end;
- if gRenderBackgrounds <> nil then
- for I := Low(gRenderBackgrounds) to High(gRenderBackgrounds) do
- if gRenderBackgrounds[I] <> nil then
- with gRenderBackgrounds[I] do
- begin
- if (GetTextureCount > 1) then
- MH_SEND_PanelTexture(PanelType, I, LastAnimLoop, ID);
- if Moved then
- MH_SEND_PanelState(PanelType, I, ID);
- end;
- if gWater <> nil then
- for I := Low(gWater) to High(gWater) do
- if gWater[I] <> nil then
- with gWater[I] do
- if GetTextureCount > 1 then
- MH_SEND_PanelTexture(PanelType, I, LastAnimLoop, ID);
- if gAcid1 <> nil then
- for I := Low(gAcid1) to High(gAcid1) do
- if gAcid1[I] <> nil then
- with gAcid1[I] do
- if GetTextureCount > 1 then
- MH_SEND_PanelTexture(PanelType, I, LastAnimLoop, ID);
- if gAcid2 <> nil then
- for I := Low(gAcid2) to High(gAcid2) do
- if gAcid2[I] <> nil then
- with gAcid2[I] do
- if GetTextureCount > 1 then
- MH_SEND_PanelTexture(PanelType, I, LastAnimLoop, ID);
- if gSteps <> nil then
- for I := Low(gSteps) to High(gSteps) do
- if gSteps[I] <> nil then
- with gSteps[I] do
- if GetTextureCount > 1 then
- MH_SEND_PanelTexture(PanelType, I, LastAnimLoop, ID);
+ g_Map_ForEachPanel(sendPanelState);
if gTriggers <> nil then
+ begin
for I := Low(gTriggers) to High(gTriggers) do
+ begin
if gTriggers[I].TriggerType = TRIGGER_SOUND then
+ begin
MH_SEND_TriggerSound(gTriggers[I], ID);
+ end;
+ end;
+ end;
if Shots <> nil then
+ begin
for I := Low(Shots) to High(Shots) do
+ begin
if Shots[i].ShotType in [6, 7, 8] then
+ begin
MH_SEND_CreateShot(i, ID);
+ end;
+ end;
+ end;
MH_SEND_TriggerMusic(ID);
if gGameSettings.GameMode = GM_CTF then
begin
- if gFlags[FLAG_RED].State <> FLAG_STATE_CAPTURED then
- MH_SEND_FlagEvent(gFlags[FLAG_RED].State, FLAG_RED, 0, True, ID);
- if gFlags[FLAG_BLUE].State <> FLAG_STATE_CAPTURED then
- MH_SEND_FlagEvent(gFlags[FLAG_BLUE].State, FLAG_BLUE, 0, True, ID);
+ if gFlags[FLAG_RED].State <> FLAG_STATE_CAPTURED then MH_SEND_FlagEvent(gFlags[FLAG_RED].State, FLAG_RED, 0, True, ID);
+ if gFlags[FLAG_BLUE].State <> FLAG_STATE_CAPTURED then MH_SEND_FlagEvent(gFlags[FLAG_BLUE].State, FLAG_BLUE, 0, True, ID);
end;
if CreatePlayers and (ID >= 0) then NetClients[ID].State := NET_STATE_GAME;
if gLMSRespawn > LMS_RESPAWN_NONE then
+ begin
MH_SEND_GameEvent(NET_EV_LMS_WARMUP, (gLMSRespawnTime - gTime) div 1000, 'N', ID);
+ end;
end;
procedure MH_SEND_Info(ID: Byte);
if Mode = NET_CHAT_PLAYER then
begin
g_Console_Add(Txt, True);
- e_WriteLog('[Chat] ' + b_Text_Unformat(Txt), MSG_NOTIFY);
- g_Sound_PlayEx('SOUND_GAME_RADIO');
+ e_WriteLog('[Chat] ' + b_Text_Unformat(Txt), TMsgType.Notify);
+ g_Game_ChatSound(b_Text_Unformat(Txt));
end
else
if Mode = NET_CHAT_TEAM then
if (gPlayer1.Team = TEAM_RED) and (Team = TEAM_RED) then
begin
g_Console_Add(#18'[Team] '#2 + Txt, True);
- e_WriteLog('[Team Chat] ' + b_Text_Unformat(Txt), MSG_NOTIFY);
- g_Sound_PlayEx('SOUND_GAME_RADIO');
+ e_WriteLog('[Team Chat] ' + b_Text_Unformat(Txt), TMsgType.Notify);
+ g_Game_ChatSound(b_Text_Unformat(Txt));
end
else if (gPlayer1.Team = TEAM_BLUE) and (Team = TEAM_BLUE) then
begin
g_Console_Add(#20'[Team] '#2 + Txt, True);
- e_WriteLog('[Team Chat] ' + b_Text_Unformat(Txt), MSG_NOTIFY);
- g_Sound_PlayEx('SOUND_GAME_RADIO');
+ e_WriteLog('[Team Chat] ' + b_Text_Unformat(Txt), TMsgType.Notify);
+ g_Game_ChatSound(b_Text_Unformat(Txt));
end;
end;
end
begin
Name := g_Net_ClientName_ByID(ID);
g_Console_Add('-> ' + Name + ': ' + Txt, True);
- e_WriteLog('[Tell ' + Name + '] ' + b_Text_Unformat(Txt), MSG_NOTIFY);
- g_Sound_PlayEx('SOUND_GAME_RADIO');
+ e_WriteLog('[Tell ' + Name + '] ' + b_Text_Unformat(Txt), TMsgType.Notify);
+ g_Game_ChatSound(b_Text_Unformat(Txt), False);
end;
end;
NetOut.Write(EvStr);
NetOut.Write(Byte(gLastMap));
NetOut.Write(gTime);
- if (EvType = NET_EV_MAPSTART) and (Pos(':\', EvStr) > 0) then
+ if (EvType = NET_EV_MAPSTART) and isWadPath(EvStr) then
begin
NetOut.Write(Byte(1));
NetOut.Write(gWADHash);
end;
NetOut.Write(kByte);
- if Direction = D_LEFT then NetOut.Write(Byte(0)) else NetOut.Write(Byte(1));
+ if Direction = TDirection.D_LEFT then NetOut.Write(Byte(0)) else NetOut.Write(Byte(1));
NetOut.Write(GameX);
NetOut.Write(GameY);
NetOut.Write(GameVelX);
with P do
begin
- NetOut.Write(Byte(Live));
+ NetOut.Write(Byte(alive));
NetOut.Write(Byte(GodMode));
NetOut.Write(Health);
NetOut.Write(Armor);
NetOut.Write(Byte(FNoRespawn));
NetOut.Write(Byte(FJetpack));
NetOut.Write(FFireTime);
+ NetOut.Write(Byte(FFlaming));
end;
g_Net_Host_Send(ID, True, NET_CHAN_PLAYER);
procedure MH_SEND_ItemSpawn(Quiet: Boolean; IID: Word; ID: Integer = NET_EVERYONE);
var
it: PItem;
+ tt: Byte;
begin
it := g_Items_ByIdx(IID);
NetOut.Write(Byte(NET_MSG_ISPAWN));
NetOut.Write(IID);
NetOut.Write(Byte(Quiet));
- NetOut.Write(it.ItemType);
+ tt := it.ItemType;
+ if it.dropped then tt := tt or $80;
+ NetOut.Write(tt);
NetOut.Write(Byte(it.Fall));
NetOut.Write(Byte(it.Respawnable));
NetOut.Write(it.Obj.X);
// PANEL
-procedure MH_SEND_PanelTexture(PType: Word; PGUID: Integer; AnimLoop: Byte; ID: Integer = NET_EVERYONE);
+procedure MH_SEND_PanelTexture(PGUID: Integer; AnimLoop: Byte; ID: Integer = NET_EVERYONE);
var
TP: TPanel;
begin
TP := g_Map_PanelByGUID(PGUID);
if (TP = nil) then exit;
- {
- case PType of
- PANEL_WALL, PANEL_OPENDOOR, PANEL_CLOSEDOOR:
- TP := gWalls[PID];
- PANEL_FORE:
- TP := gRenderForegrounds[PID];
- PANEL_BACK:
- TP := gRenderBackgrounds[PID];
- PANEL_WATER:
- TP := gWater[PID];
- PANEL_ACID1:
- TP := gAcid1[PID];
- PANEL_ACID2:
- TP := gAcid2[PID];
- PANEL_STEP:
- TP := gSteps[PID];
- else
- Exit;
- end;
- }
with TP do
begin
NetOut.Write(Byte(NET_MSG_PTEX));
- NetOut.Write(PType);
NetOut.Write(LongWord(PGUID));
NetOut.Write(FCurTexture);
NetOut.Write(FCurFrame);
g_Net_Host_Send(ID, True, NET_CHAN_LARGEDATA);
end;
-procedure MH_SEND_PanelState(PType: Word; PGUID: Integer; ID: Integer = NET_EVERYONE);
+procedure MH_SEND_PanelState(PGUID: Integer; ID: Integer = NET_EVERYONE);
var
TP: TPanel;
+ mpflags: Byte = 0;
begin
TP := g_Map_PanelByGUID(PGUID);
if (TP = nil) then exit;
- case PType of
- {
- PANEL_WALL, PANEL_OPENDOOR, PANEL_CLOSEDOOR: TP := gWalls[PID];
- PANEL_LIFTUP, PANEL_LIFTDOWN, PANEL_LIFTLEFT, PANEL_LIFTRIGHT: TP := gLifts[PID];
- }
- PANEL_BACK:
- begin
- //TP := gRenderBackgrounds[PID];
- TP.Moved := True;
- end;
- PANEL_FORE:
- begin
- //TP := gRenderForegrounds[PID];
- TP.Moved := True;
- end;
- {
- else
- Exit;
- }
- end;
NetOut.Write(Byte(NET_MSG_PSTATE));
- NetOut.Write(PType);
NetOut.Write(LongWord(PGUID));
NetOut.Write(Byte(TP.Enabled));
NetOut.Write(TP.LiftType);
NetOut.Write(TP.X);
NetOut.Write(TP.Y);
+ NetOut.Write(Word(TP.Width));
+ NetOut.Write(Word(TP.Height));
+ // mplats
+ NetOut.Write(LongInt(TP.movingSpeedX));
+ NetOut.Write(LongInt(TP.movingSpeedY));
+ NetOut.Write(LongInt(TP.movingStartX));
+ NetOut.Write(LongInt(TP.movingStartY));
+ NetOut.Write(LongInt(TP.movingEndX));
+ NetOut.Write(LongInt(TP.movingEndY));
+ NetOut.Write(LongInt(TP.sizeSpeedX));
+ NetOut.Write(LongInt(TP.sizeSpeedY));
+ NetOut.Write(LongInt(TP.sizeEndX));
+ NetOut.Write(LongInt(TP.sizeEndY));
+ if TP.movingActive then mpflags := mpflags or 1;
+ if TP.moveOnce then mpflags := mpflags or 2;
+ NetOut.Write(Byte(mpflags));
g_Net_Host_Send(ID, True, NET_CHAN_LARGEDATA);
end;
if Mode = NET_CHAT_PLAYER then
begin
g_Console_Add(Txt, True);
- e_WriteLog('[Chat] ' + b_Text_Unformat(Txt), MSG_NOTIFY);
- g_Sound_PlayEx('SOUND_GAME_RADIO');
+ e_WriteLog('[Chat] ' + b_Text_Unformat(Txt), TMsgType.Notify);
+ g_Game_ChatSound(b_Text_Unformat(Txt));
end else
if (Mode = NET_CHAT_TEAM) and (gPlayer1 <> nil) then
begin
g_Console_Add(b_Text_Format('\r[Team] ') + Txt, True);
if gPlayer1.Team = TEAM_BLUE then
g_Console_Add(b_Text_Format('\b[Team] ') + Txt, True);
- e_WriteLog('[Team Chat] ' + b_Text_Unformat(Txt), MSG_NOTIFY);
- g_Sound_PlayEx('SOUND_GAME_RADIO');
+ e_WriteLog('[Team Chat] ' + b_Text_Unformat(Txt), TMsgType.Notify);
+ g_Game_ChatSound(b_Text_Unformat(Txt));
end;
end else
g_Console_Add(Txt, True);
gWADHash := EvHash;
if not g_Game_StartMap(EvStr, True) then
begin
- if Pos(':\', EvStr) = 0 then
+ if not isWadPath(EvStr) then
g_FatalError(Format(_lc[I_GAME_ERROR_MAP_LOAD], [gGameSettings.WAD + ':\' + EvStr]))
else
g_FatalError(Format(_lc[I_GAME_ERROR_MAP_LOAD], [EvStr]));
pl.Touch();
end;
+ NET_EV_SECRET:
+ begin
+ pl := g_Player_Get(EvNum);
+ if pl <> nil then
+ begin
+ g_Console_Add(Format(_lc[I_PLAYER_SECRET], [pl.Name]), True);
+ g_Sound_PlayEx('SOUND_GAME_SECRET');
+ end;
+ end;
+
+ NET_EV_INTER_READY:
+ begin
+ pl := g_Player_Get(EvNum);
+ if pl <> nil then pl.FReady := (EvStr = 'Y');
+ end;
end;
end;
PID: Word;
Pl: TPlayer;
EvType: Byte;
- Fl: Byte;
+ Fl, a: Byte;
Quiet: Boolean;
s, ts: string;
begin
s := _lc[I_PLAYER_FLAG_BLUE];
g_Game_Message(Format(_lc[I_MESSAGE_FLAG_RETURN], [AnsiUpperCase(s)]), 144);
+
+ if ((Pl = gPlayer1) or (Pl = gPlayer2)
+ or ((gPlayer1 <> nil) and (gPlayer1.Team = Pl.Team))
+ or ((gPlayer2 <> nil) and (gPlayer2.Team = Pl.Team))) then
+ a := 0
+ else
+ a := 1;
+
+ if not sound_ret_flag[a].IsPlaying() then
+ sound_ret_flag[a].Play();
end;
FLAG_STATE_CAPTURED:
g_Console_Add(Format(_lc[I_PLAYER_FLAG_GET], [Pl.Name, s]), True);
g_Game_Message(Format(_lc[I_MESSAGE_FLAG_GET], [AnsiUpperCase(s)]), 144);
+
+ if ((Pl = gPlayer1) or (Pl = gPlayer2)
+ or ((gPlayer1 <> nil) and (gPlayer1.Team = Pl.Team))
+ or ((gPlayer2 <> nil) and (gPlayer2.Team = Pl.Team))) then
+ a := 0
+ else
+ a := 1;
+
+ if not sound_get_flag[a].IsPlaying() then
+ sound_get_flag[a].Play();
end;
FLAG_STATE_DROPPED:
g_Console_Add(Format(_lc[I_PLAYER_FLAG_DROP], [Pl.Name, s]), True);
g_Game_Message(Format(_lc[I_MESSAGE_FLAG_DROP], [AnsiUpperCase(s)]), 144);
+
+ if ((Pl = gPlayer1) or (Pl = gPlayer2)
+ or ((gPlayer1 <> nil) and (gPlayer1.Team = Pl.Team))
+ or ((gPlayer2 <> nil) and (gPlayer2.Team = Pl.Team))) then
+ a := 0
+ else
+ a := 1;
+
+ if not sound_lost_flag[a].IsPlaying() then
+ sound_lost_flag[a].Play();
end;
FLAG_STATE_SCORED:
Insert('.', ts, Length(ts) + 1 - 3);
g_Console_Add(Format(_lc[I_PLAYER_FLAG_CAPTURE], [Pl.Name, s, ts]), True);
g_Game_Message(Format(_lc[I_MESSAGE_FLAG_CAPTURE], [AnsiUpperCase(s)]), 144);
+
+ if ((Pl = gPlayer1) or (Pl = gPlayer2)
+ or ((gPlayer1 <> nil) and (gPlayer1.Team = Pl.Team))
+ or ((gPlayer2 <> nil) and (gPlayer2.Team = Pl.Team))) then
+ a := 0
+ else
+ a := 1;
+
+ if not sound_cap_flag[a].IsPlaying() then
+ sound_cap_flag[a].Play();
end;
FLAG_STATE_RETURNED:
s := _lc[I_PLAYER_FLAG_BLUE];
g_Game_Message(Format(_lc[I_MESSAGE_FLAG_RETURN], [AnsiUpperCase(s)]), 144);
+
+ if ((Pl = gPlayer1) or (Pl = gPlayer2)
+ or ((gPlayer1 <> nil) and (gPlayer1.Team = Pl.Team))
+ or ((gPlayer2 <> nil) and (gPlayer2.Team = Pl.Team))) then
+ a := 0
+ else
+ a := 1;
+
+ if not sound_ret_flag[a].IsPlaying() then
+ sound_ret_flag[a].Play();
end;
end;
end;
end;
g_Console_Add(Format(_lc[I_PLAYER_JOIN], [PName]), True);
- e_WriteLog('NET: Player ' + PName + ' [' + IntToStr(PID) + '] added.', MSG_NOTIFY);
+ e_WriteLog('NET: Player ' + PName + ' [' + IntToStr(PID) + '] added.', TMsgType.Notify);
Result := PID;
end;
var
PID: Word;
Pl: TPlayer;
- I: Integer;
- OldJet: Boolean;
+ I, OldFire: Integer;
+ OldJet, Flam: Boolean;
NewTeam: Byte;
begin
PID := M.ReadWord();
with Pl do
begin
- Live := (M.ReadByte() <> 0);
+ alive := (M.ReadByte() <> 0);
GodMode := (M.ReadByte() <> 0);
Health := M.ReadLongInt();
Armor := M.ReadLongInt();
FNoRespawn := M.ReadByte() <> 0;
OldJet := FJetpack;
FJetpack := M.ReadByte() <> 0;
+ OldFire := FFireTime;
FFireTime := M.ReadLongInt();
+ if (OldFire <= 0) and (FFireTime > 0) then
+ g_Sound_PlayExAt('SOUND_IGNITE', Obj.X, Obj.Y);
+ Flam := M.ReadByte() <> 0;
if OldJet and not FJetpack then
JetpackOff
else if not OldJet and FJetpack then
JetpackOn;
+ if FFlaming and not Flam then
+ FlamerOff;
if Team <> NewTeam then
Pl.ChangeTeam(NewTeam);
end;
if Pl = nil then Exit;
g_Console_Add(Format(_lc[I_PLAYER_LEAVE], [Pl.Name]), True);
- e_WriteLog('NET: Player ' + Pl.Name + ' [' + IntToStr(PID) + '] removed.', MSG_NOTIFY);
+ e_WriteLog('NET: Player ' + Pl.Name + ' [' + IntToStr(PID) + '] removed.', TMsgType.Notify);
g_Player_Remove(PID);
SHID := M.ReadLongInt();
with Pl do
- if Live then NetFire(Weap, X, Y, AX, AY, SHID);
+ if alive then NetFire(Weap, X, Y, AX, AY, SHID);
end;
procedure MC_RECV_PlayerSettings(var M: TMsg);
VX := M.ReadLongInt();
VY := M.ReadLongInt();
- g_Items_Create(X, Y, T, Fall, False, False, ID);
+ g_Items_Create(X, Y, T and $7F, Fall, False, False, ID);
+ if ((T and $80) <> 0) then g_Items_SetDrop(ID);
it := g_Items_ByIdx(ID);
it.Obj.Vel.X := VX;
procedure MC_RECV_PanelTexture(var M: TMsg);
var
TP: TPanel;
- //PType: Word;
PGUID: Integer;
Tex, Fr: Integer;
Loop, Cnt: Byte;
begin
if not gGameOn then Exit;
- {PType :=} M.ReadWord();
+
PGUID := Integer(M.ReadLongWord());
Tex := M.ReadLongInt();
Fr := M.ReadLongInt();
Loop := M.ReadByte();
TP := g_Map_PanelByGUID(PGUID);
-
- {
- case PType of
- PANEL_WALL, PANEL_OPENDOOR, PANEL_CLOSEDOOR: if gWalls <> nil then TP := gWalls[ID];
- PANEL_FORE: if gRenderForegrounds <> nil then TP := gRenderForegrounds[ID];
- PANEL_BACK: if gRenderBackgrounds <> nil then TP := gRenderBackgrounds[ID];
- PANEL_WATER: if gWater <> nil then TP := gWater[ID];
- PANEL_ACID1: if gAcid1 <> nil then TP := gAcid1[ID];
- PANEL_ACID2: if gAcid2 <> nil then TP := gAcid2[ID];
- PANEL_STEP: if gSteps <> nil then TP := gSteps[ID];
- else Exit;
- end;
- }
-
- if TP <> nil then
+ if (TP <> nil) then
begin
- if Loop = 0 then
- begin
- // switch texture
- TP.SetTexture(Tex, Loop);
- TP.SetFrame(Fr, Cnt);
- end
- else
- begin
- // looped or non-looped animation
- TP.NextTexture(Loop);
- end;
+ // switch texture
+ TP.SetTexture(Tex, Loop);
+ TP.SetFrame(Fr, Cnt);
end;
end;
PGUID: Integer;
E: Boolean;
Lift: Byte;
- PType: Word;
- X, Y: Integer;
+ X, Y, W, H: Integer;
TP: TPanel;
+ speedX, speedY, startX, startY, endX, endY: Integer;
+ sizeSpX, sizeSpY, sizeEX, sizeEY: Integer;
+ mpflags: Byte;
begin
if not gGameOn then Exit;
- PType := M.ReadWord();
+
PGUID := Integer(M.ReadLongWord());
E := (M.ReadByte() <> 0);
Lift := M.ReadByte();
X := M.ReadLongInt();
Y := M.ReadLongInt();
+ W := M.ReadWord();
+ H := M.ReadWord();
+ // mplats
+ speedX := M.ReadLongInt();
+ speedY := M.ReadLongInt();
+ startX := M.ReadLongInt();
+ startY := M.ReadLongInt();
+ endX := M.ReadLongInt();
+ endY := M.ReadLongInt();
+ sizeSpX := M.ReadLongInt();
+ sizeSpY := M.ReadLongInt();
+ sizeEX := M.ReadLongInt();
+ sizeEY := M.ReadLongInt();
+ mpflags := M.ReadByte(); // bit0: TP.movingActive; bit1: TP.moveOnce
- case PType of
- PANEL_WALL, PANEL_OPENDOOR, PANEL_CLOSEDOOR:
- if E then g_Map_EnableWallGUID(PGUID) else g_Map_DisableWallGUID(PGUID);
-
- PANEL_LIFTUP, PANEL_LIFTDOWN, PANEL_LIFTLEFT, PANEL_LIFTRIGHT:
- g_Map_SetLiftGUID(PGUID, Lift);
-
- {PANEL_BACK,
- PANEL_FORE:}
- else
- begin
- TP := g_Map_PanelByGUID(PGUID);
- if (TP <> nil) then
- begin
- TP.X := X;
- TP.Y := Y;
- TP.positionChanged();
- end;
- //gRenderBackgrounds[ID].X := X;
- //gRenderBackgrounds[ID].Y := Y;
- end;
+ TP := g_Map_PanelByGUID(PGUID);
+ if (TP = nil) then exit;
- {
- PANEL_FORE:
- begin
- gRenderForegrounds[ID].X := X;
- gRenderForegrounds[ID].Y := Y;
- end;
- }
- end;
+ // update lifts state
+ if TP.isGLift then g_Map_SetLiftGUID(PGUID, Lift);
+
+ // update enabled/disabled state for all panels
+ if E then g_Map_EnableWallGUID(PGUID) else g_Map_DisableWallGUID(PGUID);
+
+ // update panel position, as it can be moved (mplat)
+ TP.X := X;
+ TP.Y := Y;
+ TP.Width := W;
+ TP.Height := H;
+ // update mplat state
+ TP.movingSpeedX := speedX;
+ TP.movingSpeedY := speedY;
+ TP.movingStartX := startX;
+ TP.movingStartY := startY;
+ TP.movingEndX := endX;
+ TP.movingEndY := endY;
+ TP.sizeSpeedX := sizeSpX;
+ TP.sizeSpeedY := sizeSpY;
+ TP.sizeEndX := sizeEX;
+ TP.sizeEndY := sizeEY;
+ TP.movingActive := ((mpflags and 1) <> 0);
+ TP.moveOnce := ((mpflags and 2) <> 0);
+ // notify panel of it's position/size change, so it can fix other internal structures
+ TP.positionChanged();
end;
// TRIGGERS
if gTriggers[I].ClientID = SID then
with gTriggers[I] do
begin
- if SPlaying then
+ if Sound <> nil then
begin
- if trigData.trigLocal then
- Sound.PlayVolumeAt(X+(Width div 2), Y+(Height div 2), trigData.trigVolume/255.0)
+ if SPlaying then
+ begin
+ if tgcLocal then
+ Sound.PlayVolumeAt(X+(Width div 2), Y+(Height div 2), tgcVolume/255.0)
+ else
+ Sound.PlayPanVolume((tgcPan-127.0)/128.0, tgcVolume/255.0);
+ Sound.SetPosition(SPos);
+ end
else
- Sound.PlayPanVolume((trigData.trigPan-127.0)/128.0, trigData.trigVolume/255.0);
- Sound.SetPosition(SPos);
- end
- else
- if Sound.IsPlaying then Sound.Stop;
+ if Sound.IsPlaying then Sound.Stop;
+ end;
SoundPlayCount := SCount;
end;
setPosition(X, Y); // this will call positionChanged();
GameVelX := VX;
GameVelY := VY;
- //positionChanged(); // this updates spatial accelerators
end;
end;
GameVelX := M.ReadLongInt();
GameVelY := M.ReadLongInt();
GameDirection := TDirection(M.ReadByte());
- //positionChanged(); // this updates spatial accelerators
end;
end;
procedure MC_RECV_MonsterState(var M: TMsg);
var
- ID: Integer;
+ ID, OldFire: Integer;
MState, MFAnm: Byte;
Mon: TMonster;
AnimRevert: Boolean;
MonsterAmmo := M.ReadLongInt();
MonsterPain := M.ReadLongInt();
AnimRevert := M.ReadByte() <> 0;
+ OldFire := FFireTime;
FFireTime := M.ReadLongInt();
+ if (OldFire <= 0) and (FFireTime > 0) then
+ g_Sound_PlayExAt('SOUND_IGNITE', Obj.X, Obj.Y);
RevertAnim(AnimRevert);
if MonsterState <> MState then
begin
- if (MState = MONSTATE_GO) and (MonsterState = MONSTATE_SLEEP) then
- WakeUpSound;
- if (MState = MONSTATE_DIE) then
- DieSound;
- if (MState = MONSTATE_PAIN) then
- MakeBloodSimple(Min(200, MonsterPain));
- if (MState = MONSTATE_ATTACK) then
- kick(nil);
- if (MState = MONSTATE_DEAD) then
- SetDeadAnim;
+ if (MState = MONSTATE_GO) and (MonsterState = MONSTATE_SLEEP) then WakeUpSound();
+ if (MState = MONSTATE_DIE) then DieSound();
+ if (MState = MONSTATE_PAIN) then MakeBloodSimple(Min(200, MonsterPain));
+ if (MState = MONSTATE_ATTACK) then kick(nil);
+ if (MState = MONSTATE_DEAD) then SetDeadAnim();
SetState(MState, MFAnm);
end;
g_Net_Client_Send(True, NET_CHAN_CHAT);
end;
-function isKeyPressed (key1: Word; key2: Word): Boolean;
-begin
- if (key1 <> 0) and e_KeyPressed(key1) then begin result := true; exit; end;
- if (key2 <> 0) and e_KeyPressed(key2) then begin result := true; exit; end;
- result := false;
-end;
-
procedure MC_SEND_PlayerPos();
var
kByte: Word;
Predict: Boolean;
strafeDir: Byte;
WeaponSelect: Word = 0;
- I: Integer;
+ i: Integer;
begin
if not gGameOn then Exit;
if gPlayers = nil then Exit;
begin
strafeDir := P1MoveButton shr 4;
P1MoveButton := P1MoveButton and $0F;
- with gGameControls.P1Control do
+
+ if gPlayerAction[0, ACTION_MOVELEFT] and (not gPlayerAction[0, ACTION_MOVERIGHT]) then
+ P1MoveButton := 1
+ else if (not gPlayerAction[0, ACTION_MOVELEFT]) and gPlayerAction[0, ACTION_MOVERIGHT] then
+ P1MoveButton := 2
+ else if (not gPlayerAction[0, ACTION_MOVELEFT]) and (not gPlayerAction[0, ACTION_MOVERIGHT]) then
+ P1MoveButton := 0;
+
+ // strafing
+ if gPlayerAction[0, ACTION_STRAFE] then
+ begin
+ // new strafe mechanics
+ if (strafeDir = 0) then
+ strafeDir := P1MoveButton; // start strafing
+ // now set direction according to strafe (reversed)
+ if (strafeDir = 2) then
+ gPlayer1.SetDirection(TDirection.D_LEFT)
+ else if (strafeDir = 1) then
+ gPlayer1.SetDirection(TDirection.D_RIGHT)
+ end
+ else
begin
- if isKeyPressed(KeyLeft, KeyLeft2) and (not isKeyPressed(KeyRight, KeyRight2)) then P1MoveButton := 1
- else if (not isKeyPressed(KeyLeft, KeyLeft2)) and isKeyPressed(KeyRight, KeyRight2) then P1MoveButton := 2
- else if (not isKeyPressed(KeyLeft, KeyLeft2)) and (not isKeyPressed(KeyRight, KeyRight2)) then P1MoveButton := 0;
+ strafeDir := 0; // not strafing anymore
+ if (P1MoveButton = 2) and gPlayerAction[0, ACTION_MOVELEFT] then
+ gPlayer1.SetDirection(TDirection.D_LEFT)
+ else if (P1MoveButton = 1) and gPlayerAction[0, ACTION_MOVERIGHT] then
+ gPlayer1.SetDirection(TDirection.D_RIGHT)
+ else if P1MoveButton <> 0 then
+ gPlayer1.SetDirection(TDirection(P1MoveButton-1));
+ end;
- // strafing
- if isKeyPressed(KeyStrafe, KeyStrafe2) then
- begin
- // new strafe mechanics
- if (strafeDir = 0) then strafeDir := P1MoveButton; // start strafing
- // now set direction according to strafe (reversed)
- if (strafeDir = 2) then gPlayer1.SetDirection(D_LEFT)
- else if (strafeDir = 1) then gPlayer1.SetDirection(D_RIGHT);
- end
- else
- begin
- if (P1MoveButton = 2) and isKeyPressed(KeyLeft, KeyLeft2) then gPlayer1.SetDirection(D_LEFT)
- else if (P1MoveButton = 1) and isKeyPressed(KeyRight, KeyRight2) then gPlayer1.SetDirection(D_RIGHT)
- else if P1MoveButton <> 0 then gPlayer1.SetDirection(TDirection(P1MoveButton-1));
- end;
+ gPlayer1.ReleaseKeys;
+ if P1MoveButton = 1 then
+ begin
+ kByte := kByte or NET_KEY_LEFT;
+ if Predict then gPlayer1.PressKey(KEY_LEFT, 10000);
+ end;
+ if P1MoveButton = 2 then
+ begin
+ kByte := kByte or NET_KEY_RIGHT;
+ if Predict then gPlayer1.PressKey(KEY_RIGHT, 10000);
+ end;
+ if gPlayerAction[0, ACTION_LOOKUP] then
+ begin
+ kByte := kByte or NET_KEY_UP;
+ gPlayer1.PressKey(KEY_UP, 10000);
+ end;
+ if gPlayerAction[0, ACTION_LOOKDOWN] then
+ begin
+ kByte := kByte or NET_KEY_DOWN;
+ gPlayer1.PressKey(KEY_DOWN, 10000);
+ end;
+ if gPlayerAction[0, ACTION_JUMP] then
+ begin
+ kByte := kByte or NET_KEY_JUMP;
+ // gPlayer1.PressKey(KEY_JUMP, 10000); // TODO: Make a prediction option
+ end;
+ if gPlayerAction[0, ACTION_ATTACK] then kByte := kByte or NET_KEY_FIRE;
+ if gPlayerAction[0, ACTION_ACTIVATE] then kByte := kByte or NET_KEY_OPEN;
+ if gPlayerAction[0, ACTION_WEAPNEXT] then kByte := kByte or NET_KEY_NW;
+ if gPlayerAction[0, ACTION_WEAPPREV] then kByte := kByte or NET_KEY_PW;
- gPlayer1.ReleaseKeys;
- if P1MoveButton = 1 then
- begin
- kByte := kByte or NET_KEY_LEFT;
- if Predict then gPlayer1.PressKey(KEY_LEFT, 10000);
- end;
- if P1MoveButton = 2 then
- begin
- kByte := kByte or NET_KEY_RIGHT;
- if Predict then gPlayer1.PressKey(KEY_RIGHT, 10000);
- end;
- if isKeyPressed(KeyUp, KeyUp2) then
- begin
- kByte := kByte or NET_KEY_UP;
- gPlayer1.PressKey(KEY_UP, 10000);
- end;
- if isKeyPressed(KeyDown, KeyDown2) then
- begin
- kByte := kByte or NET_KEY_DOWN;
- gPlayer1.PressKey(KEY_DOWN, 10000);
- end;
- if isKeyPressed(KeyJump, KeyJump2) then
+ gPlayerAction[0, ACTION_WEAPNEXT] := False; // HACK, remove after readyweaon&pendinweapon implementation
+ gPlayerAction[0, ACTION_WEAPPREV] := False; // HACK, remove after readyweaon&pendinweapon implementation
+
+ for i := WP_FIRST to WP_LAST do
+ begin
+ if gSelectWeapon[0, i] then
begin
- kByte := kByte or NET_KEY_JUMP;
- // gPlayer1.PressKey(KEY_JUMP, 10000); // TODO: Make a prediction option
- end;
- if isKeyPressed(KeyFire, KeyFire2) then kByte := kByte or NET_KEY_FIRE;
- if isKeyPressed(KeyOpen, KeyOpen2) then kByte := kByte or NET_KEY_OPEN;
- if isKeyPressed(KeyNextWeapon, KeyNextWeapon2) then kByte := kByte or NET_KEY_NW;
- if isKeyPressed(KeyPrevWeapon, KeyPrevWeapon2) then kByte := kByte or NET_KEY_PW;
- for I := 0 to High(KeyWeapon) do
- if isKeyPressed(KeyWeapon[I], KeyWeapon2[I]) then
- WeaponSelect := WeaponSelect or Word(1 shl I);
+ WeaponSelect := WeaponSelect or Word(1 shl i);
+ gSelectWeapon[0, i] := False
+ end
end;
+
// fix movebutton state
P1MoveButton := P1MoveButton or (strafeDir shl 4);
end
FileStream : TStream;
fname: string;
begin
- e_WriteLog(Format('NETWORK: looking for file "%s"', [FileName]), MSG_NOTIFY);
+ e_WriteLog(Format('NETWORK: looking for file "%s"', [FileName]), TMsgType.Notify);
fname := findDiskWad(FileName);
if length(fname) = 0 then
begin
- e_WriteLog(Format('NETWORK: file "%s" not found!', [FileName]), MSG_FATALERROR);
+ e_WriteLog(Format('NETWORK: file "%s" not found!', [FileName]), TMsgType.Fatal);
SetLength(Result, 0);
exit;
end;
- e_WriteLog(Format('NETWORK: found file "%s"', [fname]), MSG_NOTIFY);
+ e_WriteLog(Format('NETWORK: found file "%s"', [fname]), TMsgType.Notify);
Result := nil;
FileStream := openDiskFileRO(fname);
try
mapDataMsg: TMapDataMsg;
begin
e_WriteLog('NET: Received map request from ' +
- DecodeIPV4(C.Peer.address.host), MSG_NOTIFY);
+ DecodeIPV4(C^.Peer.address.host), TMsgType.Notify);
mapDataMsg := CreateMapDataMsg(MapsDir + gGameSettings.WAD, gExternalResources);
- peer := NetClients[C.ID].Peer;
+ peer := NetClients[C^.ID].Peer;
MapDataMsgToBytes(payload, mapDataMsg);
g_Net_SendData(payload, peer, True, NET_CHAN_DOWNLOAD);
begin
FileName := ExtractFileName(M.ReadString());
e_WriteLog('NET: Received res request: ' + FileName +
- ' from ' + DecodeIPV4(C.Peer.address.host), MSG_NOTIFY);
+ ' from ' + DecodeIPV4(C^.Peer.address.host), TMsgType.Notify);
if not IsValidFilePath(FileName) then
begin
- e_WriteLog('Invalid filename: ' + FileName, MSG_WARNING);
+ e_WriteLog('Invalid filename: ' + FileName, TMsgType.Warning);
exit;
end;
- peer := NetClients[C.ID].Peer;
+ peer := NetClients[C^.ID].Peer;
if gExternalResources.IndexOf(FileName) > -1 then
begin