1
0
mirror of https://github.com/VCMP-SqMod/SqMod.git synced 2024-11-08 16:57:16 +01:00
SqMod/source/Entity.hpp

2845 lines
98 KiB
C++
Raw Normal View History

2015-09-30 02:56:11 +02:00
#ifndef _ENTITY_HPP_
#define _ENTITY_HPP_
// ------------------------------------------------------------------------------------------------
#include "Common.hpp"
#include "Signal.hpp"
// ------------------------------------------------------------------------------------------------
#include "Base/Vector3.hpp"
#include "Base/Color4.hpp"
// ------------------------------------------------------------------------------------------------
#include <array>
#include <bitset>
2015-09-30 02:56:11 +02:00
// ------------------------------------------------------------------------------------------------
namespace SqMod {
/* ------------------------------------------------------------------------------------------------
* Helper enum to have a numeric way of identifying entity types.
2015-09-30 02:56:11 +02:00
*/
enum EntityType
{
ENT_UNKNOWN = 0,
ENT_BLIP,
ENT_CHECKPOINT,
ENT_KEYBIND,
ENT_OBJECT,
ENT_PICKUP,
ENT_PLAYER,
ENT_SPHERE,
ENT_SPRITE,
ENT_TEXTDRAW,
ENT_VEHICLE,
ENT_COUNT
};
/* ------------------------------------------------------------------------------------------------
* Helper functions used by the entity interfaces to obtain global signals from the core instance.
*/
EBlipCreated & GBlipCreated() noexcept;
ECheckpointCreated & GCheckpointCreated() noexcept;
EKeybindCreated & GKeybindCreated() noexcept;
EObjectCreated & GObjectCreated() noexcept;
EPickupCreated & GPickupCreated() noexcept;
EPlayerCreated & GPlayerCreated() noexcept;
ESphereCreated & GSphereCreated() noexcept;
ESpriteCreated & GSpriteCreated() noexcept;
ETextdrawCreated & GTextdrawCreated() noexcept;
EVehicleCreated & GVehicleCreated() noexcept;
/* ------------------------------------------------------------------------------------------------
* Helper functions used by the entity interfaces to obtain global signals from the core instance.
*/
EBlipDestroyed & GBlipDestroyed() noexcept;
ECheckpointDestroyed & GCheckpointDestroyed() noexcept;
EKeybindDestroyed & GKeybindDestroyed() noexcept;
EObjectDestroyed & GObjectDestroyed() noexcept;
EPickupDestroyed & GPickupDestroyed() noexcept;
EPlayerDestroyed & GPlayerDestroyed() noexcept;
ESphereDestroyed & GSphereDestroyed() noexcept;
ESpriteDestroyed & GSpriteDestroyed() noexcept;
ETextdrawDestroyed & GTextdrawDestroyed() noexcept;
EVehicleDestroyed & GVehicleDestroyed() noexcept;
/* ------------------------------------------------------------------------------------------------
* Helper functions used by the entity interfaces to obtain global signals from the core instance.
*/
EBlipCustom & GBlipCustom() noexcept;
ECheckpointCustom & GCheckpointCustom() noexcept;
EKeybindCustom & GKeybindCustom() noexcept;
EObjectCustom & GObjectCustom() noexcept;
EPickupCustom & GPickupCustom() noexcept;
EPlayerCustom & GPlayerCustom() noexcept;
ESphereCustom & GSphereCustom() noexcept;
ESpriteCustom & GSpriteCustom() noexcept;
ETextdrawCustom & GTextdrawCustom() noexcept;
EVehicleCustom & GVehicleCustom() noexcept;
/* ------------------------------------------------------------------------------------------------
* Forward declaration of an entity interface.
2015-09-30 02:56:11 +02:00
*/
template < class T > class Ent;
/* ------------------------------------------------------------------------------------------------
* Specialized entity interface for the blip entity type.
2015-09-30 02:56:11 +02:00
*/
template <> class Ent< CBlip >
{
private:
// --------------------------------------------------------------------------------------------
friend class EntMan< CBlip >;
friend class Reference< CBlip >;
// --------------------------------------------------------------------------------------------
typedef Reference< CBlip > RefType;
/* --------------------------------------------------------------------------------------------
* Default destructor (disabled)
*/
Ent() = delete;
/* --------------------------------------------------------------------------------------------
* Helper structure that holds information about each entity instance of this type.
2015-09-30 02:56:11 +02:00
*/
typedef struct Blip
{
// ----------------------------------------------------------------------------------------
Blip() noexcept
: ID(-1), Root(0), Owned(false), Fresh(true)
{
/* ... */
}
2015-09-30 02:56:11 +02:00
// ----------------------------------------------------------------------------------------
SQInt32 ID;
// ----------------------------------------------------------------------------------------
RefType* Root;
// ----------------------------------------------------------------------------------------
bool Owned;
bool Fresh;
// ----------------------------------------------------------------------------------------
SqTag Tag;
SqObj Data;
// ----------------------------------------------------------------------------------------
SQInt32 World;
SQInt32 Scale;
// ----------------------------------------------------------------------------------------
SQInt32 SprID;
// ----------------------------------------------------------------------------------------
Vector3 Position;
Color4 Color;
// ----------------------------------------------------------------------------------------
EBlipCreated BlipCreated;
EBlipDestroyed BlipDestroyed;
EBlipCustom BlipCustom;
// ----------------------------------------------------------------------------------------
EBlipCreated & Created() noexcept
{
return BlipCreated;
}
EBlipDestroyed & Destroyed() noexcept
{
return BlipDestroyed;
}
EBlipCustom & Custom() noexcept
{
return BlipCustom;
}
// ----------------------------------------------------------------------------------------
EBlipCreated & GCreated() noexcept
{
return GBlipCreated();
}
EBlipDestroyed & GDestroyed() noexcept
{
return GBlipDestroyed();
}
EBlipCustom & GCustom() noexcept
{
return GBlipCustom();
}
2015-09-30 02:56:11 +02:00
} Instance;
// --------------------------------------------------------------------------------------------
static void Store(Instance & inst) noexcept
{
inst.World = SQMOD_UNKNOWN;
inst.Scale = SQMOD_UNKNOWN;
inst.SprID = SQMOD_UNKNOWN;
inst.Position.Clear();
inst.Color.Clear();
}
// --------------------------------------------------------------------------------------------
static void Store(Instance & inst, SQInt32 index, SQInt32 world, SQFloat x, SQFloat y, SQFloat z,
SQInt32 scale, SQUint32 color, SQInt32 sprid) noexcept
2015-09-30 02:56:11 +02:00
{
inst.World = world;
inst.Scale = scale;
inst.SprID = sprid;
inst.Position.x = x;
inst.Position.y = y;
inst.Position.z = z;
inst.Color.SetRGBA(color);
2015-09-30 02:56:11 +02:00
}
// --------------------------------------------------------------------------------------------
static void Clear(Instance & inst) noexcept
{
inst.BlipCreated.Clear();
inst.BlipDestroyed.Clear();
inst.BlipCustom.Clear();
}
// --------------------------------------------------------------------------------------------
static SQInt32 Create(SQInt32 index, SQInt32 world, SQFloat x, SQFloat y, SQFloat z,
SQInt32 scale, SQUint32 color, SQInt32 sprid) noexcept
{
return _Func->CreateCoordBlip(index, world, x, y, z, scale, color, sprid);
}
// --------------------------------------------------------------------------------------------
static void Destroy(SQInt32 id) noexcept
{
_Func->DestroyCoordBlip(id);
}
2015-09-30 02:56:11 +02:00
public:
// --------------------------------------------------------------------------------------------
static constexpr const SQChar* Name = "Blip";
static constexpr const SQChar* CName = "CBlip";
// --------------------------------------------------------------------------------------------
static constexpr SQInt32 TypeID = ENT_BLIP;
static constexpr SQInt32 Limit = SQMOD_BLIP_POOL;
// --------------------------------------------------------------------------------------------
static constexpr SQInt32 CreateEvID = EVT_BLIPCREATED;
static constexpr SQInt32 DestroyEvID = EVT_BLIPDESTROYED;
static constexpr SQInt32 CustomEvID = EVT_BLIPCUSTOM;
2015-09-30 02:56:11 +02:00
// --------------------------------------------------------------------------------------------
typedef std::array< Instance, Limit > Instances;
// --------------------------------------------------------------------------------------------
typedef std::bitset< Limit > Set;
// --------------------------------------------------------------------------------------------
static bool InEvent(SQInt32 type) noexcept
{
switch (type)
{
case EVT_BLIPCREATED:
case EVT_BLIPDESTROYED:
case EVT_BLIPCUSTOM:
return true;
default:
return false;
}
}
// --------------------------------------------------------------------------------------------
static bool InEvent(SQInt32 type, bool /* inversed */) noexcept
{
switch (type)
{
case EVT_BLIPCREATED:
case EVT_BLIPDESTROYED:
case EVT_BLIPCUSTOM:
return true;
default:
return false;
}
}
2015-09-30 02:56:11 +02:00
};
/* ------------------------------------------------------------------------------------------------
* Specialized entity interface for the checkpoint entity type.
2015-09-30 02:56:11 +02:00
*/
template <> class Ent< CCheckpoint >
{
private:
// --------------------------------------------------------------------------------------------
friend class EntMan< CCheckpoint >;
friend class Reference< CCheckpoint >;
// --------------------------------------------------------------------------------------------
typedef Reference< CCheckpoint > RefType;
/* --------------------------------------------------------------------------------------------
* Default destructor (disabled)
*/
Ent() = delete;
/* --------------------------------------------------------------------------------------------
* Helper structure that holds information about each entity instance of this type.
2015-09-30 02:56:11 +02:00
*/
typedef struct Checkpoint
{
// ----------------------------------------------------------------------------------------
Checkpoint() noexcept
: ID(-1), Root(0), Owned(false), Fresh(true)
{
/* ... */
}
2015-09-30 02:56:11 +02:00
// ----------------------------------------------------------------------------------------
SQInt32 ID;
// ----------------------------------------------------------------------------------------
RefType* Root;
// ----------------------------------------------------------------------------------------
bool Owned;
bool Fresh;
// ----------------------------------------------------------------------------------------
SqTag Tag;
SqObj Data;
// ----------------------------------------------------------------------------------------
ECheckpointCreated CheckpointCreated;
ECheckpointDestroyed CheckpointDestroyed;
ECheckpointCustom CheckpointCustom;
ECheckpointEntered CheckpointEntered;
ECheckpointExited CheckpointExited;
// ----------------------------------------------------------------------------------------
ECheckpointCreated & Created() noexcept
{
return CheckpointCreated;
}
ECheckpointDestroyed & Destroyed() noexcept
{
return CheckpointDestroyed;
}
ECheckpointCustom & Custom() noexcept
{
return CheckpointCustom;
}
// ----------------------------------------------------------------------------------------
ECheckpointCreated & GCreated() noexcept
{
return GCheckpointCreated();
}
ECheckpointDestroyed & GDestroyed() noexcept
{
return GCheckpointDestroyed();
}
ECheckpointCustom & GCustom() noexcept
{
return GCheckpointCustom();
}
2015-09-30 02:56:11 +02:00
} Instance;
// --------------------------------------------------------------------------------------------
static void Store(Instance & inst) noexcept
{
/* ... */
}
// --------------------------------------------------------------------------------------------
static void Store(Instance & inst, SQInt32 player, SQInt32 world, SQFloat x, SQFloat y, SQFloat z,
SQUint32 r, SQUint32 g, SQUint32 b, SQUint32 a, SQFloat radius) noexcept
{
/* ... */
}
2015-09-30 02:56:11 +02:00
// --------------------------------------------------------------------------------------------
static void Clear(Instance & inst) noexcept
{
inst.CheckpointCreated.Clear();
inst.CheckpointDestroyed.Clear();
inst.CheckpointCustom.Clear();
inst.CheckpointEntered.Clear();
inst.CheckpointExited.Clear();
}
// --------------------------------------------------------------------------------------------
static SQInt32 Create(SQInt32 player, SQInt32 world, SQFloat x, SQFloat y, SQFloat z,
SQUint32 r, SQUint32 g, SQUint32 b, SQUint32 a, SQFloat radius) noexcept
{
return _Func->CreateCheckpoint(player, world, x, y, z, r, g, b, a, radius);
}
// --------------------------------------------------------------------------------------------
static void Destroy(SQInt32 id) noexcept
{
_Func->DeleteCheckpoint(id);
}
2015-09-30 02:56:11 +02:00
public:
// --------------------------------------------------------------------------------------------
static constexpr const SQChar* Name = "Checkpoint";
static constexpr const SQChar* CName = "CCheckpoint";
// --------------------------------------------------------------------------------------------
static constexpr SQInt32 TypeID = ENT_CHECKPOINT;
static constexpr SQInt32 Limit = SQMOD_CHECKPOINT_POOL;
// --------------------------------------------------------------------------------------------
static constexpr SQInt32 CreateEvID = EVT_CHECKPOINTCREATED;
static constexpr SQInt32 DestroyEvID = EVT_CHECKPOINTDESTROYED;
static constexpr SQInt32 CustomEvID = EVT_CHECKPOINTCUSTOM;
2015-09-30 02:56:11 +02:00
// --------------------------------------------------------------------------------------------
typedef std::array< Instance, Limit > Instances;
// --------------------------------------------------------------------------------------------
typedef std::bitset< Limit > Set;
// --------------------------------------------------------------------------------------------
static bool InEvent(SQInt32 type) noexcept
{
switch (type)
{
case EVT_CHECKPOINTCREATED:
case EVT_CHECKPOINTDESTROYED:
case EVT_CHECKPOINTCUSTOM:
case EVT_CHECKPOINTENTERED:
case EVT_CHECKPOINTEXITED:
return true;
default:
return false;
}
}
// --------------------------------------------------------------------------------------------
static bool InEvent(SQInt32 type, bool inversed) noexcept
{
switch (type)
{
case EVT_CHECKPOINTCREATED:
case EVT_CHECKPOINTDESTROYED:
case EVT_CHECKPOINTCUSTOM:
return true;
case EVT_CHECKPOINTENTERED:
case EVT_CHECKPOINTEXITED:
return !inversed;
default:
return false;
}
}
2015-09-30 02:56:11 +02:00
};
/* ------------------------------------------------------------------------------------------------
* Specialized entity interface for the keybind entity type.
2015-09-30 02:56:11 +02:00
*/
template <> class Ent< CKeybind >
{
private:
// --------------------------------------------------------------------------------------------
friend class EntMan< CKeybind >;
friend class Reference< CKeybind >;
// --------------------------------------------------------------------------------------------
typedef Reference< CKeybind > RefType;
/* --------------------------------------------------------------------------------------------
* Default destructor (disabled)
*/
Ent() = delete;
/* --------------------------------------------------------------------------------------------
* Helper structure that holds information about each entity instance of this type.
2015-09-30 02:56:11 +02:00
*/
typedef struct Keybind
{
// ----------------------------------------------------------------------------------------
Keybind() noexcept
: ID(-1), Root(0), Owned(false), Fresh(true)
{
/* ... */
}
2015-09-30 02:56:11 +02:00
// ----------------------------------------------------------------------------------------
SQInt32 ID;
// ----------------------------------------------------------------------------------------
RefType* Root;
// ----------------------------------------------------------------------------------------
bool Owned;
bool Fresh;
// ----------------------------------------------------------------------------------------
SqTag Tag;
SqObj Data;
// ----------------------------------------------------------------------------------------
SQInt32 Primary;
SQInt32 Secondary;
SQInt32 Alternative;
// ----------------------------------------------------------------------------------------
bool Release;
// ----------------------------------------------------------------------------------------
EKeybindCreated KeybindCreated;
EKeybindDestroyed KeybindDestroyed;
EKeybindCustom KeybindCustom;
EKeybindKeyPress KeybindKeyPress;
EKeybindKeyRelease KeybindKeyRelease;
// ----------------------------------------------------------------------------------------
EKeybindCreated & Created() noexcept
{
return KeybindCreated;
}
EKeybindDestroyed & Destroyed() noexcept
{
return KeybindDestroyed;
}
EKeybindCustom & Custom() noexcept
{
return KeybindCustom;
}
// ----------------------------------------------------------------------------------------
EKeybindCreated & GCreated() noexcept
{
return GKeybindCreated();
}
EKeybindDestroyed & GDestroyed() noexcept
{
return GKeybindDestroyed();
}
EKeybindCustom & GCustom() noexcept
{
return GKeybindCustom();
}
2015-09-30 02:56:11 +02:00
} Instance;
// --------------------------------------------------------------------------------------------
static void Store(Instance & inst) noexcept
{
inst.Primary = SQMOD_UNKNOWN;
inst.Secondary = SQMOD_UNKNOWN;
inst.Alternative = SQMOD_UNKNOWN;
inst.Release = false;
}
// --------------------------------------------------------------------------------------------
static void Store(Instance & inst, SQInt32 slot, bool release, SQInt32 primary, SQInt32 secondary,
SQInt32 alternative) noexcept
2015-09-30 02:56:11 +02:00
{
inst.Primary = primary;
inst.Secondary = secondary;
inst.Alternative = alternative;
inst.Release = release;
}
// --------------------------------------------------------------------------------------------
static void Clear(Instance & inst) noexcept
{
inst.KeybindCreated.Clear();
inst.KeybindDestroyed.Clear();
inst.KeybindCustom.Clear();
inst.KeybindKeyPress.Clear();
inst.KeybindKeyRelease.Clear();
}
// --------------------------------------------------------------------------------------------
static SQInt32 Create(SQInt32 slot, bool release, SQInt32 primary, SQInt32 secondary,
SQInt32 alternative) noexcept
{
return _Func->RegisterKeyBind(slot, release, primary, secondary, alternative);
}
// --------------------------------------------------------------------------------------------
static void Destroy(SQInt32 id) noexcept
{
_Func->RemoveKeyBind(id);
}
2015-09-30 02:56:11 +02:00
public:
// --------------------------------------------------------------------------------------------
static constexpr const SQChar* Name = "Keybind";
static constexpr const SQChar* CName = "CKeybind";
// --------------------------------------------------------------------------------------------
static constexpr SQInt32 TypeID = ENT_KEYBIND;
static constexpr SQInt32 Limit = SQMOD_KEYBIND_POOL;
// --------------------------------------------------------------------------------------------
static constexpr SQInt32 CreateEvID = EVT_KEYBINDCREATED;
static constexpr SQInt32 DestroyEvID = EVT_KEYBINDDESTROYED;
static constexpr SQInt32 CustomEvID = EVT_KEYBINDCUSTOM;
2015-09-30 02:56:11 +02:00
// --------------------------------------------------------------------------------------------
typedef std::array< Instance, Limit > Instances;
// --------------------------------------------------------------------------------------------
typedef std::bitset< Limit > Set;
// --------------------------------------------------------------------------------------------
static bool InEvent(SQInt32 type) noexcept
{
switch (type)
{
case EVT_KEYBINDCREATED:
case EVT_KEYBINDDESTROYED:
case EVT_KEYBINDCUSTOM:
case EVT_KEYBINDKEYPRESS:
case EVT_KEYBINDKEYRELEASE:
return true;
default:
return false;
}
}
// --------------------------------------------------------------------------------------------
static bool InEvent(SQInt32 type, bool inversed) noexcept
{
switch (type)
{
case EVT_KEYBINDCREATED:
case EVT_KEYBINDDESTROYED:
case EVT_KEYBINDCUSTOM:
return true;
case EVT_KEYBINDKEYPRESS:
case EVT_KEYBINDKEYRELEASE:
return !inversed;
default:
return false;
}
}
2015-09-30 02:56:11 +02:00
};
/* ------------------------------------------------------------------------------------------------
* Specialized entity interface for the object entity type.
2015-09-30 02:56:11 +02:00
*/
template <> class Ent< CObject >
{
private:
// --------------------------------------------------------------------------------------------
friend class EntMan< CObject >;
friend class Reference< CObject >;
// --------------------------------------------------------------------------------------------
typedef Reference< CObject > RefType;
/* --------------------------------------------------------------------------------------------
* Default destructor (disabled)
*/
Ent() = delete;
/* --------------------------------------------------------------------------------------------
* Helper structure that holds information about each entity instance of this type.
2015-09-30 02:56:11 +02:00
*/
typedef struct Object
{
// ----------------------------------------------------------------------------------------
Object() noexcept
: ID(-1), Root(0), Owned(false), Fresh(true)
{
/* ... */
}
2015-09-30 02:56:11 +02:00
// ----------------------------------------------------------------------------------------
SQInt32 ID;
// ----------------------------------------------------------------------------------------
RefType* Root;
// ----------------------------------------------------------------------------------------
bool Owned;
bool Fresh;
// ----------------------------------------------------------------------------------------
SqTag Tag;
SqObj Data;
// ----------------------------------------------------------------------------------------
EObjectCreated ObjectCreated;
EObjectDestroyed ObjectDestroyed;
EObjectCustom ObjectCustom;
EObjectShot ObjectShot;
EObjectBump ObjectBump;
// ----------------------------------------------------------------------------------------
EObjectCreated & Created() noexcept
{
return ObjectCreated;
}
EObjectDestroyed & Destroyed() noexcept
{
return ObjectDestroyed;
}
EObjectCustom & Custom() noexcept
{
return ObjectCustom;
}
// ----------------------------------------------------------------------------------------
EObjectCreated & GCreated() noexcept
{
return GObjectCreated();
}
EObjectDestroyed & GDestroyed() noexcept
{
return GObjectDestroyed();
}
EObjectCustom & GCustom() noexcept
{
return GObjectCustom();
}
2015-09-30 02:56:11 +02:00
} Instance;
// --------------------------------------------------------------------------------------------
static void Store(Instance & inst) noexcept
{
/* ... */
}
// --------------------------------------------------------------------------------------------
static void Store(Instance & inst, SQInt32 model, SQInt32 world, SQFloat x, SQFloat y, SQFloat z,
SQInt32 alpha) noexcept
{
/* ... */
}
2015-09-30 02:56:11 +02:00
// --------------------------------------------------------------------------------------------
static void Clear(Instance & inst) noexcept
{
inst.ObjectCreated.Clear();
inst.ObjectDestroyed.Clear();
inst.ObjectCustom.Clear();
inst.ObjectShot.Clear();
inst.ObjectBump.Clear();
}
// --------------------------------------------------------------------------------------------
static SQInt32 Create(SQInt32 model, SQInt32 world, SQFloat x, SQFloat y, SQFloat z,
SQInt32 alpha) noexcept
{
return _Func->CreateObject(model, world, x, y, z, alpha);
}
// --------------------------------------------------------------------------------------------
static void Destroy(SQInt32 id) noexcept
{
_Func->DeleteObject(id);
}
2015-09-30 02:56:11 +02:00
public:
// --------------------------------------------------------------------------------------------
static constexpr const SQChar* Name = "Object";
static constexpr const SQChar* CName = "CObject";
// --------------------------------------------------------------------------------------------
static constexpr SQInt32 TypeID = ENT_OBJECT;
static constexpr SQInt32 Limit = SQMOD_OBJECT_POOL;
// --------------------------------------------------------------------------------------------
static constexpr SQInt32 CreateEvID = EVT_OBJECTCREATED;
static constexpr SQInt32 DestroyEvID = EVT_OBJECTDESTROYED;
static constexpr SQInt32 CustomEvID = EVT_OBJECTCUSTOM;
2015-09-30 02:56:11 +02:00
// --------------------------------------------------------------------------------------------
typedef std::array< Instance, Limit > Instances;
// --------------------------------------------------------------------------------------------
typedef std::bitset< Limit > Set;
// --------------------------------------------------------------------------------------------
static bool InEvent(SQInt32 type) noexcept
{
switch (type)
{
case EVT_OBJECTCREATED:
case EVT_OBJECTDESTROYED:
case EVT_OBJECTCUSTOM:
case EVT_OBJECTSHOT:
case EVT_OBJECTBUMP:
return true;
default:
return false;
}
}
// --------------------------------------------------------------------------------------------
static bool InEvent(SQInt32 type, bool inversed) noexcept
{
switch (type)
{
case EVT_OBJECTCREATED:
case EVT_OBJECTDESTROYED:
case EVT_OBJECTCUSTOM:
return true;
case EVT_OBJECTSHOT:
case EVT_OBJECTBUMP:
return !inversed;
default:
return false;
}
}
2015-09-30 02:56:11 +02:00
};
/* ------------------------------------------------------------------------------------------------
* Specialized entity interface for the pickup entity type.
2015-09-30 02:56:11 +02:00
*/
template <> class Ent< CPickup >
{
private:
// --------------------------------------------------------------------------------------------
friend class EntMan< CPickup >;
friend class Reference< CPickup >;
// --------------------------------------------------------------------------------------------
typedef Reference< CPickup > RefType;
/* --------------------------------------------------------------------------------------------
* Default destructor (disabled)
*/
Ent() = delete;
/* --------------------------------------------------------------------------------------------
* Helper structure that holds information about each entity instance of this type.
2015-09-30 02:56:11 +02:00
*/
typedef struct Pickup
{
// ----------------------------------------------------------------------------------------
Pickup() noexcept
: ID(-1), Root(0), Owned(false), Fresh(true)
{
/* ... */
}
2015-09-30 02:56:11 +02:00
// ----------------------------------------------------------------------------------------
SQInt32 ID;
// ----------------------------------------------------------------------------------------
RefType* Root;
// ----------------------------------------------------------------------------------------
bool Owned;
bool Fresh;
// ----------------------------------------------------------------------------------------
SqTag Tag;
SqObj Data;
// ----------------------------------------------------------------------------------------
EPickupCreated PickupCreated;
EPickupDestroyed PickupDestroyed;
EPickupCustom PickupCustom;
EPickupRespawn PickupRespawn;
EPickupClaimed PickupClaimed;
EPickupCollected PickupCollected;
// ----------------------------------------------------------------------------------------
EPickupCreated & Created() noexcept
{
return PickupCreated;
}
EPickupDestroyed & Destroyed() noexcept
{
return PickupDestroyed;
}
EPickupCustom & Custom() noexcept
{
return PickupCustom;
}
// ----------------------------------------------------------------------------------------
EPickupCreated & GCreated() noexcept
{
return GPickupCreated();
}
EPickupDestroyed & GDestroyed() noexcept
{
return GPickupDestroyed();
}
EPickupCustom & GCustom() noexcept
{
return GPickupCustom();
}
2015-09-30 02:56:11 +02:00
} Instance;
// --------------------------------------------------------------------------------------------
static void Store(Instance & inst) noexcept
{
/* ... */
}
// --------------------------------------------------------------------------------------------
static void Store(Instance & inst, SQInt32 model, SQInt32 world, SQInt32 quantity,
SQFloat x, SQFloat y, SQFloat z, SQInt32 alpha, bool automatic) noexcept
{
/* ... */
}
2015-09-30 02:56:11 +02:00
// --------------------------------------------------------------------------------------------
static void Clear(Instance & inst) noexcept
{
inst.PickupCreated.Clear();
inst.PickupDestroyed.Clear();
inst.PickupCustom.Clear();
inst.PickupRespawn.Clear();
inst.PickupClaimed.Clear();
inst.PickupCollected.Clear();
}
// --------------------------------------------------------------------------------------------
static SQInt32 Create(SQInt32 model, SQInt32 world, SQInt32 quantity,
SQFloat x, SQFloat y, SQFloat z, SQInt32 alpha, bool automatic) noexcept
{
return _Func->CreatePickup(model, world, quantity, x, y, z, alpha, automatic);
}
// --------------------------------------------------------------------------------------------
static void Destroy(SQInt32 id) noexcept
{
_Func->DeletePickup(id);
}
2015-09-30 02:56:11 +02:00
public:
// --------------------------------------------------------------------------------------------
static constexpr const SQChar* Name = "Pickup";
static constexpr const SQChar* CName = "CPickup";
// --------------------------------------------------------------------------------------------
static constexpr SQInt32 TypeID = ENT_PICKUP;
static constexpr SQInt32 Limit = SQMOD_PICKUP_POOL;
// --------------------------------------------------------------------------------------------
static constexpr SQInt32 CreateEvID = EVT_PICKUPCREATED;
static constexpr SQInt32 DestroyEvID = EVT_PICKUPDESTROYED;
static constexpr SQInt32 CustomEvID = EVT_PICKUPCUSTOM;
2015-09-30 02:56:11 +02:00
// --------------------------------------------------------------------------------------------
typedef std::array< Instance, Limit > Instances;
// --------------------------------------------------------------------------------------------
typedef std::bitset< Limit > Set;
// --------------------------------------------------------------------------------------------
static bool InEvent(SQInt32 type) noexcept
{
switch (type)
{
case EVT_PICKUPCREATED:
case EVT_PICKUPDESTROYED:
case EVT_PICKUPCUSTOM:
case EVT_PICKUPRESPAWN:
case EVT_PICKUPCLAIMED:
case EVT_PICKUPCOLLECTED:
return true;
default:
return false;
}
}
// --------------------------------------------------------------------------------------------
static bool InEvent(SQInt32 type, bool inversed) noexcept
{
switch (type)
{
case EVT_PICKUPCREATED:
case EVT_PICKUPDESTROYED:
case EVT_PICKUPCUSTOM:
case EVT_PICKUPRESPAWN:
return true;
case EVT_PICKUPCLAIMED:
case EVT_PICKUPCOLLECTED:
return !inversed;
default:
return false;
}
}
2015-09-30 02:56:11 +02:00
};
/* ------------------------------------------------------------------------------------------------
* Specialized entity interface for the player entity type.
2015-09-30 02:56:11 +02:00
*/
template <> class Ent< CPlayer >
{
private:
// --------------------------------------------------------------------------------------------
friend class EntMan< CPlayer >;
friend class Reference< CPlayer >;
// --------------------------------------------------------------------------------------------
typedef Reference< CPlayer > RefType;
/* --------------------------------------------------------------------------------------------
* Default destructor (disabled)
*/
Ent() = delete;
/* --------------------------------------------------------------------------------------------
* Helper structure that holds information about each entity instance of this type.
2015-09-30 02:56:11 +02:00
*/
typedef struct Player
{
// ----------------------------------------------------------------------------------------
Player() noexcept
: ID(-1), Root(0), Owned(false), Fresh(true)
{
/* ... */
}
2015-09-30 02:56:11 +02:00
// ----------------------------------------------------------------------------------------
SQInt32 ID;
// ----------------------------------------------------------------------------------------
RefType* Root;
// ----------------------------------------------------------------------------------------
bool Owned; /* Useless but required by the instance activation system */
bool Fresh;
// ----------------------------------------------------------------------------------------
SqTag Tag;
SqObj Data;
// ----------------------------------------------------------------------------------------
EPlayerCreated PlayerCreated;
EPlayerDestroyed PlayerDestroyed;
EPlayerCustom PlayerCustom;
EPlayerAway PlayerAway;
EPlayerGameKeys PlayerGameKeys;
EPlayerRename PlayerRename;
EPlayerRequestClass PlayerRequestClass;
EPlayerRequestSpawn PlayerRequestSpawn;
EPlayerSpawn PlayerSpawn;
EPlayerStartTyping PlayerStartTyping;
EPlayerStopTyping PlayerStopTyping;
EPlayerChat PlayerChat;
EPlayerCommand PlayerCommand;
EPlayerMessage PlayerMessage;
EPlayerHealth PlayerHealth;
EPlayerArmour PlayerArmour;
EPlayerWeapon PlayerWeapon;
EPlayerMove PlayerMove;
EPlayerWasted PlayerWasted;
EPlayerKilled PlayerKilled;
EPlayerTeamKill PlayerTeamKill;
EPlayerSpectate PlayerSpectate;
EPlayerCrashreport PlayerCrashreport;
EPlayerBurning PlayerBurning;
EPlayerCrouching PlayerCrouching;
EPlayerState PlayerState;
EPlayerAction PlayerAction;
EStateNone StateNone;
EStateNormal StateNormal;
EStateShooting StateShooting;
EStateDriver StateDriver;
EStatePassenger StatePassenger;
EStateEnterDriver StateEnterDriver;
EStateEnterPassenger StateEnterPassenger;
EStateExitVehicle StateExitVehicle;
EStateUnspawned StateUnspawned;
EActionNone ActionNone;
EActionNormal ActionNormal;
EActionAiming ActionAiming;
EActionShooting ActionShooting;
EActionJumping ActionJumping;
EActionLieDown ActionLieDown;
EActionGettingUp ActionGettingUp;
EActionJumpVehicle ActionJumpVehicle;
EActionDriving ActionDriving;
EActionDying ActionDying;
EActionWasted ActionWasted;
EActionEmbarking ActionEmbarking;
EActionDisembarking ActionDisembarking;
EKeybindKeyPress KeybindKeyPress;
EKeybindKeyRelease KeybindKeyRelease;
EVehicleEmbarking VehicleEmbarking;
EVehicleEmbarked VehicleEmbarked;
EVehicleDisembark VehicleDisembark;
EPickupClaimed PickupClaimed;
EPickupCollected PickupCollected;
EObjectShot ObjectShot;
EObjectBump ObjectBump;
ECheckpointEntered CheckpointEntered;
ECheckpointExited CheckpointExited;
ESphereEntered SphereEntered;
ESphereExited SphereExited;
// ----------------------------------------------------------------------------------------
EPlayerCreated & Created() noexcept
{
return PlayerCreated;
}
EPlayerDestroyed & Destroyed() noexcept
{
return PlayerDestroyed;
}
EPlayerCustom & Custom() noexcept
{
return PlayerCustom;
}
// ----------------------------------------------------------------------------------------
EPlayerCreated & GCreated() noexcept
{
return GPlayerCreated();
}
EPlayerDestroyed & GDestroyed() noexcept
{
return GPlayerDestroyed();
}
EPlayerCustom & GCustom() noexcept
{
return GPlayerCustom();
}
2015-09-30 02:56:11 +02:00
} Instance;
// --------------------------------------------------------------------------------------------
static void Store(Instance & inst) noexcept
{
/* ... */
}
// --------------------------------------------------------------------------------------------
static void Clear(Instance & inst) noexcept
{
inst.PlayerCreated.Clear();
inst.PlayerDestroyed.Clear();
inst.PlayerCustom.Clear();
inst.PlayerAway.Clear();
inst.PlayerGameKeys.Clear();
inst.PlayerRename.Clear();
inst.PlayerRequestClass.Clear();
inst.PlayerRequestSpawn.Clear();
inst.PlayerSpawn.Clear();
inst.PlayerStartTyping.Clear();
inst.PlayerStopTyping.Clear();
inst.PlayerChat.Clear();
inst.PlayerCommand.Clear();
inst.PlayerMessage.Clear();
inst.PlayerHealth.Clear();
inst.PlayerArmour.Clear();
inst.PlayerWeapon.Clear();
inst.PlayerMove.Clear();
inst.PlayerWasted.Clear();
inst.PlayerKilled.Clear();
inst.PlayerTeamKill.Clear();
inst.PlayerSpectate.Clear();
inst.PlayerCrashreport.Clear();
inst.PlayerBurning.Clear();
inst.PlayerCrouching.Clear();
inst.PlayerState.Clear();
inst.PlayerAction.Clear();
inst.StateNone.Clear();
inst.StateNormal.Clear();
inst.StateShooting.Clear();
inst.StateDriver.Clear();
inst.StatePassenger.Clear();
inst.StateEnterDriver.Clear();
inst.StateEnterPassenger.Clear();
inst.StateExitVehicle.Clear();
inst.StateUnspawned.Clear();
inst.ActionNone.Clear();
inst.ActionNormal.Clear();
inst.ActionAiming.Clear();
inst.ActionShooting.Clear();
inst.ActionJumping.Clear();
inst.ActionLieDown.Clear();
inst.ActionGettingUp.Clear();
inst.ActionJumpVehicle.Clear();
inst.ActionDriving.Clear();
inst.ActionDying.Clear();
inst.ActionWasted.Clear();
inst.ActionEmbarking.Clear();
inst.ActionDisembarking.Clear();
inst.KeybindKeyPress.Clear();
inst.KeybindKeyRelease.Clear();
inst.VehicleEmbarking.Clear();
inst.VehicleEmbarked.Clear();
inst.VehicleDisembark.Clear();
inst.PickupClaimed.Clear();
inst.PickupCollected.Clear();
inst.ObjectShot.Clear();
inst.ObjectBump.Clear();
inst.CheckpointEntered.Clear();
inst.CheckpointExited.Clear();
inst.SphereEntered.Clear();
inst.SphereExited.Clear();
2015-09-30 02:56:11 +02:00
}
// --------------------------------------------------------------------------------------------
static SQInt32 Create() noexcept
{
return SQMOD_UNKNOWN;
}
// --------------------------------------------------------------------------------------------
static void Destroy(SQInt32 id) noexcept
{
/* @TODO: Implement as kick. */
}
2015-09-30 02:56:11 +02:00
public:
// --------------------------------------------------------------------------------------------
static constexpr const SQChar* Name = "Player";
static constexpr const SQChar* CName = "CPlayer";
// --------------------------------------------------------------------------------------------
static constexpr SQInt32 TypeID = ENT_PLAYER;
static constexpr SQInt32 Limit = SQMOD_PLAYER_POOL;
// --------------------------------------------------------------------------------------------
static constexpr SQInt32 CreateEvID = EVT_PLAYERCREATED;
static constexpr SQInt32 DestroyEvID = EVT_PLAYERDESTROYED;
static constexpr SQInt32 CustomEvID = EVT_PLAYERCUSTOM;
2015-09-30 02:56:11 +02:00
// --------------------------------------------------------------------------------------------
typedef std::array< Instance, Limit > Instances;
// --------------------------------------------------------------------------------------------
typedef std::bitset< Limit > Set;
// --------------------------------------------------------------------------------------------
static bool InEvent(SQInt32 type) noexcept
{
switch (type)
{
case EVT_PLAYERCREATED:
case EVT_PLAYERDESTROYED:
case EVT_PLAYERCUSTOM:
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_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;
}
}
// --------------------------------------------------------------------------------------------
static bool InEvent(SQInt32 type, bool inversed) noexcept
{
switch (type)
{
case EVT_PLAYERCREATED:
case EVT_PLAYERDESTROYED:
case EVT_PLAYERCUSTOM:
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:
return true;
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 inversed;
default:
return false;
}
}
2015-09-30 02:56:11 +02:00
};
/* ------------------------------------------------------------------------------------------------
* Specialized entity interface for the sphere entity type.
2015-09-30 02:56:11 +02:00
*/
template <> class Ent< CSphere >
{
private:
// --------------------------------------------------------------------------------------------
friend class EntMan< CSphere >;
friend class Reference< CSphere >;
// --------------------------------------------------------------------------------------------
typedef Reference< CSphere > RefType;
/* --------------------------------------------------------------------------------------------
* Default destructor (disabled)
*/
Ent() = delete;
/* --------------------------------------------------------------------------------------------
* Helper structure that holds information about each entity instance of this type.
2015-09-30 02:56:11 +02:00
*/
typedef struct Sphere
{
// ----------------------------------------------------------------------------------------
Sphere() noexcept
: ID(-1), Root(0), Owned(false), Fresh(true)
{
/* ... */
}
2015-09-30 02:56:11 +02:00
// ----------------------------------------------------------------------------------------
SQInt32 ID;
// ----------------------------------------------------------------------------------------
RefType* Root;
// ----------------------------------------------------------------------------------------
bool Owned;
bool Fresh;
// ----------------------------------------------------------------------------------------
SqTag Tag;
SqObj Data;
// ----------------------------------------------------------------------------------------
ESphereCreated SphereCreated;
ESphereDestroyed SphereDestroyed;
ESphereCustom SphereCustom;
ESphereEntered SphereEntered;
ESphereExited SphereExited;
// ----------------------------------------------------------------------------------------
ESphereCreated & Created() noexcept
{
return SphereCreated;
}
ESphereDestroyed & Destroyed() noexcept
{
return SphereDestroyed;
}
ESphereCustom & Custom() noexcept
{
return SphereCustom;
}
// ----------------------------------------------------------------------------------------
ESphereCreated & GCreated() noexcept
{
return GSphereCreated();
}
ESphereDestroyed & GDestroyed() noexcept
{
return GSphereDestroyed();
}
ESphereCustom & GCustom() noexcept
{
return GSphereCustom();
}
2015-09-30 02:56:11 +02:00
} Instance;
// --------------------------------------------------------------------------------------------
static void Store(Instance & inst) noexcept
{
/* ... */
}
// --------------------------------------------------------------------------------------------
static void Store(Instance & inst, SQInt32 player, SQInt32 world, SQFloat x, SQFloat y, SQFloat z,
SQUint32 r, SQUint32 g, SQUint32 b, SQFloat radius) noexcept
{
/* ... */
}
2015-09-30 02:56:11 +02:00
// --------------------------------------------------------------------------------------------
static void Clear(Instance & inst) noexcept
{
inst.SphereCreated.Clear();
inst.SphereDestroyed.Clear();
inst.SphereCustom.Clear();
inst.SphereEntered.Clear();
inst.SphereExited.Clear();
}
// --------------------------------------------------------------------------------------------
static SQInt32 Create(SQInt32 player, SQInt32 world, SQFloat x, SQFloat y, SQFloat z,
SQUint32 r, SQUint32 g, SQUint32 b, SQFloat radius) noexcept
{
return _Func->CreateSphere(_SCI32(player), world, x, y, z, r, g, b, radius);
}
// --------------------------------------------------------------------------------------------
static void Destroy(SQInt32 id) noexcept
{
_Func->DeleteSphere(id);
}
2015-09-30 02:56:11 +02:00
public:
// --------------------------------------------------------------------------------------------
static constexpr const SQChar* Name = "Sphere";
static constexpr const SQChar* CName = "CSphere";
// --------------------------------------------------------------------------------------------
static constexpr SQInt32 TypeID = ENT_SPHERE;
static constexpr SQInt32 Limit = SQMOD_SPHERE_POOL;
// --------------------------------------------------------------------------------------------
static constexpr SQInt32 CreateEvID = EVT_SPHERECREATED;
static constexpr SQInt32 DestroyEvID = EVT_SPHEREDESTROYED;
static constexpr SQInt32 CustomEvID = EVT_SPHERECUSTOM;
2015-09-30 02:56:11 +02:00
// --------------------------------------------------------------------------------------------
typedef std::array< Instance, Limit > Instances;
// --------------------------------------------------------------------------------------------
typedef std::bitset< Limit > Set;
// --------------------------------------------------------------------------------------------
static bool InEvent(SQInt32 type) noexcept
{
switch (type)
{
case EVT_SPHERECREATED:
case EVT_SPHEREDESTROYED:
case EVT_SPHERECUSTOM:
case EVT_SPHEREENTERED:
case EVT_SPHEREEXITED:
return true;
default:
return false;
}
}
// --------------------------------------------------------------------------------------------
static bool InEvent(SQInt32 type, bool inversed) noexcept
{
switch (type)
{
case EVT_SPHERECREATED:
case EVT_SPHEREDESTROYED:
case EVT_SPHERECUSTOM:
return true;
case EVT_SPHEREENTERED:
case EVT_SPHEREEXITED:
return !inversed;
default:
return false;
}
}
2015-09-30 02:56:11 +02:00
};
/* ------------------------------------------------------------------------------------------------
* Specialized entity interface for the sprite entity type.
2015-09-30 02:56:11 +02:00
*/
template <> class Ent< CSprite >
{
private:
// --------------------------------------------------------------------------------------------
friend class EntMan< CSprite >;
friend class Reference< CSprite >;
// --------------------------------------------------------------------------------------------
typedef Reference< CSprite > RefType;
/* --------------------------------------------------------------------------------------------
* Default destructor (disabled)
*/
Ent() = delete;
/* --------------------------------------------------------------------------------------------
* Helper structure that holds information about each entity instance of this type.
2015-09-30 02:56:11 +02:00
*/
typedef struct Sprite
{
// ----------------------------------------------------------------------------------------
Sprite() noexcept
: ID(-1), Root(0), Owned(false), Fresh(true)
{
/* ... */
}
2015-09-30 02:56:11 +02:00
// ----------------------------------------------------------------------------------------
SQInt32 ID;
// ----------------------------------------------------------------------------------------
RefType* Root;
// ----------------------------------------------------------------------------------------
bool Owned;
bool Fresh;
// ----------------------------------------------------------------------------------------
SqTag Tag;
SqObj Data;
// ----------------------------------------------------------------------------------------
String Path;
// ----------------------------------------------------------------------------------------
ESpriteCreated SpriteCreated;
ESpriteDestroyed SpriteDestroyed;
ESpriteCustom SpriteCustom;
// ----------------------------------------------------------------------------------------
ESpriteCreated & Created() noexcept
{
return SpriteCreated;
}
ESpriteDestroyed & Destroyed() noexcept
{
return SpriteDestroyed;
}
ESpriteCustom & Custom() noexcept
{
return SpriteCustom;
}
// ----------------------------------------------------------------------------------------
ESpriteCreated & GCreated() noexcept
{
return GSpriteCreated();
}
ESpriteDestroyed & GDestroyed() noexcept
{
return GSpriteDestroyed();
}
ESpriteCustom & GCustom() noexcept
{
return GSpriteCustom();
}
2015-09-30 02:56:11 +02:00
} Instance;
// --------------------------------------------------------------------------------------------
static void Store(Instance & inst) noexcept
2015-09-30 02:56:11 +02:00
{
inst.Path.clear();
}
// --------------------------------------------------------------------------------------------
static void Store(Instance & inst, SQInt32 index, const SQChar * file, SQInt32 xp, SQInt32 yp,
SQInt32 xr, SQInt32 yr, SQFloat angle, SQInt32 alpha, bool rel) noexcept
{
inst.Path.assign(file);
2015-09-30 02:56:11 +02:00
}
// --------------------------------------------------------------------------------------------
static void Clear(Instance & inst) noexcept
{
inst.SpriteCreated.Clear();
inst.SpriteDestroyed.Clear();
inst.SpriteCustom.Clear();
}
// --------------------------------------------------------------------------------------------
static SQInt32 Create(SQInt32 index, const SQChar * file, SQInt32 xp, SQInt32 yp,
SQInt32 xr, SQInt32 yr, SQFloat angle, SQInt32 alpha, bool rel) noexcept
{
return _Func->CreateSprite(index, file, xp, yp, xr, yr, angle, alpha, rel);
}
// --------------------------------------------------------------------------------------------
static void Destroy(SQInt32 id) noexcept
{
_Func->DestroySprite(id);
}
2015-09-30 02:56:11 +02:00
public:
// --------------------------------------------------------------------------------------------
static constexpr const SQChar* Name = "Sprite";
static constexpr const SQChar* CName = "CSprite";
// --------------------------------------------------------------------------------------------
static constexpr SQInt32 TypeID = ENT_SPRITE;
static constexpr SQInt32 Limit = SQMOD_SPRITE_POOL;
// --------------------------------------------------------------------------------------------
static constexpr SQInt32 CreateEvID = EVT_SPRITECREATED;
static constexpr SQInt32 DestroyEvID = EVT_SPRITEDESTROYED;
static constexpr SQInt32 CustomEvID = EVT_SPRITECUSTOM;
2015-09-30 02:56:11 +02:00
// --------------------------------------------------------------------------------------------
typedef std::array< Instance, Limit > Instances;
// --------------------------------------------------------------------------------------------
typedef std::bitset< Limit > Set;
// --------------------------------------------------------------------------------------------
static bool InEvent(SQInt32 type) noexcept
{
switch (type)
{
case EVT_SPRITECREATED:
case EVT_SPRITEDESTROYED:
case EVT_SPRITECUSTOM:
return true;
default:
return false;
}
}
// --------------------------------------------------------------------------------------------
static bool InEvent(SQInt32 type, bool /* inversed */) noexcept
{
switch (type)
{
case EVT_SPRITECREATED:
case EVT_SPRITEDESTROYED:
case EVT_SPRITECUSTOM:
return true;
default:
return false;
}
}
2015-09-30 02:56:11 +02:00
};
/* ------------------------------------------------------------------------------------------------
* Specialized entity interface for the textdraw entity type.
2015-09-30 02:56:11 +02:00
*/
template <> class Ent< CTextdraw >
{
private:
// --------------------------------------------------------------------------------------------
friend class EntMan< CTextdraw >;
friend class Reference< CTextdraw >;
// --------------------------------------------------------------------------------------------
typedef Reference< CTextdraw > RefType;
/* --------------------------------------------------------------------------------------------
* Default destructor (disabled)
*/
Ent() = delete;
/* --------------------------------------------------------------------------------------------
* Helper structure that holds information about each entity instance of this type.
2015-09-30 02:56:11 +02:00
*/
typedef struct Textdraw
{
// ----------------------------------------------------------------------------------------
Textdraw() noexcept
: ID(-1), Root(0), Owned(false), Fresh(true)
{
/* ... */
}
2015-09-30 02:56:11 +02:00
// ----------------------------------------------------------------------------------------
SQInt32 ID;
// ----------------------------------------------------------------------------------------
RefType* Root;
// ----------------------------------------------------------------------------------------
bool Owned;
bool Fresh;
// ----------------------------------------------------------------------------------------
SqTag Tag;
SqObj Data;
// ----------------------------------------------------------------------------------------
String Text;
// ----------------------------------------------------------------------------------------
ETextdrawCreated TextdrawCreated;
ETextdrawDestroyed TextdrawDestroyed;
ETextdrawCustom TextdrawCustom;
// ----------------------------------------------------------------------------------------
ETextdrawCreated & Created() noexcept
{
return TextdrawCreated;
}
ETextdrawDestroyed & Destroyed() noexcept
{
return TextdrawDestroyed;
}
ETextdrawCustom & Custom() noexcept
{
return TextdrawCustom;
}
// ----------------------------------------------------------------------------------------
ETextdrawCreated & GCreated() noexcept
{
return GTextdrawCreated();
}
ETextdrawDestroyed & GDestroyed() noexcept
{
return GTextdrawDestroyed();
}
ETextdrawCustom & GCustom() noexcept
{
return GTextdrawCustom();
}
2015-09-30 02:56:11 +02:00
} Instance;
// --------------------------------------------------------------------------------------------
static void Store(Instance & inst) noexcept
{
inst.Text.clear();
}
// --------------------------------------------------------------------------------------------
static void Store(Instance & inst, SQInt32 index, const SQChar * text, SQInt32 xp, SQInt32 yp,
SQUint32 color, bool rel) noexcept
2015-09-30 02:56:11 +02:00
{
inst.Text.assign(text);
2015-09-30 02:56:11 +02:00
}
// --------------------------------------------------------------------------------------------
static void Clear(Instance & inst) noexcept
{
inst.TextdrawCreated.Clear();
inst.TextdrawDestroyed.Clear();
inst.TextdrawCustom.Clear();
}
// --------------------------------------------------------------------------------------------
static SQInt32 Create(SQInt32 index, const SQChar * text, SQInt32 xp, SQInt32 yp,
SQUint32 color, bool rel) noexcept
{
return _Func->CreateTextdraw(index, text, xp, yp, color, rel);
}
// --------------------------------------------------------------------------------------------
static void Destroy(SQInt32 id) noexcept
{
_Func->DestroyTextdraw(id);
}
2015-09-30 02:56:11 +02:00
public:
// --------------------------------------------------------------------------------------------
static constexpr const SQChar* Name = "Textdraw";
static constexpr const SQChar* CName = "CTextdraw";
// --------------------------------------------------------------------------------------------
static constexpr SQInt32 TypeID = ENT_TEXTDRAW;
static constexpr SQInt32 Limit = SQMOD_TEXTDRAW_POOL;
// --------------------------------------------------------------------------------------------
static constexpr SQInt32 CreateEvID = EVT_TEXTDRAWCREATED;
static constexpr SQInt32 DestroyEvID = EVT_TEXTDRAWDESTROYED;
static constexpr SQInt32 CustomEvID = EVT_TEXTDRAWCUSTOM;
2015-09-30 02:56:11 +02:00
// --------------------------------------------------------------------------------------------
typedef std::array< Instance, Limit > Instances;
// --------------------------------------------------------------------------------------------
typedef std::bitset< Limit > Set;
// --------------------------------------------------------------------------------------------
static bool InEvent(SQInt32 type) noexcept
{
switch (type)
{
case EVT_TEXTDRAWCREATED:
case EVT_TEXTDRAWDESTROYED:
case EVT_TEXTDRAWCUSTOM:
return true;
default:
return false;
}
}
// --------------------------------------------------------------------------------------------
static bool InEvent(SQInt32 type, bool /* inversed */) noexcept
{
switch (type)
{
case EVT_TEXTDRAWCREATED:
case EVT_TEXTDRAWDESTROYED:
case EVT_TEXTDRAWCUSTOM:
return true;
default:
return false;
}
}
2015-09-30 02:56:11 +02:00
};
/* ------------------------------------------------------------------------------------------------
* Specialized entity interface for the vehicle entity type.
2015-09-30 02:56:11 +02:00
*/
template <> class Ent< CVehicle >
{
private:
// --------------------------------------------------------------------------------------------
friend class EntMan< CVehicle >;
friend class Reference< CVehicle >;
// --------------------------------------------------------------------------------------------
typedef Reference< CVehicle > RefType;
/* --------------------------------------------------------------------------------------------
* Default destructor (disabled)
*/
Ent() = delete;
/* --------------------------------------------------------------------------------------------
* Helper structure that holds information about each entity instance of this type.
2015-09-30 02:56:11 +02:00
*/
typedef struct Vehicle
{
// ----------------------------------------------------------------------------------------
Vehicle() noexcept
: ID(-1), Root(0), Owned(false), Fresh(true)
{
/* ... */
}
2015-09-30 02:56:11 +02:00
// ----------------------------------------------------------------------------------------
SQInt32 ID;
// ----------------------------------------------------------------------------------------
RefType* Root;
// ----------------------------------------------------------------------------------------
bool Owned;
bool Fresh;
// ----------------------------------------------------------------------------------------
SqTag Tag;
SqObj Data;
// ----------------------------------------------------------------------------------------
EVehicleCreated VehicleCreated;
EVehicleDestroyed VehicleDestroyed;
EVehicleCustom VehicleCustom;
EVehicleRespawn VehicleRespawn;
EVehicleExplode VehicleExplode;
EVehicleHealth VehicleHealth;
EVehicleMove VehicleMove;
EVehicleEmbarking VehicleEmbarking;
EVehicleEmbarked VehicleEmbarked;
EVehicleDisembark VehicleDisembark;
// ----------------------------------------------------------------------------------------
EVehicleCreated & Created() noexcept
{
return VehicleCreated;
}
EVehicleDestroyed & Destroyed() noexcept
{
return VehicleDestroyed;
}
EVehicleCustom & Custom() noexcept
{
return VehicleCustom;
}
// ----------------------------------------------------------------------------------------
EVehicleCreated & GCreated() noexcept
{
return GVehicleCreated();
}
EVehicleDestroyed & GDestroyed() noexcept
{
return GVehicleDestroyed();
}
EVehicleCustom & GCustom() noexcept
{
return GVehicleCustom();
}
2015-09-30 02:56:11 +02:00
} Instance;
// --------------------------------------------------------------------------------------------
static void Store(Instance & inst) noexcept
{
/* ... */
}
2015-09-30 02:56:11 +02:00
// --------------------------------------------------------------------------------------------
static void Store(Instance & inst, SQInt32 model, SQInt32 world, SQFloat x, SQFloat y, SQFloat z,
SQFloat angle, SQInt32 primary, SQInt32 secondary) noexcept
{
/* ... */
2015-09-30 02:56:11 +02:00
}
// --------------------------------------------------------------------------------------------
static void Clear(Instance & inst) noexcept
{
inst.VehicleCreated.Clear();
inst.VehicleDestroyed.Clear();
inst.VehicleCustom.Clear();
inst.VehicleRespawn.Clear();
inst.VehicleExplode.Clear();
inst.VehicleHealth.Clear();
inst.VehicleMove.Clear();
inst.VehicleEmbarking.Clear();
inst.VehicleEmbarked.Clear();
inst.VehicleDisembark.Clear();
}
// --------------------------------------------------------------------------------------------
static SQInt32 Create(SQInt32 model, SQInt32 world, SQFloat x, SQFloat y, SQFloat z,
SQFloat angle, SQInt32 primary, SQInt32 secondary) noexcept
{
return _Func->CreateVehicle(model, world, x, y, z, angle, primary, secondary);
}
// --------------------------------------------------------------------------------------------
static void Destroy(SQInt32 id) noexcept
{
_Func->DeleteVehicle(id);
}
2015-09-30 02:56:11 +02:00
public:
// --------------------------------------------------------------------------------------------
static constexpr const SQChar* Name = "Vehicle";
static constexpr const SQChar* CName = "CVehicle";
// --------------------------------------------------------------------------------------------
static constexpr SQInt32 TypeID = ENT_VEHICLE;
static constexpr SQInt32 Limit = SQMOD_VEHICLE_POOL;
// --------------------------------------------------------------------------------------------
static constexpr SQInt32 CreateEvID = EVT_VEHICLECREATED;
static constexpr SQInt32 DestroyEvID = EVT_VEHICLEDESTROYED;
static constexpr SQInt32 CustomEvID = EVT_VEHICLECUSTOM;
2015-09-30 02:56:11 +02:00
// --------------------------------------------------------------------------------------------
typedef std::array< Instance, Limit > Instances;
// --------------------------------------------------------------------------------------------
typedef std::bitset< Limit > Set;
// --------------------------------------------------------------------------------------------
static bool InEvent(SQInt32 type) noexcept
{
switch (type)
{
case EVT_VEHICLECREATED:
case EVT_VEHICLEDESTROYED:
case EVT_VEHICLECUSTOM:
case EVT_VEHICLERESPAWN:
case EVT_VEHICLEEXPLODE:
case EVT_VEHICLEHEALTH:
case EVT_VEHICLEMOVE:
case EVT_VEHICLEEMBARKING:
case EVT_VEHICLEEMBARKED:
case EVT_VEHICLEDISEMBARK:
return true;
default:
return false;
}
}
// --------------------------------------------------------------------------------------------
static bool InEvent(SQInt32 type, bool inversed) noexcept
{
switch (type)
{
case EVT_VEHICLECREATED:
case EVT_VEHICLEDESTROYED:
case EVT_VEHICLECUSTOM:
case EVT_VEHICLERESPAWN:
case EVT_VEHICLEEXPLODE:
case EVT_VEHICLEHEALTH:
case EVT_VEHICLEMOVE:
return true;
case EVT_VEHICLEEMBARKING:
case EVT_VEHICLEEMBARKED:
case EVT_VEHICLEDISEMBARK:
return !inversed;
default:
return false;
}
}
2015-09-30 02:56:11 +02:00
};
/* ------------------------------------------------------------------------------------------------
* ...
*/
template < class T > class Reference
{
// --------------------------------------------------------------------------------------------
friend class EntMan< T >;
public:
// --------------------------------------------------------------------------------------------
typedef T Type;
// --------------------------------------------------------------------------------------------
typedef Reference< T > RefType;
// --------------------------------------------------------------------------------------------
static constexpr SQInt32 Max = Ent< T >::Limit;
// --------------------------------------------------------------------------------------------
static constexpr SQInt32 TypeID = Ent< T >::TypeID;
2015-09-30 02:56:11 +02:00
protected:
// --------------------------------------------------------------------------------------------
static typename Ent< T >::Instances s_Instances;
protected:
// --------------------------------------------------------------------------------------------
SQInt32 m_ID;
// --------------------------------------------------------------------------------------------
SqTag m_Tag;
SqObj m_Data;
// --------------------------------------------------------------------------------------------
Reference< T > * m_Prev;
Reference< T > * m_Next;
// --------------------------------------------------------------------------------------------
bool m_Persistent;
protected:
/* --------------------------------------------------------------------------------------------
* ...
*/
void InsertIntoChain() noexcept
{
if (VALID_ENTITY(m_ID))
{
if (s_Instances[m_ID].Root)
{
m_Next = s_Instances[m_ID].Root;
m_Prev = m_Next->m_Prev;
m_Next->m_Prev = this;
}
s_Instances[m_ID].Root = this;
}
}
/* --------------------------------------------------------------------------------------------
* ...
*/
void RemoveFromChain() noexcept
{
if (VALID_ENTITY(m_ID))
{
if (m_Next)
{
m_Next->m_Prev = m_Prev;
}
if (m_Prev)
{
m_Prev->m_Next = m_Next;
}
if (s_Instances[m_ID].Root == this)
{
s_Instances[m_ID].Root = (m_Next ? m_Next : (m_Prev ? m_Prev : 0));
}
m_Next = 0;
m_Prev = 0;
}
}
public:
/* --------------------------------------------------------------------------------------------
* Verify that the specified entity instance is active
2015-09-30 02:56:11 +02:00
*/
static bool Verify(SQInt32 id) noexcept
{
return (VALID_ENTITYEX(id, Max) && VALID_ENTITY(s_Instances[id].ID));
}
/* --------------------------------------------------------------------------------------------
* Returns a reference to the specified entity instance
*/
static typename Ent< T >::Instance & Get(SQInt32 id) noexcept
{
return s_Instances[id]; /* Expects the callee to deal with range checks! */
}
2015-09-30 02:56:11 +02:00
public:
/* --------------------------------------------------------------------------------------------
* ...
*/
Reference() noexcept
: Reference(SQMOD_UNKNOWN)
{
}
/* --------------------------------------------------------------------------------------------
* ...
*/
Reference(SQInt32 id) noexcept
: m_ID(Verify(id) ? id : SQMOD_UNKNOWN)
, m_Tag()
, m_Data()
, m_Prev(0)
, m_Next(0)
, m_Persistent(false)
{
InsertIntoChain();
}
/* --------------------------------------------------------------------------------------------
* ...
*/
Reference(const Reference< T > & r) noexcept
: m_ID(r.m_ID)
, m_Tag(r.m_Tag)
, m_Data(r.m_Data)
, m_Prev(0)
, m_Next(0)
, m_Persistent(r.m_Persistent)
{
InsertIntoChain();
}
/* --------------------------------------------------------------------------------------------
* ...
*/
Reference(Reference< T > && r) noexcept
: m_ID(r.m_ID)
, m_Tag(r.m_Tag)
, m_Data(r.m_Data)
, m_Prev(0)
, m_Next(0)
, m_Persistent(r.m_Persistent)
{
InsertIntoChain();
}
/* --------------------------------------------------------------------------------------------
* ...
*/
~Reference()
{
RemoveFromChain();
}
/* --------------------------------------------------------------------------------------------
* ...
*/
Reference< T > & operator = (const Reference< T > & r) noexcept
{
if (this != &r)
{
RemoveFromChain();
m_ID = r.m_ID;
m_Tag = r.m_Tag;
m_Data = r.m_Data;
m_Persistent = r.m_Persistent;
InsertIntoChain();
}
return *this;
}
/* --------------------------------------------------------------------------------------------
* ...
*/
Reference< T > & operator = (Reference< T > &&) = delete;
/* --------------------------------------------------------------------------------------------
* ...
*/
operator SQInt32 () const noexcept
{
return m_ID;
}
/* --------------------------------------------------------------------------------------------
* ...
*/
operator SQUint32 () const noexcept
{
return static_cast< SQUint32 >(m_ID);
}
/* --------------------------------------------------------------------------------------------
* ...
*/
operator bool () const noexcept
{
return VALID_ENTITY(m_ID);
2015-09-30 02:56:11 +02:00
}
/* --------------------------------------------------------------------------------------------
* ...
*/
bool operator ! () const noexcept
{
return INVALID_ENTITY(m_ID);
2015-09-30 02:56:11 +02:00
}
/* --------------------------------------------------------------------------------------------
* ...
*/
SQInteger Cmp(const Reference< T > & r) const noexcept
{
return m_ID == r.m_ID ? 0 : (m_ID > r.m_ID ? 1 : -1);
}
/* --------------------------------------------------------------------------------------------
* ...
*/
const SQChar * ToString() const noexcept
{
return ToStringF("%d", m_ID);
}
/* --------------------------------------------------------------------------------------------
* ...
*/
SQInteger GetID() const noexcept
{
return m_ID;
}
/* --------------------------------------------------------------------------------------------
* ...
*/
void SetID(SQInt32 id) noexcept
{
if (id != m_ID)
{
RemoveFromChain();
m_ID = id;
InsertIntoChain();
}
}
/* --------------------------------------------------------------------------------------------
* ...
*/
bool GetPersistent() const noexcept
{
return m_Persistent;
}
/* --------------------------------------------------------------------------------------------
* ...
*/
void SetPersistent(bool toggle) noexcept
{
m_Persistent = toggle;
}
/* --------------------------------------------------------------------------------------------
* ...
*/
const SQChar * GetGlobalTag() const noexcept
{
if (VALID_ENTITY(m_ID))
2015-09-30 02:56:11 +02:00
{
return s_Instances[m_ID].Tag.c_str();
}
else
{
LogWrn(_SC("Attempting to <get global tag> using an invalid reference: %d"), m_ID);
}
return _SC("");
}
/* --------------------------------------------------------------------------------------------
* ...
*/
void SetGlobalTag(const SQChar * tag) const noexcept
{
if (VALID_ENTITY(m_ID))
2015-09-30 02:56:11 +02:00
{
s_Instances[m_ID].Tag.assign(tag);
}
else
{
LogWrn(_SC("Attempting to <set global tag> using an invalid reference: %d"), m_ID);
}
}
/* --------------------------------------------------------------------------------------------
* ...
*/
SqObj & GetGlobalData() noexcept
{
if (VALID_ENTITY(m_ID))
2015-09-30 02:56:11 +02:00
{
return s_Instances[m_ID].Data;
}
else
{
LogWrn(_SC("Attempting to <get global data> using an invalid reference: %d"), m_ID);
}
return NullData();
}
/* --------------------------------------------------------------------------------------------
* ...
*/
void SetGlobalData(SqObj & data) const noexcept
{
if (VALID_ENTITY(m_ID))
2015-09-30 02:56:11 +02:00
{
s_Instances[m_ID].Data = data;
}
else
{
LogWrn(_SC("Attempting to <set global tag> using an invalid reference: %d"), m_ID);
}
}
/* --------------------------------------------------------------------------------------------
* ...
*/
const SQChar * GetLocalTag() const noexcept
{
return m_Tag.c_str();
}
/* --------------------------------------------------------------------------------------------
* ...
*/
void SetLocalTag(const SQChar * tag) noexcept
{
m_Tag.assign(tag);
}
/* --------------------------------------------------------------------------------------------
* ...
*/
SqObj & GetLocalData() noexcept
{
return m_Data;
}
/* --------------------------------------------------------------------------------------------
* ...
*/
void SetLocalData(SqObj & data) noexcept
{
m_Data = data;
}
/* --------------------------------------------------------------------------------------------
* ...
*/
SQUint32 GetMax() const noexcept
{
return Max;
}
/* --------------------------------------------------------------------------------------------
* Return a new reference from the base reference.
2015-09-30 02:56:11 +02:00
*/
T GetReference() const noexcept
{
return T(m_ID);
}
/* --------------------------------------------------------------------------------------------
* Returns whether this entity reference points to an active entity.
2015-09-30 02:56:11 +02:00
*/
bool IsActive() const noexcept
{
return VALID_ENTITYEX(m_ID, Max);
}
/* --------------------------------------------------------------------------------------------
* Counts the number of active references for this entity.
2015-09-30 02:56:11 +02:00
*/
SQUint32 CountRefs() const noexcept
{
SQUint32 refs = 0;
// Make sure the reference is valid
if (VALID_ENTITYEX(m_ID, Max))
{
// Count this instance
++refs;
// Count backward references
for (RefType * ref = m_Prev; ref; ref = ref->m_Prev)
{
++refs;
}
// Count forward references
for (RefType * ref = m_Next; ref; ref = ref->m_Next)
{
++refs;
}
}
return refs;
}
/* --------------------------------------------------------------------------------------------
* Counts the number of persistent references for this entity.
2015-10-02 00:34:28 +02:00
*/
SQUint32 CountPersistentRefs() const noexcept
2015-09-30 02:56:11 +02:00
{
SQUint32 refs = 0;
// Make sure the reference is valid
if (VALID_ENTITYEX(m_ID, Max))
{
// Count this instance if persistent
if (m_Persistent)
{
++refs;
}
2015-09-30 02:56:11 +02:00
// Count backward references
for (RefType * ref = m_Prev; ref; ref = ref->m_Prev)
{
if (ref->m_Persistent)
{
++refs;
}
}
// Count forward references
for (RefType * ref = m_Next; ref; ref = ref->m_Next)
{
if (ref->m_Persistent)
{
++refs;
}
}
}
return refs;
}
/* --------------------------------------------------------------------------------------------
* Destroy the referenced entity.
*/
bool Destroy() noexcept
{
return Destroy(0, NullData());
}
/* --------------------------------------------------------------------------------------------
* Destroy the referenced entity.
*/
bool Destroy(SQInt32 header) noexcept
{
return Destroy(header, NullData());
}
/* --------------------------------------------------------------------------------------------
* Destroy the referenced entity.
*/
bool Destroy(SQInt32 header, SqObj & payload) noexcept
{
if (VALID_ENTITY(m_ID))
{
return EntMan< T >::Deactivate(m_ID, header, payload, true);
}
else
{
LogWrn(_SC("Attempting to <destroy %d entity> using an invalid reference: %d"), Ent< T >::Name, m_ID);
}
return false;
}
2015-09-30 02:56:11 +02:00
};
// ------------------------------------------------------------------------------------------------
template < class T > typename Ent< T >::Instances Reference< T >::s_Instances;
/* ------------------------------------------------------------------------------------------------
* Utility meant to reduce the code duplication for entity management required by the Core class
*/
template < class T > class EntMan
{
// --------------------------------------------------------------------------------------------
friend class Reference< T >;
2015-09-30 02:56:11 +02:00
friend class Core;
public:
// --------------------------------------------------------------------------------------------
typedef Reference< T > RefType;
typedef Ent< T > EntType;
private:
// --------------------------------------------------------------------------------------------
static RefType NullRef;
/* --------------------------------------------------------------------------------------------
* Deactivates the specified entity instance.
2015-09-30 02:56:11 +02:00
*/
static bool Deactivate(SQInt32 id, SQInt32 header, SqObj & payload, bool notify) noexcept
2015-09-30 02:56:11 +02:00
{
// Make sure this entity even exists
if (RefType::Verify(id))
{
// Trigger this associated events if required
if (notify)
{
RefType::s_Instances[id].Destroyed().Emit(id, header, payload);
RefType::s_Instances[id].GDestroyed().Emit(id, header, payload);
}
RefType * ref = 0, * bkp = 0;
2015-10-02 00:34:28 +02:00
// Get the pointer to the first backward reference
2015-09-30 02:56:11 +02:00
ref = RefType::s_Instances[id].Root->m_Prev;
// Deactivate backward references
while (ref)
{
if (ref->m_Persistent)
{
// Just disable the entity if persistent
ref->m_ID = SQMOD_UNKNOWN;
// Move to the previous reference
ref = ref->m_Prev;
}
else
{
// Backup the current reference
bkp = ref;
// Move to the previous reference before unchaining
ref = ref->m_Prev;
// Now it's safe to unchain the reference
bkp->RemoveFromChain();
}
}
2015-10-02 00:34:28 +02:00
// Get the pointer to the first forward reference
2015-09-30 02:56:11 +02:00
ref = RefType::s_Instances[id].Root->m_Next;
// Deactivate forward references
while (ref)
{
if (ref->m_Persistent)
{
// Just disable the entity if persistent
ref->m_ID = SQMOD_UNKNOWN;
// Move to the next reference
ref = ref->m_Next;
}
else
{
// Backup the current reference
bkp = ref;
// Move to the next reference before unchaining
ref = ref->m_Next;
// Now it's safe to unchain the reference
bkp->RemoveFromChain();
}
}
// Disable this entity instance
EntType::Destroy(id);
2015-09-30 02:56:11 +02:00
// Disable this entity instance
RefType::s_Instances[id].ID = SQMOD_UNKNOWN;
// Clear any events that are still listening
EntType::Clear(RefType::s_Instances[id]);
// Successfully deactivated the instance
2015-09-30 02:56:11 +02:00
return true;
}
else
{
LogErr("Cannot deactivate an already deactivated <%s> instance with identifier (%d)", EntType::Name, id);
}
// Failed to destroy the entity
return false;
}
/* --------------------------------------------------------------------------------------------
* Activates the specified entity instance.
2015-09-30 02:56:11 +02:00
*/
template < typename... Args > static bool Activate(SQInt32 id, bool owned, Args&&... args) noexcept
{
// Validate the specified entity identifier
if (INVALID_ENTITYEX(id, EntType::Limit))
{
LogErr("Cannot initialize <%s> instance (%d) with invalid identifier", EntType::Name, id);
}
// Make sure this entity instance isn't already activated
else if (!RefType::Verify(id))
{
// See if there's any persistent references to activate
if (RefType::s_Instances[id].Root)
{
2015-10-02 00:34:28 +02:00
// @TODO Remove the reference from the chain, if somehow
// is present there without being persistent
// Resurrect backward references
2015-09-30 02:56:11 +02:00
for (RefType * ref = RefType::s_Instances[id].Root->m_Prev; ref; ref = ref->m_Prev)
{
if (ref->m_Persistent)
{
ref->m_ID = id;
}
}
// Resurrect forward references
2015-09-30 02:56:11 +02:00
for (RefType * ref = RefType::s_Instances[id].Root->m_Next; ref; ref = ref->m_Next)
{
if (ref->m_Persistent)
{
ref->m_ID = id;
}
}
}
// Enable this entity instance
RefType::s_Instances[id].ID = id;
// Set the instance ownership
RefType::s_Instances[id].Owned = owned;
// See if the user data needs purging
if (RefType::s_Instances[id].Fresh)
{
RefType::s_Instances[id].Tag.clear();
RefType::s_Instances[id].Data.Release();
}
// Store any specified values on the instance
EntType::Store(RefType::s_Instances[id], std::forward< Args >(args)...);
// Initialization successful
return true;
}
else
{
LogErr("Cannot activate an already activated <%s> instance with identifier (%d)", EntType::Name, id);
}
// Failed to activate the entity
return false;
}
/* --------------------------------------------------------------------------------------------
* Creates a new entity instance of the specified type.
*/
template < typename... Args > static SQInt32 Create(SQInt32 header, SqObj & payload, bool notify, Args&&... args) noexcept
{
// Attempt to create an instance on the server and obtain it's identifier
SQInt32 id = EntType::Create(std::forward< Args >(args)...);
// Attempt to activate the instance in the plugin at the received identifier
if (!Activate(id, true, std::forward< Args >(args)...))
{
LogErr("Unable to <create a new %s> instance", EntType::Name);
// Destroy this entity instance
EntType::Destroy(id);
// Replace the id with an invalid one
id = SQMOD_UNKNOWN;
}
// Trigger this associated events if required
else if (notify)
{
RefType::s_Instances[id].Created().Emit(id, header, payload);
RefType::s_Instances[id].GCreated().Emit(id, header, payload);
}
// Return the obtained entity identifier
return id;
}
2015-09-30 02:56:11 +02:00
};
// ------------------------------------------------------------------------------------------------
template < class T > typename EntMan< T >::RefType EntMan< T >::NullRef;
// ------------------------------------------------------------------------------------------------
template < class T > bool Register_Reference(HSQUIRRELVM vm, const SQChar * cname)
{
// Typedef the reference type to simplify code
typedef Reference< T > Ref;
// Output debugging information
LogDbg("Beginning registration of <%s> type", cname);
// Attempt to register the specified type
Sqrat::RootTable(vm).Bind(cname, Sqrat::Class< Ref >(vm, cname)
/* Constructors */
2015-09-30 02:56:11 +02:00
.Ctor()
.template Ctor< SQInt32 >()
/* Metamethods */
2015-09-30 02:56:11 +02:00
.Func(_SC("_cmp"), &Ref::Cmp)
.Func(_SC("_tostring"), &Ref::ToString)
/* Functions */
2015-09-30 02:56:11 +02:00
.Prop(_SC("id"), &Ref::GetID, &Ref::SetID)
.Prop(_SC("persistent"), &Ref::GetPersistent, &Ref::SetPersistent)
.Prop(_SC("gtag"), &Ref::GetGlobalTag, &Ref::SetGlobalTag)
.Prop(_SC("gdata"), &Ref::GetGlobalData, &Ref::SetGlobalData)
.Prop(_SC("ltag"), &Ref::GetLocalTag, &Ref::SetLocalTag)
.Prop(_SC("ldata"), &Ref::GetLocalData, &Ref::SetLocalData)
.Prop(_SC("max"), &Ref::GetMax)
.Prop(_SC("sref"), &Ref::GetReference)
.Prop(_SC("active"), &Ref::IsActive)
.Prop(_SC("refs"), &Ref::CountRefs)
.Prop(_SC("prefs"), &Ref::CountPersistentRefs)
/* Overloads */
.template Overload< bool (Ref::*)(void) >(_SC("destroy"), &Ref::Destroy)
.template Overload< bool (Ref::*)(SQInt32) >(_SC("destroy"), &Ref::Destroy)
.template Overload< bool (Ref::*)(SQInt32, SqObj &) >(_SC("destroy"), &Ref::Destroy)
2015-09-30 02:56:11 +02:00
);
// Output debugging information
LogDbg("Registration of <%s> type was successful", cname);
// Registration succeeded
return true;
}
} // Namespace:: SqMod
#endif // _ENTITY_HPP_