diff --git a/src/g_inventory/a_keys.cpp b/src/g_inventory/a_keys.cpp index a2b5b308a..286286ef7 100644 --- a/src/g_inventory/a_keys.cpp +++ b/src/g_inventory/a_keys.cpp @@ -533,32 +533,6 @@ IMPLEMENT_CLASS(AKey, false, false) DEFINE_FIELD(AKey, KeyNumber) -bool AKey::HandlePickup (AInventory *item) -{ - // In single player, you can pick up an infinite number of keys - // even though you can only hold one of each. - if (multiplayer) - { - return Super::HandlePickup (item); - } - if (GetClass() == item->GetClass()) - { - item->ItemFlags |= IF_PICKUPGOOD; - return true; - } - return false; -} - -//=========================================================================== -// -// -//=========================================================================== - -bool AKey::ShouldStay () -{ - return !!multiplayer; -} - //========================================================================== // // These functions can be used to get color information for diff --git a/src/g_inventory/a_keys.h b/src/g_inventory/a_keys.h index eda0473a3..bb5336fb4 100644 --- a/src/g_inventory/a_keys.h +++ b/src/g_inventory/a_keys.h @@ -7,12 +7,7 @@ class AKey : public AInventory { DECLARE_CLASS (AKey, AInventory) public: - virtual bool HandlePickup (AInventory *item) override; - BYTE KeyNumber; - -protected: - virtual bool ShouldStay () override; }; bool P_CheckKeys (AActor *owner, int keynum, bool remote); @@ -37,10 +32,6 @@ class APuzzleItem : public AInventory DECLARE_CLASS_WITH_META(APuzzleItem, AInventory, PClassPuzzleItem) public: - virtual bool ShouldStay () override; - virtual bool Use (bool pickup) override; - virtual bool HandlePickup (AInventory *item) override; - int PuzzleItemNumber; }; diff --git a/src/g_inventory/a_puzzleitems.cpp b/src/g_inventory/a_puzzleitems.cpp index 7617f6383..ecb2fb9dd 100644 --- a/src/g_inventory/a_puzzleitems.cpp +++ b/src/g_inventory/a_puzzleitems.cpp @@ -49,6 +49,7 @@ IMPLEMENT_CLASS(PClassPuzzleItem, false, false) IMPLEMENT_CLASS(APuzzleItem, false, false) DEFINE_FIELD(APuzzleItem, PuzzleItemNumber) +DEFINE_FIELD(PClassPuzzleItem, PuzzFailMessage) //=========================================================================== // @@ -62,56 +63,3 @@ void PClassPuzzleItem::DeriveData(PClass *newclass) assert(newclass->IsKindOf(RUNTIME_CLASS(PClassPuzzleItem))); static_cast(newclass)->PuzzFailMessage = PuzzFailMessage; } - - -//=========================================================================== -// -// -// -//=========================================================================== - -bool APuzzleItem::HandlePickup (AInventory *item) -{ - // Can't carry more than 1 of each puzzle item in coop netplay - if (multiplayer && !deathmatch && item->GetClass() == GetClass()) - { - return true; - } - return Super::HandlePickup (item); -} - -//=========================================================================== -// -// -// -//=========================================================================== - -bool APuzzleItem::Use (bool pickup) -{ - if (P_UsePuzzleItem (Owner, PuzzleItemNumber)) - { - return true; - } - // [RH] Always play the sound if the use fails. - S_Sound (Owner, CHAN_VOICE, "*puzzfail", 1, ATTN_IDLE); - if (Owner != NULL && Owner->CheckLocalView (consoleplayer)) - { - FString message = GetClass()->PuzzFailMessage; - if (message.IsNotEmpty() && message[0] == '$') message = GStrings[&message[1]]; - if (message.IsEmpty()) message = GStrings("TXT_USEPUZZLEFAILED"); - C_MidPrintBold (SmallFont, message); - } - return false; -} - -//=========================================================================== -// -// -// -//=========================================================================== - -bool APuzzleItem::ShouldStay () -{ - return !!multiplayer; -} - diff --git a/src/p_map.cpp b/src/p_map.cpp index c3fd2dc88..ae3dfd0f2 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -5515,6 +5515,13 @@ bool P_UsePuzzleItem(AActor *PuzzleItemUser, int PuzzleItemType) return false; } +DEFINE_ACTION_FUNCTION(AActor, UsePuzzleItem) +{ + PARAM_SELF_PROLOGUE(AActor); + PARAM_INT(puzznum); + ACTION_RETURN_BOOL(P_UsePuzzleItem(self, puzznum)); +} + //========================================================================== // // RADIUS ATTACK diff --git a/src/scripting/thingdef_data.cpp b/src/scripting/thingdef_data.cpp index 7cbaec634..9a533f020 100644 --- a/src/scripting/thingdef_data.cpp +++ b/src/scripting/thingdef_data.cpp @@ -914,7 +914,10 @@ DEFINE_ACTION_FUNCTION(FStringTable, Localize) { PARAM_PROLOGUE; PARAM_STRING(label); - ACTION_RETURN_STRING(GStrings(label)); + PARAM_BOOL_DEF(prefixed); + if (!prefixed) ACTION_RETURN_STRING(GStrings(label)); + if (label[0] != '$') ACTION_RETURN_STRING(label); + ACTION_RETURN_STRING(GStrings(&label[1])); } DEFINE_ACTION_FUNCTION(FString, Replace) diff --git a/wadsrc/static/zscript/actor.txt b/wadsrc/static/zscript/actor.txt index edc11192d..ef47f62d7 100644 --- a/wadsrc/static/zscript/actor.txt +++ b/wadsrc/static/zscript/actor.txt @@ -493,6 +493,7 @@ class Actor : Thinker native native bool UseInventory(Inventory item); native void ObtainInventory(Actor other); native bool GiveAmmo (Class type, int amount); + native bool UsePuzzleItem(int PuzzleItemType); native float AccuracyFactor(); // DECORATE compatible functions diff --git a/wadsrc/static/zscript/base.txt b/wadsrc/static/zscript/base.txt index 3c302cd6d..0ed230186 100644 --- a/wadsrc/static/zscript/base.txt +++ b/wadsrc/static/zscript/base.txt @@ -148,7 +148,7 @@ struct LevelLocals native struct StringTable native { - native static String Localize(String val); + native static String Localize(String val, bool prefixed = false); } // a few values of this need to be readable by the play code. diff --git a/wadsrc/static/zscript/inventory/inv_misc.txt b/wadsrc/static/zscript/inventory/inv_misc.txt index fbc6d1322..9c5ffc205 100644 --- a/wadsrc/static/zscript/inventory/inv_misc.txt +++ b/wadsrc/static/zscript/inventory/inv_misc.txt @@ -1,3 +1,9 @@ +//=========================================================================== +// +// +// +//=========================================================================== + class ScoreItem : Inventory { Default @@ -16,6 +22,12 @@ class ScoreItem : Inventory } } +//=========================================================================== +// +// +// +//=========================================================================== + class Key : Inventory native { native uint8 KeyNumber; @@ -26,20 +38,41 @@ class Key : Inventory native Inventory.InterHubAmount 0; Inventory.PickupSound "misc/k_pkup"; } + + override bool HandlePickup (Inventory item) + { + // In single player, you can pick up an infinite number of keys + // even though you can only hold one of each. + if (multiplayer) + { + return Super.HandlePickup (item); + } + if (GetClass() == item.GetClass()) + { + item.bPickupGood = true; + return true; + } + return false; + } + + override bool ShouldStay () + { + return !!multiplayer; + } } +//=========================================================================== +// +// AMapRevealer +// +// A MapRevealer reveals the whole map for the player who picks it up. +// The MapRevealer doesn't actually go in your inventory. Instead, it sets +// a flag on the level. +// +//=========================================================================== + class MapRevealer : Inventory { - //=========================================================================== - // - // AMapRevealer . TryPickup - // - // A MapRevealer reveals the whole map for the player who picks it up. - // The MapRevealer doesn't actually go in your inventory. Instead, it sets - // a flag on the level. - // - //=========================================================================== - override bool TryPickup (in out Actor toucher) { level.allmap = true; @@ -48,9 +81,16 @@ class MapRevealer : Inventory } } +//=========================================================================== +// +// +// +//=========================================================================== + class PuzzleItem : Inventory native { native int PuzzleItemNumber; + native meta String PuzzFailMessage; Default { @@ -59,6 +99,40 @@ class PuzzleItem : Inventory native Inventory.DefMaxAmount; Inventory.UseSound "PuzzleSuccess"; Inventory.PickupSound "misc/i_pkup"; + PuzzleItem.FailMessage("TXT_USEPUZZLEFAILED"); } + + override bool HandlePickup (Inventory item) + { + // Can't carry more than 1 of each puzzle item in coop netplay + if (multiplayer && !deathmatch && item.GetClass() == GetClass()) + { + return true; + } + return Super.HandlePickup (item); + } + + override bool Use (bool pickup) + { + if (Owner == NULL) return false; + if (Owner.UsePuzzleItem (PuzzleItemNumber)) + { + return true; + } + // [RH] Always play the sound if the use fails. + Owner.A_PlaySound ("*puzzfail", CHAN_VOICE); + if (Owner.CheckLocalView (consoleplayer)) + { + C_MidPrint ("SmallFont", PuzzFailMessage, true); + } + return false; + } + + + override bool ShouldStay () + { + return !!multiplayer; + } + }