mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-26 14:01:45 +00:00
Added WorldThingDamaged hook
This commit is contained in:
parent
9942a59866
commit
89c475c2d1
4 changed files with 72 additions and 23 deletions
|
@ -259,6 +259,15 @@ void E_WorldThingRevived(AActor* 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)
|
||||
{
|
||||
// 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, Thing);
|
||||
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)
|
||||
{
|
||||
|
@ -409,6 +422,7 @@ DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldUnloaded)
|
|||
DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldThingSpawned)
|
||||
DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldThingDied)
|
||||
DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldThingRevived)
|
||||
DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldThingDamaged)
|
||||
DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldThingDestroyed)
|
||||
DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldLightning)
|
||||
DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldTick)
|
||||
|
@ -427,6 +441,11 @@ static DWorldEvent* E_SetupWorldEvent()
|
|||
e->IsSaveGame = savegamerestore;
|
||||
e->Thing = nullptr;
|
||||
e->Inflictor = nullptr;
|
||||
e->Damage = 0;
|
||||
e->DamageAngle = 0.0;
|
||||
e->DamageFlags = 0;
|
||||
e->DamageSource = 0;
|
||||
e->DamageType = NAME_None;
|
||||
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)
|
||||
{
|
||||
IFVIRTUAL(DStaticEventHandler, WorldThingDestroyed)
|
||||
|
|
32
src/events.h
32
src/events.h
|
@ -31,6 +31,8 @@ void E_WorldThingSpawned(AActor* actor);
|
|||
void E_WorldThingDied(AActor* actor, AActor* inflictor);
|
||||
// called after AActor::Revive.
|
||||
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.
|
||||
void E_WorldThingDestroyed(AActor* actor);
|
||||
// same as ACS SCRIPT_Lightning
|
||||
|
@ -89,6 +91,7 @@ public:
|
|||
virtual void WorldThingSpawned(AActor*);
|
||||
virtual void WorldThingDied(AActor*, AActor*);
|
||||
virtual void WorldThingRevived(AActor*);
|
||||
virtual void WorldThingDamaged(AActor*, AActor*, AActor*, int, FName, int, DAngle);
|
||||
virtual void WorldThingDestroyed(AActor*);
|
||||
virtual void WorldLightning();
|
||||
virtual void WorldTick();
|
||||
|
@ -136,18 +139,6 @@ public:
|
|||
FracTic = 0;
|
||||
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
|
||||
|
@ -160,20 +151,21 @@ public:
|
|||
AActor* Thing;
|
||||
// for thingdied
|
||||
AActor* Inflictor; // can be null
|
||||
// for damagemobj
|
||||
int Damage;
|
||||
AActor* DamageSource; // can be null
|
||||
FName DamageType;
|
||||
int DamageFlags;
|
||||
DAngle DamageAngle;
|
||||
|
||||
DWorldEvent()
|
||||
{
|
||||
IsSaveGame = false;
|
||||
Thing = nullptr;
|
||||
Inflictor = nullptr;
|
||||
}
|
||||
|
||||
void Serialize(FSerializer& arc) override
|
||||
{
|
||||
Super::Serialize(arc);
|
||||
arc("IsSaveGame", IsSaveGame);
|
||||
arc("Thing", Thing);
|
||||
arc("Inflictor", Inflictor);
|
||||
Damage = 0;
|
||||
DamageSource = nullptr;
|
||||
DamageFlags = 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -1597,7 +1597,12 @@ DEFINE_ACTION_FUNCTION(AActor, DamageMobj)
|
|||
PARAM_NAME(mod);
|
||||
PARAM_INT_DEF(flags);
|
||||
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)
|
||||
|
@ -1611,7 +1616,14 @@ int P_DamageMobj(AActor *target, AActor *inflictor, AActor *source, int damage,
|
|||
GlobalVMStack.Call(func, params, 7, &ret, 1, nullptr);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -18,6 +18,12 @@ class WorldEvent : BaseEvent native
|
|||
native readonly Actor Thing;
|
||||
// for thingdied. can be null
|
||||
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
|
||||
|
@ -37,6 +43,7 @@ class StaticEventHandler : Object native
|
|||
virtual native void WorldThingSpawned(WorldEvent e);
|
||||
virtual native void WorldThingDied(WorldEvent e);
|
||||
virtual native void WorldThingRevived(WorldEvent e);
|
||||
virtual native void WorldThingDamaged(WorldEvent e);
|
||||
virtual native void WorldThingDestroyed(WorldEvent e);
|
||||
virtual native void WorldLightning(WorldEvent e); // for the sake of completeness.
|
||||
virtual native void WorldTick(WorldEvent e);
|
||||
|
|
Loading…
Reference in a new issue