Added WorldThingGround event to hook into the actor at exact moment its corpse spawns gibs upon being crushed.

This commit is contained in:
nashmuhandes 2020-09-06 20:34:40 +08:00 committed by Christoph Oelckers
parent 54f85d4caa
commit 7285c5aca8
4 changed files with 33 additions and 1 deletions

View file

@ -331,6 +331,18 @@ void EventManager::WorldThingDied(AActor* actor, AActor* inflictor)
handler->WorldThingDied(actor, inflictor); handler->WorldThingDied(actor, inflictor);
} }
void EventManager::WorldThingGround(AActor* actor)
{
// don't call anything if actor was destroyed on PostBeginPlay/BeginPlay/whatever.
if (actor->ObjectFlags & OF_EuthanizeMe)
return;
if (ShouldCallStatic(true)) staticEventManager.WorldThingGround(actor);
for (DStaticEventHandler* handler = FirstEventHandler; handler; handler = handler->next)
handler->WorldThingGround(actor);
}
void EventManager::WorldThingRevived(AActor* actor) void EventManager::WorldThingRevived(AActor* actor)
{ {
// don't call anything if actor was destroyed on PostBeginPlay/BeginPlay/whatever. // don't call anything if actor was destroyed on PostBeginPlay/BeginPlay/whatever.
@ -795,6 +807,20 @@ void DStaticEventHandler::WorldThingDied(AActor* actor, AActor* inflictor)
} }
} }
void DStaticEventHandler::WorldThingGround(AActor* actor)
{
IFVIRTUAL(DStaticEventHandler, WorldThingGround)
{
// don't create excessive DObjects if not going to be processed anyway
if (isEmpty(func)) return;
FWorldEvent e = owner->SetupWorldEvent();
e.Thing = actor;
VMValue params[2] = { (DStaticEventHandler*)this, &e };
VMCall(func, params, 2, nullptr, 0);
}
}
void DStaticEventHandler::WorldThingRevived(AActor* actor) void DStaticEventHandler::WorldThingRevived(AActor* actor)
{ {
IFVIRTUAL(DStaticEventHandler, WorldThingRevived) IFVIRTUAL(DStaticEventHandler, WorldThingRevived)

View file

@ -80,6 +80,7 @@ public:
void WorldUnloaded(); void WorldUnloaded();
void WorldThingSpawned(AActor* actor); void WorldThingSpawned(AActor* actor);
void WorldThingDied(AActor* actor, AActor* inflictor); void WorldThingDied(AActor* actor, AActor* inflictor);
void WorldThingGround(AActor* actor);
void WorldThingRevived(AActor* actor); void WorldThingRevived(AActor* actor);
void WorldThingDamaged(AActor* actor, AActor* inflictor, AActor* source, int damage, FName mod, int flags, DAngle angle); void WorldThingDamaged(AActor* actor, AActor* inflictor, AActor* source, int damage, FName mod, int flags, DAngle angle);
void WorldThingDestroyed(AActor* actor); void WorldThingDestroyed(AActor* actor);
@ -234,6 +235,8 @@ struct EventManager
void WorldThingSpawned(AActor* actor); void WorldThingSpawned(AActor* actor);
// called after AActor::Die of each actor. // called after AActor::Die of each actor.
void WorldThingDied(AActor* actor, AActor* inflictor); void WorldThingDied(AActor* actor, AActor* inflictor);
// called inside AActor::Grind just before the corpse is destroyed
void WorldThingGround(AActor* actor);
// called after AActor::Revive. // called after AActor::Revive.
void WorldThingRevived(AActor* actor); void WorldThingRevived(AActor* actor);
// called before P_DamageMobj and before AActor::DamageMobj virtuals. // called before P_DamageMobj and before AActor::DamageMobj virtuals.

View file

@ -1204,6 +1204,7 @@ bool AActor::Grind(bool items)
S_Sound (this, CHAN_BODY, 0, "misc/fallingsplat", 1, ATTN_IDLE); S_Sound (this, CHAN_BODY, 0, "misc/fallingsplat", 1, ATTN_IDLE);
Translation = BloodTranslation; Translation = BloodTranslation;
} }
Level->localEventManager->WorldThingGround(this);
return false; return false;
} }
if (!(flags & MF_NOBLOOD)) if (!(flags & MF_NOBLOOD))
@ -1246,6 +1247,7 @@ bool AActor::Grind(bool items)
gib->Translation = BloodTranslation; gib->Translation = BloodTranslation;
} }
S_Sound (this, CHAN_BODY, 0, "misc/fallingsplat", 1, ATTN_IDLE); S_Sound (this, CHAN_BODY, 0, "misc/fallingsplat", 1, ATTN_IDLE);
Level->localEventManager->WorldThingGround(this);
} }
if (flags & MF_ICECORPSE) if (flags & MF_ICECORPSE)
{ {

View file

@ -15,7 +15,7 @@ struct WorldEvent native play version("2.4")
native readonly bool IsSaveGame; native readonly bool IsSaveGame;
// this will be true if we are re-entering the hub level. // this will be true if we are re-entering the hub level.
native readonly bool IsReopen; native readonly bool IsReopen;
// for thingspawned/thingdied/thingdestroyed // for thingspawned/thingdied/thingdestroyed/thingground
native readonly Actor Thing; native readonly Actor Thing;
// for thingdied. can be null // for thingdied. can be null
native readonly Actor Inflictor; native readonly Actor Inflictor;
@ -323,6 +323,7 @@ class StaticEventHandler : Object native play version("2.4")
virtual void WorldUnloaded(WorldEvent e) {} virtual void WorldUnloaded(WorldEvent e) {}
virtual void WorldThingSpawned(WorldEvent e) {} virtual void WorldThingSpawned(WorldEvent e) {}
virtual void WorldThingDied(WorldEvent e) {} virtual void WorldThingDied(WorldEvent e) {}
virtual void WorldThingGround(WorldEvent e) {}
virtual void WorldThingRevived(WorldEvent e) {} virtual void WorldThingRevived(WorldEvent e) {}
virtual void WorldThingDamaged(WorldEvent e) {} virtual void WorldThingDamaged(WorldEvent e) {}
virtual void WorldThingDestroyed(WorldEvent e) {} virtual void WorldThingDestroyed(WorldEvent e) {}