diff --git a/src/actor.h b/src/actor.h index 92e277d48b..4c0f33dde6 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 3ce3dc776e..a57d90bcd6 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 2fe680231f..429b2ab905 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 040e05ce07..c2d958050e 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 c7cf50f5e4..ad1c317e8b 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 8acd261f3b..64a62a8225 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 54a2b0ba9c..dab317ea62 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 2d5be62781..136feb32e1 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);