2017-01-22 00:33:53 +00:00
|
|
|
#ifndef EVENTS_H
|
|
|
|
#define EVENTS_H
|
|
|
|
|
|
|
|
#include "dobject.h"
|
2017-01-23 21:05:51 +00:00
|
|
|
#include "serializer.h"
|
2017-02-03 10:28:40 +00:00
|
|
|
#include "d_event.h"
|
|
|
|
#include "d_gui.h"
|
2017-03-29 21:51:53 +00:00
|
|
|
#include "sbar.h"
|
2017-01-22 00:33:53 +00:00
|
|
|
|
2017-01-22 06:56:57 +00:00
|
|
|
class DStaticEventHandler;
|
2017-01-22 05:04:35 +00:00
|
|
|
|
2018-10-31 14:52:39 +00:00
|
|
|
enum class EventHandlerType
|
|
|
|
{
|
|
|
|
Global,
|
|
|
|
PerMap
|
|
|
|
};
|
|
|
|
|
2017-01-30 06:47:15 +00:00
|
|
|
// ==============================================
|
|
|
|
//
|
|
|
|
// EventHandler - base class
|
|
|
|
//
|
|
|
|
// ==============================================
|
|
|
|
|
2017-01-22 06:56:57 +00:00
|
|
|
class DStaticEventHandler : public DObject // make it a part of normal GC process
|
2017-01-22 00:33:53 +00:00
|
|
|
{
|
2017-02-26 09:58:22 +00:00
|
|
|
DECLARE_CLASS(DStaticEventHandler, DObject);
|
2017-02-09 13:35:45 +00:00
|
|
|
HAS_OBJECT_POINTERS
|
2017-01-22 00:33:53 +00:00
|
|
|
public:
|
2017-01-30 05:50:09 +00:00
|
|
|
DStaticEventHandler()
|
|
|
|
{
|
|
|
|
prev = 0;
|
|
|
|
next = 0;
|
2017-02-03 10:28:40 +00:00
|
|
|
Order = 0;
|
|
|
|
IsUiProcessor = false;
|
2017-01-30 05:50:09 +00:00
|
|
|
}
|
|
|
|
|
2017-01-22 06:56:57 +00:00
|
|
|
DStaticEventHandler* prev;
|
|
|
|
DStaticEventHandler* next;
|
|
|
|
virtual bool IsStatic() { return true; }
|
2017-01-22 00:33:53 +00:00
|
|
|
|
2017-02-03 10:28:40 +00:00
|
|
|
//
|
|
|
|
int Order;
|
|
|
|
bool IsUiProcessor;
|
2017-02-03 18:34:34 +00:00
|
|
|
bool RequireMouse;
|
2017-02-02 17:57:00 +00:00
|
|
|
|
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);
|
2017-02-09 13:35:45 +00:00
|
|
|
/*
|
2017-01-23 22:17:12 +00:00
|
|
|
if (arc.isReading())
|
|
|
|
{
|
|
|
|
Printf("DStaticEventHandler::Serialize: reading object %s\n", GetClass()->TypeName.GetChars());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Printf("DStaticEventHandler::Serialize: store object %s\n", GetClass()->TypeName.GetChars());
|
|
|
|
}
|
2017-02-09 13:35:45 +00:00
|
|
|
*/
|
2017-02-03 10:28:40 +00:00
|
|
|
|
|
|
|
arc("Order", Order);
|
|
|
|
arc("IsUiProcessor", IsUiProcessor);
|
2017-02-03 18:34:34 +00:00
|
|
|
arc("RequireMouse", RequireMouse);
|
2017-01-23 22:17:12 +00:00
|
|
|
}
|
|
|
|
|
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-02-03 10:28:40 +00:00
|
|
|
void OnRegister(); // you can set order and IsUi here.
|
|
|
|
void OnUnregister();
|
|
|
|
|
|
|
|
//
|
|
|
|
void WorldLoaded();
|
|
|
|
void WorldUnloaded();
|
2018-04-14 08:27:48 +00:00
|
|
|
void WorldThingSpawned(AActor* actor);
|
|
|
|
void WorldThingDied(AActor* actor, AActor* inflictor);
|
|
|
|
void WorldThingRevived(AActor* actor);
|
|
|
|
void WorldThingDamaged(AActor* actor, AActor* inflictor, AActor* source, int damage, FName mod, int flags, DAngle angle);
|
|
|
|
void WorldThingDestroyed(AActor* actor);
|
2018-04-14 08:33:17 +00:00
|
|
|
void WorldLinePreActivated(line_t* line, AActor* actor, int activationType, bool* shouldactivate);
|
|
|
|
void WorldLineActivated(line_t* line, AActor* actor, int activationType);
|
2018-11-06 02:59:17 +00:00
|
|
|
int WorldSectorDamaged(sector_t* sector, AActor* source, int damage, FName damagetype, int part, DVector3 position, bool isradius);
|
|
|
|
int WorldLineDamaged(line_t* line, AActor* source, int damage, FName damagetype, int side, DVector3 position, bool isradius);
|
2017-02-03 10:28:40 +00:00
|
|
|
void WorldLightning();
|
|
|
|
void WorldTick();
|
2017-02-02 18:26:56 +00:00
|
|
|
|
|
|
|
//
|
2017-02-03 10:28:40 +00:00
|
|
|
void RenderFrame();
|
2017-03-29 21:51:53 +00:00
|
|
|
void RenderOverlay(EHudState state);
|
2017-02-02 17:57:00 +00:00
|
|
|
|
2017-02-02 18:26:56 +00:00
|
|
|
//
|
2017-02-03 10:28:40 +00:00
|
|
|
void PlayerEntered(int num, bool fromhub);
|
|
|
|
void PlayerRespawned(int num);
|
|
|
|
void PlayerDied(int num);
|
|
|
|
void PlayerDisconnected(int num);
|
2017-02-02 18:26:56 +00:00
|
|
|
|
2017-02-03 10:28:40 +00:00
|
|
|
// return true if handled.
|
2017-03-07 09:43:14 +00:00
|
|
|
bool InputProcess(const event_t* ev);
|
|
|
|
bool UiProcess(const event_t* ev);
|
2017-03-09 12:49:18 +00:00
|
|
|
void UiTick();
|
2018-03-09 01:06:41 +00:00
|
|
|
void PostUiTick();
|
2017-02-06 13:52:20 +00:00
|
|
|
|
|
|
|
//
|
2017-03-06 09:25:30 +00:00
|
|
|
void ConsoleProcess(int player, FString name, int arg1, int arg2, int arg3, bool manual);
|
2018-08-15 15:46:03 +00:00
|
|
|
|
|
|
|
//
|
2018-08-16 18:46:40 +00:00
|
|
|
void CheckReplacement(PClassActor* replacee, PClassActor** replacement, bool* final);
|
2019-01-28 00:03:04 +00:00
|
|
|
void CheckReplacee(PClassActor** replacee, PClassActor* replacement, bool* final);
|
2018-09-15 02:57:07 +00:00
|
|
|
|
|
|
|
//
|
|
|
|
void NewGame();
|
2017-01-22 00:33:53 +00:00
|
|
|
};
|
2017-01-22 06:56:57 +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; }
|
|
|
|
};
|
2017-01-22 00:33:53 +00:00
|
|
|
|
2017-03-06 21:27:51 +00:00
|
|
|
struct FRenderEvent
|
2017-01-30 23:28:47 +00:00
|
|
|
{
|
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;
|
2017-03-06 21:27:51 +00:00
|
|
|
double FracTic = 0; // 0..1 value that describes where we are inside the current gametic, render-wise.
|
|
|
|
AActor* Camera = nullptr;
|
2017-03-29 21:51:53 +00:00
|
|
|
int HudState;
|
2017-01-22 06:56:57 +00:00
|
|
|
};
|
2017-01-22 00:33:53 +00:00
|
|
|
|
2017-03-06 21:27:51 +00:00
|
|
|
struct FWorldEvent
|
2017-01-30 06:47:15 +00:00
|
|
|
{
|
2017-01-30 23:28:47 +00:00
|
|
|
// for loaded/unloaded
|
2017-03-06 21:27:51 +00:00
|
|
|
bool IsSaveGame = false;
|
|
|
|
bool IsReopen = false;
|
2017-01-30 23:28:47 +00:00
|
|
|
// for thingspawned, thingdied, thingdestroyed
|
2017-03-06 21:27:51 +00:00
|
|
|
AActor* Thing = nullptr; // for thingdied
|
|
|
|
AActor* Inflictor = nullptr; // can be null - for damagemobj
|
|
|
|
AActor* DamageSource = nullptr; // can be null
|
2018-11-06 02:59:17 +00:00
|
|
|
int Damage = 0; // thingdamaged, sector/line damaged
|
|
|
|
FName DamageType = NAME_None; // thingdamaged, sector/line damaged
|
|
|
|
int DamageFlags = 0; // thingdamaged
|
|
|
|
DAngle DamageAngle; // thingdamaged
|
2018-03-24 14:59:20 +00:00
|
|
|
// for line(pre)activated
|
2018-03-17 15:01:47 +00:00
|
|
|
line_t* ActivatedLine = nullptr;
|
2018-04-14 08:33:17 +00:00
|
|
|
int ActivationType = 0;
|
2018-03-24 14:59:20 +00:00
|
|
|
bool ShouldActivate = true;
|
2018-11-06 02:59:17 +00:00
|
|
|
// for line/sector damaged
|
|
|
|
int DamageSectorPart = 0;
|
|
|
|
line_t* DamageLine = nullptr;
|
|
|
|
sector_t* DamageSector = nullptr;
|
|
|
|
int DamageLineSide = -1;
|
|
|
|
DVector3 DamagePosition;
|
|
|
|
bool DamageIsRadius; // radius damage yes/no
|
|
|
|
int NewDamage = 0; // sector/line damaged. allows modifying damage
|
2017-01-30 06:47:15 +00:00
|
|
|
};
|
|
|
|
|
2017-03-06 21:27:51 +00:00
|
|
|
struct FPlayerEvent
|
2017-02-02 18:26:56 +00:00
|
|
|
{
|
|
|
|
// 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;
|
|
|
|
};
|
|
|
|
|
2017-03-06 21:27:51 +00:00
|
|
|
struct FUiEvent
|
2017-02-03 10:28:40 +00:00
|
|
|
{
|
|
|
|
// this essentially translates event_t UI events to ZScript.
|
|
|
|
EGUIEvent Type;
|
|
|
|
// for keys/chars/whatever
|
|
|
|
FString KeyString;
|
|
|
|
int KeyChar;
|
|
|
|
// for mouse
|
|
|
|
int MouseX;
|
|
|
|
int MouseY;
|
|
|
|
// global (?)
|
|
|
|
bool IsShift;
|
|
|
|
bool IsCtrl;
|
|
|
|
bool IsAlt;
|
|
|
|
|
2017-03-07 09:43:14 +00:00
|
|
|
FUiEvent(const event_t *ev);
|
2017-02-03 10:28:40 +00:00
|
|
|
};
|
|
|
|
|
2017-03-06 21:27:51 +00:00
|
|
|
struct FInputEvent
|
2017-02-03 10:28:40 +00:00
|
|
|
{
|
|
|
|
// this translates regular event_t events to ZScript (not UI, UI events are sent via DUiEvent and only if requested!)
|
2017-03-06 21:27:51 +00:00
|
|
|
EGenericEvent Type = EV_None;
|
2017-02-03 10:28:40 +00:00
|
|
|
// for keys
|
|
|
|
int KeyScan;
|
|
|
|
FString KeyString;
|
|
|
|
int KeyChar;
|
|
|
|
// for mouse
|
|
|
|
int MouseX;
|
|
|
|
int MouseY;
|
|
|
|
|
2017-03-07 09:43:14 +00:00
|
|
|
FInputEvent(const event_t *ev);
|
2017-02-03 10:28:40 +00:00
|
|
|
};
|
|
|
|
|
2017-03-06 21:27:51 +00:00
|
|
|
struct FConsoleEvent
|
2017-02-06 13:52:20 +00:00
|
|
|
{
|
|
|
|
// player that activated this event. note that it's always -1 for non-playsim events (i.e. these not called with netevent)
|
|
|
|
int Player;
|
|
|
|
//
|
|
|
|
FString Name;
|
|
|
|
int Args[3];
|
2017-03-06 09:25:30 +00:00
|
|
|
//
|
|
|
|
bool IsManual;
|
2017-02-06 13:52:20 +00:00
|
|
|
};
|
|
|
|
|
2018-08-15 15:46:03 +00:00
|
|
|
struct FReplaceEvent
|
|
|
|
{
|
|
|
|
PClassActor* Replacee;
|
|
|
|
PClassActor* Replacement;
|
2018-08-16 18:46:40 +00:00
|
|
|
bool IsFinal;
|
2018-08-15 15:46:03 +00:00
|
|
|
};
|
|
|
|
|
2019-01-28 00:03:04 +00:00
|
|
|
struct FReplacedEvent
|
|
|
|
{
|
|
|
|
PClassActor* Replacee;
|
|
|
|
PClassActor* Replacement;
|
|
|
|
bool IsFinal;
|
|
|
|
};
|
|
|
|
|
2019-02-02 09:46:34 +00:00
|
|
|
struct EventManager
|
|
|
|
{
|
|
|
|
DStaticEventHandler* FirstEventHandler = nullptr;
|
|
|
|
DStaticEventHandler* LastEventHandler = nullptr;
|
|
|
|
|
|
|
|
// register
|
|
|
|
bool RegisterHandler(DStaticEventHandler* handler);
|
|
|
|
// unregister
|
|
|
|
bool UnregisterHandler(DStaticEventHandler* handler);
|
|
|
|
// find
|
|
|
|
bool CheckHandler(DStaticEventHandler* handler);
|
|
|
|
// check type
|
|
|
|
bool IsStaticType(PClass* type);
|
|
|
|
// init static handlers
|
|
|
|
void InitStaticHandlers(bool map);
|
|
|
|
// shutdown handlers
|
|
|
|
void Shutdown(bool map);
|
|
|
|
|
|
|
|
// called right after the map has loaded (approximately same time as OPEN ACS scripts)
|
|
|
|
void WorldLoaded();
|
|
|
|
// called when the map is about to unload (approximately same time as UNLOADING ACS scripts)
|
|
|
|
void WorldUnloaded();
|
|
|
|
// called right after the map has loaded (every time, UNSAFE VERSION)
|
|
|
|
void WorldLoadedUnsafe();
|
|
|
|
// called right before the map is unloaded (every time, UNSAFE VERSION)
|
|
|
|
void WorldUnloadedUnsafe();
|
|
|
|
// called around PostBeginPlay of each actor.
|
|
|
|
void WorldThingSpawned(AActor* actor);
|
|
|
|
// called after AActor::Die of each actor.
|
|
|
|
void WorldThingDied(AActor* actor, AActor* inflictor);
|
|
|
|
// called after AActor::Revive.
|
|
|
|
void WorldThingRevived(AActor* actor);
|
|
|
|
// called before P_DamageMobj and before AActor::DamageMobj virtuals.
|
|
|
|
void WorldThingDamaged(AActor* actor, AActor* inflictor, AActor* source, int damage, FName mod, int flags, DAngle angle);
|
|
|
|
// called before AActor::Destroy of each actor.
|
|
|
|
void WorldThingDestroyed(AActor* actor);
|
|
|
|
// called in P_ActivateLine before executing special, set shouldactivate to false to prevent activation.
|
|
|
|
void WorldLinePreActivated(line_t* line, AActor* actor, int activationType, bool* shouldactivate);
|
|
|
|
// called in P_ActivateLine after successful special execution.
|
|
|
|
void WorldLineActivated(line_t* line, AActor* actor, int activationType);
|
|
|
|
// called in P_DamageSector and P_DamageLinedef before receiving damage to the sector. returns actual damage
|
|
|
|
int WorldSectorDamaged(sector_t* sector, AActor* source, int damage, FName damagetype, int part, DVector3 position, bool isradius);
|
|
|
|
// called in P_DamageLinedef before receiving damage to the linedef. returns actual damage
|
|
|
|
int WorldLineDamaged(line_t* line, AActor* source, int damage, FName damagetype, int side, DVector3 position, bool isradius);
|
|
|
|
// same as ACS SCRIPT_Lightning
|
|
|
|
void WorldLightning();
|
|
|
|
// this executes on every tick, before everything, only when in valid level and not paused
|
|
|
|
void WorldTick();
|
|
|
|
// this executes on every tick on UI side, always
|
|
|
|
void UiTick();
|
|
|
|
// this executes on every tick on UI side, always AND immediately after everything else
|
|
|
|
void PostUiTick();
|
|
|
|
// called on each render frame once.
|
|
|
|
void RenderFrame();
|
|
|
|
// called after everything's been rendered, but before console/menus
|
|
|
|
void RenderOverlay(EHudState state);
|
|
|
|
// this executes when a player enters the level (once). PlayerEnter+inhub = RETURN
|
|
|
|
void PlayerEntered(int num, bool fromhub);
|
|
|
|
// this executes when a player respawns. includes resurrect cheat.
|
|
|
|
void PlayerRespawned(int num);
|
|
|
|
// this executes when a player dies (partially duplicating worldthingdied, but whatever)
|
|
|
|
void PlayerDied(int num);
|
|
|
|
// this executes when a player leaves the game
|
|
|
|
void PlayerDisconnected(int num);
|
|
|
|
// this executes on events.
|
|
|
|
bool Responder(const event_t* ev); // splits events into InputProcess and UiProcess
|
|
|
|
// this executes on console/net events.
|
|
|
|
void Console(int player, FString name, int arg1, int arg2, int arg3, bool manual);
|
|
|
|
|
|
|
|
// called when looking up the replacement for an actor class
|
|
|
|
bool CheckReplacement(PClassActor* replacee, PClassActor** replacement);
|
|
|
|
// called when looking up the replaced for an actor class
|
|
|
|
bool CheckReplacee(PClassActor** replacee, PClassActor* replacement);
|
|
|
|
|
|
|
|
// called on new game
|
|
|
|
void NewGame(EventHandlerType handlerType);
|
|
|
|
|
|
|
|
// send networked event. unified function.
|
|
|
|
bool SendNetworkEvent(FString name, int arg1, int arg2, int arg3, bool manual);
|
|
|
|
|
|
|
|
// check if there is anything that should receive GUI events
|
|
|
|
bool CheckUiProcessors();
|
|
|
|
// check if we need native mouse due to UiProcessors
|
|
|
|
bool CheckRequireMouse();
|
|
|
|
|
|
|
|
// serialization stuff
|
|
|
|
void SerializeEvents(FSerializer& arc);
|
|
|
|
|
|
|
|
void InitHandler(PClass* type);
|
|
|
|
FWorldEvent SetupWorldEvent();
|
|
|
|
FRenderEvent SetupRenderEvent();
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
extern EventManager eventManager;
|
|
|
|
|
2018-03-17 15:01:47 +00:00
|
|
|
#endif
|