diff --git a/src/g_hexen/a_clericholy.cpp b/src/g_hexen/a_clericholy.cpp index 01d13931cc..560c1d87c8 100644 --- a/src/g_hexen/a_clericholy.cpp +++ b/src/g_hexen/a_clericholy.cpp @@ -25,44 +25,6 @@ static FRandom pr_wraithvergedrop ("WraithvergeDrop"); void SpawnSpiritTail (AActor *spirit); //========================================================================== - -class AClericWeaponPiece : public AWeaponPiece -{ - DECLARE_CLASS (AClericWeaponPiece, AWeaponPiece) -protected: - bool TryPickup (AActor *&toucher); -}; - -IMPLEMENT_CLASS (AClericWeaponPiece) - -bool AClericWeaponPiece::TryPickup (AActor *&toucher) -{ - if (!toucher->IsKindOf (PClass::FindClass(NAME_MagePlayer)) && - !toucher->IsKindOf (PClass::FindClass(NAME_FighterPlayer))) - { - return Super::TryPickup(toucher); - } - else - { // Wrong class, but try to pick up for ammo - if (ShouldStay()) - { - // Can't pick up weapons for other classes in coop netplay - return false; - } - - AWeapon * Defaults=(AWeapon*)GetDefaultByType(WeaponClass); - - bool gaveSome = !!(toucher->GiveAmmo (Defaults->AmmoType1, Defaults->AmmoGive1) + - toucher->GiveAmmo (Defaults->AmmoType2, Defaults->AmmoGive2)); - - if (gaveSome) - { - GoAwayAndDie (); - } - return gaveSome; - } -} - // Cleric's Wraithverge (Holy Symbol?) -------------------------------------- class ACWeapWraithverge : public AClericWeapon diff --git a/src/g_hexen/a_fighterplayer.cpp b/src/g_hexen/a_fighterplayer.cpp index 0867a86e4b..ec1e1a827d 100644 --- a/src/g_hexen/a_fighterplayer.cpp +++ b/src/g_hexen/a_fighterplayer.cpp @@ -11,87 +11,10 @@ #include "thingdef/thingdef.h" */ -// Fighter Weapon Base Class ------------------------------------------------ - IMPLEMENT_CLASS (AFighterWeapon) IMPLEMENT_CLASS (AClericWeapon) IMPLEMENT_CLASS (AMageWeapon) -bool AFighterWeapon::TryPickup (AActor *&toucher) -{ - // The Doom and Hexen players are not excluded from pickup in case - // somebody wants to use these weapons with either of those games. - if (toucher->IsKindOf (PClass::FindClass(NAME_ClericPlayer)) || - toucher->IsKindOf (PClass::FindClass(NAME_MagePlayer))) - { // Wrong class, but try to pick up for mana - if (ShouldStay()) - { // Can't pick up weapons for other classes in coop netplay - return false; - } - - bool gaveSome = (NULL != AddAmmo (toucher, AmmoType1, AmmoGive1)); - gaveSome |= (NULL != AddAmmo (toucher, AmmoType2, AmmoGive2)); - if (gaveSome) - { - GoAwayAndDie (); - } - return gaveSome; - } - return Super::TryPickup (toucher); -} - -// Cleric Weapon Base Class ------------------------------------------------- - -bool AClericWeapon::TryPickup (AActor *&toucher) -{ - // The Doom and Hexen players are not excluded from pickup in case - // somebody wants to use these weapons with either of those games. - if (toucher->IsKindOf (PClass::FindClass(NAME_FighterPlayer)) || - toucher->IsKindOf (PClass::FindClass(NAME_MagePlayer))) - { // Wrong class, but try to pick up for mana - if (ShouldStay()) - { // Can't pick up weapons for other classes in coop netplay - return false; - } - - bool gaveSome = (NULL != AddAmmo (toucher, AmmoType1, AmmoGive1)); - gaveSome |= (NULL != AddAmmo (toucher, AmmoType2, AmmoGive2)); - if (gaveSome) - { - GoAwayAndDie (); - } - return gaveSome; - } - return Super::TryPickup (toucher); -} - -// Mage Weapon Base Class --------------------------------------------------- - -bool AMageWeapon::TryPickup (AActor *&toucher) -{ - // The Doom and Hexen players are not excluded from pickup in case - // somebody wants to use these weapons with either of those games. - if (toucher->IsKindOf (PClass::FindClass(NAME_FighterPlayer)) || - toucher->IsKindOf (PClass::FindClass(NAME_ClericPlayer))) - { // Wrong class, but try to pick up for mana - if (ShouldStay()) - { // Can't pick up weapons for other classes in coop netplay - return false; - } - - bool gaveSome = (NULL != AddAmmo (toucher, AmmoType1, AmmoGive1)); - gaveSome |= (NULL != AddAmmo (toucher, AmmoType2, AmmoGive2)); - if (gaveSome) - { - GoAwayAndDie (); - } - return gaveSome; - } - return Super::TryPickup (toucher); -} - - - static FRandom pr_fpatk ("FPunchAttack"); //============================================================================ diff --git a/src/g_hexen/a_fighterquietus.cpp b/src/g_hexen/a_fighterquietus.cpp index dc930a34f1..8bc27751c5 100644 --- a/src/g_hexen/a_fighterquietus.cpp +++ b/src/g_hexen/a_fighterquietus.cpp @@ -18,43 +18,6 @@ static FRandom pr_fswordflame ("FSwordFlame"); //========================================================================== -class AFighterWeaponPiece : public AWeaponPiece -{ - DECLARE_CLASS (AFighterWeaponPiece, AWeaponPiece) -protected: - bool TryPickup (AActor *&toucher); -}; - -IMPLEMENT_CLASS (AFighterWeaponPiece) - -bool AFighterWeaponPiece::TryPickup (AActor *&toucher) -{ - if (!toucher->IsKindOf (PClass::FindClass(NAME_ClericPlayer)) && - !toucher->IsKindOf (PClass::FindClass(NAME_MagePlayer))) - { - return Super::TryPickup(toucher); - } - else - { // Wrong class, but try to pick up for ammo - if (ShouldStay()) - { - // Can't pick up weapons for other classes in coop netplay - return false; - } - - AWeapon * Defaults=(AWeapon*)GetDefaultByType(WeaponClass); - - bool gaveSome = !!(toucher->GiveAmmo (Defaults->AmmoType1, Defaults->AmmoGive1) + - toucher->GiveAmmo (Defaults->AmmoType2, Defaults->AmmoGive2)); - - if (gaveSome) - { - GoAwayAndDie (); - } - return gaveSome; - } -} - //============================================================================ // // A_DropQuietusPieces diff --git a/src/g_hexen/a_hexenglobal.h b/src/g_hexen/a_hexenglobal.h index a20827774a..44ffc6d577 100644 --- a/src/g_hexen/a_hexenglobal.h +++ b/src/g_hexen/a_hexenglobal.h @@ -15,21 +15,18 @@ class AFighterWeapon : public AWeapon { DECLARE_CLASS (AFighterWeapon, AWeapon); public: - bool TryPickup (AActor *&toucher); }; class AClericWeapon : public AWeapon { DECLARE_CLASS (AClericWeapon, AWeapon); public: - bool TryPickup (AActor *&toucher); }; class AMageWeapon : public AWeapon { DECLARE_CLASS (AMageWeapon, AWeapon); public: - bool TryPickup (AActor *&toucher); }; #endif //__A_HEXENGLOBAL_H__ diff --git a/src/g_hexen/a_magestaff.cpp b/src/g_hexen/a_magestaff.cpp index 2316edde32..743a1b5f7f 100644 --- a/src/g_hexen/a_magestaff.cpp +++ b/src/g_hexen/a_magestaff.cpp @@ -23,44 +23,6 @@ static AActor *FrontBlockCheck (AActor *mo, int index, void *); static divline_t BlockCheckLine; //========================================================================== - -class AMageWeaponPiece : public AWeaponPiece -{ - DECLARE_CLASS (AMageWeaponPiece, AWeaponPiece) -protected: - bool TryPickup (AActor *&toucher); -}; - -IMPLEMENT_CLASS (AMageWeaponPiece) - -bool AMageWeaponPiece::TryPickup (AActor *&toucher) -{ - if (!toucher->IsKindOf (PClass::FindClass(NAME_ClericPlayer)) && - !toucher->IsKindOf (PClass::FindClass(NAME_FighterPlayer))) - { - return Super::TryPickup(toucher); - } - else - { // Wrong class, but try to pick up for ammo - if (ShouldStay()) - { - // Can't pick up weapons for other classes in coop netplay - return false; - } - - AWeapon * Defaults=(AWeapon*)GetDefaultByType(WeaponClass); - - bool gaveSome = !!(toucher->GiveAmmo (Defaults->AmmoType1, Defaults->AmmoGive1) + - toucher->GiveAmmo (Defaults->AmmoType2, Defaults->AmmoGive2)); - - if (gaveSome) - { - GoAwayAndDie (); - } - return gaveSome; - } -} - // The Mages's Staff (Bloodscourge) ----------------------------------------- class AMWeapBloodscourge : public AMageWeapon diff --git a/src/g_shared/a_pickups.cpp b/src/g_shared/a_pickups.cpp index 207c35cec7..7075aeb872 100644 --- a/src/g_shared/a_pickups.cpp +++ b/src/g_shared/a_pickups.cpp @@ -1266,13 +1266,29 @@ bool AInventory::TryPickup (AActor *&toucher) //=========================================================================== // -// AInventory :: TryPickup +// AInventory :: TryPickupRestricted +// +//=========================================================================== + +bool AInventory::TryPickupRestricted (AActor *&toucher) +{ + return false; +} + +//=========================================================================== +// +// AInventory :: CallTryPickup // //=========================================================================== bool AInventory::CallTryPickup (AActor *toucher, AActor **toucher_return) { - bool res = TryPickup(toucher); + bool res; + if (CanPickup(toucher)) + res = TryPickup(toucher); + else + res = TryPickupRestricted(toucher); // let an item decide for itself how it will handle this + // Morph items can change the toucher so we need an option to return this info. if (toucher_return != NULL) *toucher_return = toucher; @@ -1288,6 +1304,40 @@ bool AInventory::CallTryPickup (AActor *toucher, AActor **toucher_return) } +//=========================================================================== +// +// AInventory :: CanPickup +// +//=========================================================================== + +bool AInventory::CanPickup (AActor *toucher) +{ + if (!toucher) + return false; + + FActorInfo *ai = GetClass()->ActorInfo; + // Is the item restricted to certain player classes? + if (ai->RestrictedToPlayerClass.Size() != 0) + { + for (unsigned i = 0; i < ai->RestrictedToPlayerClass.Size(); ++i) + { + if (toucher->IsKindOf(ai->RestrictedToPlayerClass[i])) + return true; + } + return false; + } + // Or is it forbidden to certain other classes? + else + { + for (unsigned i = 0; i < ai->ForbiddenToPlayerClass.Size(); ++i) + { + if (toucher->IsKindOf(ai->ForbiddenToPlayerClass[i])) + return false; + } + } + return true; +} + //=========================================================================== // // CCMD printinv diff --git a/src/g_shared/a_pickups.h b/src/g_shared/a_pickups.h index efc7a8c378..10572c9ce7 100644 --- a/src/g_shared/a_pickups.h +++ b/src/g_shared/a_pickups.h @@ -198,6 +198,8 @@ public: protected: virtual bool TryPickup (AActor *&toucher); + virtual bool TryPickupRestricted (AActor *&toucher); + bool CanPickup(AActor * toucher); void GiveQuest(AActor * toucher); private: @@ -277,6 +279,7 @@ public: virtual AInventory *CreateCopy (AActor *other); virtual AInventory *CreateTossable (); virtual bool TryPickup (AActor *&toucher); + virtual bool TryPickupRestricted (AActor *&toucher); virtual bool PickupForAmmo (AWeapon *ownedWeapon); virtual bool Use (bool pickup); virtual void Destroy(); diff --git a/src/g_shared/a_weaponpiece.cpp b/src/g_shared/a_weaponpiece.cpp index 4d4729e37f..a73b2511cc 100644 --- a/src/g_shared/a_weaponpiece.cpp +++ b/src/g_shared/a_weaponpiece.cpp @@ -23,6 +23,34 @@ void AWeaponPiece::Serialize (FArchive &arc) arc << WeaponClass << FullWeapon << PieceValue; } +//========================================================================== +// +// TryPickupWeaponPiece +// +//========================================================================== + +bool AWeaponPiece::TryPickupRestricted (AActor *&toucher) +{ + // Wrong class, but try to pick up for ammo + if (ShouldStay()) + { + // Can't pick up weapons for other classes in coop netplay + return false; + } + + AWeapon * Defaults=(AWeapon*)GetDefaultByType(WeaponClass); + + bool gaveSome = !!(toucher->GiveAmmo (Defaults->AmmoType1, Defaults->AmmoGive1) + + toucher->GiveAmmo (Defaults->AmmoType2, Defaults->AmmoGive2)); + + if (gaveSome) + { + GoAwayAndDie (); + } + return gaveSome; +} + + //========================================================================== // // TryPickupWeaponPiece diff --git a/src/g_shared/a_weaponpiece.h b/src/g_shared/a_weaponpiece.h index b59c77f6e4..c07f56f24e 100644 --- a/src/g_shared/a_weaponpiece.h +++ b/src/g_shared/a_weaponpiece.h @@ -8,6 +8,7 @@ protected: public: void Serialize (FArchive &arc); bool TryPickup (AActor *&toucher); + bool TryPickupRestricted (AActor *&toucher); bool ShouldStay (); virtual const char *PickupMessage (); virtual void PlayPickupSound (AActor *toucher); diff --git a/src/g_shared/a_weapons.cpp b/src/g_shared/a_weapons.cpp index 0687568693..3095ecbe04 100644 --- a/src/g_shared/a_weapons.cpp +++ b/src/g_shared/a_weapons.cpp @@ -72,6 +72,30 @@ void AWeapon::Serialize (FArchive &arc) // //=========================================================================== +bool AWeapon::TryPickupRestricted (AActor *&toucher) +{ + // Wrong class, but try to pick up for ammo + if (ShouldStay()) + { // Can't pick up weapons for other classes in coop netplay + return false; + } + + bool gaveSome = (NULL != AddAmmo (toucher, AmmoType1, AmmoGive1)); + gaveSome |= (NULL != AddAmmo (toucher, AmmoType2, AmmoGive2)); + if (gaveSome) + { + GoAwayAndDie (); + } + return gaveSome; +} + + +//=========================================================================== +// +// AWeapon :: TryPickup +// +//=========================================================================== + bool AWeapon::TryPickup (AActor *&toucher) { FState * ReadyState = FindState(NAME_Ready); diff --git a/src/info.h b/src/info.h index 0ac7a0feda..39d73f4a70 100644 --- a/src/info.h +++ b/src/info.h @@ -211,6 +211,8 @@ struct FActorInfo PainFlashList *PainFlashes; FPlayerColorSetMap *ColorSets; TArray VisibleToPlayerClass; + TArray RestrictedToPlayerClass; + TArray ForbiddenToPlayerClass; }; class FDoomEdMap diff --git a/src/thingdef/thingdef.cpp b/src/thingdef/thingdef.cpp index ea067ae88f..aba84b265d 100644 --- a/src/thingdef/thingdef.cpp +++ b/src/thingdef/thingdef.cpp @@ -146,6 +146,11 @@ FActorInfo *CreateNewActor(const FScriptPosition &sc, FName typeName, FName pare info = ti->ActorInfo; } + // Copy class lists from parent + info->ForbiddenToPlayerClass = parent->ActorInfo->ForbiddenToPlayerClass; + info->RestrictedToPlayerClass = parent->ActorInfo->RestrictedToPlayerClass; + info->VisibleToPlayerClass = parent->ActorInfo->VisibleToPlayerClass; + if (parent->ActorInfo->DamageFactors != NULL) { // copy damage factors from parent diff --git a/src/thingdef/thingdef_properties.cpp b/src/thingdef/thingdef_properties.cpp index 3cb22e778c..0a3a6c9f37 100644 --- a/src/thingdef/thingdef_properties.cpp +++ b/src/thingdef/thingdef_properties.cpp @@ -1248,10 +1248,12 @@ DEFINE_PROPERTY(visibletoteam, I, Actor) //========================================================================== DEFINE_PROPERTY(visibletoplayerclass, S_s, Actor) { + info->VisibleToPlayerClass.Clear(); for(int i = 0;i < PROP_PARM_COUNT;++i) { PROP_STRING_PARM(n, i); - info->VisibleToPlayerClass.Push(FindClassTentative(n, "PlayerPawn")); + if (*n != 0) + info->VisibleToPlayerClass.Push(FindClassTentative(n, "PlayerPawn")); } } @@ -1261,6 +1263,34 @@ DEFINE_PROPERTY(visibletoplayerclass, S_s, Actor) // //========================================================================== +//========================================================================== +// +//========================================================================== +DEFINE_CLASS_PROPERTY(restrictedto, S_s, Inventory) +{ + info->RestrictedToPlayerClass.Clear(); + for(int i = 0;i < PROP_PARM_COUNT;++i) + { + PROP_STRING_PARM(n, i); + if (*n != 0) + info->RestrictedToPlayerClass.Push(FindClassTentative(n, "PlayerPawn")); + } +} + +//========================================================================== +// +//========================================================================== +DEFINE_CLASS_PROPERTY(forbiddento, S_s, Inventory) +{ + info->ForbiddenToPlayerClass.Clear(); + for(int i = 0;i < PROP_PARM_COUNT;++i) + { + PROP_STRING_PARM(n, i); + if (*n != 0) + info->ForbiddenToPlayerClass.Push(FindClassTentative(n, "PlayerPawn")); + } +} + //========================================================================== // //========================================================================== diff --git a/wadsrc/static/actors/hexen/baseweapons.txt b/wadsrc/static/actors/hexen/baseweapons.txt index 08bd2881f2..5348e437d5 100644 --- a/wadsrc/static/actors/hexen/baseweapons.txt +++ b/wadsrc/static/actors/hexen/baseweapons.txt @@ -1,14 +1,20 @@ +// The Doom and Heretic players are not excluded from pickup in case +// somebody wants to use these weapons with either of those games. + ACTOR FighterWeapon : Weapon native { Weapon.Kickback 150 + Inventory.ForbiddenTo ClericPlayer, MagePlayer } ACTOR ClericWeapon : Weapon native { Weapon.Kickback 150 + Inventory.ForbiddenTo FighterPlayer, MagePlayer } ACTOR MageWeapon : Weapon native { Weapon.Kickback 150 + Inventory.ForbiddenTo FighterPlayer, ClericPlayer } diff --git a/wadsrc/static/actors/hexen/clericholy.txt b/wadsrc/static/actors/hexen/clericholy.txt index 15673ab1b5..e97be8b178 100644 --- a/wadsrc/static/actors/hexen/clericholy.txt +++ b/wadsrc/static/actors/hexen/clericholy.txt @@ -1,10 +1,11 @@ // Cleric Weapon Piece ------------------------------------------------------ -ACTOR ClericWeaponPiece : WeaponPiece native +ACTOR ClericWeaponPiece : WeaponPiece { Inventory.PickupSound "misc/w_pkup" Inventory.PickupMessage "$TXT_WRAITHVERGE_PIECE" + Inventory.ForbiddenTo FighterPlayer, MagePlayer WeaponPiece.Weapon CWeapWraithverge +FLOATBOB } diff --git a/wadsrc/static/actors/hexen/fighterquietus.txt b/wadsrc/static/actors/hexen/fighterquietus.txt index 034914d23d..a77e851d89 100644 --- a/wadsrc/static/actors/hexen/fighterquietus.txt +++ b/wadsrc/static/actors/hexen/fighterquietus.txt @@ -1,10 +1,11 @@ // Fighter Weapon Piece ----------------------------------------------------- -ACTOR FighterWeaponPiece : WeaponPiece native +ACTOR FighterWeaponPiece : WeaponPiece { Inventory.PickupSound "misc/w_pkup" Inventory.PickupMessage "$TXT_QUIETUS_PIECE" + Inventory.ForbiddenTo ClericPlayer, MagePlayer WeaponPiece.Weapon FWeapQuietus +FLOATBOB } diff --git a/wadsrc/static/actors/hexen/magestaff.txt b/wadsrc/static/actors/hexen/magestaff.txt index 65c0ac8931..aa75ed4465 100644 --- a/wadsrc/static/actors/hexen/magestaff.txt +++ b/wadsrc/static/actors/hexen/magestaff.txt @@ -1,10 +1,11 @@ // Mage Weapon Piece -------------------------------------------------------- -ACTOR MageWeaponPiece : WeaponPiece native +ACTOR MageWeaponPiece : WeaponPiece { Inventory.PickupSound "misc/w_pkup" Inventory.PickupMessage "$TXT_BLOODSCOURGE_PIECE" + Inventory.ForbiddenTo FighterPlayer, ClericPlayer WeaponPiece.Weapon MWeapBloodscourge +FLOATBOB }