qzdoom/src/events.h

216 lines
5.9 KiB
C
Raw Normal View History

2017-01-22 00:33:53 +00:00
#ifndef EVENTS_H
#define EVENTS_H
#include "dobject.h"
#include "serializer.h"
2017-01-22 00:33:53 +00:00
class DStaticEventHandler;
2017-01-22 05:04:35 +00:00
// register
bool E_RegisterHandler(DStaticEventHandler* handler);
2017-01-22 05:04:35 +00:00
// unregister
bool E_UnregisterHandler(DStaticEventHandler* handler);
// find
bool E_CheckHandler(DStaticEventHandler* handler);
// check type
bool E_IsStaticType(PClass* type);
// init static handlers
void E_InitStaticHandlers(bool map);
2017-01-22 05:04:35 +00:00
// called right after the map has loaded (approximately same time as OPEN ACS scripts)
2017-01-23 22:17:12 +00:00
void E_WorldLoaded();
2017-01-22 05:04:35 +00:00
// called when the map is about to unload (approximately same time as UNLOADING ACS scripts)
void E_WorldUnloaded();
2017-01-23 22:17:12 +00:00
// called right after the map has loaded (every time, UNSAFE VERSION)
void E_WorldLoadedUnsafe();
// called right before the map is unloaded (every time, UNSAFE VERSION)
void E_WorldUnloadedUnsafe();
// called around PostBeginPlay of each actor.
void E_WorldThingSpawned(AActor* actor);
// called after AActor::Die of each actor.
void E_WorldThingDied(AActor* actor, AActor* inflictor);
// called after AActor::Revive.
void E_WorldThingRevived(AActor* actor);
2017-01-31 02:35:44 +00:00
// 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
void E_WorldLightning();
// this executes on every tick, before everything
void E_WorldTick();
2017-01-22 05:04:35 +00:00
// called on each render frame once.
void E_RenderFrame();
2017-02-02 18:26:56 +00:00
// this executes when a player enters the level (once). PlayerEnter+inhub = RETURN
void E_PlayerEntered(int num);
// this executes when a player respawns. includes resurrect cheat.
void E_PlayerRespawned(int num);
// this executes when a player dies (partially duplicating worldthingdied, but whatever)
void E_PlayerDied(int num);
// this executes when a player leaves the game
void E_PlayerDisconnected(int num);
// serialization stuff
void E_SerializeEvents(FSerializer& arc);
2017-01-22 05:04:35 +00:00
// ==============================================
//
// EventHandler - base class
//
// ==============================================
class DStaticEventHandler : public DObject // make it a part of normal GC process
2017-01-22 00:33:53 +00:00
{
DECLARE_CLASS(DStaticEventHandler, DObject)
2017-01-22 00:33:53 +00:00
public:
DStaticEventHandler()
{
prev = 0;
next = 0;
order = 0;
haveorder = false;
}
DStaticEventHandler* prev;
DStaticEventHandler* next;
virtual bool IsStatic() { return true; }
2017-01-22 00:33:53 +00:00
// order is cached to avoid calling the VM for sorting too much
int order;
bool haveorder;
2017-01-23 22:17:12 +00:00
// serialization handler. let's keep it here so that I don't get lost in serialized/not serialized fields
void Serialize(FSerializer& arc) override
{
Super::Serialize(arc);
if (arc.isReading())
{
Printf("DStaticEventHandler::Serialize: reading object %s\n", GetClass()->TypeName.GetChars());
}
else
{
Printf("DStaticEventHandler::Serialize: store object %s\n", GetClass()->TypeName.GetChars());
}
/* do nothing */
}
2017-01-22 00:33:53 +00:00
// destroy handler. this unlinks EventHandler from the list automatically.
void OnDestroy() override;
2017-02-02 18:26:56 +00:00
//
2017-01-23 22:17:12 +00:00
virtual void WorldLoaded();
virtual void WorldUnloaded();
virtual void WorldThingSpawned(AActor*);
virtual void WorldThingDied(AActor*, AActor*);
virtual void WorldThingRevived(AActor*);
2017-01-31 02:35:44 +00:00
virtual void WorldThingDamaged(AActor*, AActor*, AActor*, int, FName, int, DAngle);
virtual void WorldThingDestroyed(AActor*);
virtual void WorldLightning();
virtual void WorldTick();
2017-02-02 18:26:56 +00:00
//
2017-01-22 00:33:53 +00:00
virtual void RenderFrame();
2017-02-02 18:26:56 +00:00
//
virtual void PlayerEntered(int num);
virtual void PlayerRespawned(int num);
virtual void PlayerDied(int num);
virtual void PlayerDisconnected(int num);
// gets the order of this item.
int GetOrder();
2017-01-22 00:33:53 +00:00
};
class DEventHandler : public DStaticEventHandler
{
DECLARE_CLASS(DEventHandler, DStaticEventHandler) // TODO: make sure this does not horribly break anything
public:
bool IsStatic() override { return false; }
};
extern DStaticEventHandler* E_FirstEventHandler;
2017-01-22 00:33:53 +00:00
// we cannot call this DEvent because in ZScript, 'event' is a keyword
class DBaseEvent : public DObject
{
DECLARE_CLASS(DBaseEvent, DObject)
public:
DBaseEvent()
{
// each type of event is created only once to avoid new/delete hell
// since from what I remember object creation and deletion results in a lot of GC processing
// (and we aren't supposed to pass event objects around anyway)
this->ObjectFlags |= OF_Fixed;
// we don't want to store events into the savegames because they are global.
this->ObjectFlags |= OF_Transient;
}
};
class DRenderEvent : public DBaseEvent
2017-01-22 00:33:53 +00:00
{
DECLARE_CLASS(DRenderEvent, DBaseEvent)
2017-01-22 00:33:53 +00:00
public:
2017-01-22 05:04:35 +00:00
// these are for all render events
2017-01-22 00:33:53 +00:00
DVector3 ViewPos;
DAngle ViewAngle;
DAngle ViewPitch;
DAngle ViewRoll;
double FracTic; // 0..1 value that describes where we are inside the current gametic, render-wise.
2017-01-22 05:04:35 +00:00
AActor* Camera;
2017-01-22 00:33:53 +00:00
DRenderEvent()
{
FracTic = 0;
Camera = nullptr;
}
};
2017-01-22 00:33:53 +00:00
class DWorldEvent : public DBaseEvent
{
DECLARE_CLASS(DWorldEvent, DBaseEvent)
public:
// for loaded/unloaded
bool IsSaveGame;
2017-02-02 18:26:56 +00:00
bool IsReopen;
// for thingspawned, thingdied, thingdestroyed
AActor* Thing;
// for thingdied
AActor* Inflictor; // can be null
2017-01-31 02:35:44 +00:00
// for damagemobj
int Damage;
AActor* DamageSource; // can be null
FName DamageType;
int DamageFlags;
DAngle DamageAngle;
DWorldEvent()
{
IsSaveGame = false;
2017-02-02 18:26:56 +00:00
IsReopen = false;
Thing = nullptr;
Inflictor = nullptr;
2017-01-31 02:35:44 +00:00
Damage = 0;
DamageSource = nullptr;
DamageFlags = 0;
}
};
2017-02-02 18:26:56 +00:00
class DPlayerEvent : public DBaseEvent
{
DECLARE_CLASS(DPlayerEvent, DBaseEvent)
public:
// we currently have only one member: player index
// in ZScript, we have global players[] array from which we can
// get both the player itself and player's body,
// so no need to pass it here.
int PlayerNumber;
// we set this to true if level was reopened (RETURN scripts)
bool IsReturn;
DPlayerEvent()
{
PlayerNumber = -1;
IsReturn = false;
}
};
2017-01-22 00:33:53 +00:00
#endif