diff --git a/docs/rh-log.txt b/docs/rh-log.txt index d34caf346..50172f5d4 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,4 +1,8 @@ -March 11, 2009 (Changes by Graf Zahl) +March 11, 2009 +- Moved weapon slot initialization into APlayerPawn::PostBeginPlay() so that + they can be initialized when players respawn in multiplayer. + +March 11, 2009 (Changes by Graf Zahl) - Added a Check for the Vavoom namespace to the UDMF parser. Functionally it's 100% identical with ZDoom's own but needs to be checked for in case Vavoom compatible UDMF maps are released. diff --git a/src/d_player.h b/src/d_player.h index 709257860..ec3cab928 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -80,6 +80,7 @@ class APlayerPawn : public AActor public: virtual void Serialize (FArchive &arc); + virtual void PostBeginPlay(); virtual void Tick(); virtual void AddInventory (AInventory *item); virtual void RemoveInventory (AInventory *item); diff --git a/src/g_level.cpp b/src/g_level.cpp index 935b2de74..e368688f9 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -922,7 +922,6 @@ void G_DoLoadLevel (int position, bool autosave) } P_SetupLevel (level.mapname, position); - P_CompleteWeaponSetup(); AM_LevelInit(); diff --git a/src/g_shared/a_pickups.h b/src/g_shared/a_pickups.h index dd6067b74..023002dd6 100644 --- a/src/g_shared/a_pickups.h +++ b/src/g_shared/a_pickups.h @@ -16,13 +16,15 @@ class AWeapon; class FWeaponSlot { public: + FWeaponSlot() { Clear(); } + FWeaponSlot(const FWeaponSlot &other) { Weapons = other.Weapons; } FWeaponSlot &operator= (const FWeaponSlot &other) { Weapons = other.Weapons; return *this; } void Clear() { Weapons.Clear(); } bool AddWeapon (const char *type); bool AddWeapon (const PClass *type); void AddWeaponList (const char *list, bool clear); AWeapon *PickWeapon (player_t *player); - int Size () { return (int)Weapons.Size(); } + int Size () const { return (int)Weapons.Size(); } int LocateWeapon (const PClass *type); inline const PClass *GetWeapon (int index) const @@ -59,6 +61,9 @@ enum ESlotDef struct FWeaponSlots { + FWeaponSlots() { Clear(); } + FWeaponSlots(const FWeaponSlots &other); + FWeaponSlot Slots[NUM_WEAPON_SLOTS]; AWeapon *PickNextWeapon (player_t *player); @@ -69,7 +74,9 @@ struct FWeaponSlots ESlotDef AddDefaultWeapon (int slot, const PClass *type); void AddExtraWeapons(); void SetFromPlayer(const PClass *type); - void CompleteSetup(const PClass *type); + void StandardSetup(const PClass *type); + void LocalSetup(const PClass *type); + void SendDifferences(const FWeaponSlots &other); int RestoreSlots (FConfigFile *config, const char *section); void PrintSettings(); @@ -78,8 +85,7 @@ struct FWeaponSlots }; -void P_PlaybackKeyConfWeapons(); -void P_CompleteWeaponSetup(); +void P_PlaybackKeyConfWeapons(FWeaponSlots *slots); void Net_WriteWeapon(const PClass *type); const PClass *Net_ReadWeapon(BYTE **stream); diff --git a/src/g_shared/a_weapons.cpp b/src/g_shared/a_weapons.cpp index 6dc70c03c..ab6ed7382 100644 --- a/src/g_shared/a_weapons.cpp +++ b/src/g_shared/a_weapons.cpp @@ -28,7 +28,7 @@ END_POINTERS FString WeaponSection; TArray KeyConfWeapons; -bool PlayingKeyConf; +FWeaponSlots *PlayingKeyConf; TArray Weapons_ntoh; TMap Weapons_hton; @@ -642,8 +642,6 @@ bool AWeaponGiver::TryPickup(AActor *&toucher) /* Weapon slots ***********************************************************/ -FWeaponSlots LocalWeapons; - //=========================================================================== // // FWeaponSlot :: AddWeapon @@ -844,6 +842,20 @@ void FWeaponSlot::Sort() } } +//=========================================================================== +// +// FWeaponSlots - Copy Constructor +// +//=========================================================================== + +FWeaponSlots::FWeaponSlots(const FWeaponSlots &other) +{ + for (int i = 0; i < NUM_WEAPON_SLOTS; ++i) + { + Slots[i] = other.Slots[i]; + } +} + //=========================================================================== // // FWeaponSlots :: Clear @@ -1105,24 +1117,36 @@ void FWeaponSlots::AddExtraWeapons() //=========================================================================== // -// FWeaponSlots :: CompleteSetup +// FWeaponSlots :: StandardSetup // -// Sets up local weapon slots in this order: +// Setup weapons in this order: // 1. Use slots from player class. -// 2. Add extra weapons that specify their own slot. -// 3. Run KEYCONF weapon commands, affecting slots accordingly. -// 4. Read config slots, overriding current slots. If WeaponSection is set, +// 2. Add extra weapons that specify their own slots. +// +//=========================================================================== + +void FWeaponSlots::StandardSetup(const PClass *type) +{ + SetFromPlayer(type); + AddExtraWeapons(); +} + +//=========================================================================== +// +// FWeaponSlots :: LocalSetup +// +// Setup weapons in this order: +// 1. Run KEYCONF weapon commands, affecting slots accordingly. +// 2. Read config slots, overriding current slots. If WeaponSection is set, // then [..Weapons] is tried, followed by // [.Weapons] if that did not exist. If WeaponSection is // empty, then the slots are read from [.Weapons]. // //=========================================================================== -void FWeaponSlots::CompleteSetup(const PClass *type) +void FWeaponSlots::LocalSetup(const PClass *type) { - SetFromPlayer(type); - AddExtraWeapons(); - P_PlaybackKeyConfWeapons(); + P_PlaybackKeyConfWeapons(this); if (WeaponSection.IsNotEmpty()) { FString sectionclass(WeaponSection); @@ -1138,25 +1162,41 @@ void FWeaponSlots::CompleteSetup(const PClass *type) } } -void P_CompleteWeaponSetup() +//=========================================================================== +// +// FWeaponSlots :: SendDifferences +// +// Sends the weapon slots from this instance that differ from other's. +// +//=========================================================================== + +void FWeaponSlots::SendDifferences(const FWeaponSlots &other) { - if (players[consoleplayer].mo != NULL) + int i, j; + + for (i = 0; i < NUM_WEAPON_SLOTS; ++i) { - // Set up the weapon slots locally - LocalWeapons.CompleteSetup(players[consoleplayer].mo->GetClass()); - // Now transmit them across the network - for (int i = 0; i < NUM_WEAPON_SLOTS; ++i) + if (other.Slots[i].Size() == Slots[i].Size()) { - if (LocalWeapons.Slots[i].Size() > 0) + for (j = (int)Slots[i].Size(); j-- > 0; ) { - Net_WriteByte(DEM_SETSLOT); - Net_WriteByte(i); - Net_WriteByte(LocalWeapons.Slots[i].Size()); - for(int j = 0; j < LocalWeapons.Slots[i].Size(); j++) + if (other.Slots[i].GetWeapon(j) != Slots[i].GetWeapon(j)) { - Net_WriteWeapon(LocalWeapons.Slots[i].GetWeapon(j)); + break; } } + if (j < 0) + { // The two slots are the same. + continue; + } + } + // The slots differ. Send mine. + Net_WriteByte(DEM_SETSLOT); + Net_WriteByte(i); + Net_WriteByte(Slots[i].Size()); + for (j = 0; j < Slots[i].Size(); ++j) + { + Net_WriteWeapon(Slots[i].GetWeapon(j)); } } } @@ -1268,12 +1308,12 @@ CCMD (setslot) { KeyConfWeapons.Push(argv.args()); } - else if (PlayingKeyConf) + else if (PlayingKeyConf != NULL) { - LocalWeapons.Slots[slot].Clear(); + PlayingKeyConf->Slots[slot].Clear(); for (int i = 2; i < argv.argc(); ++i) { - LocalWeapons.Slots[slot].AddWeapon(argv[i]); + PlayingKeyConf->Slots[slot].AddWeapon(argv[i]); } } else @@ -1321,9 +1361,9 @@ CCMD (addslot) { KeyConfWeapons.Push(argv.args()); } - else if (PlayingKeyConf) + else if (PlayingKeyConf != NULL) { - LocalWeapons.AddSlot(int(slot), PClass::FindClass(argv[2]), false); + PlayingKeyConf->AddSlot(int(slot), PClass::FindClass(argv[2]), false); } else { @@ -1397,9 +1437,9 @@ CCMD (addslotdefault) { KeyConfWeapons.Push(argv.args()); } - else if (PlayingKeyConf) + else if (PlayingKeyConf != NULL) { - LocalWeapons.AddSlotDefault(int(slot), PClass::FindClass(argv[2]), false); + PlayingKeyConf->AddSlotDefault(int(slot), PClass::FindClass(argv[2]), false); } else { @@ -1417,15 +1457,15 @@ CCMD (addslotdefault) // //=========================================================================== -void P_PlaybackKeyConfWeapons() +void P_PlaybackKeyConfWeapons(FWeaponSlots *slots) { - PlayingKeyConf = true; + PlayingKeyConf = slots; for (unsigned int i = 0; i < KeyConfWeapons.Size(); ++i) { FString cmd(KeyConfWeapons[i]); AddCommandString(cmd.LockBuffer()); } - PlayingKeyConf = false; + PlayingKeyConf = NULL; } //=========================================================================== diff --git a/src/p_user.cpp b/src/p_user.cpp index 4721ff1fc..f54c6b5bc 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -491,7 +491,26 @@ void APlayerPawn::Tick() Super::Tick(); } +//=========================================================================== +// +// APlayerPawn :: PostBeginPlay +// +//=========================================================================== +void APlayerPawn::PostBeginPlay() +{ + // If we're not a voodoo doll, set up our weapons. + 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. + FWeaponSlots local_slots(player->weapons); + local_slots.LocalSetup(GetClass()); + local_slots.SendDifferences(player->weapons); + } + } +} //=========================================================================== //