From fceaa55824a6d74ff226ff88dc9d1f01c95cd647 Mon Sep 17 00:00:00 2001 From: Marrub Date: Tue, 2 Apr 2019 13:37:02 -0400 Subject: [PATCH] add documentation for most of the event handling stuff --- api-base-Thinker.md | 2 +- api-drawing-BrokenLines.md | 2 +- api-drawing-Shape2D.md | 2 +- api-events-ConsoleEvent.md | 36 +++++ api-events-EventHandler.md | 34 +++++ api-events-RenderEvent.md | 44 ++++++ api-events-ReplaceEvent.md | 30 ++++ api-events-StaticEventHandler.md | 249 +++++++++++++++++++++++++++++++ api-inter-InterBackground.md | 2 +- api-inter-StatusScreen.md | 2 +- api-level-LineIdIterator.md | 2 +- api-sound-SeqNode.md | 2 +- api-wep-PSprite.md | 2 +- api.md | 6 +- entry.md | 6 +- 15 files changed, 409 insertions(+), 12 deletions(-) create mode 100644 api-events-ConsoleEvent.md create mode 100644 api-events-EventHandler.md create mode 100644 api-events-RenderEvent.md create mode 100644 api-events-ReplaceEvent.md create mode 100644 api-events-StaticEventHandler.md diff --git a/api-base-Thinker.md b/api-base-Thinker.md index feae093..cbd6e52 100644 --- a/api-base-Thinker.md +++ b/api-base-Thinker.md @@ -48,7 +48,7 @@ Thinkers which do think and are mandatory to many checks: | `Thinker.STAT_BOT` | All bot logic. This is not bound to their actor. | ``` -class Thinker play +class Thinker : Object play { const TICRATE; diff --git a/api-drawing-BrokenLines.md b/api-drawing-BrokenLines.md index 82741f8..f57e2da 100644 --- a/api-drawing-BrokenLines.md +++ b/api-drawing-BrokenLines.md @@ -4,7 +4,7 @@ A container representing an array of lines of text that have been broken up to fit the screen and clipping region. ``` -class BrokenLines +class BrokenLines : Object { int Count(); string StringAt(int line); diff --git a/api-drawing-Shape2D.md b/api-drawing-Shape2D.md index be9e08b..9de9cd8 100644 --- a/api-drawing-Shape2D.md +++ b/api-drawing-Shape2D.md @@ -3,7 +3,7 @@ Represents an arbitrary polygonal 2D shape. ``` -class Shape2D +class Shape2D : Object { void Clear(int which = C_Verts | C_Coords | C_Indices); void PushCoord(vector2 c); diff --git a/api-events-ConsoleEvent.md b/api-events-ConsoleEvent.md new file mode 100644 index 0000000..0184133 --- /dev/null +++ b/api-events-ConsoleEvent.md @@ -0,0 +1,36 @@ +# ConsoleEvent + +The information for a `ConsoleProcess` or `NetworkProcess` event. + +``` +struct ConsoleEvent +{ + readonly int Player; + readonly string Name; + readonly int Args[3]; + readonly bool IsManual; +} +``` + +- `Player` + + The player who created this event, or `-1` if there was no activator. This + will always be positive for `NetworkProcess` events and always `-1` for + `ConsoleProcess` events. + +- `Name` + + The name as provided to `SendNetworkEvent`. Use this to distinguish between + event types. It is favorable to prefix names with the name of your mod or + game so that it will not potentially conflict with other mods. + +- `Args` + + The arguments as provided to `SendNetworkEvent`. + +- `IsManual` + + `true` if this event was created manually, for instance through a console + command. + + diff --git a/api-events-EventHandler.md b/api-events-EventHandler.md new file mode 100644 index 0000000..06f4e2f --- /dev/null +++ b/api-events-EventHandler.md @@ -0,0 +1,34 @@ +# EventHandler + +Event handlers handle events on a per-game or per-map level. This means that +they are registered when you start a new game or map, and un-register when you +finish the game or map. This is unlike `StaticEventHandler`, which registers +when the engine is started, and un-registers when it exits. + +All of the virtual functions on `EventHandler` have empty implementations by +default, so you only need to override the events your event handler needs to +override. + +See `StaticEventHandler` for more information on the events that can be +overridden on this type. + +``` +class EventHandler : StaticEventHandler +{ + clearscope static StaticEventHandler Find(class type); + clearscope static void SendNetworkEvent(string name, int arg1 = 0, int arg2 = 0, int arg3 = 0); +} +``` + +- `Find` + + Finds and returns the `StaticEventHandler` type `type` if it is registered, + or `null` if it does not exist. It should be noted that this is exactly the + same as `StaticEventHandler`'s, and does not actually check for + `EventHandlers`, although due to inheritance will return them correctly. + +- `SendNetworkEvent` + + Sends a network event with no activator. + + diff --git a/api-events-RenderEvent.md b/api-events-RenderEvent.md new file mode 100644 index 0000000..b85f44f --- /dev/null +++ b/api-events-RenderEvent.md @@ -0,0 +1,44 @@ +# RenderEvent + +The information for a `RenderOverlay` event. + +``` +struct RenderEvent +{ + readonly vector3 ViewPos; + readonly double ViewAngle; + readonly double ViewPitch; + readonly double ViewRoll; + readonly double FracTic; + readonly Actor Camera; +} +``` + +- `ViewPos` + + The position at which the camera is at. + +- `ViewAngle` + + The yaw angle of the camera. + +- `ViewPitch` + + The pitch angle of the camera. + +- `ViewRoll` + + The roll angle of the camera. + +- `FracTic` + + A value between 0 and 1 (exclusive) representing the time between the last + game tick and the next game tick. This is most useful for interpolation, and + you can add it to the current game tick to get the real time at which this + event has been called. Precision is not specified. + +- `Camera` + + The actor which is acting as the camera for the player's view. + + diff --git a/api-events-ReplaceEvent.md b/api-events-ReplaceEvent.md new file mode 100644 index 0000000..6494795 --- /dev/null +++ b/api-events-ReplaceEvent.md @@ -0,0 +1,30 @@ +# ReplaceEvent + +The information for a `CheckReplacement` event. You can mutate the variables in +this event to change the result of replacement checking. + +``` +struct ReplaceEvent +{ + readonly class Replacee; + class Replacement; + bool IsFinal; +} +``` + +- `Replacee` + + The actor class which is being replaced. + +- `Replacement` + + What to replace it with. This class type is already effected by skill and + actor definition replacements, so it may be useful to read it. Modify this + to change what the resulting replacement class ends up being. + +- `IsFinal` + + If `true`, the engine will not attempt to continue going down the + replacement chain, and will directly replace the actor with `Replacement`. + + diff --git a/api-events-StaticEventHandler.md b/api-events-StaticEventHandler.md new file mode 100644 index 0000000..68e588d --- /dev/null +++ b/api-events-StaticEventHandler.md @@ -0,0 +1,249 @@ +# StaticEventHandler + +Static event handlers handle events on a per-instance level. This means that +they are registered when you start GZDoom, and un-register when you exit +GZDoom. This is unlike `EventHandler`, which registers when a new game is +started, and un-registers when it ends. Care should be taken to make sure that +variables kept in a static event handler don't interact with the game directly, +or it will act **non-deterministically** and cause a desync. + +All of the virtual functions on `StaticEventHandler` have empty implementations +by default, so you only need to override the events your event handler needs to +override. + +Differences in virtual function behaviour are listed in the `EventHandler` +documentation. + +``` +class StaticEventHandler : Object play +{ + clearscope static StaticEventHandler Find(class type); + + virtual void OnRegister(); + virtual void OnUnregister(); + + virtual void WorldLoaded(WorldEvent e); + virtual void WorldUnloaded(WorldEvent e); + virtual void WorldThingSpawned(WorldEvent e); + virtual void WorldThingDied(WorldEvent e); + virtual void WorldThingRevived(WorldEvent e); + virtual void WorldThingDamaged(WorldEvent e); + virtual void WorldThingDestroyed(WorldEvent e); + virtual void WorldLinePreActivated(WorldEvent e); + virtual void WorldLineActivated(WorldEvent e); + virtual void WorldSectorDamaged(WorldEvent e); + virtual void WorldLineDamaged(WorldEvent e); + virtual void WorldLightning(WorldEvent e); + virtual void WorldTick(); + + virtual ui void RenderOverlay(RenderEvent e); + + virtual void PlayerEntered(PlayerEvent e); + virtual void PlayerRespawned(PlayerEvent e); + virtual void PlayerDied(PlayerEvent e); + virtual void PlayerDisconnected(PlayerEvent e); + + virtual ui bool UiProcess(UiEvent e); + virtual ui void UiTick(); + virtual ui void PostUiTick(); + + virtual ui bool InputProcess(InputEvent e); + + virtual ui void ConsoleProcess(ConsoleEvent e); + virtual void NetworkProcess(ConsoleEvent e); + + virtual void CheckReplacement(ReplaceEvent e); + + virtual void NewGame(); + + void SetOrder(int order); + + readonly int Order; + bool IsUiProcessor; + bool RequireMouse; +} +``` + +- `Find` + + Finds and returns the `StaticEventHandler` type `type` if it is registered, + or `null` if it does not exist. + +- `OnRegister` + + Called when this type is registered. This is where you should set `Order`, + `IsUiProcessor` and `RequireMouse`. + +- `OnUnregister` + + Called when this type is un-registered. With `StaticEventHandler`s this is + called when the engine shuts down, so it isn't particularly useful. + +- `WorldLoaded` + + Called directly after the status bar is attached to the player and after + `REOPEN` ACS scripts are called, just before the display is flushed and + auto-save is done. + +- `WorldUnloaded` + + Called directly after `UNLOADING` ACS scripts, just before the level is + changed. + +- `WorldThingSpawned` + + Called directly after an actor's `PostBeginPlay` function. + +- `WorldThingDied` + + Called after `MorphedDeath`, inventory items have called `OwnerDied`, and + the target is set to the damage source, just before `KILL` ACS scripts are + called and the rest of the death handling is done. + +- `WorldThingRevived` + + Called when an actor is revived, after everything is finished. + +- `WorldThingDamaged` + + Called directly before `Die`, or directly after after `DamageMobj` finishes. + +- `WorldThingDestroyed` + + Called at the beginning of an actor's `OnDestroy` function. + +- `WorldLinePreActivated` + + Called directly after a line is tested for activation, before any other + activation specials are called (such as checking for keys, executing the + line special, etc.) + +- `WorldLineActivated` + + Called directly after a line's special is executed, if it succeeded, before + any other handling (such as changing a switch's texture) is completed. + +- `WorldSectorDamaged` + + Called when a sector is damaged if it has any health groups, before any + other handling is done. + +- `WorldLineDamaged` + + Called when a line is damaged if it has any health groups, before any other + handling is done. + +- `WorldLightning` + + Called when lightning strikes, directly after the sound is played, just + before `LIGHTNING` ACS scripts are called. + +- `WorldTick` + + Called on every world tick, after interpolators are updated, world freeze is + updated, sight counters are reset, particles have run their thinkers, and + players have run their thinkers, just before the status bar is ticked, the + level ticks, thinkers are ticked, and the level time is updated. This is not + called when the game is paused, and its execution is entirely deterministic + regardless of how this event handler is applied. + +- `RenderOverlay` + + Despite the name, this is actually run on the status bar, specifically in + `BaseStatusBar::DrawTopStuff`. It is run after `HudMessage`s are drawn and + power-ups are drawn, just before ゴゴゴ「The Log」ゴゴゴ is drawn. You may + use `Screen` functions in this function. + +- `PlayerEntered` + + Called during level load when each player enters the game, after the camera + is set but just before `RETURN` ACS scripts are called. + +- `PlayerRespawned` + + Called when a player spawns, directly after the teleport fog is spanwed and + just before `RESPAWN` ACS scripts are called. Also called similarly at the + end of the `Respawn` function, for example when the `resurrect` cheat is + used. + +- `PlayerDied` + + Called after `WorldThingDied` and `GetDeathHeight`, and after the actor's + thing special is activated, when the obituary has been displayed, just + before `DEATH` ACS scripts have been called. + +- `PlayerDisconnected` + + Called when a bot is removed and when a player disconnects from the game, + just before `DISCONNECT` ACS scripts are called. + +- `UiProcess` + + Called only if `IsUiProcessor` is `true`. Called when a GUI event is + dispatched by the engine, for example when the UI is active and the player + has pressed a key or moved the mouse. Mouse movements will only be captured + if `RequireMouse` is `true`. Because this interacts directly with the OS it + is not part of the game simulation, therefore has `ui` scope and must + dispatch commands to the game as networked events. If the return value is + `true`, the function will block any further handlers from processing this + event, essentially "eating" it. If the return value is `false`, other + handlers will continue to be called as normal. + +- `UiTick` + + Despite what it may seem, this function is actually called deterministically + within the game loop, just before the level is ticked and after the player's + network commands are created. Albeit this, it is `ui` scope, so it should + be used to process UI code. + +- `PostUiTick` + + Similar to `UiTick`, this is also deterministic, but called after all other + tickers. + +- `InputProcess` + + The same as `UiProcess`, but this is only called when inputs are being + directed to the game, rather than to the GUI. All of the same restrictions + apply to this as they do to `UiProcess`, and the return value acts the same. + +- `ConsoleProcess` + + Called when network events which have no player activator are received. + +- `NetworkProcess` + + Called when network events which have a player activator are received. + +- `CheckReplacement` + + Called during actor replacement, after skill replacement is done, but before + any other replacement (such as actor replacements done in ZScript actor + definitions.) + +- `NewGame` + + Called on a new game, directly after level data is reset and right before + the level is set up. + +- `SetOrder` + + Sets the ordering of this event handler, which can be read from `Order`. + +- `Order` + + The arbitrary ordering of this event handler relative to other ones. Event + handlers with lower ordering numbers have their functions executed first. + You can set this variable with `SetOrder`. + +- `IsUiProcessor` + + If `true`, GUI events will be sent to this event handler through + `UiProcess`. This is mainly for optimization purposes. + +- `RequireMouse` + + If `true`, mouse events will be sent to this event handler through + `InputProcess` and/or `UiProcess`. This is mainly for optimization purposes. + + diff --git a/api-inter-InterBackground.md b/api-inter-InterBackground.md index b5cafb9..289271e 100644 --- a/api-inter-InterBackground.md +++ b/api-inter-InterBackground.md @@ -3,7 +3,7 @@ A class containing an animated intermission background. ``` -class InterBackground play +class InterBackground : Object play { static InterBackground Create(WBStartStruct wbs); diff --git a/api-inter-StatusScreen.md b/api-inter-StatusScreen.md index 478d600..bb8d3dc 100644 --- a/api-inter-StatusScreen.md +++ b/api-inter-StatusScreen.md @@ -13,7 +13,7 @@ Status screens have four stages: These are provided as constants in `StatusScreen`. The starting stage is `StatCount`. ``` -class StatusScreen abstract play +class StatusScreen : Object abstract play { const NG_STATSY; const SHOWNEXTLOCDELAY; diff --git a/api-level-LineIdIterator.md b/api-level-LineIdIterator.md index af96385..3ae8c33 100644 --- a/api-level-LineIdIterator.md +++ b/api-level-LineIdIterator.md @@ -3,7 +3,7 @@ Iterates over line indices with a specified tag. ``` -class LineIdIterator +class LineIdIterator : Object { static LineIdIterator Create(int tag); diff --git a/api-sound-SeqNode.md b/api-sound-SeqNode.md index e2eb9c6..7657aec 100644 --- a/api-sound-SeqNode.md +++ b/api-sound-SeqNode.md @@ -3,7 +3,7 @@ A sound sequence (`SNDSEQ`) node. ``` -class SeqNode +class SeqNode : Object { static name GetSequenceSlot(int sequence, int type); static void MarkPrecacheSounds(int sequence, int type); diff --git a/api-wep-PSprite.md b/api-wep-PSprite.md index 9ac1111..7388d84 100644 --- a/api-wep-PSprite.md +++ b/api-wep-PSprite.md @@ -17,7 +17,7 @@ The predefined layers are: | `PSprite.Weapon` | `1` | The default layer for all weapons. | ``` -class PSprite play +class PSprite : Object play { readonly State CurState; readonly int ID; diff --git a/api.md b/api.md index b10a2b1..f4ce950 100644 --- a/api.md +++ b/api.md @@ -77,7 +77,11 @@ TODO - +* [ConsoleEvent](api-events-ConsoleEvent.md) +* [EventHandler](api-events-EventHandler.md) +* [RenderEvent](api-events-RenderEvent.md) +* [ReplaceEvent](api-events-ReplaceEvent.md) +* [StaticEventHandler](api-events-StaticEventHandler.md) diff --git a/entry.md b/entry.md index 5138aeb..3bf22d2 100644 --- a/entry.md +++ b/entry.md @@ -73,9 +73,9 @@ class MyOtherActor : Actor replaces OtherActor {} // OtherActor will now be repl # Console Commands While ZScript cannot be directly called by console commands, one can use the -`event` and `netevent` console commands. `event` will call the `ConsoleProcess` -event handler, or `NetworkProcess` if it was not called by a player. `netevent` -acts the same as `EventHandler::SendNetworkEvent`. +`event` and `netevent` console commands. `event` will dispatch a non-player +network event, and `netevent` will dispatch a network event for the player that +ran it. # CVARINFO