X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_netmsg.pas;h=36c0aa15e5e293f5a64713e87706577d27149864;hb=d55f78661cd9bd77609beed2552d7dd6262ad65c;hp=235cbb1b280b1ebb1c821f508f1cd3fc2bcbdc5d;hpb=c8d7811d45c2d34a7e297613e50570f253a0d8e9;p=d2df-sdl.git diff --git a/src/game/g_netmsg.pas b/src/game/g_netmsg.pas index 235cbb1..36c0aa1 100644 --- a/src/game/g_netmsg.pas +++ b/src/game/g_netmsg.pas @@ -31,6 +31,7 @@ const NET_MSG_FLAG = 107; NET_MSG_REQFST = 108; NET_MSG_GSET = 109; + NET_MSG_FLAGPOS= 110; NET_MSG_PLR = 111; NET_MSG_PLRPOS = 112; @@ -44,6 +45,7 @@ const NET_MSG_ISPAWN = 121; NET_MSG_IDEL = 122; + NET_MSG_IPOS = 123; NET_MSG_MSPAWN = 131; NET_MSG_MPOS = 132; @@ -51,8 +53,8 @@ const NET_MSG_MSHOT = 134; NET_MSG_MDEL = 135; - NET_MSG_PSTATE = 141; - NET_MSG_PTEX = 142; + NET_MSG_PSTATE = 141; + NET_MSG_PTEX = 142; NET_MSG_TSOUND = 151; NET_MSG_TMUSIC = 152; @@ -112,6 +114,7 @@ const 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; @@ -128,6 +131,7 @@ const NET_CHEAT_SUICIDE = 1; NET_CHEAT_SPECTATE = 2; NET_CHEAT_READY = 3; + NET_CHEAT_DROPFLAG = 4; NET_MAX_DIFFTIME = 5000 div 36; @@ -160,6 +164,7 @@ procedure MH_SEND_GameStats(ID: Integer = NET_EVERYONE); procedure MH_SEND_CoopStats(ID: Integer = NET_EVERYONE); procedure MH_SEND_GameEvent(EvType: Byte; EvNum: Integer = 0; EvStr: string = 'N'; ID: Integer = NET_EVERYONE); procedure MH_SEND_FlagEvent(EvType: Byte; Flag: Byte; PID: Word; Quiet: Boolean = False; ID: Integer = NET_EVERYONE); +procedure MH_SEND_FlagPos(Flag: Byte; ID: Integer = NET_EVERYONE); procedure MH_SEND_GameSettings(ID: Integer = NET_EVERYONE); // PLAYER procedure MH_SEND_PlayerCreate(PID: Word; ID: Integer = NET_EVERYONE); @@ -173,6 +178,7 @@ procedure MH_SEND_PlayerSettings(PID: Word; Mdl: string = ''; ID: Integer = NET_ // ITEM procedure MH_SEND_ItemSpawn(Quiet: Boolean; IID: Word; ID: Integer = NET_EVERYONE); 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_PanelState(PGUID: Integer; ID: Integer = NET_EVERYONE); @@ -202,6 +208,7 @@ procedure MC_RECV_GameStats(var M: TMsg); procedure MC_RECV_CoopStats(var M: TMsg); procedure MC_RECV_GameEvent(var M: TMsg); procedure MC_RECV_FlagEvent(var M: TMsg); +procedure MC_RECV_FlagPos(var M: TMsg); procedure MC_RECV_GameSettings(var M: TMsg); // PLAYER function MC_RECV_PlayerCreate(var M: TMsg): Word; @@ -215,6 +222,7 @@ procedure MC_RECV_PlayerSettings(var M: TMsg); // ITEM procedure MC_RECV_ItemSpawn(var M: TMsg); procedure MC_RECV_ItemDestroy(var M: TMsg); +procedure MC_RECV_ItemPos(var M: TMsg); // PANEL procedure MC_RECV_PanelTexture(var M: TMsg); procedure MC_RECV_PanelState(var M: TMsg); @@ -281,17 +289,15 @@ uses g_language, g_monsters, g_netmaster, utils, wadreader, MAPDEF; const - NET_KEY_LEFT = 1; - NET_KEY_RIGHT = 2; - NET_KEY_UP = 4; - NET_KEY_DOWN = 8; - NET_KEY_JUMP = 16; - NET_KEY_FIRE = 32; - NET_KEY_OPEN = 64; - NET_KEY_NW = 256; - NET_KEY_PW = 512; - NET_KEY_CHAT = 2048; - NET_KEY_FORCEDIR = 4096; + NET_KEY_LEFT = 1 shl 0; + NET_KEY_RIGHT = 1 shl 1; + NET_KEY_UP = 1 shl 2; + NET_KEY_DOWN = 1 shl 3; + NET_KEY_JUMP = 1 shl 4; + NET_KEY_FIRE = 1 shl 5; + NET_KEY_OPEN = 1 shl 6; + NET_KEY_CHAT = 1 shl 7; + NET_KEY_FORCEDIR = 1 shl 8; //var //kBytePrev: Word = 0; @@ -429,37 +435,26 @@ begin 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 @@ -496,7 +491,18 @@ begin 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; @@ -518,6 +524,7 @@ end; function MH_RECV_PlayerPos(C: pTNetClient; var M: TMsg): Word; var Dir, i: Byte; + WeaponAct: Byte; WeaponSelect: Word; PID: Word; kByte: Word; @@ -540,6 +547,7 @@ begin NetTime := GT; kByte := M.ReadWord(); Dir := M.ReadByte(); + WeaponAct := M.ReadByte(); WeaponSelect := M.ReadWord(); //e_WriteLog(Format('R:ws=%d', [WeaponSelect]), MSG_WARNING); if Direction <> TDirection(Dir) then @@ -561,8 +569,15 @@ begin if LongBool(kByte and NET_KEY_JUMP) then PressKey(KEY_JUMP, 10000); if LongBool(kByte and NET_KEY_FIRE) then PressKey(KEY_FIRE, 10000); if LongBool(kByte and NET_KEY_OPEN) then PressKey(KEY_OPEN, 10000); - if LongBool(kByte and NET_KEY_NW) then PressKey(KEY_NEXTWEAPON, 10000); - if LongBool(kByte and NET_KEY_PW) then PressKey(KEY_PREVWEAPON, 10000); + + for i := 0 to 7 do + begin + if (WeaponAct and Byte(1 shl i)) <> 0 then + begin + //e_WriteLog(Format(' R:wn=%d', [i]), MSG_WARNING); + ProcessWeaponAction(i); + end; + end; for i := 0 to 15 do begin @@ -593,7 +608,12 @@ begin 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; @@ -612,6 +632,8 @@ begin Dec(gInterReadyCount); end; end; + NET_CHEAT_DROPFLAG: + Pl.TryDropFlag(); end; end; @@ -815,12 +837,6 @@ begin 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; @@ -1044,10 +1060,23 @@ begin NetOut.Write(gFlags[Flag].Obj.Y); NetOut.Write(gFlags[Flag].Obj.Vel.X); NetOut.Write(gFlags[Flag].Obj.Vel.Y); + NetOut.Write(Byte(gFlags[Flag].Direction)); g_Net_Host_Send(ID, True, NET_CHAN_IMPORTANT); end; +procedure MH_SEND_FlagPos(Flag: Byte; ID: Integer = NET_EVERYONE); +begin + NetOut.Write(Byte(NET_MSG_FLAGPOS)); + NetOut.Write(Flag); + NetOut.Write(gFlags[Flag].Obj.X); + NetOut.Write(gFlags[Flag].Obj.Y); + NetOut.Write(gFlags[Flag].Obj.Vel.X); + NetOut.Write(gFlags[Flag].Obj.Vel.Y); + + g_Net_Host_Send(ID, False, NET_CHAN_IMPORTANT); +end; + procedure MH_SEND_GameSettings(ID: Integer = NET_EVERYONE); begin NetOut.Write(Byte(NET_MSG_GSET)); @@ -1110,9 +1139,10 @@ begin if IsKeyPressed(KEY_UP) then kByte := kByte or NET_KEY_UP; if IsKeyPressed(KEY_DOWN) then kByte := kByte or NET_KEY_DOWN; if IsKeyPressed(KEY_JUMP) then kByte := kByte or NET_KEY_JUMP; - if JustTeleported then kByte := kByte or NET_KEY_FORCEDIR; end; + if JustTeleported then kByte := kByte or NET_KEY_FORCEDIR; + NetOut.Write(kByte); if Direction = TDirection.D_LEFT then NetOut.Write(Byte(0)) else NetOut.Write(Byte(1)); NetOut.Write(GameX); @@ -1286,6 +1316,22 @@ begin g_Net_Host_Send(ID, True, NET_CHAN_LARGEDATA); end; +procedure MH_SEND_ItemPos(IID: Word; ID: Integer = NET_EVERYONE); +var + it: PItem; +begin + it := g_Items_ByIdx(IID); + + NetOut.Write(Byte(NET_MSG_IPOS)); + NetOut.Write(IID); + NetOut.Write(it.Obj.X); + NetOut.Write(it.Obj.Y); + NetOut.Write(it.Obj.Vel.X); + NetOut.Write(it.Obj.Vel.Y); + + g_Net_Host_Send(ID, False, NET_CHAN_LARGEDATA); +end; + // PANEL procedure MH_SEND_PanelTexture(PGUID: Integer; AnimLoop: Byte; ID: Integer = NET_EVERYONE); @@ -1515,22 +1561,25 @@ begin if Mode <> NET_CHAT_SYSTEM then begin - if Mode = NET_CHAT_PLAYER then + if NetDeafLevel = 0 then begin - g_Console_Add(Txt, True); - 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 - if gPlayer1.Team = TEAM_RED then - 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), TMsgType.Notify); - g_Game_ChatSound(b_Text_Unformat(Txt)); + if Mode = NET_CHAT_PLAYER then + begin + g_Console_Add(Txt, True); + 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 + if gPlayer1.Team = TEAM_RED then + 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), TMsgType.Notify); + g_Game_ChatSound(b_Text_Unformat(Txt)); + end; end; - end else + end else if (NetDeafLevel < 2) then g_Console_Add(Txt, True); end; @@ -1777,6 +1826,7 @@ begin 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; @@ -1813,6 +1863,8 @@ begin 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; @@ -1838,10 +1890,13 @@ begin NET_EV_CHANGE_TEAM: begin - if EvNum = TEAM_RED then - g_Console_Add(Format(_lc[I_PLAYER_CHTEAM_RED], [EvStr]), True); - if EvNum = TEAM_BLUE then - g_Console_Add(Format(_lc[I_PLAYER_CHTEAM_BLUE], [EvStr]), True); + if NetDeafLevel < 2 then + begin + if EvNum = TEAM_RED then + g_Console_Add(Format(_lc[I_PLAYER_CHTEAM_RED], [EvStr]), True); + if EvNum = TEAM_BLUE then + g_Console_Add(Format(_lc[I_PLAYER_CHTEAM_BLUE], [EvStr]), True); + end; end; NET_EV_PLAYER_KICK: @@ -1857,13 +1912,24 @@ begin 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_BIGTEXT: - g_Game_Message(AnsiUpperCase(EvStr), Word(EvNum)); + if NetDeafLevel < 2 then g_Game_Message(AnsiUpperCase(EvStr), Word(EvNum)); NET_EV_SCORE: begin @@ -1943,6 +2009,7 @@ begin NET_EV_LMS_START: begin g_Player_RemoveAllCorpses; + gLMSRespawn := LMS_RESPAWN_NONE; g_Game_Message(_lc[I_MESSAGE_LMS_START], 144); end; @@ -1963,6 +2030,9 @@ begin 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); @@ -1991,6 +2061,18 @@ begin end; end; +procedure MC_RECV_FlagPos(var M: TMsg); +var + Fl: Byte; +begin + Fl := M.ReadByte(); + if Fl = FLAG_NONE then Exit; + gFlags[Fl].Obj.X := M.ReadLongInt(); + gFlags[Fl].Obj.Y := M.ReadLongInt(); + gFlags[Fl].Obj.Vel.X := M.ReadLongInt(); + gFlags[Fl].Obj.Vel.Y := M.ReadLongInt(); +end; + procedure MC_RECV_FlagEvent(var M: TMsg); var PID: Word; @@ -2014,6 +2096,7 @@ begin gFlags[Fl].Obj.Y := M.ReadLongInt(); gFlags[Fl].Obj.Vel.X := M.ReadLongInt(); gFlags[Fl].Obj.Vel.Y := M.ReadLongInt(); + gFlags[Fl].Direction := TDirection(M.ReadByte()); Pl := g_Player_Get(PID); if (Pl = nil) and @@ -2203,7 +2286,8 @@ begin end; end; - g_Console_Add(Format(_lc[I_PLAYER_JOIN], [PName]), True); + if NetDeafLevel < 3 then + g_Console_Add(Format(_lc[I_PLAYER_JOIN], [PName]), True); e_WriteLog('NET: Player ' + PName + ' [' + IntToStr(PID) + '] added.', TMsgType.Notify); Result := PID; end; @@ -2246,7 +2330,7 @@ begin ReleaseKeys; - if (kByte = NET_KEY_CHAT) then + if LongBool(kByte and NET_KEY_CHAT) then PressKey(KEY_CHAT, 10000) else begin @@ -2257,7 +2341,9 @@ begin if LongBool(kByte and NET_KEY_JUMP) then PressKey(KEY_JUMP, 10000); end; - if ((Pl <> gPlayer1) and (Pl <> gPlayer2)) or LongBool(kByte and NET_KEY_FORCEDIR) then + JustTeleported := LongBool(kByte and NET_KEY_FORCEDIR); + + if ((Pl <> gPlayer1) and (Pl <> gPlayer2)) or JustTeleported then SetDirection(TDirection(Dir)); GameVelX := M.ReadLongInt(); @@ -2326,23 +2412,29 @@ begin 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; @@ -2354,6 +2446,7 @@ begin 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 @@ -2427,7 +2520,8 @@ begin Result := 0; if Pl = nil then Exit; - g_Console_Add(Format(_lc[I_PLAYER_LEAVE], [Pl.Name]), True); + if NetDeafLevel < 3 then + g_Console_Add(Format(_lc[I_PLAYER_LEAVE], [Pl.Name]), True); e_WriteLog('NET: Player ' + Pl.Name + ' [' + IntToStr(PID) + '] removed.', TMsgType.Notify); g_Player_Remove(PID); @@ -2492,7 +2586,8 @@ begin if Pl.Name <> TmpName then begin - g_Console_Add(Format(_lc[I_PLAYER_NAME], [Pl.Name, TmpName]), True); + if NetDeafLevel < 3 then + g_Console_Add(Format(_lc[I_PLAYER_NAME], [Pl.Name, TmpName]), True); Pl.Name := TmpName; end; @@ -2558,6 +2653,31 @@ begin g_Items_Remove(ID); end; +procedure MC_RECV_ItemPos(var M: TMsg); +var + ID: Word; + X, Y, VX, VY: Integer; + it: PItem; +begin + if not gGameOn then Exit; + + ID := M.ReadWord(); + X := M.ReadLongInt(); + Y := M.ReadLongInt(); + VX := M.ReadLongInt(); + VY := M.ReadLongInt(); + + if g_Items_ValidId(ID) then + begin + it := g_Items_ByIdx(ID); + it.Obj.X := X; + it.Obj.Y := Y; + it.Obj.Vel.X := VX; + it.Obj.Vel.Y := VY; + it.positionChanged(); + end; +end; + // PANEL procedure MC_RECV_PanelTexture(var M: TMsg); @@ -2886,18 +3006,19 @@ begin Str1 := M.ReadString(); Str2 := M.ReadString(); - case EvID of - NET_VE_STARTED: - g_Console_Add(Format(_lc[I_MESSAGE_VOTE_STARTED], [Str1, Str2, Int1]), True); - NET_VE_PASSED: - g_Console_Add(Format(_lc[I_MESSAGE_VOTE_PASSED], [Str1]), True); - NET_VE_FAILED: - g_Console_Add(_lc[I_MESSAGE_VOTE_FAILED], True); - NET_VE_VOTE: - g_Console_Add(Format(_lc[I_MESSAGE_VOTE_VOTE], [Str1, Int1, Int2]), True); - NET_VE_INPROGRESS: - g_Console_Add(Format(_lc[I_MESSAGE_VOTE_INPROGRESS], [Str1]), True); - end; + if NetDeafLevel < 2 then + case EvID of + NET_VE_STARTED: + g_Console_Add(Format(_lc[I_MESSAGE_VOTE_STARTED], [Str1, Str2, Int1]), True); + NET_VE_PASSED: + g_Console_Add(Format(_lc[I_MESSAGE_VOTE_PASSED], [Str1]), True); + NET_VE_FAILED: + g_Console_Add(_lc[I_MESSAGE_VOTE_FAILED], True); + NET_VE_VOTE: + g_Console_Add(Format(_lc[I_MESSAGE_VOTE_VOTE], [Str1, Int1, Int2]), True); + NET_VE_INPROGRESS: + g_Console_Add(Format(_lc[I_MESSAGE_VOTE_INPROGRESS], [Str1]), True); + end; end; // CLIENT SEND @@ -2933,6 +3054,7 @@ var kByte: Word; Predict: Boolean; strafeDir: Byte; + WeaponAct: Byte = 0; WeaponSelect: Word = 0; i: Integer; begin @@ -3006,11 +3128,15 @@ begin 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; - 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_FACT to WP_LACT do + begin + if gWeaponAction[0, i] then + begin + WeaponAct := WeaponAct or Byte(1 shl i); + gWeaponAction[0, i] := False + end + end; for i := WP_FIRST to WP_LAST do begin @@ -3031,6 +3157,7 @@ begin NetOut.Write(gTime); NetOut.Write(kByte); NetOut.Write(Byte(gPlayer1.Direction)); + NetOut.Write(WeaponAct); NetOut.Write(WeaponSelect); //e_WriteLog(Format('S:ws=%d', [WeaponSelect]), MSG_WARNING); g_Net_Client_Send(True, NET_CHAN_PLAYERPOS);