Added WorldThingDamaged hook

This commit is contained in:
ZZYZX 2017-01-31 04:35:44 +02:00
parent 9942a59866
commit 89c475c2d1
4 changed files with 72 additions and 23 deletions

View file

@ -259,6 +259,15 @@ void E_WorldThingRevived(AActor* actor)
handler->WorldThingRevived(actor); handler->WorldThingRevived(actor);
} }
void E_WorldThingDamaged(AActor* actor, AActor* inflictor, AActor* source, int damage, FName mod, int flags, DAngle angle)
{
// don't call anything if actor was destroyed on PostBeginPlay/BeginPlay/whatever.
if (actor->ObjectFlags & OF_EuthanizeMe)
return;
for (DStaticEventHandler* handler = E_FirstEventHandler; handler; handler = handler->next)
handler->WorldThingDamaged(actor, inflictor, source, damage, mod, flags, angle);
}
void E_WorldThingDestroyed(AActor* actor) void E_WorldThingDestroyed(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.
@ -290,7 +299,11 @@ DEFINE_FIELD_X(RenderEvent, DRenderEvent, Camera);
DEFINE_FIELD_X(WorldEvent, DWorldEvent, IsSaveGame); DEFINE_FIELD_X(WorldEvent, DWorldEvent, IsSaveGame);
DEFINE_FIELD_X(WorldEvent, DWorldEvent, Thing); DEFINE_FIELD_X(WorldEvent, DWorldEvent, Thing);
DEFINE_FIELD_X(WorldEvent, DWorldEvent, Inflictor); DEFINE_FIELD_X(WorldEvent, DWorldEvent, Inflictor);
DEFINE_FIELD_X(WorldEvent, DWorldEvent, Damage);
DEFINE_FIELD_X(WorldEvent, DWorldEvent, DamageSource);
DEFINE_FIELD_X(WorldEvent, DWorldEvent, DamageType);
DEFINE_FIELD_X(WorldEvent, DWorldEvent, DamageFlags);
DEFINE_FIELD_X(WorldEvent, DWorldEvent, DamageAngle);
DEFINE_ACTION_FUNCTION(DEventHandler, Create) DEFINE_ACTION_FUNCTION(DEventHandler, Create)
{ {
@ -409,6 +422,7 @@ DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldUnloaded)
DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldThingSpawned) DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldThingSpawned)
DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldThingDied) DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldThingDied)
DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldThingRevived) DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldThingRevived)
DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldThingDamaged)
DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldThingDestroyed) DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldThingDestroyed)
DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldLightning) DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldLightning)
DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldTick) DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldTick)
@ -427,6 +441,11 @@ static DWorldEvent* E_SetupWorldEvent()
e->IsSaveGame = savegamerestore; e->IsSaveGame = savegamerestore;
e->Thing = nullptr; e->Thing = nullptr;
e->Inflictor = nullptr; e->Inflictor = nullptr;
e->Damage = 0;
e->DamageAngle = 0.0;
e->DamageFlags = 0;
e->DamageSource = 0;
e->DamageType = NAME_None;
return e; return e;
} }
@ -499,6 +518,25 @@ void DStaticEventHandler::WorldThingRevived(AActor* actor)
} }
} }
void DStaticEventHandler::WorldThingDamaged(AActor* actor, AActor* inflictor, AActor* source, int damage, FName mod, int flags, DAngle angle)
{
IFVIRTUAL(DStaticEventHandler, WorldThingDamaged)
{
// don't create excessive DObjects if not going to be processed anyway
if (func == DStaticEventHandler_WorldThingDamaged_VMPtr)
return;
DWorldEvent* e = E_SetupWorldEvent();
e->Thing = actor;
e->Damage = damage;
e->DamageSource = source;
e->DamageType = mod;
e->DamageFlags = flags;
e->DamageAngle = angle;
VMValue params[2] = { (DStaticEventHandler*)this, e };
GlobalVMStack.Call(func, params, 2, nullptr, 0, nullptr);
}
}
void DStaticEventHandler::WorldThingDestroyed(AActor* actor) void DStaticEventHandler::WorldThingDestroyed(AActor* actor)
{ {
IFVIRTUAL(DStaticEventHandler, WorldThingDestroyed) IFVIRTUAL(DStaticEventHandler, WorldThingDestroyed)

View file

@ -31,6 +31,8 @@ void E_WorldThingSpawned(AActor* actor);
void E_WorldThingDied(AActor* actor, AActor* inflictor); void E_WorldThingDied(AActor* actor, AActor* inflictor);
// called after AActor::Revive. // called after AActor::Revive.
void E_WorldThingRevived(AActor* actor); void E_WorldThingRevived(AActor* actor);
// called before P_DamageMobj and before AActor::DamageMobj virtuals.
void E_WorldThingDamaged(AActor* actor, AActor* inflictor, AActor* source, int damage, FName mod, int flags, DAngle angle);
// called before AActor::Destroy of each actor. // called before AActor::Destroy of each actor.
void E_WorldThingDestroyed(AActor* actor); void E_WorldThingDestroyed(AActor* actor);
// same as ACS SCRIPT_Lightning // same as ACS SCRIPT_Lightning
@ -89,6 +91,7 @@ public:
virtual void WorldThingSpawned(AActor*); virtual void WorldThingSpawned(AActor*);
virtual void WorldThingDied(AActor*, AActor*); virtual void WorldThingDied(AActor*, AActor*);
virtual void WorldThingRevived(AActor*); virtual void WorldThingRevived(AActor*);
virtual void WorldThingDamaged(AActor*, AActor*, AActor*, int, FName, int, DAngle);
virtual void WorldThingDestroyed(AActor*); virtual void WorldThingDestroyed(AActor*);
virtual void WorldLightning(); virtual void WorldLightning();
virtual void WorldTick(); virtual void WorldTick();
@ -136,18 +139,6 @@ public:
FracTic = 0; FracTic = 0;
Camera = nullptr; Camera = nullptr;
} }
// serialization handler for our local stuff
void Serialize(FSerializer& arc) override
{
Super::Serialize(arc);
arc("ViewPos", ViewPos);
arc("ViewAngle", ViewAngle);
arc("ViewPitch", ViewPitch);
arc("ViewRoll", ViewRoll);
arc("FracTic", FracTic);
arc("Camera", Camera);
}
}; };
class DWorldEvent : public DBaseEvent class DWorldEvent : public DBaseEvent
@ -160,20 +151,21 @@ public:
AActor* Thing; AActor* Thing;
// for thingdied // for thingdied
AActor* Inflictor; // can be null AActor* Inflictor; // can be null
// for damagemobj
int Damage;
AActor* DamageSource; // can be null
FName DamageType;
int DamageFlags;
DAngle DamageAngle;
DWorldEvent() DWorldEvent()
{ {
IsSaveGame = false; IsSaveGame = false;
Thing = nullptr; Thing = nullptr;
Inflictor = nullptr; Inflictor = nullptr;
} Damage = 0;
DamageSource = nullptr;
void Serialize(FSerializer& arc) override DamageFlags = 0;
{
Super::Serialize(arc);
arc("IsSaveGame", IsSaveGame);
arc("Thing", Thing);
arc("Inflictor", Inflictor);
} }
}; };

