From 096c51d5464df360e1ba2dd5b75b07805f33dcce Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 27 Nov 2016 10:40:43 +0100 Subject: [PATCH] - changed AInventory::HandlePickup to work iteratively instead of recursively. Two reasons for this: 1. if this has to be routed through the VM each recursion will cost 1000 bytes of stack space which simply is not good. 2. having the virtual function only care about the item itself but not the entire inventory chain is a lot less error prone for scripting. Since the scripting interface needs a separate caller function anyway this seemed like a good time to change it. The same will be done for the other chained inventory handlers as well. --- src/CMakeLists.txt | 1 - src/dobjtype.cpp | 1 + src/g_game.cpp | 8 ++--- src/g_hexen/a_hexenglobal.h | 15 -------- src/g_shared/a_armor.cpp | 8 ----- src/g_shared/a_artifacts.cpp | 4 --- src/g_shared/a_keys.cpp | 4 --- src/g_shared/a_pickups.cpp | 49 ++++++++++++++++----------- src/g_shared/a_pickups.h | 1 + src/g_shared/a_weaponpiece.h | 2 ++ src/g_shared/a_weapons.cpp | 4 --- src/g_shared/sbarinfo.cpp | 1 + src/g_strife/a_coin.cpp | 4 --- src/g_strife/a_strifeweapons.cpp | 4 --- src/p_mobj.cpp | 11 +++++- src/scripting/thingdef.cpp | 1 + src/scripting/thingdef_properties.cpp | 8 ++--- wadsrc/static/zscript/actor.txt | 1 + 18 files changed, 55 insertions(+), 72 deletions(-) delete mode 100644 src/g_hexen/a_hexenglobal.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c5a54d1ba..368654698 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -855,7 +855,6 @@ set( NOT_COMPILED_SOURCE_FILES ${OTHER_SYSTEM_SOURCES} sc_man_scanner.h sc_man_scanner.re - g_hexen/a_flechette.cpp g_hexen/a_flies.cpp g_hexen/a_heresiarch.cpp g_hexen/a_hexenspecialdecs.cpp diff --git a/src/dobjtype.cpp b/src/dobjtype.cpp index 079890f86..e9f574ea4 100644 --- a/src/dobjtype.cpp +++ b/src/dobjtype.cpp @@ -45,6 +45,7 @@ #include "autosegs.h" #include "v_text.h" #include "a_pickups.h" +#include "a_artifacts.h" #include "a_weaponpiece.h" #include "d_player.h" #include "doomerrors.h" diff --git a/src/g_game.cpp b/src/g_game.cpp index 9af9b4532..350669cfe 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -478,15 +478,15 @@ CCMD (useflechette) { // Select from one of arti_poisonbag1-3, whichever the player has static const ENamedName bagnames[3] = { + NAME_ArtiPoisonBag3, // use type 3 first because that's the default when the player has none specified. NAME_ArtiPoisonBag1, - NAME_ArtiPoisonBag2, - NAME_ArtiPoisonBag3 + NAME_ArtiPoisonBag2 }; if (who == NULL) return; - PClassActor *type = GetFlechetteType(who); + PClassActor *type = who->FlechetteType; if (type != NULL) { AInventory *item; @@ -497,7 +497,7 @@ CCMD (useflechette) } } - // The default flechette could not be found. Try all 3 types then. + // The default flechette could not be found, or the player had no default. Try all 3 types then. for (int j = 0; j < 3; ++j) { AInventory *item; diff --git a/src/g_hexen/a_hexenglobal.h b/src/g_hexen/a_hexenglobal.h deleted file mode 100644 index 277d1bff1..000000000 --- a/src/g_hexen/a_hexenglobal.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef __A_HEXENGLOBAL_H__ -#define __A_HEXENGLOBAL_H__ - -#include "d_player.h" - -class AArtiPoisonBag : public AInventory -{ - DECLARE_CLASS (AArtiPoisonBag, AInventory) -public: - bool HandlePickup (AInventory *item); - AInventory *CreateCopy (AActor *other); - void BeginPlay (); -}; - -#endif //__A_HEXENGLOBAL_H__ diff --git a/src/g_shared/a_armor.cpp b/src/g_shared/a_armor.cpp index 6be1472bf..25d45d35d 100644 --- a/src/g_shared/a_armor.cpp +++ b/src/g_shared/a_armor.cpp @@ -115,10 +115,6 @@ bool ABasicArmor::HandlePickup (AInventory *item) armor->SaveAmount = int(armor->SaveAmount * G_SkillProperty(SKILLP_ArmorFactor)); } - if (Inventory != NULL) - { - return Inventory->HandlePickup (item); - } return false; } @@ -474,10 +470,6 @@ bool AHexenArmor::HandlePickup (AInventory *item) } return true; } - else if (Inventory != NULL) - { - return Inventory->HandlePickup (item); - } return false; } diff --git a/src/g_shared/a_artifacts.cpp b/src/g_shared/a_artifacts.cpp index 854881647..99a4f46d8 100644 --- a/src/g_shared/a_artifacts.cpp +++ b/src/g_shared/a_artifacts.cpp @@ -309,10 +309,6 @@ bool APowerup::HandlePickup (AInventory *item) power->ItemFlags |= IF_PICKUPGOOD; return true; } - if (Inventory != NULL) - { - return Inventory->HandlePickup (item); - } return false; } diff --git a/src/g_shared/a_keys.cpp b/src/g_shared/a_keys.cpp index 51962c1b0..fc9363be5 100644 --- a/src/g_shared/a_keys.cpp +++ b/src/g_shared/a_keys.cpp @@ -487,10 +487,6 @@ bool AKey::HandlePickup (AInventory *item) item->ItemFlags |= IF_PICKUPGOOD; return true; } - if (Inventory != NULL) - { - return Inventory->HandlePickup (item); - } return false; } diff --git a/src/g_shared/a_pickups.cpp b/src/g_shared/a_pickups.cpp index b026a61d7..3ce3dc776 100644 --- a/src/g_shared/a_pickups.cpp +++ b/src/g_shared/a_pickups.cpp @@ -183,10 +183,6 @@ bool AAmmo::HandlePickup (AInventory *item) } return true; } - if (Inventory != NULL) - { - return Inventory->HandlePickup (item); - } return false; } @@ -718,13 +714,39 @@ bool AInventory::HandlePickup (AInventory *item) } return true; } - if (Inventory != NULL) + return false; +} + +DEFINE_ACTION_FUNCTION(AInventory, HandlePickup) +{ + PARAM_SELF_PROLOGUE(AInventory); + PARAM_OBJECT(item, AInventory); + ACTION_RETURN_BOOL(self->HandlePickup(item)); +} + +bool AInventory::CallHandlePickup(AInventory *item) +{ + auto self = this; + while (self != nullptr) { - return Inventory->HandlePickup (item); + IFVIRTUAL(AActor, HandlePickup) + { + // Without the type cast this picks the 'void *' assignment... + VMValue params[2] = { (DObject*)self, (DObject*)item }; + VMReturn ret; + VMFrameStack stack; + int retval; + ret.IntAt(&retval); + stack.Call(func, params, 2, &ret, 1, nullptr); + if (retval) return true; + } + else if (self->HandlePickup(item)) return true; + self = self->Inventory; } return false; } + //=========================================================================== // // AInventory :: GoAway @@ -1480,7 +1502,7 @@ bool AInventory::TryPickup (AActor *&toucher) // picked up, then it leaves the flag cleared. ItemFlags &= ~IF_PICKUPGOOD; - if (toucher->Inventory != NULL && toucher->Inventory->HandlePickup (this)) + if (toucher->Inventory != NULL && toucher->Inventory->CallHandlePickup (this)) { // Let something else the player is holding intercept the pickup. if (!(ItemFlags & IF_PICKUPGOOD)) @@ -1892,10 +1914,6 @@ bool AHealthPickup::HandlePickup (AInventory *item) { return Super::HandlePickup (item); } - if (Inventory != NULL) - { - return Inventory->HandlePickup (item); - } return false; } @@ -2044,14 +2062,7 @@ bool ABackpackItem::HandlePickup (AInventory *item) item->ItemFlags |= IF_PICKUPGOOD; return true; } - else if (Inventory != NULL) - { - return Inventory->HandlePickup (item); - } - else - { - return false; - } + return false; } //=========================================================================== diff --git a/src/g_shared/a_pickups.h b/src/g_shared/a_pickups.h index bc8319931..2fe680231 100644 --- a/src/g_shared/a_pickups.h +++ b/src/g_shared/a_pickups.h @@ -203,6 +203,7 @@ public: virtual bool GoAway (); virtual void GoAwayAndDie (); virtual bool HandlePickup (AInventory *item); + bool CallHandlePickup(AInventory *item); virtual bool Use (bool pickup); bool CallUse(bool pickup); virtual void Travelled (); diff --git a/src/g_shared/a_weaponpiece.h b/src/g_shared/a_weaponpiece.h index 88f3da02c..3a6fbcbd7 100644 --- a/src/g_shared/a_weaponpiece.h +++ b/src/g_shared/a_weaponpiece.h @@ -1,3 +1,5 @@ +#pragma once +#include "a_pickups.h" // class PClassWeaponPiece : public PClassInventory diff --git a/src/g_shared/a_weapons.cpp b/src/g_shared/a_weapons.cpp index b19896e91..c2feebec6 100644 --- a/src/g_shared/a_weapons.cpp +++ b/src/g_shared/a_weapons.cpp @@ -346,10 +346,6 @@ bool AWeapon::HandlePickup (AInventory *item) } return true; } - if (Inventory != NULL) - { - return Inventory->HandlePickup (item); - } return false; } diff --git a/src/g_shared/sbarinfo.cpp b/src/g_shared/sbarinfo.cpp index a005c1ada..ed91be4c7 100644 --- a/src/g_shared/sbarinfo.cpp +++ b/src/g_shared/sbarinfo.cpp @@ -50,6 +50,7 @@ #include "sbarinfo.h" #include "gi.h" #include "r_data/r_translate.h" +#include "a_artifacts.h" #include "a_weaponpiece.h" #include "a_strifeglobal.h" #include "g_level.h" diff --git a/src/g_strife/a_coin.cpp b/src/g_strife/a_coin.cpp index 53cc59f50..f74d92e55 100644 --- a/src/g_strife/a_coin.cpp +++ b/src/g_strife/a_coin.cpp @@ -41,10 +41,6 @@ bool ACoin::HandlePickup (AInventory *item) } return true; } - if (Inventory != NULL) - { - return Inventory->HandlePickup (item); - } return false; } diff --git a/src/g_strife/a_strifeweapons.cpp b/src/g_strife/a_strifeweapons.cpp index 0268682f3..1909ec781 100644 --- a/src/g_strife/a_strifeweapons.cpp +++ b/src/g_strife/a_strifeweapons.cpp @@ -786,10 +786,6 @@ bool ASigil::HandlePickup (AInventory *item) } return true; } - if (Inventory != NULL) - { - return Inventory->HandlePickup (item); - } return false; } diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 2e87729d0..c7cf50f5e 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -41,7 +41,6 @@ #include "c_dispatch.h" #include "b_bot.h" //Added by MC: #include "stats.h" -#include "a_hexenglobal.h" #include "a_sharedglobal.h" #include "gi.h" #include "sbar.h" @@ -69,6 +68,7 @@ #include "serializer.h" #include "r_utility.h" #include "thingdef.h" +#include "d_player.h" #include "virtual.h" // MACROS ------------------------------------------------------------------ @@ -7436,6 +7436,15 @@ DEFINE_ACTION_FUNCTION(AActor, SetFriendPlayer) self->SetFriendPlayer(player); return 0; } + +DEFINE_ACTION_FUNCTION(AActor, ClearBounce) +{ + PARAM_SELF_PROLOGUE(AActor); + self->BounceFlags = 0; + return 0; +} + + //---------------------------------------------------------------------------- // // DropItem handling diff --git a/src/scripting/thingdef.cpp b/src/scripting/thingdef.cpp index d6c53dd8d..5708f89d2 100644 --- a/src/scripting/thingdef.cpp +++ b/src/scripting/thingdef.cpp @@ -57,6 +57,7 @@ #include "m_argv.h" #include "p_local.h" #include "doomerrors.h" +#include "a_artifacts.h" #include "a_weaponpiece.h" #include "p_conversation.h" #include "v_text.h" diff --git a/src/scripting/thingdef_properties.cpp b/src/scripting/thingdef_properties.cpp index 8968dc1d6..8586d32af 100644 --- a/src/scripting/thingdef_properties.cpp +++ b/src/scripting/thingdef_properties.cpp @@ -39,7 +39,7 @@ */ #include "gi.h" -#include "actor.h" +#include "d_player.h" #include "info.h" #include "tarray.h" #include "w_wad.h" @@ -57,8 +57,7 @@ #include "p_effect.h" #include "v_palette.h" #include "doomerrors.h" -#include "a_hexenglobal.h" -#include "a_weaponpiece.h" +#include "a_artifacts.h" #include "p_conversation.h" #include "v_text.h" #include "thingdef.h" @@ -69,6 +68,7 @@ #include "teaminfo.h" #include "v_video.h" #include "r_data/colormaps.h" +#include "a_weaponpiece.h" #include "vmbuilder.h" extern TArray OptionalClassPtrs; @@ -2800,7 +2800,7 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, morphweapon, S, PlayerPawn) DEFINE_CLASS_PROPERTY_PREFIX(player, flechettetype, S, PlayerPawn) { PROP_STRING_PARM(str, 0); - defaults->FlechetteType = FindClassTentative(str, RUNTIME_CLASS(AArtiPoisonBag)); + defaults->FlechetteType = FindClassTentative(str, PClass::FindActor("ArtiPoisonBag")); } //========================================================================== diff --git a/wadsrc/static/zscript/actor.txt b/wadsrc/static/zscript/actor.txt index 92f1073fd..8acd261f3 100644 --- a/wadsrc/static/zscript/actor.txt +++ b/wadsrc/static/zscript/actor.txt @@ -280,6 +280,7 @@ class Actor : Thinker native native int PlayerNumber(); native void SetFriendPlayer(PlayerInfo player); native void NoiseAlert(Actor emitter, bool splash = false, double maxdist = 0); + native void ClearBounce(); native void RestoreDamage(); native int SpawnHealth();