diff --git a/module/Core.hpp b/module/Core.hpp index 3fb1ea3e..31dc3950 100644 --- a/module/Core.hpp +++ b/module/Core.hpp @@ -1049,4 +1049,37 @@ template < class F > SQMOD_NODISCARD inline int32_t ForeachConnectedPlayerUntil( return -1; } +/* ------------------------------------------------------------------------------------------------ + * Used to select entity instances based on type. +*/ +template < class > struct EntityInstSelect; +// Specialization for blips. +template < > struct EntityInstSelect< CBlip > { + static BlipInst & Get(int32_t id) { return Core::Get().GetBlip(id); } +}; +// Specialization for checkpoints. +template < > struct EntityInstSelect< CCheckpoint > { + static CheckpointInst & Get(int32_t id) { return Core::Get().GetCheckpoint(id); } +}; +// Specialization for keybinds. +template < > struct EntityInstSelect< CKeyBind > { + static KeyBindInst & Get(int32_t id) { return Core::Get().GetKeyBind(id); } +}; +// Specialization for objects. +template < > struct EntityInstSelect< CObject > { + static ObjectInst & Get(int32_t id) { return Core::Get().GetObj(id); } +}; +// Specialization for pickups. +template < > struct EntityInstSelect< CPickup > { + static PickupInst & Get(int32_t id) { return Core::Get().GetPickup(id); } +}; +// Specialization for players. +template < > struct EntityInstSelect< CPlayer > { + static PlayerInst & Get(int32_t id) { return Core::Get().GetPlayer(id); } +}; +// Specialization for vehicles. +template < > struct EntityInstSelect< CVehicle > { + static VehicleInst & Get(int32_t id) { return Core::Get().GetVehicle(id); } +}; + } // Namespace:: SqMod diff --git a/module/Misc/Official.cpp b/module/Misc/Official.cpp index 3e924880..aecd4e48 100644 --- a/module/Misc/Official.cpp +++ b/module/Misc/Official.cpp @@ -52,6 +52,46 @@ SQMOD_DECL_TYPENAME(CPickupTn, _SC("CPickup")) SQMOD_DECL_TYPENAME(CPlayerTn, _SC("CPlayer")) SQMOD_DECL_TYPENAME(CVehicleTn, _SC("CVehicle")) +/* ------------------------------------------------------------------------------------------------ + * Used to fetch the legacy entity instance even if a native one was specified. +*/ +template < class T, class U > inline T & GetLgEnt(LightObj & o) +{ + auto type = static_cast< AbstractStaticClassData * >(o.GetTypeTag()); + // Legacy entity type? + if (type == StaticClassTypeTag< T >::Get()) + { + return *o.CastI< T >(); + } + // Native entity type? + if (type == StaticClassTypeTag< U >::Get()) + { + return *EntityInstSelect< U >(o.CastI< U >()->GetID()).mLgInst; + } + STHROWF("Invalid entity type"); + SQ_UNREACHABLE +} + +/* ------------------------------------------------------------------------------------------------ + * Used to fetch the legacy entity identifier even if a native one was specified. +*/ +template < class T, class U > SQMOD_NODISCARD inline int32_t GetLgEntID(LightObj & o) +{ + auto type = static_cast< AbstractStaticClassData * >(o.GetTypeTag()); + // Legacy entity type? + if (type == StaticClassTypeTag< T >::Get()) + { + return o.CastI< T >()->mID; + } + // Native entity type? + if (type == StaticClassTypeTag< U >::Get()) + { + return o.CastI< U >()->GetID(); + } + STHROWF("Invalid entity type"); + SQ_UNREACHABLE +} + /* ------------------------------------------------------------------------------------------------ * Entity type enumeration. */ @@ -1249,10 +1289,10 @@ static void LgClientMessageToAllWithAlpha(StackStrF & msg, int r, int g, int b, static_cast< uint8_t >(b), static_cast< uint8_t >(a)).GetRGBA(); ForeachActivePlayer([&](auto & p) { _Func->SendClientMessage(p.mID, c, "%s", msg.mPtr); }); } -static void LgGameMessage(StackStrF & msg, LgPlayer & player, int type) -{ _Func->SendGameMessage(player.GetIdentifier(), type, msg.mPtr); } -static void LgGameMessageAlternate(StackStrF & msg, LgPlayer & player) -{ { _Func->SendGameMessage(player.GetIdentifier(), 1, msg.mPtr); } } +static void LgGameMessage(StackStrF & msg, LightObj & player, int type) +{ _Func->SendGameMessage(GetLgEntID< LgPlayer, CPlayer >(player), type, msg.mPtr); } +static void LgGameMessageAlternate(StackStrF & msg, LightObj & player) +{ { _Func->SendGameMessage(GetLgEntID< LgPlayer, CPlayer >(player), 1, msg.mPtr); } } static void LgGameMessageToAll(StackStrF & msg, int type) { _Func->SendGameMessage(-1, type, msg.mPtr); } static void LgGameMessageToAllAlternate(StackStrF & msg)