View file

@ -1597,7 +1597,12 @@ DEFINE_ACTION_FUNCTION(AActor, DamageMobj)
PARAM_NAME(mod); PARAM_NAME(mod);
PARAM_INT_DEF(flags); PARAM_INT_DEF(flags);
PARAM_FLOAT_DEF(angle); PARAM_FLOAT_DEF(angle);
ACTION_RETURN_INT(DamageMobj(self, inflictor, source, damage, mod, flags, angle));
// [ZZ] event handlers need the result.
int realdamage = DamageMobj(self, inflictor, source, damage, mod, flags, angle);
if (!realdamage) ACTION_RETURN_INT(0);
E_WorldThingDamaged(self, inflictor, source, realdamage, mod, flags, angle);
ACTION_RETURN_INT(realdamage);
} }
int P_DamageMobj(AActor *target, AActor *inflictor, AActor *source, int damage, FName mod, int flags, DAngle angle) int P_DamageMobj(AActor *target, AActor *inflictor, AActor *source, int damage, FName mod, int flags, DAngle angle)
@ -1611,7 +1616,14 @@ int P_DamageMobj(AActor *target, AActor *inflictor, AActor *source, int damage,
GlobalVMStack.Call(func, params, 7, &ret, 1, nullptr); GlobalVMStack.Call(func, params, 7, &ret, 1, nullptr);
return retval; return retval;
} }
else return DamageMobj(target, inflictor, source, damage, mod, flags, angle); else
{
int realdamage = DamageMobj(target, inflictor, source, damage, mod, flags, angle);
if (!realdamage) return 0;
// [ZZ] event handlers only need the resultant damage (they can't do anything about it anyway)
E_WorldThingDamaged(target, inflictor, source, realdamage, mod, flags, angle);
return realdamage;
}
} }

View file

@ -18,6 +18,12 @@ class WorldEvent : BaseEvent native
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;
// for thingdamaged.
native readonly int Damage;
native readonly Actor DamageSource;
native readonly Name DamageType;
native readonly EDmgFlags DamageFlags;
native readonly double DamageAngle;
} }
class StaticEventHandler : Object native class StaticEventHandler : Object native
@ -37,6 +43,7 @@ class StaticEventHandler : Object native
virtual native void WorldThingSpawned(WorldEvent e); virtual native void WorldThingSpawned(WorldEvent e);
virtual native void WorldThingDied(WorldEvent e); virtual native void WorldThingDied(WorldEvent e);
virtual native void WorldThingRevived(WorldEvent e); virtual native void WorldThingRevived(WorldEvent e);
virtual native void WorldThingDamaged(WorldEvent e);
virtual native void WorldThingDestroyed(WorldEvent e); virtual native void WorldThingDestroyed(WorldEvent e);
virtual native void WorldLightning(WorldEvent e); // for the sake of completeness. virtual native void WorldLightning(WorldEvent e); // for the sake of completeness.
virtual native void WorldTick(WorldEvent e); virtual native void WorldTick(WorldEvent e);