diff --git a/source/Event/Global.cpp b/source/Event/Global.cpp index 5b4984a7..ab7ad31e 100644 --- a/source/Event/Global.cpp +++ b/source/Event/Global.cpp @@ -1,67 +1,2239 @@ #include "Event/Global.hpp" +#include "Register.hpp" +#include "Entity.hpp" +#include "Core.hpp" // ------------------------------------------------------------------------------------------------ namespace SqMod { // ------------------------------------------------------------------------------------------------ GlobalEvent::GlobalEvent() noexcept + : GlobalEvent(EVT_UNKNOWN, false) { - + /* ... */ } // ------------------------------------------------------------------------------------------------ GlobalEvent::GlobalEvent(SQInt32 type) noexcept + : GlobalEvent(type, false) { - + /* ... */ } // ------------------------------------------------------------------------------------------------ GlobalEvent::GlobalEvent(SQInt32 type, bool suspended) noexcept + : m_Type(type) + , m_Stride(0) + , m_Ignore(0) + , m_Primary(SQMOD_UNKNOWN) + , m_Secondary(SQMOD_UNKNOWN) + , m_Idle() + , m_OnTrigger() + , m_OnInclude() + , m_OnExclude() + , m_OnCleared() + , m_OnRelease() + , m_Tag() + , m_Data() + , m_Confined(false) + , m_Suspended(suspended) + , m_Blips(this) + , m_Checkpoints(this) + , m_Keybinds(this) + , m_Objects(this) + , m_Pickups(this) + , m_Players(this) + , m_Spheres(this) + , m_Sprites(this) + , m_Textdraws(this) + , m_Vehicles(this) { - + // Attach to the specified event signal + Attach(); + /* Entity filters are empty so there's nothing to hook to! */ } // ------------------------------------------------------------------------------------------------ GlobalEvent::GlobalEvent(const GlobalEvent & o) noexcept + : m_Type(o.m_Type) + , m_Stride(o.m_Stride) + , m_Ignore(o.m_Ignore) + , m_Primary(o.m_Primary) + , m_Secondary(o.m_Secondary) + , m_Idle(o.m_Idle) + , m_OnTrigger(o.m_OnTrigger) + , m_OnInclude(o.m_OnInclude) + , m_OnExclude(o.m_OnExclude) + , m_OnCleared(o.m_OnCleared) + , m_OnRelease(o.m_OnRelease) + , m_Tag(o.m_Tag) + , m_Data(o.m_Data) + , m_Confined(o.m_Confined) + , m_Suspended(o.m_Suspended) + , m_Blips(o.m_Blips) + , m_Checkpoints(o.m_Checkpoints) + , m_Keybinds(o.m_Keybinds) + , m_Objects(o.m_Objects) + , m_Pickups(o.m_Pickups) + , m_Players(o.m_Players) + , m_Spheres(o.m_Spheres) + , m_Sprites(o.m_Sprites) + , m_Textdraws(o.m_Textdraws) + , m_Vehicles(o.m_Vehicles) { - -} - -// ------------------------------------------------------------------------------------------------ -GlobalEvent::GlobalEvent(GlobalEvent && o) noexcept -{ + /* The filter copy constructor should already take care of hooking to the copied entities! */ } // ------------------------------------------------------------------------------------------------ GlobalEvent::~GlobalEvent() { - + // Detach from the specified event signal + Detach(); + /* We're expecting the entity filters to unhook themselves from the destroy signal! */ } // ------------------------------------------------------------------------------------------------ GlobalEvent & GlobalEvent::operator = (const GlobalEvent & o) noexcept { + // Make sure we're not doing self assignment + if (this != &o) + { + // Clear anything that cannot adapt to the new event type + Adaptable(o.m_Type); + // Now it's safe to copy the values from the other event instance + m_Type = o.m_Type; + m_Stride = o.m_Stride; + m_Ignore = o.m_Ignore; + m_Primary = o.m_Primary; + m_Secondary = o.m_Secondary; + m_Idle = o.m_Idle; + m_OnTrigger = o.m_OnTrigger; + m_OnInclude = o.m_OnInclude; + m_OnExclude = o.m_OnExclude; + m_OnCleared = o.m_OnCleared; + m_OnRelease = o.m_OnRelease; + m_Tag = o.m_Tag; + m_Data = o.m_Data; + m_Confined = o.m_Confined; + m_Suspended = o.m_Suspended; + m_Blips = o.m_Blips; + m_Checkpoints = o.m_Checkpoints; + m_Keybinds = o.m_Keybinds; + m_Objects = o.m_Objects; + m_Pickups = o.m_Pickups; + m_Players = o.m_Players; + m_Spheres = o.m_Spheres; + m_Sprites = o.m_Sprites; + m_Textdraws = o.m_Textdraws; + m_Vehicles = o.m_Vehicles; + /* The filter copy assignment should already take care of hooking to the copied entities! */ + } + return *this; } // ------------------------------------------------------------------------------------------------ -GlobalEvent & GlobalEvent::operator = (GlobalEvent && o) noexcept +bool GlobalEvent::operator == (const GlobalEvent & o) const noexcept { - return *this; + return (m_Type == o.m_Type); +} + +// ------------------------------------------------------------------------------------------------ +bool GlobalEvent::operator != (const GlobalEvent & o) const noexcept +{ + return (m_Type != o.m_Type); +} + +// ------------------------------------------------------------------------------------------------ +bool GlobalEvent::operator < (const GlobalEvent & o) const noexcept +{ + return (m_Type < o.m_Type); +} + +// ------------------------------------------------------------------------------------------------ +bool GlobalEvent::operator > (const GlobalEvent & o) const noexcept +{ + return (m_Type > o.m_Type); +} + +// ------------------------------------------------------------------------------------------------ +bool GlobalEvent::operator <= (const GlobalEvent & o) const noexcept +{ + return (m_Type <= o.m_Type); +} + +// ------------------------------------------------------------------------------------------------ +bool GlobalEvent::operator >= (const GlobalEvent & o) const noexcept +{ + return (m_Type >= o.m_Type); +} + +// ------------------------------------------------------------------------------------------------ +SQInt32 GlobalEvent::Cmp(const GlobalEvent & o) const noexcept +{ + if (m_Type == o.m_Type) + { + return 0; + } + else if (m_Type > o.m_Type) + { + return 1; + } + else + { + return -1; + } +} + +// ------------------------------------------------------------------------------------------------ +const SQChar * GlobalEvent::GetName() const noexcept +{ + return GetEventName(m_Type); +} + +// ------------------------------------------------------------------------------------------------ +const SQChar * GlobalEvent::GetTag() const noexcept +{ + return m_Tag.c_str(); +} + +void GlobalEvent::SetTag(const SQChar * tag) noexcept +{ + m_Tag = tag; +} + +// ------------------------------------------------------------------------------------------------ +SqObj & GlobalEvent::GetData() noexcept +{ + return m_Data; +} + +void GlobalEvent::SetData(SqObj & data) noexcept +{ + m_Data = data; +} + +// ------------------------------------------------------------------------------------------------ +SQInt32 GlobalEvent::GetType() const noexcept +{ + return m_Type; +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::SetType(SQInt32 type) noexcept +{ + // Make sure the newly specified event is compatible + if (!Compatible(type)) + { + LogErr("Cannot change the event to an incompatible type: %s", GetEventName(type)); + } + else + { + // Clear anything that cannot adapt to the new event type + Adaptable(type); + // Detach from the current event type + Detach(); + // Set the new event type + m_Type = type; + // Attach to the new event type + Attach(); + /* We don't need to hook back filters that could adapt because they're already hooked! */ + } +} + +// ------------------------------------------------------------------------------------------------ +SQInteger GlobalEvent::GetIdle() const noexcept +{ + return _SCSQI(std::chrono::duration_cast(m_Idle - std::chrono::steady_clock::now()).count()); +} + +void GlobalEvent::SetIdle(SQInteger millis) noexcept +{ + m_Idle = (std::chrono::steady_clock::now() + std::chrono::milliseconds(_SCI64(millis))); +} + +bool GlobalEvent::IsIdle() const noexcept +{ + return (m_Idle > std::chrono::steady_clock::now()); +} + +// ------------------------------------------------------------------------------------------------ +SQInt32 GlobalEvent::GetStride() const noexcept +{ + return m_Stride; +} + +void GlobalEvent::SetStride(SQInt32 stride) noexcept +{ + m_Stride = stride > 0 ? stride : 0; +} + +// ------------------------------------------------------------------------------------------------ +SQInt32 GlobalEvent::GetIgnore() const noexcept +{ + return m_Ignore; +} + +void GlobalEvent::SetIgnore(SQInt32 ignore) noexcept +{ + m_Ignore = ignore > 0 ? ignore : 0; +} + +// ------------------------------------------------------------------------------------------------ +SQInt32 GlobalEvent::GetPrimary() const noexcept +{ + return m_Primary; +} + +void GlobalEvent::SetPrimary(SQInt32 subset) noexcept +{ + m_Primary = subset; +} + +// ------------------------------------------------------------------------------------------------ +SQInt32 GlobalEvent::GetSecondary() const noexcept +{ + return m_Secondary; +} + +void GlobalEvent::SetSecondary(SQInt32 subset) noexcept +{ + m_Secondary = subset; +} + +// ------------------------------------------------------------------------------------------------ +bool GlobalEvent::GetSuspended() const noexcept +{ + return m_Suspended; +} + +void GlobalEvent::SetSuspended(bool toggle) noexcept +{ + m_Suspended = toggle; +} + +// ------------------------------------------------------------------------------------------------ +bool GlobalEvent::GetConfined() const noexcept +{ + return m_Confined; +} + +void GlobalEvent::SetConfined(bool toggle) noexcept +{ + m_Confined = toggle; +} + +// ------------------------------------------------------------------------------------------------ +Function GlobalEvent::GetOnTrigger() const noexcept +{ + return m_OnTrigger; +} + +void GlobalEvent::SetOnTrigger(const Function & func) noexcept +{ + m_OnTrigger = func; +} + +// ------------------------------------------------------------------------------------------------ +Function GlobalEvent::GetOnInclude() const noexcept +{ + return m_OnInclude; +} + +void GlobalEvent::SetOnInclude(const Function & func) noexcept +{ + m_OnInclude = func; +} + +// ------------------------------------------------------------------------------------------------ +Function GlobalEvent::GetOnExclude() const noexcept +{ + return m_OnExclude; +} + +void GlobalEvent::SetOnExclude(const Function & func) noexcept +{ + m_OnExclude = func; +} + +// ------------------------------------------------------------------------------------------------ +Function GlobalEvent::GetOnCleared() const noexcept +{ + return m_OnCleared; +} + +void GlobalEvent::SetOnCleared(const Function & func) noexcept +{ + m_OnCleared = func; +} + +// ------------------------------------------------------------------------------------------------ +Function GlobalEvent::GetOnRelease() const noexcept +{ + return m_OnRelease; +} + +void GlobalEvent::SetOnRelease(const Function & func) noexcept +{ + m_OnRelease = func; +} + +// ------------------------------------------------------------------------------------------------ +GlobalEvent::BlipFilter & GlobalEvent::GetBlipFilter() noexcept +{ + return m_Blips; /* This reference should not be stored anywhere! */ +} + +// ------------------------------------------------------------------------------------------------ +GlobalEvent::CheckpointFilter & GlobalEvent::GetCheckpointFilter() noexcept +{ + return m_Checkpoints; /* This reference should not be stored anywhere! */ +} + +// ------------------------------------------------------------------------------------------------ +GlobalEvent::KeybindFilter & GlobalEvent::GetKeybindFilter() noexcept +{ + return m_Keybinds; /* This reference should not be stored anywhere! */ +} + +// ------------------------------------------------------------------------------------------------ +GlobalEvent::ObjectFilter & GlobalEvent::GetObjectFilter() noexcept +{ + return m_Objects; /* This reference should not be stored anywhere! */ +} + +// ------------------------------------------------------------------------------------------------ +GlobalEvent::PickupFilter & GlobalEvent::GetPickupFilter() noexcept +{ + return m_Pickups; /* This reference should not be stored anywhere! */ +} + +// ------------------------------------------------------------------------------------------------ +GlobalEvent::PlayerFilter & GlobalEvent::GetPlayerFilter() noexcept +{ + return m_Players; /* This reference should not be stored anywhere! */ +} + +// ------------------------------------------------------------------------------------------------ +GlobalEvent::SphereFilter & GlobalEvent::GetSphereFilter() noexcept +{ + return m_Spheres; /* This reference should not be stored anywhere! */ +} + +// ------------------------------------------------------------------------------------------------ +GlobalEvent::SpriteFilter & GlobalEvent::GetSpriteFilter() noexcept +{ + return m_Sprites; /* This reference should not be stored anywhere! */ +} + +// ------------------------------------------------------------------------------------------------ +GlobalEvent::TextdrawFilter & GlobalEvent::GetTextdrawFilter() noexcept +{ + return m_Textdraws; /* This reference should not be stored anywhere! */ +} + +// ------------------------------------------------------------------------------------------------ +GlobalEvent::VehicleFilter & GlobalEvent::GetVehicleFilter() noexcept +{ + return m_Vehicles; /* This reference should not be stored anywhere! */ +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::BlipDestroyed(SQInt32 blip, SQInt32 header, Object & payload) noexcept +{ + // If the entity was included then block the signal an exclude it from filters + if (m_Blips.m_Filter[blip]) + { + m_Blips.Release(blip); + } + else if (Trigger() && \ + (m_Primary < 0 || header == m_Primary) && (m_Secondary < 0 || header == m_Secondary)) + { + m_OnTrigger.Execute< SQInt32, SQInt32, Object & >(blip, header, payload); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::CheckpointDestroyed(SQInt32 checkpoint, SQInt32 header, Object & payload) noexcept +{ + // If the entity was included then block the signal an exclude it from filters + if (m_Checkpoints.m_Filter[checkpoint]) + { + m_Checkpoints.Release(checkpoint); + } + else if (Trigger() && \ + (m_Primary < 0 || header == m_Primary) && (m_Secondary < 0 || header == m_Secondary)) + { + m_OnTrigger.Execute< SQInt32, SQInt32, Object & >(checkpoint, header, payload); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::KeybindDestroyed(SQInt32 keybind, SQInt32 header, Object & payload) noexcept +{ + // If the entity was included then block the signal an exclude it from filters + if (m_Keybinds.m_Filter[keybind]) + { + m_Keybinds.Release(keybind); + } + else if (Trigger() && \ + (m_Primary < 0 || header == m_Primary) && (m_Secondary < 0 || header == m_Secondary)) + { + m_OnTrigger.Execute< SQInt32, SQInt32, Object & >(keybind, header, payload); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::ObjectDestroyed(SQInt32 object, SQInt32 header, Object & payload) noexcept +{ + // If the entity was included then block the signal an exclude it from filters + if (m_Objects.m_Filter[object]) + { + m_Objects.Release(object); + } + else if (Trigger() && \ + (m_Primary < 0 || header == m_Primary) && (m_Secondary < 0 || header == m_Secondary)) + { + m_OnTrigger.Execute< SQInt32, SQInt32, Object & >(object, header, payload); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::PickupDestroyed(SQInt32 pickup, SQInt32 header, Object & payload) noexcept +{ + // If the entity was included then block the signal an exclude it from filters + if (m_Pickups.m_Filter[pickup]) + { + m_Pickups.Release(pickup); + } + else if (Trigger() && \ + (m_Primary < 0 || header == m_Primary) && (m_Secondary < 0 || header == m_Secondary)) + { + m_OnTrigger.Execute< SQInt32, SQInt32, Object & >(pickup, header, payload); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::PlayerDestroyed(SQInt32 player, SQInt32 header, Object & payload) noexcept +{ + // If the entity was included then block the signal an exclude it from filters + if (m_Players.m_Filter[player]) + { + m_Players.Release(player); + } + else if (Trigger() && \ + (m_Primary < 0 || header == m_Primary) && (m_Secondary < 0 || header == m_Secondary)) + { + m_OnTrigger.Execute< SQInt32, SQInt32, Object & >(player, header, payload); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::SphereDestroyed(SQInt32 sphere, SQInt32 header, Object & payload) noexcept +{ + // If the entity was included then block the signal an exclude it from filters + if (m_Spheres.m_Filter[sphere]) + { + m_Spheres.Release(sphere); + } + else if (Trigger() && \ + (m_Primary < 0 || header == m_Primary) && (m_Secondary < 0 || header == m_Secondary)) + { + m_OnTrigger.Execute< SQInt32, SQInt32, Object & >(sphere, header, payload); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::SpriteDestroyed(SQInt32 sprite, SQInt32 header, Object & payload) noexcept +{ + // If the entity was included then block the signal an exclude it from filters + if (m_Sprites.m_Filter[sprite]) + { + m_Sprites.Release(sprite); + } + else if (Trigger() && \ + (m_Primary < 0 || header == m_Primary) && (m_Secondary < 0 || header == m_Secondary)) + { + m_OnTrigger.Execute< SQInt32, SQInt32, Object & >(sprite, header, payload); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::TextdrawDestroyed(SQInt32 textdraw, SQInt32 header, Object & payload) noexcept +{ + // If the entity was included then block the signal an exclude it from filters + if (m_Textdraws.m_Filter[textdraw]) + { + m_Textdraws.Release(textdraw); + } + else if (Trigger() && \ + (m_Primary < 0 || header == m_Primary) && (m_Secondary < 0 || header == m_Secondary)) + { + m_OnTrigger.Execute< SQInt32, SQInt32, Object & >(textdraw, header, payload); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::VehicleDestroyed(SQInt32 vehicle, SQInt32 header, Object & payload) noexcept +{ + // If the entity was included then block the signal an exclude it from filters + if (m_Vehicles.m_Filter[vehicle]) + { + m_Vehicles.Release(vehicle); + } + else if (Trigger() && \ + (m_Primary < 0 || header == m_Primary) && (m_Secondary < 0 || header == m_Secondary)) + { + m_OnTrigger.Execute< SQInt32, SQInt32, Object & >(vehicle, header, payload); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::BlipCustom(SQInt32 blip, SQInt32 header, Object & payload) noexcept +{ + if (!m_Blips.m_Filter[blip] && Trigger() && \ + (m_Primary < 0 || header == m_Primary) && (m_Secondary < 0 || header == m_Secondary)) + { + m_OnTrigger.Execute< SQInt32, SQInt32, Object & >(blip, header, payload); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::CheckpointCustom(SQInt32 checkpoint, SQInt32 header, Object & payload) noexcept +{ + if (!m_Checkpoints.m_Filter[checkpoint] && Trigger() && \ + (m_Primary < 0 || header == m_Primary) && (m_Secondary < 0 || header == m_Secondary)) + { + m_OnTrigger.Execute< SQInt32, SQInt32, Object & >(checkpoint, header, payload); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::KeybindCustom(SQInt32 keybind, SQInt32 header, Object & payload) noexcept +{ + if (!m_Keybinds.m_Filter[keybind] && Trigger() && \ + (m_Primary < 0 || header == m_Primary) && (m_Secondary < 0 || header == m_Secondary)) + { + m_OnTrigger.Execute< SQInt32, SQInt32, Object & >(keybind, header, payload); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::ObjectCustom(SQInt32 object, SQInt32 header, Object & payload) noexcept +{ + if (!m_Objects.m_Filter[object] && Trigger() && \ + (m_Primary < 0 || header == m_Primary) && (m_Secondary < 0 || header == m_Secondary)) + { + m_OnTrigger.Execute< SQInt32, SQInt32, Object & >(object, header, payload); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::PickupCustom(SQInt32 pickup, SQInt32 header, Object & payload) noexcept +{ + if (!m_Pickups.m_Filter[pickup] && Trigger() && \ + (m_Primary < 0 || header == m_Primary) && (m_Secondary < 0 || header == m_Secondary)) + { + m_OnTrigger.Execute< SQInt32, SQInt32, Object & >(pickup, header, payload); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::PlayerCustom(SQInt32 player, SQInt32 header, Object & payload) noexcept +{ + if (!m_Players.m_Filter[player] && Trigger() && \ + (m_Primary < 0 || header == m_Primary) && (m_Secondary < 0 || header == m_Secondary)) + { + m_OnTrigger.Execute< SQInt32, SQInt32, Object & >(player, header, payload); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::SphereCustom(SQInt32 sphere, SQInt32 header, Object & payload) noexcept +{ + if (!m_Spheres.m_Filter[sphere] && Trigger() && \ + (m_Primary < 0 || header == m_Primary) && (m_Secondary < 0 || header == m_Secondary)) + { + m_OnTrigger.Execute< SQInt32, SQInt32, Object & >(sphere, header, payload); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::SpriteCustom(SQInt32 sprite, SQInt32 header, Object & payload) noexcept +{ + if (!m_Sprites.m_Filter[sprite] && Trigger() && \ + (m_Primary < 0 || header == m_Primary) && (m_Secondary < 0 || header == m_Secondary)) + { + m_OnTrigger.Execute< SQInt32, SQInt32, Object & >(sprite, header, payload); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::TextdrawCustom(SQInt32 textdraw, SQInt32 header, Object & payload) noexcept +{ + if (!m_Textdraws.m_Filter[textdraw] && Trigger() && \ + (m_Primary < 0 || header == m_Primary) && (m_Secondary < 0 || header == m_Secondary)) + { + m_OnTrigger.Execute< SQInt32, SQInt32, Object & >(textdraw, header, payload); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::VehicleCustom(SQInt32 vehicle, SQInt32 header, Object & payload) noexcept +{ + if (!m_Vehicles.m_Filter[vehicle] && Trigger() && \ + (m_Primary < 0 || header == m_Primary) && (m_Secondary < 0 || header == m_Secondary)) + { + m_OnTrigger.Execute< SQInt32, SQInt32, Object & >(vehicle, header, payload); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::PlayerAway(SQInt32 player, bool status) noexcept +{ + if (!m_Players.m_Filter[player] && Trigger() && \ + (m_Primary < 0 || status == m_Primary) && (m_Secondary < 0 || status == m_Secondary)) + { + m_OnTrigger.Execute< SQInt32, bool >(player, status); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::PlayerGameKeys(SQInt32 player, SQInt32 previous, SQInt32 current) noexcept +{ + if (!m_Players.m_Filter[player] && Trigger() && \ + (m_Primary < 0 || previous == m_Primary) && (m_Secondary < 0 || current == m_Secondary)) + { + m_OnTrigger.Execute< SQInt32, SQInt32, SQInt32 >(player, previous, current); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::PlayerRename(SQInt32 player, const SQChar * previous, const SQChar * current) noexcept +{ + if (!m_Players.m_Filter[player] && Trigger()) + { + m_OnTrigger.Execute< SQInt32, const SQChar *, const SQChar * >(player, previous, current); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::PlayerRequestClass(SQInt32 player, SQInt32 offset) noexcept +{ + if (!m_Players.m_Filter[player] && Trigger() && \ + (m_Primary < 0 || offset == m_Primary) && (m_Secondary < 0 || offset == m_Secondary)) + { + m_OnTrigger.Execute< SQInt32, SQInt32 >(player, offset); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::PlayerRequestSpawn(SQInt32 player) noexcept +{ + if (!m_Players.m_Filter[player] && Trigger()) + { + m_OnTrigger.Execute< SQInt32 >(player); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::PlayerSpawn(SQInt32 player) noexcept +{ + if (!m_Players.m_Filter[player] && Trigger()) + { + m_OnTrigger.Execute< SQInt32 >(player); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::PlayerStartTyping(SQInt32 player) noexcept +{ + if (!m_Players.m_Filter[player] && Trigger()) + { + m_OnTrigger.Execute< SQInt32 >(player); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::PlayerStopTyping(SQInt32 player) noexcept +{ + if (!m_Players.m_Filter[player] && Trigger()) + { + m_OnTrigger.Execute< SQInt32 >(player); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::PlayerChat(SQInt32 player, const SQChar * message) noexcept +{ + if (!m_Players.m_Filter[player] && Trigger()) + { + m_OnTrigger.Execute< SQInt32, const SQChar * >(player, message); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::PlayerCommand(SQInt32 player, const SQChar * command) noexcept +{ + if (!m_Players.m_Filter[player] && Trigger()) + { + m_OnTrigger.Execute< SQInt32, const SQChar * >(player, command); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::PlayerMessage(SQInt32 player, SQInt32 receiver, const SQChar * message) noexcept +{ + const char res = (!m_Players.m_Filter[player] << 1) | !m_Players.m_Filter[receiver]; + + if (((m_Confined && res != 3) || (!m_Confined && res != 0)) && Trigger()) + { + m_OnTrigger.Execute< SQInt32, SQInt32, const SQChar * >(player, receiver, message); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::PlayerHealth(SQInt32 player, SQFloat previous, SQFloat current) noexcept +{ + if (!m_Players.m_Filter[player] && Trigger()) + { + m_OnTrigger.Execute< SQInt32, SQFloat, SQFloat >(player, previous, current); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::PlayerArmour(SQInt32 player, SQFloat previous, SQFloat current) noexcept +{ + if (!m_Players.m_Filter[player] && Trigger()) + { + m_OnTrigger.Execute< SQInt32, SQFloat, SQFloat >(player, previous, current); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::PlayerWeapon(SQInt32 player, SQInt32 previous, SQInt32 current) noexcept +{ + if (!m_Players.m_Filter[player] && Trigger() && \ + (m_Primary < 0 || previous == m_Primary) && (m_Secondary < 0 || current == m_Secondary)) + { + m_OnTrigger.Execute< SQInt32, SQInt32, SQInt32 >(player, previous, current); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::PlayerMove(SQInt32 player, const Vector3 & previous, const Vector3 & current) noexcept +{ + if (!m_Players.m_Filter[player] && Trigger()) + { + m_OnTrigger.Execute< SQInt32, const Vector3 &, const Vector3 & >(player, previous, current); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::PlayerWasted(SQInt32 player, SQInt32 reason) noexcept +{ + if (!m_Players.m_Filter[player] && Trigger() && \ + (m_Primary < 0 || reason == m_Primary) && (m_Secondary < 0 || reason == m_Secondary)) + { + m_OnTrigger.Execute< SQInt32, SQInt32 >(player, reason); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::PlayerKilled(SQInt32 player, SQInt32 killer, SQInt32 reason, SQInt32 body_part) noexcept +{ + const char res = (!m_Players.m_Filter[player] << 1) | !m_Players.m_Filter[killer]; + + if (((m_Confined && res != 3) || (!m_Confined && res != 0)) && Trigger() && \ + (m_Primary < 0 || reason == m_Primary) && (m_Secondary < 0 || body_part == m_Secondary)) + { + m_OnTrigger.Execute< SQInt32, SQInt32, SQInt32, SQInt32 >(player, killer, reason, body_part); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::PlayerTeamKill(SQInt32 player, SQInt32 killer, SQInt32 reason, SQInt32 body_part) noexcept +{ + const char res = (!m_Players.m_Filter[player] << 1) | !m_Players.m_Filter[killer]; + + if (((m_Confined && res != 3) || (!m_Confined && res != 0)) && Trigger() && \ + (m_Primary < 0 || reason == m_Primary) && (m_Secondary < 0 || body_part == m_Secondary)) + { + m_OnTrigger.Execute< SQInt32, SQInt32, SQInt32, SQInt32 >(player, killer, reason, body_part); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::PlayerSpectate(SQInt32 player, SQInt32 target) noexcept +{ + const char res = (!m_Players.m_Filter[player] << 1) | !m_Players.m_Filter[target]; + + if (((m_Confined && res != 3) || (!m_Confined && res != 0)) && Trigger()) + { + m_OnTrigger.Execute< SQInt32, SQInt32 >(player, target); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::PlayerCrashreport(SQInt32 player, const SQChar * report) noexcept +{ + if (!m_Players.m_Filter[player] && Trigger()) + { + m_OnTrigger.Execute< SQInt32, const SQChar * >(player, report); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::PlayerBurning(SQInt32 player, bool state) noexcept +{ + if (!m_Players.m_Filter[player] && Trigger() && \ + (m_Primary < 0 || state == m_Primary) && (m_Secondary < 0 || state == m_Secondary)) + { + m_OnTrigger.Execute< SQInt32, bool >(player, state); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::PlayerCrouching(SQInt32 player, bool state) noexcept +{ + if (!m_Players.m_Filter[player] && Trigger() && \ + (m_Primary < 0 || state == m_Primary) && (m_Secondary < 0 || state == m_Secondary)) + { + m_OnTrigger.Execute< SQInt32, bool >(player, state); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::PlayerState(SQInt32 player, SQInt32 previous, SQInt32 current) noexcept +{ + if (!m_Players.m_Filter[player] && Trigger() && \ + (m_Primary < 0 || previous == m_Primary) && (m_Secondary < 0 || current == m_Secondary)) + { + m_OnTrigger.Execute< SQInt32, SQInt32, SQInt32 >(player, previous, current); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::PlayerAction(SQInt32 player, SQInt32 previous, SQInt32 current) noexcept +{ + if (!m_Players.m_Filter[player] && Trigger() && \ + (m_Primary < 0 || previous == m_Primary) && (m_Secondary < 0 || current == m_Secondary)) + { + m_OnTrigger.Execute< SQInt32, SQInt32, SQInt32 >(player, previous, current); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::StateNone(SQInt32 player, SQInt32 previous) noexcept +{ + if (!m_Players.m_Filter[player] && Trigger() && \ + (m_Primary < 0 || previous == m_Primary) && (m_Secondary < 0 || previous == m_Secondary)) + { + m_OnTrigger.Execute< SQInt32, SQInt32 >(player, previous); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::StateNormal(SQInt32 player, SQInt32 previous) noexcept +{ + if (!m_Players.m_Filter[player] && Trigger() && \ + (m_Primary < 0 || previous == m_Primary) && (m_Secondary < 0 || previous == m_Secondary)) + { + m_OnTrigger.Execute< SQInt32, SQInt32 >(player, previous); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::StateShooting(SQInt32 player, SQInt32 previous) noexcept +{ + if (!m_Players.m_Filter[player] && Trigger() && \ + (m_Primary < 0 || previous == m_Primary) && (m_Secondary < 0 || previous == m_Secondary)) + { + m_OnTrigger.Execute< SQInt32, SQInt32 >(player, previous); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::StateDriver(SQInt32 player, SQInt32 previous) noexcept +{ + if (!m_Players.m_Filter[player] && Trigger() && \ + (m_Primary < 0 || previous == m_Primary) && (m_Secondary < 0 || previous == m_Secondary)) + { + m_OnTrigger.Execute< SQInt32, SQInt32 >(player, previous); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::StatePassenger(SQInt32 player, SQInt32 previous) noexcept +{ + if (!m_Players.m_Filter[player] && Trigger() && \ + (m_Primary < 0 || previous == m_Primary) && (m_Secondary < 0 || previous == m_Secondary)) + { + m_OnTrigger.Execute< SQInt32, SQInt32 >(player, previous); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::StateEnterDriver(SQInt32 player, SQInt32 previous) noexcept +{ + if (!m_Players.m_Filter[player] && Trigger() && \ + (m_Primary < 0 || previous == m_Primary) && (m_Secondary < 0 || previous == m_Secondary)) + { + m_OnTrigger.Execute< SQInt32, SQInt32 >(player, previous); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::StateEnterPassenger(SQInt32 player, SQInt32 previous) noexcept +{ + if (!m_Players.m_Filter[player] && Trigger() && \ + (m_Primary < 0 || previous == m_Primary) && (m_Secondary < 0 || previous == m_Secondary)) + { + m_OnTrigger.Execute< SQInt32, SQInt32 >(player, previous); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::StateExitVehicle(SQInt32 player, SQInt32 previous) noexcept +{ + if (!m_Players.m_Filter[player] && Trigger() && \ + (m_Primary < 0 || previous == m_Primary) && (m_Secondary < 0 || previous == m_Secondary)) + { + m_OnTrigger.Execute< SQInt32, SQInt32 >(player, previous); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::StateUnspawned(SQInt32 player, SQInt32 previous) noexcept +{ + if (!m_Players.m_Filter[player] && Trigger() && \ + (m_Primary < 0 || previous == m_Primary) && (m_Secondary < 0 || previous == m_Secondary)) + { + m_OnTrigger.Execute< SQInt32, SQInt32 >(player, previous); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::ActionNone(SQInt32 player, SQInt32 previous) noexcept +{ + if (!m_Players.m_Filter[player] && Trigger() && \ + (m_Primary < 0 || previous == m_Primary) && (m_Secondary < 0 || previous == m_Secondary)) + { + m_OnTrigger.Execute< SQInt32, SQInt32 >(player, previous); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::ActionNormal(SQInt32 player, SQInt32 previous) noexcept +{ + if (!m_Players.m_Filter[player] && Trigger() && \ + (m_Primary < 0 || previous == m_Primary) && (m_Secondary < 0 || previous == m_Secondary)) + { + m_OnTrigger.Execute< SQInt32, SQInt32 >(player, previous); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::ActionAiming(SQInt32 player, SQInt32 previous) noexcept +{ + if (!m_Players.m_Filter[player] && Trigger() && \ + (m_Primary < 0 || previous == m_Primary) && (m_Secondary < 0 || previous == m_Secondary)) + { + m_OnTrigger.Execute< SQInt32, SQInt32 >(player, previous); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::ActionShooting(SQInt32 player, SQInt32 previous) noexcept +{ + if (!m_Players.m_Filter[player] && Trigger() && \ + (m_Primary < 0 || previous == m_Primary) && (m_Secondary < 0 || previous == m_Secondary)) + { + m_OnTrigger.Execute< SQInt32, SQInt32 >(player, previous); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::ActionJumping(SQInt32 player, SQInt32 previous) noexcept +{ + if (!m_Players.m_Filter[player] && Trigger() && \ + (m_Primary < 0 || previous == m_Primary) && (m_Secondary < 0 || previous == m_Secondary)) + { + m_OnTrigger.Execute< SQInt32, SQInt32 >(player, previous); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::ActionLieDown(SQInt32 player, SQInt32 previous) noexcept +{ + if (!m_Players.m_Filter[player] && Trigger() && \ + (m_Primary < 0 || previous == m_Primary) && (m_Secondary < 0 || previous == m_Secondary)) + { + m_OnTrigger.Execute< SQInt32, SQInt32 >(player, previous); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::ActionGettingUp(SQInt32 player, SQInt32 previous) noexcept +{ + if (!m_Players.m_Filter[player] && Trigger() && \ + (m_Primary < 0 || previous == m_Primary) && (m_Secondary < 0 || previous == m_Secondary)) + { + m_OnTrigger.Execute< SQInt32, SQInt32 >(player, previous); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::ActionJumpVehicle(SQInt32 player, SQInt32 previous) noexcept +{ + if (!m_Players.m_Filter[player] && Trigger() && \ + (m_Primary < 0 || previous == m_Primary) && (m_Secondary < 0 || previous == m_Secondary)) + { + m_OnTrigger.Execute< SQInt32, SQInt32 >(player, previous); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::ActionDriving(SQInt32 player, SQInt32 previous) noexcept +{ + if (!m_Players.m_Filter[player] && Trigger() && \ + (m_Primary < 0 || previous == m_Primary) && (m_Secondary < 0 || previous == m_Secondary)) + { + m_OnTrigger.Execute< SQInt32, SQInt32 >(player, previous); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::ActionDying(SQInt32 player, SQInt32 previous) noexcept +{ + if (!m_Players.m_Filter[player] && Trigger() && \ + (m_Primary < 0 || previous == m_Primary) && (m_Secondary < 0 || previous == m_Secondary)) + { + m_OnTrigger.Execute< SQInt32, SQInt32 >(player, previous); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::ActionWasted(SQInt32 player, SQInt32 previous) noexcept +{ + if (!m_Players.m_Filter[player] && Trigger() && \ + (m_Primary < 0 || previous == m_Primary) && (m_Secondary < 0 || previous == m_Secondary)) + { + m_OnTrigger.Execute< SQInt32, SQInt32 >(player, previous); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::ActionEmbarking(SQInt32 player, SQInt32 previous) noexcept +{ + if (!m_Players.m_Filter[player] && Trigger() && \ + (m_Primary < 0 || previous == m_Primary) && (m_Secondary < 0 || previous == m_Secondary)) + { + m_OnTrigger.Execute< SQInt32, SQInt32 >(player, previous); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::ActionDisembarking(SQInt32 player, SQInt32 previous) noexcept +{ + if (!m_Players.m_Filter[player] && Trigger() && \ + (m_Primary < 0 || previous == m_Primary) && (m_Secondary < 0 || previous == m_Secondary)) + { + m_OnTrigger.Execute< SQInt32, SQInt32 >(player, previous); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::VehicleRespawn(SQInt32 vehicle) noexcept +{ + if (!m_Vehicles.m_Filter[vehicle] && Trigger()) + { + m_OnTrigger.Execute< SQInt32 >(vehicle); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::VehicleExplode(SQInt32 vehicle) noexcept +{ + if (!m_Vehicles.m_Filter[vehicle] && Trigger()) + { + m_OnTrigger.Execute< SQInt32 >(vehicle); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::VehicleHealth(SQInt32 vehicle, SQFloat previous, SQFloat current) noexcept +{ + if (!m_Vehicles.m_Filter[vehicle] && Trigger()) + { + m_OnTrigger.Execute< SQInt32, SQFloat, SQFloat >(vehicle, previous, current); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::VehicleMove(SQInt32 vehicle, const Vector3 & previous, const Vector3 ¤t) noexcept +{ + if (!m_Vehicles.m_Filter[vehicle] && Trigger()) + { + m_OnTrigger.Execute< SQInt32, const Vector3 &, const Vector3 & >(vehicle, previous, current); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::PickupRespawn(SQInt32 pickup) noexcept +{ + if (!m_Pickups.m_Filter[pickup] && Trigger()) + { + m_OnTrigger.Execute< SQInt32 >(pickup); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::KeybindKeyPress(SQInt32 player, SQInt32 keybind) noexcept +{ + const char res = (!m_Players.m_Filter[player] << 1) | !m_Keybinds.m_Filter[keybind]; + + if (((m_Confined && res != 3) || (!m_Confined && res != 0)) && Trigger()) + { + m_OnTrigger.Execute< SQInt32, SQInt32 >(player, keybind); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::KeybindKeyRelease(SQInt32 player, SQInt32 keybind) noexcept +{ + const char res = (!m_Players.m_Filter[player] << 1) | !m_Keybinds.m_Filter[keybind]; + + if (((m_Confined && res == 3) || (!m_Confined && res != 0)) && Trigger()) + { + m_OnTrigger.Execute< SQInt32, SQInt32 >(player, keybind); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::VehicleEmbarking(SQInt32 player, SQInt32 vehicle, SQInt32 slot) noexcept +{ + const char res = (!m_Players.m_Filter[player] << 1) | !m_Vehicles.m_Filter[vehicle]; + + if (((m_Confined && res == 3) || (!m_Confined && res != 0)) && Trigger() && \ + (m_Primary < 0 || slot == m_Primary) && (m_Secondary < 0 || slot == m_Secondary)) + { + m_OnTrigger.Execute< SQInt32, SQInt32, SQInt32 >(player, vehicle, slot); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::VehicleEmbarked(SQInt32 player, SQInt32 vehicle, SQInt32 slot) noexcept +{ + const char res = (!m_Players.m_Filter[player] << 1) | !m_Vehicles.m_Filter[vehicle]; + + if (((m_Confined && res == 3) || (!m_Confined && res != 0)) && Trigger() && \ + (m_Primary < 0 || slot == m_Primary) && (m_Secondary < 0 || slot == m_Secondary)) + { + m_OnTrigger.Execute< SQInt32, SQInt32, SQInt32 >(player, vehicle, slot); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::VehicleDisembark(SQInt32 player, SQInt32 vehicle) noexcept +{ + const char res = (!m_Players.m_Filter[player] << 1) | !m_Vehicles.m_Filter[vehicle]; + + if (((m_Confined && res == 3) || (!m_Confined && res != 0)) && Trigger()) + { + m_OnTrigger.Execute< SQInt32, SQInt32 >(player, vehicle); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::PickupClaimed(SQInt32 player, SQInt32 pickup) noexcept +{ + const char res = (!m_Players.m_Filter[player] << 1) | !m_Pickups.m_Filter[pickup]; + + if (((m_Confined && res == 3) || (!m_Confined && res != 0)) && Trigger()) + { + m_OnTrigger.Execute< SQInt32, SQInt32 >(player, pickup); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::PickupCollected(SQInt32 player, SQInt32 pickup) noexcept +{ + const char res = (!m_Players.m_Filter[player] << 1) | !m_Pickups.m_Filter[pickup]; + + if (((m_Confined && res == 3) || (!m_Confined && res != 0)) && Trigger()) + { + m_OnTrigger.Execute< SQInt32, SQInt32 >(player, pickup); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::ObjectShot(SQInt32 player, SQInt32 object, SQInt32 weapon) noexcept +{ + const char res = (!m_Players.m_Filter[player] << 1) | !m_Objects.m_Filter[object]; + + if (((m_Confined && res == 3) || (!m_Confined && res != 0)) && Trigger() && \ + (m_Primary < 0 || weapon == m_Primary) && (m_Secondary < 0 || weapon == m_Secondary)) + { + m_OnTrigger.Execute< SQInt32, SQInt32, SQInt32 >(player, object, weapon); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::ObjectBump(SQInt32 player, SQInt32 object) noexcept +{ + const char res = (!m_Players.m_Filter[player] << 1) | !m_Objects.m_Filter[object]; + + if (((m_Confined && res == 3) || (!m_Confined && res != 0)) && Trigger()) + { + m_OnTrigger.Execute< SQInt32, SQInt32 >(player, object); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::CheckpointEntered(SQInt32 player, SQInt32 checkpoint) noexcept +{ + const char res = (!m_Players.m_Filter[player] << 1) | !m_Checkpoints.m_Filter[checkpoint]; + + if (((m_Confined && res == 3) || (!m_Confined && res != 0)) && Trigger()) + { + m_OnTrigger.Execute< SQInt32, SQInt32 >(player, checkpoint); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::CheckpointExited(SQInt32 player, SQInt32 checkpoint) noexcept +{ + const char res = (!m_Players.m_Filter[player] << 1) | !m_Checkpoints.m_Filter[checkpoint]; + + if (((m_Confined && res == 3) || (!m_Confined && res != 0)) && Trigger()) + { + m_OnTrigger.Execute< SQInt32, SQInt32 >(player, checkpoint); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::SphereEntered(SQInt32 player, SQInt32 sphere) noexcept +{ + const char res = (!m_Players.m_Filter[player] << 1) | !m_Spheres.m_Filter[sphere]; + + if (((m_Confined && res == 3) || (!m_Confined && res != 0)) && Trigger()) + { + m_OnTrigger.Execute< SQInt32, SQInt32 >(player, sphere); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::SphereExited(SQInt32 player, SQInt32 sphere) noexcept +{ + const char res = (!m_Players.m_Filter[player] << 1) | !m_Spheres.m_Filter[sphere]; + + if (((m_Confined && res == 3) || (!m_Confined && res != 0)) && Trigger()) + { + m_OnTrigger.Execute< SQInt32, SQInt32 >(player, sphere); + } +} + +// ------------------------------------------------------------------------------------------------ +bool GlobalEvent::Trigger() noexcept +{ + if (m_Suspended || (m_Idle > std::chrono::steady_clock::now())) + { + return false; + } + else if (m_Ignore > 0) + { + --m_Ignore; + return false; + } + else if (m_OnTrigger.IsNull()) + { + return false; + } + + if (m_Stride > 0 && m_Ignore < 1) + { + m_Ignore = m_Stride; + } + + return true; +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::Attach() noexcept +{ + switch (m_Type) + { + case EVT_BLIPDESTROYED: + _Core->BlipDestroyed.Connect(this); + break; + case EVT_CHECKPOINTDESTROYED: + _Core->CheckpointDestroyed.Connect(this); + break; + case EVT_KEYBINDDESTROYED: + _Core->KeybindDestroyed.Connect(this); + break; + case EVT_OBJECTDESTROYED: + _Core->ObjectDestroyed.Connect(this); + break; + case EVT_PICKUPDESTROYED: + _Core->PickupDestroyed.Connect(this); + break; + case EVT_PLAYERDESTROYED: + _Core->PlayerDestroyed.Connect(this); + break; + case EVT_SPHEREDESTROYED: + _Core->SphereDestroyed.Connect(this); + break; + case EVT_SPRITEDESTROYED: + _Core->SpriteDestroyed.Connect(this); + break; + case EVT_TEXTDRAWDESTROYED: + _Core->TextdrawDestroyed.Connect(this); + break; + case EVT_VEHICLEDESTROYED: + _Core->VehicleDestroyed.Connect(this); + break; + case EVT_BLIPCUSTOM: + _Core->BlipCustom.Connect(this); + break; + case EVT_CHECKPOINTCUSTOM: + _Core->CheckpointCustom.Connect(this); + break; + case EVT_KEYBINDCUSTOM: + _Core->KeybindCustom.Connect(this); + break; + case EVT_OBJECTCUSTOM: + _Core->ObjectCustom.Connect(this); + break; + case EVT_PICKUPCUSTOM: + _Core->PickupCustom.Connect(this); + break; + case EVT_PLAYERCUSTOM: + _Core->PlayerCustom.Connect(this); + break; + case EVT_SPHERECUSTOM: + _Core->SphereCustom.Connect(this); + break; + case EVT_SPRITECUSTOM: + _Core->SpriteCustom.Connect(this); + break; + case EVT_TEXTDRAWCUSTOM: + _Core->TextdrawCustom.Connect(this); + break; + case EVT_VEHICLECUSTOM: + _Core->VehicleCustom.Connect(this); + break; + case EVT_PLAYERAWAY: + _Core->PlayerAway.Connect(this); + break; + case EVT_PLAYERGAMEKEYS: + _Core->PlayerGameKeys.Connect(this); + break; + case EVT_PLAYERRENAME: + _Core->PlayerRename.Connect(this); + break; + case EVT_PLAYERREQUESTCLASS: + _Core->PlayerRequestClass.Connect(this); + break; + case EVT_PLAYERREQUESTSPAWN: + _Core->PlayerRequestSpawn.Connect(this); + break; + case EVT_PLAYERSPAWN: + _Core->PlayerSpawn.Connect(this); + break; + case EVT_PLAYERSTARTTYPING: + _Core->PlayerStartTyping.Connect(this); + break; + case EVT_PLAYERSTOPTYPING: + _Core->PlayerStopTyping.Connect(this); + break; + case EVT_PLAYERCHAT: + _Core->PlayerChat.Connect(this); + break; + case EVT_PLAYERCOMMAND: + _Core->PlayerCommand.Connect(this); + break; + case EVT_PLAYERMESSAGE: + _Core->PlayerMessage.Connect(this); + break; + case EVT_PLAYERHEALTH: + _Core->PlayerHealth.Connect(this); + break; + case EVT_PLAYERARMOUR: + _Core->PlayerArmour.Connect(this); + break; + case EVT_PLAYERWEAPON: + _Core->PlayerWeapon.Connect(this); + break; + case EVT_PLAYERMOVE: + _Core->PlayerMove.Connect(this); + break; + case EVT_PLAYERWASTED: + _Core->PlayerWasted.Connect(this); + break; + case EVT_PLAYERKILLED: + _Core->PlayerKilled.Connect(this); + break; + case EVT_PLAYERTEAMKILL: + _Core->PlayerTeamKill.Connect(this); + break; + case EVT_PLAYERSPECTATE: + _Core->PlayerSpectate.Connect(this); + break; + case EVT_PLAYERCRASHREPORT: + _Core->PlayerCrashreport.Connect(this); + break; + case EVT_PLAYERBURNING: + _Core->PlayerBurning.Connect(this); + break; + case EVT_PLAYERCROUCHING: + _Core->PlayerCrouching.Connect(this); + break; + case EVT_PLAYERSTATE: + _Core->PlayerState.Connect(this); + break; + case EVT_PLAYERACTION: + _Core->PlayerAction.Connect(this); + break; + case EVT_STATENONE: + _Core->StateNone.Connect(this); + break; + case EVT_STATENORMAL: + _Core->StateNormal.Connect(this); + break; + case EVT_STATESHOOTING: + _Core->StateShooting.Connect(this); + break; + case EVT_STATEDRIVER: + _Core->StateDriver.Connect(this); + break; + case EVT_STATEPASSENGER: + _Core->StatePassenger.Connect(this); + break; + case EVT_STATEENTERDRIVER: + _Core->StateEnterDriver.Connect(this); + break; + case EVT_STATEENTERPASSENGER: + _Core->StateEnterPassenger.Connect(this); + break; + case EVT_STATEEXITVEHICLE: + _Core->StateExitVehicle.Connect(this); + break; + case EVT_STATEUNSPAWNED: + _Core->StateUnspawned.Connect(this); + break; + case EVT_ACTIONNONE: + _Core->ActionNone.Connect(this); + break; + case EVT_ACTIONNORMAL: + _Core->ActionNormal.Connect(this); + break; + case EVT_ACTIONAIMING: + _Core->ActionAiming.Connect(this); + break; + case EVT_ACTIONSHOOTING: + _Core->ActionShooting.Connect(this); + break; + case EVT_ACTIONJUMPING: + _Core->ActionJumping.Connect(this); + break; + case EVT_ACTIONLIEDOWN: + _Core->ActionLieDown.Connect(this); + break; + case EVT_ACTIONGETTINGUP: + _Core->ActionGettingUp.Connect(this); + break; + case EVT_ACTIONJUMPVEHICLE: + _Core->ActionJumpVehicle.Connect(this); + break; + case EVT_ACTIONDRIVING: + _Core->ActionDriving.Connect(this); + break; + case EVT_ACTIONDYING: + _Core->ActionDying.Connect(this); + break; + case EVT_ACTIONWASTED: + _Core->ActionWasted.Connect(this); + break; + case EVT_ACTIONEMBARKING: + _Core->ActionEmbarking.Connect(this); + break; + case EVT_ACTIONDISEMBARKING: + _Core->ActionDisembarking.Connect(this); + break; + case EVT_VEHICLERESPAWN: + _Core->VehicleRespawn.Connect(this); + break; + case EVT_VEHICLEEXPLODE: + _Core->VehicleExplode.Connect(this); + break; + case EVT_VEHICLEHEALTH: + _Core->VehicleHealth.Connect(this); + break; + case EVT_VEHICLEMOVE: + _Core->VehicleMove.Connect(this); + break; + case EVT_PICKUPRESPAWN: + _Core->PickupRespawn.Connect(this); + break; + case EVT_KEYBINDKEYPRESS: + _Core->KeybindKeyPress.Connect(this); + break; + case EVT_KEYBINDKEYRELEASE: + _Core->KeybindKeyRelease.Connect(this); + break; + case EVT_VEHICLEEMBARKING: + _Core->VehicleEmbarking.Connect(this); + break; + case EVT_VEHICLEEMBARKED: + _Core->VehicleEmbarked.Connect(this); + break; + case EVT_VEHICLEDISEMBARK: + _Core->VehicleDisembark.Connect(this); + break; + case EVT_PICKUPCLAIMED: + _Core->PickupClaimed.Connect(this); + break; + case EVT_PICKUPCOLLECTED: + _Core->PickupCollected.Connect(this); + break; + case EVT_OBJECTSHOT: + _Core->ObjectShot.Connect(this); + break; + case EVT_OBJECTBUMP: + _Core->ObjectBump.Connect(this); + break; + case EVT_CHECKPOINTENTERED: + _Core->CheckpointEntered.Connect(this); + break; + case EVT_CHECKPOINTEXITED: + _Core->CheckpointExited.Connect(this); + break; + case EVT_SPHEREENTERED: + _Core->SphereEntered.Connect(this); + break; + case EVT_SPHEREEXITED: + _Core->SphereExited.Connect(this); + break; + default: + LogErr("Attempting to to an unknown event type: %d", _SCI32(m_Type)); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::Detach() noexcept +{ + switch (m_Type) + { + case EVT_BLIPDESTROYED: + _Core->BlipDestroyed.Disconnect(this); + break; + case EVT_CHECKPOINTDESTROYED: + _Core->CheckpointDestroyed.Disconnect(this); + break; + case EVT_KEYBINDDESTROYED: + _Core->KeybindDestroyed.Disconnect(this); + break; + case EVT_OBJECTDESTROYED: + _Core->ObjectDestroyed.Disconnect(this); + break; + case EVT_PICKUPDESTROYED: + _Core->PickupDestroyed.Disconnect(this); + break; + case EVT_PLAYERDESTROYED: + _Core->PlayerDestroyed.Disconnect(this); + break; + case EVT_SPHEREDESTROYED: + _Core->SphereDestroyed.Disconnect(this); + break; + case EVT_SPRITEDESTROYED: + _Core->SpriteDestroyed.Disconnect(this); + break; + case EVT_TEXTDRAWDESTROYED: + _Core->TextdrawDestroyed.Disconnect(this); + break; + case EVT_VEHICLEDESTROYED: + _Core->VehicleDestroyed.Disconnect(this); + break; + case EVT_BLIPCUSTOM: + _Core->BlipCustom.Disconnect(this); + break; + case EVT_CHECKPOINTCUSTOM: + _Core->CheckpointCustom.Disconnect(this); + break; + case EVT_KEYBINDCUSTOM: + _Core->KeybindCustom.Disconnect(this); + break; + case EVT_OBJECTCUSTOM: + _Core->ObjectCustom.Disconnect(this); + break; + case EVT_PICKUPCUSTOM: + _Core->PickupCustom.Disconnect(this); + break; + case EVT_PLAYERCUSTOM: + _Core->PlayerCustom.Disconnect(this); + break; + case EVT_SPHERECUSTOM: + _Core->SphereCustom.Disconnect(this); + break; + case EVT_SPRITECUSTOM: + _Core->SpriteCustom.Disconnect(this); + break; + case EVT_TEXTDRAWCUSTOM: + _Core->TextdrawCustom.Disconnect(this); + break; + case EVT_VEHICLECUSTOM: + _Core->VehicleCustom.Disconnect(this); + break; + case EVT_PLAYERAWAY: + _Core->PlayerAway.Disconnect(this); + break; + case EVT_PLAYERGAMEKEYS: + _Core->PlayerGameKeys.Disconnect(this); + break; + case EVT_PLAYERRENAME: + _Core->PlayerRename.Disconnect(this); + break; + case EVT_PLAYERREQUESTCLASS: + _Core->PlayerRequestClass.Disconnect(this); + break; + case EVT_PLAYERREQUESTSPAWN: + _Core->PlayerRequestSpawn.Disconnect(this); + break; + case EVT_PLAYERSPAWN: + _Core->PlayerSpawn.Disconnect(this); + break; + case EVT_PLAYERSTARTTYPING: + _Core->PlayerStartTyping.Disconnect(this); + break; + case EVT_PLAYERSTOPTYPING: + _Core->PlayerStopTyping.Disconnect(this); + break; + case EVT_PLAYERCHAT: + _Core->PlayerChat.Disconnect(this); + break; + case EVT_PLAYERCOMMAND: + _Core->PlayerCommand.Disconnect(this); + break; + case EVT_PLAYERMESSAGE: + _Core->PlayerMessage.Disconnect(this); + break; + case EVT_PLAYERHEALTH: + _Core->PlayerHealth.Disconnect(this); + break; + case EVT_PLAYERARMOUR: + _Core->PlayerArmour.Disconnect(this); + break; + case EVT_PLAYERWEAPON: + _Core->PlayerWeapon.Disconnect(this); + break; + case EVT_PLAYERMOVE: + _Core->PlayerMove.Disconnect(this); + break; + case EVT_PLAYERWASTED: + _Core->PlayerWasted.Disconnect(this); + break; + case EVT_PLAYERKILLED: + _Core->PlayerKilled.Disconnect(this); + break; + case EVT_PLAYERTEAMKILL: + _Core->PlayerTeamKill.Disconnect(this); + break; + case EVT_PLAYERSPECTATE: + _Core->PlayerSpectate.Disconnect(this); + break; + case EVT_PLAYERCRASHREPORT: + _Core->PlayerCrashreport.Disconnect(this); + break; + case EVT_PLAYERBURNING: + _Core->PlayerBurning.Disconnect(this); + break; + case EVT_PLAYERCROUCHING: + _Core->PlayerCrouching.Disconnect(this); + break; + case EVT_PLAYERSTATE: + _Core->PlayerState.Disconnect(this); + break; + case EVT_PLAYERACTION: + _Core->PlayerAction.Disconnect(this); + break; + case EVT_STATENONE: + _Core->StateNone.Disconnect(this); + break; + case EVT_STATENORMAL: + _Core->StateNormal.Disconnect(this); + break; + case EVT_STATESHOOTING: + _Core->StateShooting.Disconnect(this); + break; + case EVT_STATEDRIVER: + _Core->StateDriver.Disconnect(this); + break; + case EVT_STATEPASSENGER: + _Core->StatePassenger.Disconnect(this); + break; + case EVT_STATEENTERDRIVER: + _Core->StateEnterDriver.Disconnect(this); + break; + case EVT_STATEENTERPASSENGER: + _Core->StateEnterPassenger.Disconnect(this); + break; + case EVT_STATEEXITVEHICLE: + _Core->StateExitVehicle.Disconnect(this); + break; + case EVT_STATEUNSPAWNED: + _Core->StateUnspawned.Disconnect(this); + break; + case EVT_ACTIONNONE: + _Core->ActionNone.Disconnect(this); + break; + case EVT_ACTIONNORMAL: + _Core->ActionNormal.Disconnect(this); + break; + case EVT_ACTIONAIMING: + _Core->ActionAiming.Disconnect(this); + break; + case EVT_ACTIONSHOOTING: + _Core->ActionShooting.Disconnect(this); + break; + case EVT_ACTIONJUMPING: + _Core->ActionJumping.Disconnect(this); + break; + case EVT_ACTIONLIEDOWN: + _Core->ActionLieDown.Disconnect(this); + break; + case EVT_ACTIONGETTINGUP: + _Core->ActionGettingUp.Disconnect(this); + break; + case EVT_ACTIONJUMPVEHICLE: + _Core->ActionJumpVehicle.Disconnect(this); + break; + case EVT_ACTIONDRIVING: + _Core->ActionDriving.Disconnect(this); + break; + case EVT_ACTIONDYING: + _Core->ActionDying.Disconnect(this); + break; + case EVT_ACTIONWASTED: + _Core->ActionWasted.Disconnect(this); + break; + case EVT_ACTIONEMBARKING: + _Core->ActionEmbarking.Disconnect(this); + break; + case EVT_ACTIONDISEMBARKING: + _Core->ActionDisembarking.Disconnect(this); + break; + case EVT_VEHICLERESPAWN: + _Core->VehicleRespawn.Disconnect(this); + break; + case EVT_VEHICLEEXPLODE: + _Core->VehicleExplode.Disconnect(this); + break; + case EVT_VEHICLEHEALTH: + _Core->VehicleHealth.Disconnect(this); + break; + case EVT_VEHICLEMOVE: + _Core->VehicleMove.Disconnect(this); + break; + case EVT_PICKUPRESPAWN: + _Core->PickupRespawn.Disconnect(this); + break; + case EVT_KEYBINDKEYPRESS: + _Core->KeybindKeyPress.Disconnect(this); + break; + case EVT_KEYBINDKEYRELEASE: + _Core->KeybindKeyRelease.Disconnect(this); + break; + case EVT_VEHICLEEMBARKING: + _Core->VehicleEmbarking.Disconnect(this); + break; + case EVT_VEHICLEEMBARKED: + _Core->VehicleEmbarked.Disconnect(this); + break; + case EVT_VEHICLEDISEMBARK: + _Core->VehicleDisembark.Disconnect(this); + break; + case EVT_PICKUPCLAIMED: + _Core->PickupClaimed.Disconnect(this); + break; + case EVT_PICKUPCOLLECTED: + _Core->PickupCollected.Disconnect(this); + break; + case EVT_OBJECTSHOT: + _Core->ObjectShot.Disconnect(this); + break; + case EVT_OBJECTBUMP: + _Core->ObjectBump.Disconnect(this); + break; + case EVT_CHECKPOINTENTERED: + _Core->CheckpointEntered.Disconnect(this); + break; + case EVT_CHECKPOINTEXITED: + _Core->CheckpointExited.Disconnect(this); + break; + case EVT_SPHEREENTERED: + _Core->SphereEntered.Disconnect(this); + break; + case EVT_SPHEREEXITED: + _Core->SphereExited.Disconnect(this); + break; + default: + LogErr("Attempting to from an unknown event type: %d", _SCI32(m_Type)); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::Hook() noexcept +{ + if (Ent< CBlip >::InEvent(m_Type)) + { + m_Blips.Hook(); + } + + if (Ent< CCheckpoint >::InEvent(m_Type)) + { + m_Checkpoints.Hook(); + } + + if (Ent< CKeybind >::InEvent(m_Type)) + { + m_Keybinds.Hook(); + } + + if (Ent< CObject >::InEvent(m_Type)) + { + m_Objects.Hook(); + } + + if (Ent< CPickup >::InEvent(m_Type)) + { + m_Pickups.Hook(); + } + + if (Ent< CPlayer >::InEvent(m_Type)) + { + m_Players.Hook(); + } + + if (Ent< CSphere >::InEvent(m_Type)) + { + m_Spheres.Hook(); + } + + if (Ent< CSprite >::InEvent(m_Type)) + { + m_Sprites.Hook(); + } + + if (Ent< CTextdraw >::InEvent(m_Type)) + { + m_Textdraws.Hook(); + } + + if (Ent< CVehicle >::InEvent(m_Type)) + { + m_Vehicles.Hook(); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::Unhook() noexcept +{ + if (Ent< CBlip >::InEvent(m_Type)) + { + m_Blips.Unhook(); + } + + if (Ent< CCheckpoint >::InEvent(m_Type)) + { + m_Checkpoints.Unhook(); + } + + if (Ent< CKeybind >::InEvent(m_Type)) + { + m_Keybinds.Unhook(); + } + + if (Ent< CObject >::InEvent(m_Type)) + { + m_Objects.Unhook(); + } + + if (Ent< CPickup >::InEvent(m_Type)) + { + m_Pickups.Unhook(); + } + + if (Ent< CPlayer >::InEvent(m_Type)) + { + m_Players.Unhook(); + } + + if (Ent< CSphere >::InEvent(m_Type)) + { + m_Spheres.Unhook(); + } + + if (Ent< CSprite >::InEvent(m_Type)) + { + m_Sprites.Unhook(); + } + + if (Ent< CTextdraw >::InEvent(m_Type)) + { + m_Textdraws.Unhook(); + } + + if (Ent< CVehicle >::InEvent(m_Type)) + { + m_Vehicles.Unhook(); + } +} + +// ------------------------------------------------------------------------------------------------ +void GlobalEvent::Adaptable(SQInt32 type) noexcept +{ + if (Ent< CBlip >::InEvent(m_Type) && !Ent< CBlip >::InEvent(type)) + { + m_Blips.Clear(0); + } + + if (Ent< CCheckpoint >::InEvent(m_Type) && !Ent< CCheckpoint >::InEvent(type)) + { + m_Checkpoints.Clear(0); + } + + if (Ent< CKeybind >::InEvent(m_Type) && !Ent< CKeybind >::InEvent(type)) + { + m_Keybinds.Clear(0); + } + + if (Ent< CObject >::InEvent(m_Type) && !Ent< CObject >::InEvent(type)) + { + m_Objects.Clear(0); + } + + if (Ent< CPickup >::InEvent(m_Type) && !Ent< CPickup >::InEvent(type)) + { + m_Pickups.Clear(0); + } + + if (Ent< CPlayer >::InEvent(m_Type) && !Ent< CPlayer >::InEvent(type)) + { + m_Players.Clear(0); + } + + if (Ent< CSphere >::InEvent(m_Type) && !Ent< CSphere >::InEvent(type)) + { + m_Spheres.Clear(0); + } + + if (Ent< CSprite >::InEvent(m_Type) && !Ent< CSprite >::InEvent(type)) + { + m_Sprites.Clear(0); + } + + if (Ent< CTextdraw >::InEvent(m_Type) && !Ent< CTextdraw >::InEvent(type)) + { + m_Textdraws.Clear(0); + } + + if (Ent< CVehicle >::InEvent(m_Type) && !Ent< CVehicle >::InEvent(type)) + { + m_Vehicles.Clear(0); + } +} + +// ------------------------------------------------------------------------------------------------ +bool GlobalEvent::Compatible(SQInt32 type) noexcept +{ + switch (type) + { + case EVT_BLIPDESTROYED: + case EVT_CHECKPOINTDESTROYED: + case EVT_KEYBINDDESTROYED: + case EVT_OBJECTDESTROYED: + case EVT_PICKUPDESTROYED: + case EVT_PLAYERDESTROYED: + case EVT_SPHEREDESTROYED: + case EVT_SPRITEDESTROYED: + case EVT_TEXTDRAWDESTROYED: + case EVT_VEHICLEDESTROYED: + case EVT_BLIPCUSTOM: + case EVT_CHECKPOINTCUSTOM: + case EVT_KEYBINDCUSTOM: + case EVT_OBJECTCUSTOM: + case EVT_PICKUPCUSTOM: + case EVT_PLAYERCUSTOM: + case EVT_SPHERECUSTOM: + case EVT_SPRITECUSTOM: + case EVT_TEXTDRAWCUSTOM: + case EVT_VEHICLECUSTOM: + case EVT_PLAYERAWAY: + case EVT_PLAYERGAMEKEYS: + case EVT_PLAYERRENAME: + case EVT_PLAYERREQUESTCLASS: + case EVT_PLAYERREQUESTSPAWN: + case EVT_PLAYERSPAWN: + case EVT_PLAYERSTARTTYPING: + case EVT_PLAYERSTOPTYPING: + case EVT_PLAYERCHAT: + case EVT_PLAYERCOMMAND: + case EVT_PLAYERMESSAGE: + case EVT_PLAYERHEALTH: + case EVT_PLAYERARMOUR: + case EVT_PLAYERWEAPON: + case EVT_PLAYERMOVE: + case EVT_PLAYERWASTED: + case EVT_PLAYERKILLED: + case EVT_PLAYERTEAMKILL: + case EVT_PLAYERSPECTATE: + case EVT_PLAYERCRASHREPORT: + case EVT_PLAYERBURNING: + case EVT_PLAYERCROUCHING: + case EVT_PLAYERSTATE: + case EVT_PLAYERACTION: + case EVT_STATENONE: + case EVT_STATENORMAL: + case EVT_STATESHOOTING: + case EVT_STATEDRIVER: + case EVT_STATEPASSENGER: + case EVT_STATEENTERDRIVER: + case EVT_STATEENTERPASSENGER: + case EVT_STATEEXITVEHICLE: + case EVT_STATEUNSPAWNED: + case EVT_ACTIONNONE: + case EVT_ACTIONNORMAL: + case EVT_ACTIONAIMING: + case EVT_ACTIONSHOOTING: + case EVT_ACTIONJUMPING: + case EVT_ACTIONLIEDOWN: + case EVT_ACTIONGETTINGUP: + case EVT_ACTIONJUMPVEHICLE: + case EVT_ACTIONDRIVING: + case EVT_ACTIONDYING: + case EVT_ACTIONWASTED: + case EVT_ACTIONEMBARKING: + case EVT_ACTIONDISEMBARKING: + case EVT_VEHICLERESPAWN: + case EVT_VEHICLEEXPLODE: + case EVT_VEHICLEHEALTH: + case EVT_VEHICLEMOVE: + case EVT_PICKUPRESPAWN: + case EVT_KEYBINDKEYPRESS: + case EVT_KEYBINDKEYRELEASE: + case EVT_VEHICLEEMBARKING: + case EVT_VEHICLEEMBARKED: + case EVT_VEHICLEDISEMBARK: + case EVT_PICKUPCLAIMED: + case EVT_PICKUPCOLLECTED: + case EVT_OBJECTSHOT: + case EVT_OBJECTBUMP: + case EVT_CHECKPOINTENTERED: + case EVT_CHECKPOINTEXITED: + case EVT_SPHEREENTERED: + case EVT_SPHEREEXITED: + return true; + default: + return false; + } } // ================================================================================================ +template < class T > static bool Register_GlobalFilter(HSQUIRRELVM vm, const SQChar * cname) +{ + // Output debugging information + LogDbg("Beginning registration of <%s> type", cname); + // Avoid using the long name of the type we're about to register + typedef GlobalFilter< T > Filter; + // Filters should not be constructed + typedef NoConstructor< Filter > Allocator; + // Attempt to register the specified type + Sqrat::RootTable(vm).Bind(cname, Sqrat::Class< Filter, Allocator >(vm, cname) + .Func(_SC("_cmp"), &Filter::Cmp) + .Func(_SC("_tostring"), &Filter::ToString) + + .Prop(_SC("count"), &Filter::Count) + .Prop(_SC("any"), &Filter::Any) + .Prop(_SC("none"), &Filter::None) + .Prop(_SC("all"), &Filter::All) + + .template Overload< void (Filter::*)(const typename Filter::RefType &) >(_SC("include"), &Filter::Include) + .template Overload< void (Filter::*)(const typename Filter::RefType &, SQInt32) >(_SC("include"), &Filter::Include) + .template Overload< void (Filter::*)(const typename Filter::RefType &) >(_SC("exclude"), &Filter::Exclude) + .template Overload< void (Filter::*)(const typename Filter::RefType &, SQInt32) >(_SC("exclude"), &Filter::Exclude) + //.Func(_SC("exclude"), &Filter::Exclude) + .Func(_SC("enabled"), &Filter::Enabled) + .Func(_SC("clear"), &Filter::Clear) + .Func(_SC("flip"), &Filter::Flip) + ); + // Output debugging information + LogDbg("Registration of <%s> type was successful", cname); + // Registration succeeded + return true; +} + bool Register_GlobalEvent(HSQUIRRELVM vm) { + // Register dependencies + if (!Register_GlobalFilter< CBlip >(vm, _SC("BlipGlobalFilter")) || \ + !Register_GlobalFilter< CCheckpoint >(vm, _SC("CheckpointGlobalFilter")) || \ + !Register_GlobalFilter< CKeybind >(vm, _SC("KeybindGlobalFilter")) || \ + !Register_GlobalFilter< CObject >(vm, _SC("ObjectGlobalFilter")) || \ + !Register_GlobalFilter< CPickup >(vm, _SC("PickupGlobalFilter")) || \ + !Register_GlobalFilter< CPlayer >(vm, _SC("PlayerGlobalFilter")) || \ + !Register_GlobalFilter< CSphere >(vm, _SC("SphereGlobalFilter")) || \ + !Register_GlobalFilter< CSprite >(vm, _SC("SpriteGlobalFilter")) || \ + !Register_GlobalFilter< CTextdraw >(vm, _SC("TextdrawGlobalFilter")) || \ + !Register_GlobalFilter< CVehicle >(vm, _SC("VehicleGlobalFilter"))) + { + return false; + } // Output debugging information LogDbg("Beginning registration of type"); // Attempt to register the specified type Sqrat::RootTable(vm).Bind(_SC("GlobalEvent"), Sqrat::Class< GlobalEvent >(vm, _SC("GlobalEvent")) .Ctor() + .Ctor() + .Ctor() + + .Func(_SC("_cmp"), &GlobalEvent::Cmp) + .Func(_SC("_tostring"), &GlobalEvent::GetName) + + .Prop(_SC("ltag"), &GlobalEvent::GetTag, &GlobalEvent::SetTag) + .Prop(_SC("ldata"), &GlobalEvent::GetData, &GlobalEvent::SetData) + .Prop(_SC("type"), &GlobalEvent::GetType, &GlobalEvent::SetType) + .Prop(_SC("idle"), &GlobalEvent::GetIdle, &GlobalEvent::SetIdle) + .Prop(_SC("is_idle"), &GlobalEvent::IsIdle) + .Prop(_SC("stride"), &GlobalEvent::GetStride, &GlobalEvent::SetStride) + .Prop(_SC("ignore"), &GlobalEvent::GetIgnore, &GlobalEvent::SetIgnore) + .Prop(_SC("primary"), &GlobalEvent::GetPrimary, &GlobalEvent::SetPrimary) + .Prop(_SC("secondary"), &GlobalEvent::GetSecondary, &GlobalEvent::SetSecondary) + .Prop(_SC("confined"), &GlobalEvent::GetConfined, &GlobalEvent::SetConfined) + .Prop(_SC("suspended"), &GlobalEvent::GetSuspended, &GlobalEvent::SetSuspended) + .Prop(_SC("name"), &GlobalEvent::GetName) + + .Prop(_SC("on_trigger"), &GlobalEvent::GetOnTrigger, &GlobalEvent::SetOnTrigger) + .Prop(_SC("on_include"), &GlobalEvent::GetOnInclude, &GlobalEvent::SetOnInclude) + .Prop(_SC("on_exclude"), &GlobalEvent::GetOnExclude, &GlobalEvent::SetOnExclude) + .Prop(_SC("on_cleared"), &GlobalEvent::GetOnCleared, &GlobalEvent::SetOnCleared) + .Prop(_SC("on_release"), &GlobalEvent::GetOnRelease, &GlobalEvent::SetOnRelease) + + .Prop(_SC("blips"), &GlobalEvent::GetBlipFilter) + .Prop(_SC("checkpoints"), &GlobalEvent::GetCheckpointFilter) + .Prop(_SC("keybinds"), &GlobalEvent::GetKeybindFilter) + .Prop(_SC("objects"), &GlobalEvent::GetObjectFilter) + .Prop(_SC("pickups"), &GlobalEvent::GetPickupFilter) + .Prop(_SC("players"), &GlobalEvent::GetPlayerFilter) + .Prop(_SC("spheres"), &GlobalEvent::GetSphereFilter) + .Prop(_SC("sprites"), &GlobalEvent::GetSpriteFilter) + .Prop(_SC("textdraws"), &GlobalEvent::GetTextdrawFilter) + .Prop(_SC("vehicles"), &GlobalEvent::GetVehicleFilter) ); // Output debugging information - LogDbg("Registration of type was successful"); + LogDbg("Registration of type was successful"); // Registration succeeded return true; } diff --git a/source/Event/Global.hpp b/source/Event/Global.hpp index cc6d3c22..56739ad1 100644 --- a/source/Event/Global.hpp +++ b/source/Event/Global.hpp @@ -5,17 +5,282 @@ #include "Common.hpp" #include "Shared.hpp" +// ------------------------------------------------------------------------------------------------ +#include "Entity/Blip.hpp" +#include "Entity/Checkpoint.hpp" +#include "Entity/Keybind.hpp" +#include "Entity/Object.hpp" +#include "Entity/Pickup.hpp" +#include "Entity/Player.hpp" +#include "Entity/Sphere.hpp" +#include "Entity/Sprite.hpp" +#include "Entity/Textdraw.hpp" +#include "Entity/Vehicle.hpp" + // ------------------------------------------------------------------------------------------------ #include // ------------------------------------------------------------------------------------------------ namespace SqMod { +/* ------------------------------------------------------------------------------------------------ + * ... +*/ +template < class T > class GlobalFilter +{ +protected: + + // -------------------------------------------------------------------------------------------- + friend class GlobalEvent; /* The parent class must be able to directly access our stuff */ + + // -------------------------------------------------------------------------------------------- + typedef typename Ent< T >::Set Container; /* Size efficient container used as the filter */ + +public: + + // -------------------------------------------------------------------------------------------- + typedef T Type; /* The type of entity that this filter applies to */ + + // -------------------------------------------------------------------------------------------- + typedef Reference< T > RefType; /* Short name for the entity reference type */ + typedef Ent< T > EntType; /* Short name for the entity specification structure */ + + /* -------------------------------------------------------------------------------------------- + * Default constructor + */ + GlobalFilter() noexcept + : m_Filter(), m_Event(nullptr) + { + /* This kind of filter should now be nothing more than dead weight! */ + } + + /* -------------------------------------------------------------------------------------------- + * Construct the filter for the specified event. + */ + GlobalFilter(GlobalEvent * evt) noexcept + : m_Filter(), m_Event(evt) + { + /* The filter is empty so there's nothing to hook to at this moment! */ + } + + /* -------------------------------------------------------------------------------------------- + * Copy constructor + */ + GlobalFilter(const GlobalFilter< T > & o) noexcept + : m_Filter(o.m_Filter), m_Event(o.m_Event) + { + // Make sure we have a parent to be considered suitable for hooking + if (m_Event != nullptr) + { + Hook(); + } + /* Parent is ignored intentionally as filters should not copy parents! */ + } + + /* -------------------------------------------------------------------------------------------- + * Move constructor (disabled) + */ + GlobalFilter(GlobalFilter< T > &&) = delete; + + /* -------------------------------------------------------------------------------------------- + * Destructor + */ + ~GlobalFilter() + { + Unhook(); /* No need to listen to the destroy signal of filtered entities anymore! */ + } + + /* -------------------------------------------------------------------------------------------- + * Copy assignment operator + */ + GlobalFilter< T > & operator = (const GlobalFilter< T > & o) noexcept; + + /* -------------------------------------------------------------------------------------------- + * Move assignment operator (disabled) + */ + GlobalFilter< T > & operator = (GlobalFilter< T > &&) = delete; + + /* -------------------------------------------------------------------------------------------- + * Convert this class to an integer with the count of the filtered entities + */ + operator SQInt32 () const noexcept + { + return _SCI32(m_Filter.count()); + } + + /* -------------------------------------------------------------------------------------------- + * Used by the script to compare two instances of this type. + */ + SQInt32 Cmp(const GlobalFilter< T > & o) const noexcept + { + // Rule out equality first + if (m_Filter.count() == o.m_Filter.count()) + { + return 0; + } + // Rule out by size second + else if (m_Filter.count() > o.m_Filter.count()) + { + return 1; + } + else + { + return -1; + } + } + + /* -------------------------------------------------------------------------------------------- + * Used by the script to convert this type to a string. + */ + String ToString() const noexcept + { + return NToS(m_Filter.count()); + } + + /* -------------------------------------------------------------------------------------------- + * Include the specified entity in the filter. + */ + void Include(const RefType & ent, SQInt32 header) noexcept; + + /* -------------------------------------------------------------------------------------------- + * Include the specified entity in the filter. + */ + void Include(const RefType & ent) noexcept + { + Include(ent, 0); + } + + /* -------------------------------------------------------------------------------------------- + * Exclude the specified entity from the filter. + */ + void Exclude(const RefType & ent, SQInt32 header) noexcept; + + /* -------------------------------------------------------------------------------------------- + * Exclude the specified entity from the filter. + */ + void Exclude(const RefType & ent) noexcept + { + Exclude(ent, 0); + } + + /* -------------------------------------------------------------------------------------------- + * Test whether the specified entity is included in the filter. + */ + bool Enabled(const RefType & ent) const noexcept + { + if (ent) + { + return m_Filter[_SCU32(ent)]; + } + else + { + LogWrn("Cannot test whether a <%s> entity is filtered or not using an invalid instance: %d", \ + EntType::Name, _SCI32(ent)); + } + + return false; + } + + /* -------------------------------------------------------------------------------------------- + * Count all the entities included in the filter. + */ + SQInt32 Count() const noexcept + { + return _SCI32(m_Filter.count()); + } + + /* -------------------------------------------------------------------------------------------- + * Remove all the entities included in the filter. + */ + void Clear(SQInt32 header) noexcept; + + /* -------------------------------------------------------------------------------------------- + * Reverse the filter to exclude currently include entities. + */ + void Flip(SQInt32 header) noexcept; + + /* -------------------------------------------------------------------------------------------- + * Test whether we have any entity included in this filter? + */ + bool Any() const noexcept + { + return m_Filter.any(); + } + + /* -------------------------------------------------------------------------------------------- + * Test whether we have no entity included in this filter? + */ + bool None() const noexcept + { + return m_Filter.none(); + } + + /* -------------------------------------------------------------------------------------------- + * Test whether we have all entities included in this filter? + */ + bool All() const noexcept + { + return m_Filter.all(); + } + + /* -------------------------------------------------------------------------------------------- + * Exclude the entity from filter when the parent event isn't attached to the destroy signal. + */ + void Destroyed(SQInt32 id, SQInt32 /* header */, Object & /* payload */) noexcept + { + Release(id); + } + +protected: + + /* -------------------------------------------------------------------------------------------- + * Used by either the parent event or it self to release an entity from the filter. + */ + void Release(SQInt32 id) noexcept; + + /* -------------------------------------------------------------------------------------------- + * Hook to the entity destroy signal that the parent didn't. + */ + void Hook() noexcept; + + /* -------------------------------------------------------------------------------------------- + * Unhook from the entity destroy signal that the parent didn't. + */ + void Unhook() noexcept; +private: + + // -------------------------------------------------------------------------------------------- + Container m_Filter; /* Entity filter */ + + // -------------------------------------------------------------------------------------------- + GlobalEvent* m_Event; /* Parent event */ +}; + /* ------------------------------------------------------------------------------------------------ * ... */ class GlobalEvent { +protected: + + // -------------------------------------------------------------------------------------------- + template < class T > friend class GlobalFilter; + + // -------------------------------------------------------------------------------------------- + typedef GlobalFilter< CBlip > BlipFilter; + typedef GlobalFilter< CCheckpoint > CheckpointFilter; + typedef GlobalFilter< CKeybind > KeybindFilter; + typedef GlobalFilter< CObject > ObjectFilter; + typedef GlobalFilter< CPickup > PickupFilter; + typedef GlobalFilter< CPlayer > PlayerFilter; + typedef GlobalFilter< CSphere > SphereFilter; + typedef GlobalFilter< CSprite > SpriteFilter; + typedef GlobalFilter< CTextdraw > TextdrawFilter; + typedef GlobalFilter< CVehicle > VehicleFilter; + + // -------------------------------------------------------------------------------------------- + typedef std::chrono::time_point< std::chrono::steady_clock > TimePoint; + public: /* -------------------------------------------------------------------------------------------- @@ -41,7 +306,7 @@ public: /* -------------------------------------------------------------------------------------------- * ... */ - GlobalEvent(GlobalEvent && o) noexcept; + GlobalEvent(GlobalEvent &&) = delete; /* -------------------------------------------------------------------------------------------- * ... @@ -56,23 +321,1007 @@ public: /* -------------------------------------------------------------------------------------------- * ... */ - GlobalEvent & operator = (GlobalEvent && o) noexcept; + GlobalEvent & operator = (GlobalEvent &&) = delete; /* -------------------------------------------------------------------------------------------- * ... */ - + bool operator == (const GlobalEvent & o) const noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + bool operator != (const GlobalEvent & o) const noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + bool operator < (const GlobalEvent & o) const noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + bool operator > (const GlobalEvent & o) const noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + bool operator <= (const GlobalEvent & o) const noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + bool operator >= (const GlobalEvent & o) const noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + operator SQInt32 () const noexcept + { + return m_Type; + } + + /* -------------------------------------------------------------------------------------------- + * ... + */ + operator bool () const noexcept + { + return (m_Type != EVT_UNKNOWN && m_Type < EVT_COUNT); + } + + /* -------------------------------------------------------------------------------------------- + * ... + */ + operator ! () const noexcept + { + return (m_Type == EVT_UNKNOWN || m_Type >= EVT_COUNT); + } + + /* -------------------------------------------------------------------------------------------- + * ... + */ + SQInt32 Cmp(const GlobalEvent & o) const noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + const SQChar * GetName() const noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + const SQChar * GetTag() const noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void SetTag(const SQChar * tag) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + SqObj & GetData() noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void SetData(SqObj & data) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + SQInt32 GetType() const noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void SetType(SQInt32 type) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + SQInteger GetIdle() const noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void SetIdle(SQInteger millis) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + bool IsIdle() const noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + SQInt32 GetStride() const noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void SetStride(SQInt32 stride) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + SQInt32 GetIgnore() const noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void SetIgnore(SQInt32 ignore) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + SQInt32 GetPrimary() const noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void SetPrimary(SQInt32 subset) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + SQInt32 GetSecondary() const noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void SetSecondary(SQInt32 subset) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + bool GetConfined() const noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void SetConfined(bool toggle) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + bool GetSuspended() const noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void SetSuspended(bool toggle) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + Function GetOnTrigger() const noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void SetOnTrigger(const Function & func) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + Function GetOnInclude() const noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void SetOnInclude(const Function & func) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + Function GetOnExclude() const noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void SetOnExclude(const Function & func) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + Function GetOnCleared() const noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void SetOnCleared(const Function & func) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + Function GetOnRelease() const noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void SetOnRelease(const Function & func) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + BlipFilter & GetBlipFilter() noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + CheckpointFilter & GetCheckpointFilter() noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + KeybindFilter & GetKeybindFilter() noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + ObjectFilter & GetObjectFilter() noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + PickupFilter & GetPickupFilter() noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + PlayerFilter & GetPlayerFilter() noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + SphereFilter & GetSphereFilter() noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + SpriteFilter & GetSpriteFilter() noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + TextdrawFilter & GetTextdrawFilter() noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + VehicleFilter & GetVehicleFilter() noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void BlipDestroyed(SQInt32 blip, SQInt32 header, Object & payload) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void CheckpointDestroyed(SQInt32 checkpoint, SQInt32 header, Object & payload) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void KeybindDestroyed(SQInt32 keybind, SQInt32 header, Object & payload) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void ObjectDestroyed(SQInt32 object, SQInt32 header, Object & payload) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void PickupDestroyed(SQInt32 pickup, SQInt32 header, Object & payload) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void PlayerDestroyed(SQInt32 player, SQInt32 header, Object & payload) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void SphereDestroyed(SQInt32 sphere, SQInt32 header, Object & payload) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void SpriteDestroyed(SQInt32 sprite, SQInt32 header, Object & payload) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void TextdrawDestroyed(SQInt32 textdraw, SQInt32 header, Object & payload) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void VehicleDestroyed(SQInt32 vehicle, SQInt32 header, Object & payload) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void BlipCustom(SQInt32 blip, SQInt32 header, Object & payload) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void CheckpointCustom(SQInt32 checkpoint, SQInt32 header, Object & payload) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void KeybindCustom(SQInt32 keybind, SQInt32 header, Object & payload) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void ObjectCustom(SQInt32 object, SQInt32 header, Object & payload) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void PickupCustom(SQInt32 pickup, SQInt32 header, Object & payload) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void PlayerCustom(SQInt32 player, SQInt32 header, Object & payload) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void SphereCustom(SQInt32 sphere, SQInt32 header, Object & payload) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void SpriteCustom(SQInt32 sprite, SQInt32 header, Object & payload) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void TextdrawCustom(SQInt32 textdraw, SQInt32 header, Object & payload) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void VehicleCustom(SQInt32 vehicle, SQInt32 header, Object & payload) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void PlayerAway(SQInt32 player, bool status) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void PlayerGameKeys(SQInt32 player, SQInt32 previous, SQInt32 current) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void PlayerRename(SQInt32 player, const SQChar * previous, const SQChar * current) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void PlayerRequestClass(SQInt32 player, SQInt32 offset) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void PlayerRequestSpawn(SQInt32 player) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void PlayerSpawn(SQInt32 player) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void PlayerStartTyping(SQInt32 player) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void PlayerStopTyping(SQInt32 player) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void PlayerChat(SQInt32 player, const SQChar * message) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void PlayerCommand(SQInt32 player, const SQChar * command) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void PlayerMessage(SQInt32 player, SQInt32 receiver, const SQChar * message) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void PlayerHealth(SQInt32 player, SQFloat previous, SQFloat current) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void PlayerArmour(SQInt32 player, SQFloat previous, SQFloat current) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void PlayerWeapon(SQInt32 player, SQInt32 previous, SQInt32 current) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void PlayerMove(SQInt32 player, const Vector3 & previous, const Vector3 & current) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void PlayerWasted(SQInt32 player, SQInt32 reason) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void PlayerKilled(SQInt32 player, SQInt32 killer, SQInt32 reason, SQInt32 body_part) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void PlayerTeamKill(SQInt32 player, SQInt32 killer, SQInt32 reason, SQInt32 body_part) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void PlayerSpectate(SQInt32 player, SQInt32 target) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void PlayerCrashreport(SQInt32 player, const SQChar * report) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void PlayerBurning(SQInt32 player, bool state) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void PlayerCrouching(SQInt32 player, bool state) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void PlayerState(SQInt32 player, SQInt32 previous, SQInt32 current) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void PlayerAction(SQInt32 player, SQInt32 previous, SQInt32 current) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void StateNone(SQInt32 player, SQInt32 previous) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void StateNormal(SQInt32 player, SQInt32 previous) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void StateShooting(SQInt32 player, SQInt32 previous) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void StateDriver(SQInt32 player, SQInt32 previous) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void StatePassenger(SQInt32 player, SQInt32 previous) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void StateEnterDriver(SQInt32 player, SQInt32 previous) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void StateEnterPassenger(SQInt32 player, SQInt32 previous) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void StateExitVehicle(SQInt32 player, SQInt32 previous) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void StateUnspawned(SQInt32 player, SQInt32 previous) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void ActionNone(SQInt32 player, SQInt32 previous) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void ActionNormal(SQInt32 player, SQInt32 previous) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void ActionAiming(SQInt32 player, SQInt32 previous) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void ActionShooting(SQInt32 player, SQInt32 previous) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void ActionJumping(SQInt32 player, SQInt32 previous) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void ActionLieDown(SQInt32 player, SQInt32 previous) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void ActionGettingUp(SQInt32 player, SQInt32 previous) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void ActionJumpVehicle(SQInt32 player, SQInt32 previous) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void ActionDriving(SQInt32 player, SQInt32 previous) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void ActionDying(SQInt32 player, SQInt32 previous) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void ActionWasted(SQInt32 player, SQInt32 previous) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void ActionEmbarking(SQInt32 player, SQInt32 previous) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void ActionDisembarking(SQInt32 player, SQInt32 previous) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void VehicleRespawn(SQInt32 vehicle) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void VehicleExplode(SQInt32 vehicle) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void VehicleHealth(SQInt32 vehicle, SQFloat previous, SQFloat current) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void VehicleMove(SQInt32 vehicle, const Vector3 & previous, const Vector3 ¤t) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void PickupRespawn(SQInt32 pickup) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void KeybindKeyPress(SQInt32 player, SQInt32 keybind) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void KeybindKeyRelease(SQInt32 player, SQInt32 keybind) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void VehicleEmbarking(SQInt32 player, SQInt32 vehicle, SQInt32 slot) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void VehicleEmbarked(SQInt32 player, SQInt32 vehicle, SQInt32 slot) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void VehicleDisembark(SQInt32 player, SQInt32 vehicle) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void PickupClaimed(SQInt32 player, SQInt32 pickup) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void PickupCollected(SQInt32 player, SQInt32 pickup) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void ObjectShot(SQInt32 player, SQInt32 object, SQInt32 weapon) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void ObjectBump(SQInt32 player, SQInt32 object) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void CheckpointEntered(SQInt32 player, SQInt32 checkpoint) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void CheckpointExited(SQInt32 player, SQInt32 checkpoint) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void SphereEntered(SQInt32 player, SQInt32 sphere) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void SphereExited(SQInt32 player, SQInt32 sphere) noexcept; protected: - // -------------------------------------------------------------------------------------------- + /* -------------------------------------------------------------------------------------------- + * ... + */ + bool Trigger() noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void Attach() noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void Detach() noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void Hook() noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void Unhook() noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + void Adaptable(SQInt32 type) noexcept; + + /* -------------------------------------------------------------------------------------------- + * ... + */ + bool Compatible(SQInt32 type) noexcept; private: // -------------------------------------------------------------------------------------------- + SQInt32 m_Type; + // -------------------------------------------------------------------------------------------- + SQInt32 m_Stride; + SQInt32 m_Ignore; + + // -------------------------------------------------------------------------------------------- + SQInt32 m_Primary; + SQInt32 m_Secondary; + + // -------------------------------------------------------------------------------------------- + TimePoint m_Idle; + + // -------------------------------------------------------------------------------------------- + Function m_OnTrigger; + Function m_OnInclude; + Function m_OnExclude; + Function m_OnCleared; + Function m_OnRelease; + + // -------------------------------------------------------------------------------------------- + SqTag m_Tag; + SqObj m_Data; + + // -------------------------------------------------------------------------------------------- + bool m_Confined; /* Toggles filtering on secondary entities */ + bool m_Suspended; /* Prevents event forwarding completely */ + + // -------------------------------------------------------------------------------------------- + BlipFilter m_Blips; + CheckpointFilter m_Checkpoints; + KeybindFilter m_Keybinds; + ObjectFilter m_Objects; + PickupFilter m_Pickups; + PlayerFilter m_Players; + SphereFilter m_Spheres; + SpriteFilter m_Sprites; + TextdrawFilter m_Textdraws; + VehicleFilter m_Vehicles; }; +// ------------------------------------------------------------------------------------------------ +template < class T > GlobalFilter< T > & GlobalFilter< T >::operator = (const GlobalFilter< T > & o) noexcept +{ + // Make sure we're not doing self assignment, work with orphan filters or incompatible events + if (this != &o && m_Event != nullptr && EntType::InEvent(m_Event->m_Type)) + { + // Unhook from the currently filtered entities + Unhook(); + // Copy the internal filter from the other instance + m_Filter = o.m_Filter; + // Hook back to the newly filtered entities + Hook(); + /* Parent is ignored intentionally as filters should not change parents! */ + } + + return *this; +} + +// ------------------------------------------------------------------------------------------------ +template < class T > void GlobalFilter< T >::Include(const RefType & ent, SQInt32 header) noexcept +{ + // Make sure the filter is parented before proceeeding + if (m_Event == nullptr) + { + LogErr("Attempting to using an orphan entity filter", \ + EntType::Name); + } + // Make sure the entity is valid before we proceed + else if (!ent) + { + LogErr("Attempting to using an invalid entity instance: %d", \ + EntType::Name, _SCI32(ent)); + } + // Make sure the entity type is allowed for this event type + else if (!EntType::InEvent(m_Event->m_Type)) + { + LogErr("Attempting to using an incompatible event type: %s", \ + EntType::Name, GetEventName(m_Event->m_Type)); + } + // Make sure the entity is not already included in the filter + else if (!m_Filter[_SCU32(ent)]) + { + // Allow the inclusion of this entity by default + bool allow = true; + // Do we have custom inclusion filter specified? + if (!m_Event->m_OnInclude.IsNull()) + { + // Ask the specified inclusion filter if this entity should be allowed + SharedPtr< bool > ret = m_Event->m_OnInclude.Evaluate< bool, RefType, SQInt32 >(ent, header); + // See what the custom inclusion filter said or default to disallow + allow = !ret ? false : *ret; + } + // Are we allowed to include this entity instance in our filter? + if (allow) + { + // Make sure the someone knows when this entity will be destroyed + if (EntType::DestroyEvID != m_Event->m_Type) + { + RefType::Get(_SCI32(ent)).Destroyed().template Connect< GlobalFilter< T >, &GlobalFilter< T >::Destroyed >(this); + } + // Enable the specified entity instance in our filter + m_Filter.set(_SCU32(ent), true); + } + } +} + +// ------------------------------------------------------------------------------------------------ +template < class T > void GlobalFilter< T >::Exclude(const RefType & ent, SQInt32 header) noexcept +{ + // Make sure the filter is parented before proceeeding + if (m_Event == nullptr) + { + LogErr("Attempting to using an orphan entity filter", \ + EntType::Name); + } + // Make sure the entity is valid before we proceed + else if (!ent) + { + LogErr("Attempting to using an invalid entity instance: %d", \ + EntType::Name, _SCI32(ent)); + } + // Make sure the entity type is allowed for this event type + else if (!EntType::InEvent(m_Event->m_Type)) + { + LogErr("Attempting to using an incompatible event type: %s", \ + EntType::Name, GetEventName(m_Event->m_Type)); + } + // Make sure the entity is not already excluded fom the filter + else if (m_Filter[_SCU32(ent)]) + { + // Allow the exclusion of this entity by default + bool allow = true; + // Do we have custom exclusion filter specified? + if (!m_Event->m_OnExclude.IsNull()) + { + // Ask the specified exclusion filter if this entity should be allowed + SharedPtr< bool > ret = m_Event->m_OnExclude.Evaluate< bool, RefType, SQInt32 >(ent, header); + // See what the custom exclusion filter said or default to disallow + allow = !ret ? false : *ret; + } + // Are we allowed to exclude this entity instance from our filter? + if (allow) + { + // We don't need to know when this entity will be destroyed anymore + if (EntType::DestroyEvID != m_Event->m_Type) + { + RefType::Get(_SCI32(ent)).Destroyed().template Disconnect< GlobalFilter< T >, &GlobalFilter< T >::Destroyed >(this); + } + // Enable the specified entity instance in our filter + m_Filter.set(_SCU32(ent), false); + } + } +} + +// ------------------------------------------------------------------------------------------------ +template < class T > void GlobalFilter< T >::Clear(SQInt32 header) noexcept +{ + // Make sure the filter is parented before proceeeding + if (m_Event == nullptr) + { + LogWrn("Attempting to using an orphan entity filter", \ + EntType::Name); + } + // Make sure the filter is compatible with the parent event type + else if (!EntType::InEvent(m_Event->m_Type)) + { + LogWrn("Attempting to using an incompatible event type: %s", \ + EntType::Name, GetEventName(m_Event->m_Type)); + } + // Don't even attempt to clear if there's nothing to be cleared + else if (m_Filter.any()) + { + // Do we have to notify someone that the filter is about to be cleared? + if (!m_Event->m_OnCleared.IsNull()) + { + m_Event->m_OnCleared.Execute< SQInt32 >(header); + } + // Unhook from the currently filtered entities + Unhook(); + // Now it's safe to reset the filter + m_Filter.reset(); + } +} + +// ------------------------------------------------------------------------------------------------ +template < class T > void GlobalFilter< T >::Flip(SQInt32 header) noexcept +{ + // Make sure the filter is parented before proceeeding + if (m_Event == nullptr) + { + LogWrn("Attempting to using an orphan entity filter", \ + EntType::Name); + } + // Make sure the filter is compatible with the parent event type + else if (!EntType::InEvent(m_Event->m_Type)) + { + LogWrn("Attempting to using an incompatible event type: %s", \ + EntType::Name, GetEventName(m_Event->m_Type)); + } + // Now it's safe to proceed with reversing the filters + else + { + // Unhook from the currently filtered entities + Unhook(); + // Reverse the values in the internal filter + m_Filter.flip(); + // Hook from the newly filtered entities + Hook(); + } +} + +// ------------------------------------------------------------------------------------------------ +template < class T > void GlobalFilter< T >::Release(SQInt32 id) noexcept +{ + // Make sure the filter is parented before proceeeding + if (m_Event == nullptr) + { + LogErr("Attempting to using an orphan entity filter", \ + EntType::Name); + } + // Now it's safe to release + else + { + // Do we have to notify someone that this entity is about to be released? + if (!m_Event->m_OnRelease.IsNull()) + { + m_Event->m_OnRelease.Execute< SQInt32 >(id); + } + // Now disable the entity in the filter + m_Filter.set(id, false); + } +} + +// ------------------------------------------------------------------------------------------------ +template < class T > void GlobalFilter< T >::Hook() noexcept +{ + // Make sure the entities inform us when being destroyed as long as we're parented + if (m_Event != nullptr && EntType::DestroyEvID != m_Event->m_Type) + { + // No iterators here because we're dealing with a bitset! + for (unsigned i = 0; i < m_Filter.size(); ++i) + { + // If this bit is enabled then this entity is included so we must hook to it + if (m_Filter[i]) + { + RefType::Get(i).Destroyed().template Connect< GlobalFilter< T >, &GlobalFilter< T >::Destroyed >(this); + } + } + } +} + +// ------------------------------------------------------------------------------------------------ +template < class T > void GlobalFilter< T >::Unhook() noexcept +{ + // Make sure the entities will not inform us when being destroyed as long as we're parented + if (m_Event != nullptr && EntType::DestroyEvID != m_Event->m_Type) + { + // No iterators here because we're dealing with a bitset! + for (unsigned i = 0; i < m_Filter.size(); ++i) + { + // If this bit is enabled then this entity is included so we must unhook from it + if (m_Filter[i]) + { + RefType::Get(i).Destroyed().template Disconnect< GlobalFilter< T >, &GlobalFilter< T >::Destroyed >(this); + } + } + } +} + } // Namespace:: SqMod #endif // _SQMOD_EVENT_GLOBAL_HPP_