diff --git a/src/game/g_netmsg.pas b/src/game/g_netmsg.pas
index 3701038e76d8f3063378d92364612cdbab798973..4ada39477e8bf9ee37c7a738029786fce98211a4 100644 (file)
--- a/src/game/g_netmsg.pas
+++ b/src/game/g_netmsg.pas
@@ -181,7 +181,7 @@ procedure MH_SEND_ItemSpawn(Quiet: Boolean; IID: Word; ID: Integer = NET_EVERYON
procedure MH_SEND_ItemDestroy(Quiet: Boolean; IID: Word; ID: Integer = NET_EVERYONE);
procedure MH_SEND_ItemPos(IID: Word; ID: Integer = NET_EVERYONE);
// PANEL
-procedure MH_SEND_PanelTexture(PGUID: Integer; AnimLoop: Byte; ID: Integer = NET_EVERYONE);
+procedure MH_SEND_PanelTexture(PGUID: Integer; 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);
implementation
-uses
- Math, ENet, e_input, e_graphics, e_log,
- g_textures, g_gfx, g_sound, g_console, g_basic, g_options, g_main,
- g_game, g_player, g_map, g_panel, g_items, g_weapons, g_phys, g_gui,
- g_language, g_monsters, g_netmaster, utils, wadreader, MAPDEF;
+ uses
+ {$IFDEF ENABLE_MENU}
+ g_gui,
+ {$ENDIF}
+ {$IFDEF ENABLE_GFX}
+ g_gfx,
+ {$ENDIF}
+ {$IFDEF ENABLE_GIBS}
+ g_gibs,
+ {$ENDIF}
+ {$IFDEF ENABLE_SHELLS}
+ g_shells,
+ {$ENDIF}
+ {$IFDEF ENABLE_CORPSES}
+ g_corpses,
+ {$ENDIF}
+ Math, ENet, e_input, e_log, g_base, g_basic,
+ g_sound, g_console, g_options,
+ g_game, g_player, g_map, g_panel, g_items, g_weapons, g_phys,
+ g_language, g_monsters, g_netmaster, utils, wadreader, MAPDEF
+ ;
const
NET_KEY_LEFT = 1 shl 0;
begin
g_Console_Add(_lc[I_NET_MSG] + _lc[I_NET_MSG_HOST_REJECT] +
_lc[I_NET_DISC_PROTOCOL]);
- enet_peer_disconnect(C^.Peer, NET_DISC_PROTOCOL);
+ g_Net_Host_Kick(C^.ID, NET_DISC_PROTOCOL);
end;
procedure MH_RECV_Chat(C: pTNetClient; var M: TMsg);
var
Ver, PName, Model, Pw: string;
R, G, B, T: Byte;
+ WeapSwitch: Byte;
+ TmpPrefArray: Array [WP_FIRST .. WP_LAST + 1] of Byte;
+ SwitchEmpty: Byte;
+ SkipF: Byte;
PID: Word;
Color: TRGB;
I: Integer;
G := M.ReadByte();
B := M.ReadByte();
T := M.ReadByte();
+ WeapSwitch := M.ReadByte();
+ for I := WP_FIRST to WP_LAST + 1 do
+ TmpPrefArray[I] := M.ReadByte();
+ SwitchEmpty := M.ReadByte();
+ SkipF := M.ReadByte();
except
Err := True;
end;
begin
g_Console_Add(_lc[I_NET_MSG] + _lc[I_NET_MSG_HOST_REJECT] +
_lc[I_NET_DISC_VERSION]);
- enet_peer_disconnect(C^.Peer, NET_DISC_VERSION);
+ g_Net_Host_Kick(C^.ID, NET_DISC_VERSION);
Exit;
end;
begin
g_Console_Add(_lc[I_NET_MSG] + _lc[I_NET_MSG_HOST_REJECT] +
_lc[I_NET_DISC_BAN]);
- enet_peer_disconnect(C^.Peer, NET_DISC_BAN);
+ g_Net_Host_Kick(C^.ID, NET_DISC_BAN);
end
else
begin
g_Console_Add(_lc[I_NET_MSG] + _lc[I_NET_MSG_HOST_REJECT] +
_lc[I_NET_DISC_BAN]);
- enet_peer_disconnect(C^.Peer, NET_DISC_TEMPBAN);
+ g_Net_Host_Kick(C^.ID, NET_DISC_TEMPBAN);
end;
Exit;
end;
begin
g_Console_Add(_lc[I_NET_MSG] + _lc[I_NET_MSG_HOST_REJECT] +
_lc[I_NET_DISC_PASSWORD]);
- enet_peer_disconnect(C^.Peer, NET_DISC_PASSWORD);
+ g_Net_Host_Kick(C^.ID, NET_DISC_PASSWORD);
Exit;
end;
with g_Player_Get(PID) do
begin
Name := PName;
+ WeapSwitchMode := WeapSwitch;
+ SetWeaponPrefs(TmpPrefArray);
+ SwitchToEmpty := SwitchEmpty;
+ SkipFist := SkipF;
+ if (g_Force_Model_Get() <> 0) then
+ SetModel(g_Forced_Model_GetName());
Reset(True);
end;
procedure MH_RECV_FullStateRequest(C: pTNetClient; var M: TMsg);
begin
//e_LogWritefln('*** client #%u (cid #%u) full state request', [C.ID, C.Player]);
+
+ if C^.FullUpdateSent then
+ begin
+ // FullStateRequest spam?
+ g_Net_Penalize(C, 'duplicate full state request');
+ exit;
+ end;
+
if gGameOn then
begin
MH_SEND_Everything((C^.State = NET_STATE_AUTH), C^.ID)
TmpModel: string;
TmpColor: TRGB;
TmpTeam: Byte;
+ TmpWeapSwitch: Byte;
+ TmpPrefArray: Array [WP_FIRST .. WP_LAST + 1] of Byte;
+ TmpSwEmpty: Byte;
+ TmpSkipF: Byte;
+ I: Integer;
Pl: TPlayer;
Err: Boolean;
begin
TmpColor.G := M.ReadByte();
TmpColor.B := M.ReadByte();
TmpTeam := M.ReadByte();
+ TmpWeapSwitch := M.ReadByte();
+ for I := WP_FIRST to WP_LAST + 1 do
+ TmpPrefArray[I] := M.ReadByte();
+ TmpSwEmpty := M.ReadByte();
+ TmpSkipF := M.ReadByte();
except
Err := True;
end;
Pl.Name := TmpName;
end;
- if TmpModel <> Pl.Model.Name then
+ if (g_Force_Model_Get() <> 0) then
+ TmpModel := g_Forced_Model_GetName();
+ if TmpModel <> Pl.Model.GetName() then
Pl.SetModel(TmpModel);
+ if (TmpWeapSwitch <> Pl.WeapSwitchMode) then
+ Pl.WeapSwitchMode := TmpWeapSwitch;
+
+ Pl.SetWeaponPrefs(TmpPrefArray);
+ if (TmpSwEmpty <> Pl.SwitchToEmpty) then
+ Pl.SwitchToEmpty := TmpSwEmpty;
+
+ if (TmpSkipF <> Pl.SkipFist) then
+ Pl.SkipFist := TmpSkipF;
+
MH_SEND_PlayerSettings(Pl.UID, TmpModel);
end;
@@ -855,17 +916,20 @@ procedure MH_SEND_Everything(CreatePlayers: Boolean {= False}; ID: Integer {= NE
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);
+ if (pan.CanChangeTexture) then MH_SEND_PanelTexture(pan.guid, ID);
end;
var
I: Integer;
begin
- if (ID >= 0) and (ID < length(NetClients)) then
- begin
- e_LogWritefln('*** client #%u (cid #%u) will get everything', [ID, NetClients[ID].Player]);
- MH_ProcessFirstSpawn(@NetClients[ID]);
- end;
+ if (ID < 0) or (ID >= Length(NetClients)) then
+ exit; // bogus client, this shouldn't happen
+
+ NetClients[ID].FullUpdateSent := True;
+
+ e_LogWritefln('*** client #%u (cid #%u) will get everything', [ID, NetClients[ID].Player]);
+
+ MH_ProcessFirstSpawn(@NetClients[ID]);
if gPlayers <> nil then
begin
NetOut.Write(g_ExtractFileName(gMapInfo.Map));
NetOut.Write(gWADHash);
NetOut.Write(gGameSettings.GameMode);
- NetOut.Write(gGameSettings.GoalLimit);
+ NetOut.Write(gGameSettings.ScoreLimit);
NetOut.Write(gGameSettings.TimeLimit);
NetOut.Write(gGameSettings.MaxLives);
NetOut.Write(gGameSettings.Options);
NetOut.Write(Byte(NET_MSG_SCORE));
if gGameSettings.GameMode in [GM_TDM, GM_CTF] then
begin
- NetOut.Write(gTeamStat[TEAM_RED].Goals);
- NetOut.Write(gTeamStat[TEAM_BLUE].Goals);
+ NetOut.Write(gTeamStat[TEAM_RED].Score);
+ NetOut.Write(gTeamStat[TEAM_BLUE].Score);
end
else
if gGameSettings.GameMode = GM_COOP then
begin
NetOut.Write(Byte(NET_MSG_GSET));
NetOut.Write(gGameSettings.GameMode);
- NetOut.Write(gGameSettings.GoalLimit);
+ NetOut.Write(gGameSettings.ScoreLimit);
NetOut.Write(gGameSettings.TimeLimit);
NetOut.Write(gGameSettings.MaxLives);
NetOut.Write(gGameSettings.Options);
NetOut.Write(PID);
NetOut.Write(Pl.Name);
if Mdl = '' then
- NetOut.Write(Pl.Model.Name)
+ NetOut.Write(Pl.Model.GetName())
else
NetOut.Write(Mdl);
NetOut.Write(Pl.FColor.R);
// PANEL
-procedure MH_SEND_PanelTexture(PGUID: Integer; AnimLoop: Byte; ID: Integer = NET_EVERYONE);
+procedure MH_SEND_PanelTexture(PGUID: Integer; ID: Integer = NET_EVERYONE);
var
TP: TPanel;
begin
TP := g_Map_PanelByGUID(PGUID);
if (TP = nil) then exit;
- with TP do
- begin
- NetOut.Write(Byte(NET_MSG_PTEX));
- NetOut.Write(LongWord(PGUID));
- NetOut.Write(FCurTexture);
- NetOut.Write(FCurFrame);
- NetOut.Write(FCurFrameCount);
- NetOut.Write(AnimLoop);
- end;
+ NetOut.Write(Byte(NET_MSG_PTEX));
+ NetOut.Write(LongWord(PGUID));
+ NetOut.Write(TP.FCurTexture);
+ NetOut.Write(TP.AnimTime);
+ NetOut.Write(TP.LastAnimLoop);
g_Net_Host_Send(ID, True, NET_CHAN_LARGEDATA);
end;
Kind: Byte;
X, Y: Integer;
Ang: SmallInt;
- Anim: TAnimation;
- ID: LongWord;
begin
if not gGameOn then Exit;
Kind := M.ReadByte();
case Kind of
NET_GFX_SPARK:
- g_GFX_Spark(X, Y, 2 + Random(2), Ang, 0, 0);
-
+ begin
+ {$IFDEF ENABLE_GFX}
+ g_GFX_Spark(X, Y, 2 + Random(2), Ang, 0, 0);
+ {$ENDIF}
+ end;
NET_GFX_TELE:
begin
- if g_Frames_Get(ID, 'FRAMES_TELEPORT') then
- begin
- Anim := TAnimation.Create(ID, False, 3);
- g_GFX_OnceAnim(X, Y, Anim);
- Anim.Free();
- end;
+ {$IFDEF ENABLE_GFX}
+ g_GFX_QueueEffect(R_GFX_TELEPORT_FAST, X, Y);
+ {$ENDIF}
if Ang = 1 then
g_Sound_PlayExAt('SOUND_GAME_TELEPORT', X, Y);
end;
-
NET_GFX_EXPLODE:
begin
- if g_Frames_Get(ID, 'FRAMES_EXPLODE_ROCKET') then
- begin
- Anim := TAnimation.Create(ID, False, 6);
- Anim.Blending := False;
- g_GFX_OnceAnim(X-64, Y-64, Anim);
- Anim.Free();
- end;
+ {$IFDEF ENABLE_GFX}
+ g_GFX_QueueEffect(R_GFX_EXPLODE_ROCKET, X - 64, Y - 64);
+ {$ENDIF}
if Ang = 1 then
g_Sound_PlayExAt('SOUND_WEAPON_EXPLODEROCKET', X, Y);
end;
-
NET_GFX_BFGEXPL:
begin
- if g_Frames_Get(ID, 'FRAMES_EXPLODE_BFG') then
- begin
- Anim := TAnimation.Create(ID, False, 6);
- Anim.Blending := False;
- g_GFX_OnceAnim(X-64, Y-64, Anim);
- Anim.Free();
- end;
+ {$IFDEF ENABLE_GFX}
+ g_GFX_QueueEffect(R_GFX_EXPLODE_BFG, X - 64, Y - 64);
+ {$ENDIF}
if Ang = 1 then
g_Sound_PlayExAt('SOUND_WEAPON_EXPLODEBFG', X, Y);
end;
-
NET_GFX_BFGHIT:
begin
- if g_Frames_Get(ID, 'FRAMES_BFGHIT') then
- begin
- Anim := TAnimation.Create(ID, False, 4);
- g_GFX_OnceAnim(X-32, Y-32, Anim);
- Anim.Free();
- end;
+ {$IFDEF ENABLE_GFX}
+ g_GFX_QueueEffect(R_GFX_BFG_HIT, X - 32, Y - 32);
+ {$ENDIF}
end;
-
NET_GFX_FIRE:
begin
- if g_Frames_Get(ID, 'FRAMES_FIRE') then
- begin
- Anim := TAnimation.Create(ID, False, 4);
- g_GFX_OnceAnim(X, Y, Anim);
- Anim.Free();
- end;
+ {$IFDEF ENABLE_GFX}
+ g_GFX_QueueEffect(R_GFX_FIRE, X, Y);
+ {$ENDIF}
if Ang = 1 then
g_Sound_PlayExAt('SOUND_FIRE', X, Y);
end;
-
NET_GFX_RESPAWN:
begin
- if g_Frames_Get(ID, 'FRAMES_ITEM_RESPAWN') then
- begin
- Anim := TAnimation.Create(ID, False, 4);
- g_GFX_OnceAnim(X, Y, Anim);
- Anim.Free();
- end;
+ {$IFDEF ENABLE_GFX}
+ g_GFX_QueueEffect(R_GFX_ITEM_RESPAWN, X, Y);
+ {$ENDIF}
if Ang = 1 then
g_Sound_PlayExAt('SOUND_ITEM_RESPAWNITEM', X, Y);
end;
-
NET_GFX_SHELL1:
- g_Player_CreateShell(X, Y, 0, -2, SHELL_BULLET);
-
+ begin
+ {$IFDEF ENABLE_SHELLS}
+ g_Shells_Create(X, Y, 0, -2, SHELL_BULLET);
+ {$ENDIF}
+ end;
NET_GFX_SHELL2:
- g_Player_CreateShell(X, Y, 0, -2, SHELL_SHELL);
-
+ begin
+ {$IFDEF ENABLE_SHELLS}
+ g_Shells_Create(X, Y, 0, -2, SHELL_SHELL);
+ {$ENDIF}
+ end;
NET_GFX_SHELL3:
begin
- g_Player_CreateShell(X, Y, 0, -2, SHELL_SHELL);
- g_Player_CreateShell(X, Y, 0, -2, SHELL_SHELL);
+ {$IFDEF ENABLE_SHELLS}
+ g_Shells_Create(X, Y, 0, -2, SHELL_SHELL);
+ g_Shells_Create(X, Y, 0, -2, SHELL_SHELL);
+ {$ENDIF}
end;
end;
end;
begin
if gGameSettings.GameMode in [GM_TDM, GM_CTF] then
begin
- gTeamStat[TEAM_RED].Goals := M.ReadSmallInt();
- gTeamStat[TEAM_BLUE].Goals := M.ReadSmallInt();
+ gTeamStat[TEAM_RED].Score := M.ReadSmallInt();
+ gTeamStat[TEAM_BLUE].Score := M.ReadSmallInt();
end
else
if gGameSettings.GameMode = GM_COOP then
NET_EV_LMS_START:
begin
- g_Player_RemoveAllCorpses;
+ {$IFDEF ENABLE_GIBS}
+ g_Gibs_RemoveAll;
+ {$ENDIF}
+ {$IFDEF ENALBE_SHELLS}
+ g_Shells_RemoveAll;
+ {$ENDIF}
+ {$IFDEF ENABLE_CORPSES}
+ g_Corpses_RemoveAll;
+ {$ENDIF}
gLMSRespawn := LMS_RESPAWN_NONE;
g_Game_Message(_lc[I_MESSAGE_LMS_START], 144);
end;
procedure MC_RECV_GameSettings(var M: TMsg);
begin
gGameSettings.GameMode := M.ReadByte();
- gGameSettings.GoalLimit := M.ReadWord();
+ gGameSettings.ScoreLimit := M.ReadWord();
gGameSettings.TimeLimit := M.ReadWord();
gGameSettings.MaxLives := M.ReadByte();
gGameSettings.Options := M.ReadLongWord();
if (PID <> NetPlrUID1) and (PID <> NetPlrUID2) then
begin
if (Pl <> nil) then Exit;
+ if (g_Force_Model_Get() <> 0) then
+ Model := g_Forced_Model_GetName();
DID := g_Player_Create(Model, Color, T, False);
with g_Player_Get(DID) do
begin
PID: Word;
Pl: TPlayer;
I, OldFire: Integer;
- checkWeapon: Boolean;
OldJet, Flam: Boolean;
NewTeam: Byte;
begin
NewTeam := M.ReadByte();
for I := WP_FIRST to WP_LAST do
- begin
- checkWeapon := (M.ReadByte() <> 0);
- if ( ((PID = gPlayer1.UID) or ( (gPlayer2 <> nil) and (PID = gPlayer2.UID))) and (I <> WEAPON_PISTOL) and (I <> WEAPON_KASTET ) and (gWeaponAutoswitch = True)) then
- begin
- if ( (checkWeapon = True) and (FWeapon[I] = False) ) then
- begin
- FWeapon[I] := True;
- if (PID = gPlayer1.UID) then gSelectWeapon[0, I] := True
- else gSelectWeapon[1, I] := True;
- end;
- end;
- FWeapon[I] := checkWeapon;
- end;
+ FWeapon[I] := (M.ReadByte() <> 0);
+
for I := A_BULLETS to A_HIGH do
FAmmo[I] := M.ReadWord();
var
TmpName: string;
TmpModel: string;
+ CheckModel: string;
TmpColor: TRGB;
TmpTeam: Byte;
Pl: TPlayer;
Pl.Name := TmpName;
end;
- if TmpModel <> Pl.Model.Name then
+ if (g_Force_Model_Get() <> 0) then
+ TmpModel := g_Forced_Model_GetName();
+ if TmpModel <> Pl.Model.GetName() then
Pl.SetModel(TmpModel);
end;
procedure MC_RECV_ItemSpawn(var M: TMsg);
var
ID: Word;
- AID: DWord;
X, Y, VX, VY: Integer;
T: Byte;
Quiet, Fall{, Resp}: Boolean;
- Anim: TAnimation;
it: PItem;
begin
if not gGameOn then Exit;
if not Quiet then
begin
g_Sound_PlayExAt('SOUND_ITEM_RESPAWNITEM', X, Y);
- if g_Frames_Get(AID, 'FRAMES_ITEM_RESPAWN') then
- begin
- Anim := TAnimation.Create(AID, False, 4);
- g_GFX_OnceAnim(X+(it.Obj.Rect.Width div 2)-16, Y+(it.Obj.Rect.Height div 2)-16, Anim);
- Anim.Free();
- end;
+ {$IFDEF ENABLE_GFX}
+ g_GFX_QueueEffect(R_GFX_ITEM_RESPAWN, X+(it.Obj.Rect.Width div 2)-16, Y+(it.Obj.Rect.Height div 2)-16);
+ {$ENDIF}
end;
end;
// PANEL
procedure MC_RECV_PanelTexture(var M: TMsg);
-var
- TP: TPanel;
- PGUID: Integer;
- Tex, Fr: Integer;
- Loop, Cnt: Byte;
+ var TP: TPanel; PGUID, Tex: Integer; AnimTime: LongWord; Loop: Byte;
begin
if not gGameOn then Exit;
PGUID := Integer(M.ReadLongWord());
Tex := M.ReadLongInt();
- Fr := M.ReadLongInt();
- Cnt := M.ReadByte();
+ AnimTime := M.ReadLongWord();
Loop := M.ReadByte();
TP := g_Map_PanelByGUID(PGUID);
begin
// switch texture
TP.SetTexture(Tex, Loop);
- TP.SetFrame(Fr, Cnt);
+ TP.SetFrame(AnimTime);
end;
end;
// CLIENT SEND
procedure MC_SEND_Info(Password: string);
+var i: Integer;
begin
NetOut.Clear();
NetOut.Write(gPlayer1Settings.Color.G);
NetOut.Write(gPlayer1Settings.Color.B);
NetOut.Write(gPlayer1Settings.Team);
+ NetOut.Write(gPlayer1Settings.WeaponSwitch);
+ for i := WP_FIRST to WP_LAST + 1 do
+ NetOut.Write(gPlayer1Settings.WeaponPreferences[i]);
+ NetOut.Write(gPlayer1Settings.SwitchToEmpty);
+ NetOut.Write(gPlayer1Settings.SkipFist);
g_Net_Client_Send(True, NET_CHAN_SERVICE);
end;
kByte := 0;
Predict := NetPredictSelf; // and (not NetGotKeys);
+{$IFDEF DISABLE_MENU}
+ if (not gConsoleShow) and (not gChatShow) then
+{$ELSE}
if (not gConsoleShow) and (not gChatShow) and (g_ActiveWindow = nil) then
+{$ENDIF}
begin
strafeDir := P1MoveButton shr 4;
P1MoveButton := P1MoveButton and $0F;
end;
procedure MC_SEND_PlayerSettings();
+var i: Integer;
begin
NetOut.Write(Byte(NET_MSG_PLRSET));
NetOut.Write(gPlayer1Settings.Name);
NetOut.Write(gPlayer1Settings.Color.G);
NetOut.Write(gPlayer1Settings.Color.B);
NetOut.Write(gPlayer1Settings.Team);
+ NetOut.Write(gPlayer1Settings.WeaponSwitch);
+ for i := WP_FIRST to WP_LAST + 1 do
+ NetOut.Write(gPlayer1Settings.WeaponPreferences[i]);
+ NetOut.Write(gPlayer1Settings.SwitchToEmpty);
+ NetOut.Write(gPlayer1Settings.SkipFist);
g_Net_Client_Send(True, NET_CHAN_IMPORTANT);
end;