diff --git a/src/actor.h b/src/actor.h index bd6b51a4da..8f0a8e9f38 100644 --- a/src/actor.h +++ b/src/actor.h @@ -814,7 +814,8 @@ public: virtual bool Massacre (); // Transforms the actor into a finely-ground paste - virtual bool Grind(bool items); + bool Grind(bool items); + bool CallGrind(bool items); // Get this actor's team int GetTeam(); diff --git a/src/g_inventory/a_pickups.cpp b/src/g_inventory/a_pickups.cpp index 7b7721b486..6ec1a4e846 100644 --- a/src/g_inventory/a_pickups.cpp +++ b/src/g_inventory/a_pickups.cpp @@ -173,33 +173,6 @@ void AInventory::MarkPrecacheSounds() const PickupSound.MarkUsed(); } -//=========================================================================== -// -// AInventory :: Grind -// -//=========================================================================== - -bool AInventory::Grind(bool items) -{ - // Does this grind request even care about items? - if (!items) - { - return false; - } - // Dropped items are normally destroyed by crushers. Set the DONTGIB flag, - // and they'll act like corpses with it set and be immune to crushers. - if (flags & MF_DROPPED) - { - if (!(flags3 & MF3_DONTGIB)) - { - Destroy(); - } - return false; - } - // Non-dropped items call the super method for compatibility. - return Super::Grind(items); -} - //=========================================================================== // // AInventory :: BecomeItem diff --git a/src/g_inventory/a_pickups.h b/src/g_inventory/a_pickups.h index 4cb202f7d2..33b7a40a23 100644 --- a/src/g_inventory/a_pickups.h +++ b/src/g_inventory/a_pickups.h @@ -76,7 +76,6 @@ public: virtual void OnDestroy() override; virtual void Tick() override; virtual bool Massacre() override; - virtual bool Grind(bool items) override; bool CallTryPickup(AActor *toucher, AActor **toucher_return = NULL); // Wrapper for script function. diff --git a/src/p_map.cpp b/src/p_map.cpp index e0b16ca2e5..5d248d2dbf 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -6485,7 +6485,7 @@ void P_FindBelowIntersectors(AActor *actor) void P_DoCrunch(AActor *thing, FChangePosition *cpos) { - if (!(thing && thing->Grind(true) && cpos)) return; + if (!(thing && thing->CallGrind(true) && cpos)) return; cpos->nofit = true; if ((cpos->crushchange > 0) && !(level.maptime & 3)) diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 0999e71eb2..67290a08ee 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -1903,6 +1903,26 @@ bool AActor::Grind(bool items) return true; } +DEFINE_ACTION_FUNCTION(AActor, Grind) +{ + PARAM_SELF_PROLOGUE(AActor); + PARAM_BOOL(items); + ACTION_RETURN_BOOL(self->Grind(items)); +} + +bool AActor::CallGrind(bool items) +{ + IFVIRTUAL(AActor, Grind) + { + VMValue params[] = { (DObject*)this, items }; + int retv; + VMReturn ret(&retv); + VMCall(func, params, 2, &ret, 1); + return !!retv; + } + return Grind(items); +} + //============================================================================ // // AActor :: Massacre diff --git a/src/po_man.cpp b/src/po_man.cpp index ca12120de8..cb934c4764 100644 --- a/src/po_man.cpp +++ b/src/po_man.cpp @@ -869,7 +869,7 @@ void FPolyObj::ThrustMobj (AActor *actor, side_t *side) P_TraceBleed (newdam > 0 ? newdam : crush, actor); } } - if (level.flags2 & LEVEL2_POLYGRIND) actor->Grind(false); // crush corpses that get caught in a polyobject's way + if (level.flags2 & LEVEL2_POLYGRIND) actor->CallGrind(false); // crush corpses that get caught in a polyobject's way } //========================================================================== diff --git a/wadsrc/static/zscript/actor.txt b/wadsrc/static/zscript/actor.txt index 1099464a1a..a77b5d559e 100644 --- a/wadsrc/static/zscript/actor.txt +++ b/wadsrc/static/zscript/actor.txt @@ -577,6 +577,7 @@ class Actor : Thinker native native void ClearCounters(); native bool GiveBody (int num, int max=0); native bool HitFloor(); + native virtual bool Grind(bool items); native clearscope bool isTeammate(Actor other) const; native clearscope int PlayerNumber() const; native void SetFriendPlayer(PlayerInfo player); diff --git a/wadsrc/static/zscript/inventory/inventory.txt b/wadsrc/static/zscript/inventory/inventory.txt index 1e47428921..8645cf74f9 100644 --- a/wadsrc/static/zscript/inventory/inventory.txt +++ b/wadsrc/static/zscript/inventory/inventory.txt @@ -144,7 +144,33 @@ class Inventory : Actor native Spawn ("ItemFog", Pos, ALLOW_REPLACE); } } - + + //=========================================================================== + // + // AInventory :: Grind + // + //=========================================================================== + + override bool Grind(bool items) + { + // Does this grind request even care about items? + if (!items) + { + return false; + } + // Dropped items are normally destroyed by crushers. Set the DONTGIB flag, + // and they'll act like corpses with it set and be immune to crushers. + if (bDropped) + { + if (!bDontGib) + { + Destroy(); + } + return false; + } + // Non-dropped items call the super method for compatibility. + return Super.Grind(items); + } //=========================================================================== //