diff --git a/src/d_net.cpp b/src/d_net.cpp index 27af76c8d..a26bd58af 100644 --- a/src/d_net.cpp +++ b/src/d_net.cpp @@ -2423,17 +2423,27 @@ void Net_DoCommand (int type, BYTE **stream, int player) break; case DEM_SETSLOT: + case DEM_SETSLOTPNUM: { + int pnum; + if (type == DEM_SETSLOTPNUM) + { + pnum = ReadByte(stream); + } + else + { + pnum = player; + } unsigned int slot = ReadByte(stream); int count = ReadByte(stream); if (slot < NUM_WEAPON_SLOTS) { - players[player].weapons.Slots[slot].Clear(); + players[pnum].weapons.Slots[slot].Clear(); } for(i = 0; i < count; ++i) { const PClass *wpn = Net_ReadWeapon(stream); - players[player].weapons.AddSlot(slot, wpn, player == consoleplayer); + players[pnum].weapons.AddSlot(slot, wpn, pnum == consoleplayer); } } break; @@ -2595,9 +2605,10 @@ void Net_SkipCommand (int type, BYTE **stream) break; case DEM_SETSLOT: + case DEM_SETSLOTPNUM: { - skip = 2; - for(int numweapons = (*stream)[1]; numweapons > 0; numweapons--) + skip = 2 + (type == DEM_SETSLOTPNUM); + for(int numweapons = (*stream)[skip-1]; numweapons > 0; numweapons--) { skip += 1 + ((*stream)[skip] >> 7); } diff --git a/src/d_protocol.h b/src/d_protocol.h index cee2fca6c..b3d72a4ca 100644 --- a/src/d_protocol.h +++ b/src/d_protocol.h @@ -163,6 +163,7 @@ enum EDemoCommand DEM_ADVANCEINTER, // 64 Advance intermission screen state DEM_RUNNAMEDSCRIPT, // 65 String: Script name, Byte: Arg count + Always flag; each arg is a 4-byte int DEM_REVERTCAMERA, // 66 + DEM_SETSLOTPNUM, // 67 Byte: player number, the rest is the same as DEM_SETSLOT }; // The following are implemented by cht_DoCheat in m_cheat.cpp diff --git a/src/g_shared/a_pickups.h b/src/g_shared/a_pickups.h index 10572c9ce..3d9a85389 100644 --- a/src/g_shared/a_pickups.h +++ b/src/g_shared/a_pickups.h @@ -76,7 +76,7 @@ struct FWeaponSlots void SetFromPlayer(const PClass *type); void StandardSetup(const PClass *type); void LocalSetup(const PClass *type); - void SendDifferences(const FWeaponSlots &other); + void SendDifferences(int playernum, const FWeaponSlots &other); int RestoreSlots (FConfigFile *config, const char *section); void PrintSettings(); diff --git a/src/g_shared/a_weapons.cpp b/src/g_shared/a_weapons.cpp index e6af6bcd2..f38207331 100644 --- a/src/g_shared/a_weapons.cpp +++ b/src/g_shared/a_weapons.cpp @@ -1264,7 +1264,7 @@ void FWeaponSlots::LocalSetup(const PClass *type) // //=========================================================================== -void FWeaponSlots::SendDifferences(const FWeaponSlots &other) +void FWeaponSlots::SendDifferences(int playernum, const FWeaponSlots &other) { int i, j; @@ -1285,7 +1285,15 @@ void FWeaponSlots::SendDifferences(const FWeaponSlots &other) } } // The slots differ. Send mine. - Net_WriteByte(DEM_SETSLOT); + if (playernum == consoleplayer) + { + Net_WriteByte(DEM_SETSLOT); + } + else + { + Net_WriteByte(DEM_SETSLOTPNUM); + Net_WriteByte(playernum); + } Net_WriteByte(i); Net_WriteByte(Slots[i].Size()); for (j = 0; j < Slots[i].Size(); ++j) diff --git a/src/p_user.cpp b/src/p_user.cpp index 1e5dd2bd9..0d7703c03 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -566,11 +566,21 @@ void APlayerPawn::SetupWeaponSlots() if (player != NULL && player->mo == this) { player->weapons.StandardSetup(GetClass()); - if (player - players == consoleplayer) - { // If we're the local player, then there's a bit more work to do. + // If we're the local player, then there's a bit more work to do. + // This also applies if we're a bot and this is the net arbitrator. + if (player - players == consoleplayer || + (player->isbot && consoleplayer == Net_Arbitrator)) + { FWeaponSlots local_slots(player->weapons); - local_slots.LocalSetup(GetClass()); - local_slots.SendDifferences(player->weapons); + if (player->isbot) + { // Bots only need weapons from KEYCONF, not INI modifications. + P_PlaybackKeyConfWeapons(&local_slots); + } + else + { + local_slots.LocalSetup(GetClass()); + } + local_slots.SendDifferences(int(player - players), player->weapons); } } }