From b10ffb5133837d8f64942366d92fd7e54fee05b1 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 27 Nov 2016 11:59:47 +0100 Subject: [PATCH] - exported a few more functions. - refactored the ModifyDamage interface to be more scripting friendly. In general it should be avoided having to call directly into chained inventory functions because they are very problematic and prone to errors. So this got wrapped into a single handler (on AActor, not AInventory!) which will later make it easier to refactor the parameters of ModifyDamage to work better for scripting and avoid the chaining. --- src/actor.h | 1 + src/g_shared/a_pickups.cpp | 25 +++++++++++++++++++++- src/g_shared/a_pickups.h | 1 + src/p_interaction.cpp | 25 +++++++++++++--------- src/p_mobj.cpp | 25 ++++++++++++++++++++++ wadsrc/static/zscript/actor.txt | 2 ++ wadsrc/static/zscript/shared/inventory.txt | 2 ++ wadsrc/static/zscript/shared/player.txt | 1 + 8 files changed, 71 insertions(+), 11 deletions(-) diff --git a/src/actor.h b/src/actor.h index 92e277d48..4c0f33dde 100644 --- a/src/actor.h +++ b/src/actor.h @@ -1420,6 +1420,7 @@ public: } int ApplyDamageFactor(FName damagetype, int damage) const; + int GetModifiedDamage(FName damagetype, int damage, bool passive); }; diff --git a/src/g_shared/a_pickups.cpp b/src/g_shared/a_pickups.cpp index 3ce3dc776..a57d90bcd 100644 --- a/src/g_shared/a_pickups.cpp +++ b/src/g_shared/a_pickups.cpp @@ -822,6 +822,29 @@ AInventory *AInventory::CreateCopy (AActor *other) return copy; } +DEFINE_ACTION_FUNCTION(AInventory, CreateCopy) +{ + PARAM_SELF_PROLOGUE(AInventory); + PARAM_OBJECT(other, AActor); + ACTION_RETURN_OBJECT(self->CreateCopy(other)); +} + +AInventory *AInventory::CallCreateCopy(AActor *other) +{ + IFVIRTUAL(AActor, CreateCopy) + { + VMValue params[2] = { (DObject*)this, (DObject*)other }; + VMReturn ret; + VMFrameStack stack; + AInventory *retval; + ret.PointerAt((void**)&retval); + stack.Call(func, params, 2, &ret, 1, nullptr); + return retval; + } + else return CreateCopy(other); +} + + //=========================================================================== // // AInventory::CreateTossable @@ -1538,7 +1561,7 @@ bool AInventory::TryPickup (AActor *&toucher) { // Add the item to the inventory. It is not already there, or HandlePickup // would have already taken care of it. - AInventory *copy = CreateCopy (toucher); + AInventory *copy = CallCreateCopy (toucher); if (copy == NULL) { return false; diff --git a/src/g_shared/a_pickups.h b/src/g_shared/a_pickups.h index 2fe680231..429b2ab90 100644 --- a/src/g_shared/a_pickups.h +++ b/src/g_shared/a_pickups.h @@ -199,6 +199,7 @@ public: virtual void AttachToOwner (AActor *other); virtual void DetachFromOwner (); virtual AInventory *CreateCopy (AActor *other); + AInventory *CallCreateCopy(AActor *other); virtual AInventory *CreateTossable (); virtual bool GoAway (); virtual void GoAwayAndDie (); diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index 040e05ce0..c2d958050 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -1105,15 +1105,15 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, damage = int(damage * source->DamageMultiply); // Handle active damage modifiers (e.g. PowerDamage) - if (damage > 0 && source->Inventory != NULL) + if (damage > 0) { - source->Inventory->ModifyDamage(damage, mod, damage, false); + damage = source->GetModifiedDamage(mod, damage, false); } } // Handle passive damage modifiers (e.g. PowerProtection), provided they are not afflicted with protection penetrating powers. - if (damage > 0 && (target->Inventory != NULL) && !(flags & DMG_NO_PROTECT)) + if (damage > 0 && !(flags & DMG_NO_PROTECT)) { - target->Inventory->ModifyDamage(damage, mod, damage, true); + damage = target->GetModifiedDamage(mod, damage, true); } if (damage > 0 && !(flags & DMG_NO_FACTOR)) { @@ -1749,8 +1749,7 @@ DEFINE_ACTION_FUNCTION(_PlayerInfo, PoisonPlayer) // //========================================================================== -void P_PoisonDamage (player_t *player, AActor *source, int damage, - bool playPainSound) +void P_PoisonDamage (player_t *player, AActor *source, int damage, bool playPainSound) { AActor *target; @@ -1771,10 +1770,7 @@ void P_PoisonDamage (player_t *player, AActor *source, int damage, // Take half damage in trainer mode damage = int(damage * G_SkillProperty(SKILLP_DamageFactor)); // Handle passive damage modifiers (e.g. PowerProtection) - if (target->Inventory != NULL) - { - target->Inventory->ModifyDamage(damage, player->poisontype, damage, true); - } + damage = target->GetModifiedDamage(player->poisontype, damage, true); // Modify with damage factors damage = target->ApplyDamageFactor(player->poisontype, damage); @@ -1845,6 +1841,15 @@ void P_PoisonDamage (player_t *player, AActor *source, int damage, */ } +DEFINE_ACTION_FUNCTION(_PlayerInfo, PoisonDamage) +{ + PARAM_SELF_STRUCT_PROLOGUE(player_t); + PARAM_OBJECT(source, AActor); + PARAM_INT(damage); + PARAM_BOOL(playsound); + P_PoisonDamage(self, source, damage, playsound); + return 0; +} CCMD (kill) { diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index c7cf50f5e..ad1c317e8 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -7158,6 +7158,23 @@ DEFINE_ACTION_FUNCTION(AActor, ClearCounters) return 0; } +int AActor::GetModifiedDamage(FName damagetype, int damage, bool passive) +{ + if (Inventory != nullptr) + Inventory->ModifyDamage(damage, damagetype, damage, false); + + return damage; +} + +DEFINE_ACTION_FUNCTION(AActor, GetModifiedDamage) +{ + PARAM_SELF_PROLOGUE(AActor); + PARAM_NAME(type); + PARAM_INT(damage); + PARAM_BOOL(passive); + ACTION_RETURN_INT(self->GetModifiedDamage(type, damage, passive)); +} + int AActor::ApplyDamageFactor(FName damagetype, int damage) const { damage = int(damage * DamageFactor); @@ -7168,6 +7185,14 @@ int AActor::ApplyDamageFactor(FName damagetype, int damage) const return damage; } +DEFINE_ACTION_FUNCTION(AActor, ApplyDamageFactor) +{ + PARAM_SELF_PROLOGUE(AActor); + PARAM_NAME(type); + PARAM_INT(damage); + ACTION_RETURN_INT(self->ApplyDamageFactor(type, damage)); +} + void AActor::SetTranslation(FName trname) { diff --git a/wadsrc/static/zscript/actor.txt b/wadsrc/static/zscript/actor.txt index 8acd261f3..64a62a822 100644 --- a/wadsrc/static/zscript/actor.txt +++ b/wadsrc/static/zscript/actor.txt @@ -303,6 +303,8 @@ class Actor : Thinker native native Actor, Actor SpawnPlayerMissile(class type, double angle = 0, double x = 0, double y = 0, double z = 0, out FTranslatedLineTarget pLineTarget = null, bool nofreeaim = false, bool noautoaim = false, int aimflags = 0); native void SpawnTeleportFog(Vector3 pos, bool beforeTele, bool setTarget); native Actor RoughMonsterSearch(int distance, bool onlyseekable = false); + native int ApplyDamageFactor(FName damagetype, int damage); + native int GetModifiedDamage(FName damagetype, int damage, bool passive); void A_Light(int extralight) { if (player) player.extralight = clamp(extralight, -20, 20); } void A_Light0() { if (player) player.extralight = 0; } diff --git a/wadsrc/static/zscript/shared/inventory.txt b/wadsrc/static/zscript/shared/inventory.txt index 54a2b0ba9..dab317ea6 100644 --- a/wadsrc/static/zscript/shared/inventory.txt +++ b/wadsrc/static/zscript/shared/inventory.txt @@ -27,6 +27,8 @@ class Inventory : Actor native virtual native bool Use (bool pickup); virtual native color GetBlend (); + virtual native bool HandlePickup(Inventory item); + virtual native Inventory CreateCopy(Actor other); // These are regular functions for the item itself. diff --git a/wadsrc/static/zscript/shared/player.txt b/wadsrc/static/zscript/shared/player.txt index 2d5be6278..136feb32e 100644 --- a/wadsrc/static/zscript/shared/player.txt +++ b/wadsrc/static/zscript/shared/player.txt @@ -228,6 +228,7 @@ FWeaponSlots weapons; native bool UndoPlayerMorph(playerinfo player, int unmorphflag = 0, bool force = false); native bool PoisonPlayer(Actor poisoner, Actor source, int poison); + native PoisonDamage(Actor source, int damage, bool playPainSound) native void SetPsprite(int id, State stat, bool pending = false); native void SetSafeFlash(Weapon weap, State flashstate, int index); native PSprite GetPSprite(int id);