X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_netmsg.pas;h=7cd1a7cc8ecd18dec4363db5ad4e55d1682206e8;hb=c97b4f7894fd3d797ecea3de574b58499c43aa85;hp=b170097d80296ec8ad3b7c7ed96e0bea1b54ccb4;hpb=8b7ced631d49879ce68703ac84389e3b4780c3db;p=d2df-sdl.git diff --git a/src/game/g_netmsg.pas b/src/game/g_netmsg.pas index b170097..7cd1a7c 100644 --- a/src/game/g_netmsg.pas +++ b/src/game/g_netmsg.pas @@ -16,6 +16,8 @@ {$INCLUDE ../shared/a_modes.inc} unit g_netmsg; +{.$DEFINE K8_XXX_WEAPON_DEBUG} + interface uses e_msg, g_net, g_triggers, Classes, SysUtils, md5; @@ -430,12 +432,13 @@ end; function MH_RECV_PlayerPos(C: pTNetClient; var M: TMsg): Word; var - Dir, i: Byte; - WeaponSelect: Word; + Dir{, i}: Byte; + //WeaponSelect: Word; PID: Word; kByte: Word; Pl: TPlayer; - GT: LongWord; + GT, wctr: LongWord; + newweapon: Byte; begin Result := 0; if not gGameOn then Exit; @@ -453,13 +456,25 @@ begin NetTime := GT; kByte := M.ReadWord(); Dir := M.ReadByte(); - WeaponSelect := M.ReadWord(); + wctr := M.ReadLongWord(); + newweapon := M.ReadByte(); + if (wctr > Pl.NetWeapCtr) then + begin + if (newweapon <> CurrWeap) then + begin +{$IFDEF K8_XXX_WEAPON_DEBUG} + writeln('HOST PLRPOS: got: currweap=', CurrWeap, '; curfrm=', gTime, '; netweap=', newweapon, '; oldweap=', CurrWeap); +{$ENDIF} + SetWeaponHost(newweapon); + end; + Pl.NetWeapCtr := wctr; + end; //e_WriteLog(Format('R:ws=%d', [WeaponSelect]), MSG_WARNING); if Direction <> TDirection(Dir) then JustTeleported := False; SetDirection(TDirection(Dir)); - ReleaseKeys; + ReleaseKeysNoWeapon(); if kByte = NET_KEY_CHAT then begin @@ -474,9 +489,10 @@ 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); + //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 15 do begin if (WeaponSelect and Word(1 shl i)) <> 0 then @@ -485,6 +501,7 @@ begin QueueWeaponSwitch(i); end; end; + *) end; // MH_SEND_PlayerPos(False, PID, C^.ID); @@ -995,7 +1012,9 @@ begin NetOut.Write(FPing); NetOut.Write(FLoss); if IsKeyPressed(KEY_CHAT) then - kByte := NET_KEY_CHAT + begin + kByte := NET_KEY_CHAT; + end else begin if IsKeyPressed(KEY_LEFT) then kByte := kByte or NET_KEY_LEFT; @@ -1008,6 +1027,10 @@ begin NetOut.Write(kByte); if Direction = TDirection.D_LEFT then NetOut.Write(Byte(0)) else NetOut.Write(Byte(1)); + + NetOut.Write(LongWord(Pl.NetWeapCtr)); + NetOut.Write(Byte(Pl.CurrWeap)); + NetOut.Write(GameX); NetOut.Write(GameY); NetOut.Write(GameVelX); @@ -1068,7 +1091,8 @@ begin NetOut.Write(Frags); NetOut.Write(Death); - NetOut.Write(CurrWeap); + NetOut.Write(LongWord(NetWeapCtr)); + NetOut.Write(Byte(CurrWeap)); // other flags ww := 0; @@ -2012,11 +2036,11 @@ end; function MC_RECV_PlayerPos(var M: TMsg): Word; var - GT: LongWord; + GT, wctr: LongWord; PID: Word; kByte: Word; Pl: TPlayer; - Dir: Byte; + Dir, weapon: Byte; TmpX, TmpY: Integer; begin Result := 0; @@ -2043,13 +2067,24 @@ begin kByte := M.ReadWord(); Dir := M.ReadByte(); + wctr := M.ReadLongWord(); + weapon := M.ReadByte(); + // `>=`, so server is still the authority + if (wctr >= Pl.NetWeapCtr) then + begin + Pl.CurrWeap := weapon; + Pl.NetWeapCtr := wctr; + end; + TmpX := M.ReadLongInt(); TmpY := M.ReadLongInt(); - ReleaseKeys; + ReleaseKeysNoWeapon; if (kByte = NET_KEY_CHAT) then - PressKey(KEY_CHAT, 10000) + begin + PressKey(KEY_CHAT, 10000); + end else begin if LongBool(kByte and NET_KEY_LEFT) then PressKey(KEY_LEFT, 10000); @@ -2079,6 +2114,8 @@ var OldJet: Boolean; NewTeam: Byte; ww: Word; + newweapon: Byte; + wctr: LongWord; begin PID := M.ReadWord(); Pl := g_Player_Get(PID); @@ -2125,7 +2162,17 @@ begin Frags := M.ReadLongInt(); Death := M.ReadLongInt(); - SetWeapon(M.ReadByte()); + wctr := M.ReadLongWord(); + newweapon := M.ReadByte(); +{$IFDEF K8_XXX_WEAPON_DEBUG} + writeln('CLIENT PLRSTATS: got: currweap=', CurrWeap, '; curfrm=', gTime, '; netweap=', newweapon, '; lastnwfrm=', NetForceWeapFIdx); +{$ENDIF} + // `>=`, so server is still the authority + if (wctr >= NetWeapCtr) then + begin + SetWeaponHost(newweapon); + NetWeapCtr := wctr; + end; // other flags ww := M.ReadByte(); @@ -2738,7 +2785,7 @@ var kByte: Word; Predict: Boolean; strafeDir: Byte; - WeaponSelect: Word = 0; + //WeaponSelect: Word = 0; I: Integer; begin if not gGameOn then Exit; @@ -2805,14 +2852,21 @@ begin 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) and gPlayer1.isWeaponSwitchKeyReleased(-1) then kByte := kByte or NET_KEY_NW; - if isKeyPressed(KeyPrevWeapon, KeyPrevWeapon2) and gPlayer1.isWeaponSwitchKeyReleased(-2) then kByte := kByte or NET_KEY_PW; + // do not send weapon switch keys, `MH_SEND_PlayerStats()` will send changed weapon anyway + if isKeyPressed(KeyNextWeapon, KeyNextWeapon2) and gPlayer1.isWeaponSwitchKeyReleased(-1) then gPlayer1.PressKey(KEY_NEXTWEAPON); //kByte := kByte or NET_KEY_NW; + if isKeyPressed(KeyPrevWeapon, KeyPrevWeapon2) and gPlayer1.isWeaponSwitchKeyReleased(-2) then gPlayer1.PressKey(KEY_PREVWEAPON); //kByte := kByte or NET_KEY_PW; for I := 0 to High(KeyWeapon) do begin if isKeyPressed(KeyWeapon[I], KeyWeapon2[I]) then begin + //writeln('keyweapon #', i, ' is pressed; released=', Integer(gPlayer1.isWeaponSwitchKeyReleased(i)), '; frm=', gPlayer1.NetForceWeapFIdx, '; gTime=', gTime); gPlayer1.weaponSwitchKeysStateChange(i, true); - if gPlayer1.isWeaponSwitchKeyReleased(i) then WeaponSelect := WeaponSelect or Word(1 shl I); + if gPlayer1.isWeaponSwitchKeyReleased(i) then + begin + //writeln('keyweapon #', i, ' is pressed; released=', Integer(gPlayer1.isWeaponSwitchKeyReleased(i)), '; frm=', gPlayer1.NetForceWeapFIdx, '; gTime=', gTime); + gPlayer1.QueueWeaponSwitch(i); // all choices are passed there, and god will take the best + //WeaponSelect := WeaponSelect or Word(1 shl I); + end; end else begin @@ -2832,7 +2886,13 @@ begin NetOut.Write(gTime); NetOut.Write(kByte); NetOut.Write(Byte(gPlayer1.Direction)); - NetOut.Write(WeaponSelect); + NetOut.Write(LongWord(gPlayer1.NetWeapCtr)); + NetOut.Write(Byte(gPlayer1.CurrWeap)); +{$IFDEF K8_XXX_WEAPON_DEBUG} + if (kByte and NET_KEY_FIRE) <> 0 then writeln('FIRE: CurrWeap=', gPlayer1.CurrWeap); +{$ENDIF} + //e_WriteLog(Format('S:nwp=%d; nwfidx=%d', [Integer(gPlayer1.NetForceWeap), Integer(gPlayer1.NetForceWeapFIdx)]), TMsgType.Warning); + //NetOut.Write(WeaponSelect); //e_WriteLog(Format('S:ws=%d', [WeaponSelect]), MSG_WARNING); g_Net_Client_Send(True, NET_CHAN_PLAYERPOS);