diff --git a/CMakeLists.txt b/CMakeLists.txt index 4fefe5f3..917dc243 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,6 +7,7 @@ set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/vendor/POCO/cmake) # Several plugin options option(ENABLE_API21 "Build for 2.1 API." OFF) +option(ENABLE_OFFICIAL "Enable compatibility with official legacy plug-in" ON) option(FORCE_32BIT_BIN "Create a 32-bit executable binary if the compiler defaults to 64-bit." OFF) # This option should only be available in certain conditions if(WIN32 AND MINGW) diff --git a/module/CMakeLists.txt b/module/CMakeLists.txt index 5c6a12be..afa2c527 100644 --- a/module/CMakeLists.txt +++ b/module/CMakeLists.txt @@ -109,8 +109,17 @@ add_library(SqModule MODULE SqBase.hpp Main.cpp Logger.cpp Logger.hpp Register.cpp ) -# Various definitions required by the plugin +# Various definitions required by the plug-in target_compile_definitions(SqModule PRIVATE SCRAT_USE_EXCEPTIONS=1) +# SDK targeting +if(ENABLE_API21) + target_compile_definitions(SqModule PRIVATE VCMP_SDK_2_1=1) +endif() +# Legacy compatibility with official plug-in +if(ENABLE_OFFICIAL) + target_compile_definitions(SqModule PRIVATE VCMP_ENABLE_OFFICIAL=1) + target_sources(SqModule PRIVATE Misc/Official.cpp Misc/Official.hpp) +endif() # Link to windows libraries if on windows if(WIN32 OR MINGW) target_compile_definitions(SqModule PRIVATE _WIN32_WINNT=0x0601) @@ -124,7 +133,7 @@ target_link_libraries(SqModule Poco::Foundation Poco::Crypto Poco::Data Poco::Ne if(ENABLE_DATA_SQLITE) # Link the libraries target_link_libraries(SqModule Poco::DataSQLite) - # Inform the plugin that it can make use of this library + # Inform the plug-in that it can make use of this library target_compile_definitions(SqModule PRIVATE SQMOD_POCO_HAS_SQLITE=1) endif() # Does POCO have MySLQ support? @@ -132,7 +141,7 @@ find_package(MySQL) if(MYSQL_FOUND) # Link the libraries target_link_libraries(SqModule Poco::DataMySQL) - # Inform the plugin that it can make use of this library + # Inform the plug-in that it can make use of this library target_compile_definitions(SqModule PRIVATE SQMOD_POCO_HAS_MYSQL=1) endif() # Does POCO have PostgreSQL support? @@ -140,7 +149,7 @@ find_package(PostgreSQL) if(POSTGRESQL_FOUND) # Link the libraries target_link_libraries(SqModule Poco::DataPostgreSQL) - # Inform the plugin that it can make use of this library + # Inform the plug-in that it can make use of this library target_compile_definitions(SqModule PRIVATE SQMOD_POCO_HAS_POSTGRESQL=1) endif() # Determine if build mode diff --git a/module/Core.cpp b/module/Core.cpp index 3e564c91..fcad652b 100644 --- a/module/Core.cpp +++ b/module/Core.cpp @@ -53,6 +53,20 @@ extern void TerminatePocoData(); // ------------------------------------------------------------------------------------------------ extern Buffer GetRealFilePath(const SQChar * path); +// ------------------------------------------------------------------------------------------------ +#ifdef VCMP_ENABLE_OFFICIAL + extern void LgCheckpointSetID(LgCheckpoint * inst, int32_t id); + extern void LgObjectSetID(LgObject * inst, int32_t id); + extern void LgPickupSetID(LgPickup * inst, int32_t id); + extern void LgPlayerSetID(LgPlayer * inst, int32_t id); + extern void LgVehicleSetID(LgVehicle * inst, int32_t id); + extern LightObj LgCheckpointObj(HSQUIRRELVM vm, int32_t id); + extern LightObj LgObjectObj(HSQUIRRELVM vm, int32_t id); + extern LightObj LgPickupObj(HSQUIRRELVM vm, int32_t id); + extern LightObj LgPlayerObj(HSQUIRRELVM vm, int32_t id); + extern LightObj LgVehicleObj(HSQUIRRELVM vm, int32_t id); +#endif + /* ------------------------------------------------------------------------------------------------ * Loader used to process a section from the configuration file and look for scripts to load. */ @@ -137,6 +151,9 @@ Core Core::s_Inst; // ------------------------------------------------------------------------------------------------ Core::Core() noexcept : m_State(0) +#ifdef VCMP_ENABLE_OFFICIAL + , m_Official(false) +#endif , m_VM(nullptr) , m_Scripts() , m_PendingScripts() @@ -219,6 +236,10 @@ bool Core::Initialize() return false; } +#ifdef VCMP_ENABLE_OFFICIAL + // See if debugging options should be enabled + m_Official = conf.GetBoolValue("Squirrel", "OfficialCompatibility", m_Official); +#endif // See if debugging options should be enabled m_Debugging = conf.GetBoolValue("Squirrel", "Debugging", m_Debugging); // Configure the empty initialization @@ -1109,6 +1130,16 @@ BlipInst & Core::AllocBlip(int32_t id, bool owned, int32_t header, LightObj & pa if (!inst.mInst || inst.mObj.IsNull()) { inst.ResetInstance(); + // Make sure that if an instance was created, it points to nothing + if (inst.mInst) + { + inst.mInst->m_ID = -1; + } + // Make sure that if an object was created, it is released + if (!inst.mObj.IsNull()) + { + inst.mObj.Release(); + } // Now we can throw the error STHROWF("Unable to create a blip instance for: {}", id); } @@ -1146,6 +1177,33 @@ CheckpointInst & Core::AllocCheckpoint(int32_t id, bool owned, int32_t header, L { return inst; // Return the existing instance } +#ifdef VCMP_ENABLE_OFFICIAL + // Do we need to support legacy API? + if (IsOfficial()) + { + // Create the legacy wrapper object + inst.mLgObj = LgCheckpointObj(m_VM, id); + // Obtain the legacy wrapper instance + inst.mLgInst = inst.mLgObj.CastI< LgCheckpoint >(); + // Make sure that both the instance and script object could be created + if (!inst.mLgInst || inst.mLgObj.IsNull()) + { + inst.ResetInstance(); + // Make sure that if an instance was created, it points to nothing + if (inst.mLgInst) + { + LgCheckpointSetID(inst.mLgInst, -1); + } + // Make sure that if an object was created, it is released + if (!inst.mLgObj.IsNull()) + { + inst.mLgObj.Release(); + } + // Now we can throw the error + STHROWF("Unable to create a checkpoint wrapper instance for: {}", id); + } + } +#endif // Instantiate the entity manager DeleteGuard< CCheckpoint > dg(new CCheckpoint(id)); // Create the script object @@ -1158,6 +1216,25 @@ CheckpointInst & Core::AllocCheckpoint(int32_t id, bool owned, int32_t header, L if (!inst.mInst || inst.mObj.IsNull()) { inst.ResetInstance(); +#ifdef VCMP_ENABLE_OFFICIAL + // Discard legacy wrapper instance + if (IsOfficial()) + { + LgCheckpointSetID(inst.mLgInst, -1); + inst.mLgObj.Release(); + inst.mLgInst = nullptr; + } +#endif + // Make sure that if an instance was created, it points to nothing + if (inst.mInst) + { + inst.mInst->m_ID = -1; + } + // Make sure that if an object was created, it is released + if (!inst.mObj.IsNull()) + { + inst.mObj.Release(); + } // Now we can throw the error STHROWF("Unable to create a checkpoint instance for: {}", id); } @@ -1207,6 +1284,16 @@ KeyBindInst & Core::AllocKeyBind(int32_t id, bool owned, int32_t header, LightOb if (!inst.mInst || inst.mObj.IsNull()) { inst.ResetInstance(); + // Make sure that if an instance was created, it points to nothing + if (inst.mInst) + { + inst.mInst->m_ID = -1; + } + // Make sure that if an object was created, it is released + if (!inst.mObj.IsNull()) + { + inst.mObj.Release(); + } // Now we can throw the error STHROWF("Unable to create a keybind instance for: {}", id); } @@ -1244,6 +1331,33 @@ ObjectInst & Core::AllocObject(int32_t id, bool owned, int32_t header, LightObj { return inst; // Return the existing instance } +#ifdef VCMP_ENABLE_OFFICIAL + // Do we need to support legacy API? + if (IsOfficial()) + { + // Create the legacy wrapper object + inst.mLgObj = LgObjectObj(m_VM, id); + // Obtain the legacy wrapper instance + inst.mLgInst = inst.mLgObj.CastI< LgObject >(); + // Make sure that both the instance and script object could be created + if (!inst.mLgInst || inst.mLgObj.IsNull()) + { + inst.ResetInstance(); + // Make sure that if an instance was created, it points to nothing + if (inst.mLgInst) + { + LgObjectSetID(inst.mLgInst, -1); + } + // Make sure that if an object was created, it is released + if (!inst.mLgObj.IsNull()) + { + inst.mLgObj.Release(); + } + // Now we can throw the error + STHROWF("Unable to create a object wrapper instance for: {}", id); + } + } +#endif // Instantiate the entity manager DeleteGuard< CObject > dg(new CObject(id)); // Create the script object @@ -1256,6 +1370,25 @@ ObjectInst & Core::AllocObject(int32_t id, bool owned, int32_t header, LightObj if (!inst.mInst || inst.mObj.IsNull()) { inst.ResetInstance(); +#ifdef VCMP_ENABLE_OFFICIAL + // Discard legacy wrapper instance + if (IsOfficial()) + { + LgObjectSetID(inst.mLgInst, -1); + inst.mLgObj.Release(); + inst.mLgInst = nullptr; + } +#endif + // Make sure that if an instance was created, it points to nothing + if (inst.mInst) + { + inst.mInst->m_ID = -1; + } + // Make sure that if an object was created, it is released + if (!inst.mObj.IsNull()) + { + inst.mObj.Release(); + } // Now we can throw the error STHROWF("Unable to create a object instance for: {}", id); } @@ -1293,6 +1426,33 @@ PickupInst & Core::AllocPickup(int32_t id, bool owned, int32_t header, LightObj { return inst; // Return the existing instance } +#ifdef VCMP_ENABLE_OFFICIAL + // Do we need to support legacy API? + if (IsOfficial()) + { + // Create the legacy wrapper object + inst.mLgObj = LgPickupObj(m_VM, id); + // Obtain the legacy wrapper instance + inst.mLgInst = inst.mLgObj.CastI< LgPickup >(); + // Make sure that both the instance and script object could be created + if (!inst.mLgInst || inst.mLgObj.IsNull()) + { + inst.ResetInstance(); + // Make sure that if an instance was created, it points to nothing + if (inst.mLgInst) + { + LgPickupSetID(inst.mLgInst, -1); + } + // Make sure that if an object was created, it is released + if (!inst.mLgObj.IsNull()) + { + inst.mLgObj.Release(); + } + // Now we can throw the error + STHROWF("Unable to create a pickup wrapper instance for: {}", id); + } + } +#endif // Instantiate the entity manager DeleteGuard< CPickup > dg(new CPickup(id)); // Create the script object @@ -1305,6 +1465,25 @@ PickupInst & Core::AllocPickup(int32_t id, bool owned, int32_t header, LightObj if (!inst.mInst || inst.mObj.IsNull()) { inst.ResetInstance(); +#ifdef VCMP_ENABLE_OFFICIAL + // Discard legacy wrapper instance + if (IsOfficial()) + { + LgPickupSetID(inst.mLgInst, -1); + inst.mLgObj.Release(); + inst.mLgInst = nullptr; + } +#endif + // Make sure that if an instance was created, it points to nothing + if (inst.mInst) + { + inst.mInst->m_ID = -1; + } + // Make sure that if an object was created, it is released + if (!inst.mObj.IsNull()) + { + inst.mObj.Release(); + } // Now we can throw the error STHROWF("Unable to create a pickup instance for: {}", id); } @@ -1342,6 +1521,33 @@ VehicleInst & Core::AllocVehicle(int32_t id, bool owned, int32_t header, LightOb { return inst; // Return the existing instance } +#ifdef VCMP_ENABLE_OFFICIAL + // Do we need to support legacy API? + if (IsOfficial()) + { + // Create the legacy wrapper object + inst.mLgObj = LgVehicleObj(m_VM, id); + // Obtain the legacy wrapper instance + inst.mLgInst = inst.mLgObj.CastI< LgVehicle >(); + // Make sure that both the instance and script object could be created + if (!inst.mLgInst || inst.mLgObj.IsNull()) + { + inst.ResetInstance(); + // Make sure that if an instance was created, it points to nothing + if (inst.mLgInst) + { + LgVehicleSetID(inst.mLgInst, -1); + } + // Make sure that if an object was created, it is released + if (!inst.mLgObj.IsNull()) + { + inst.mLgObj.Release(); + } + // Now we can throw the error + STHROWF("Unable to create a vehicle wrapper instance for: {}", id); + } + } +#endif // Instantiate the entity manager DeleteGuard< CVehicle > dg(new CVehicle(id)); // Create the script object @@ -1354,6 +1560,25 @@ VehicleInst & Core::AllocVehicle(int32_t id, bool owned, int32_t header, LightOb if (!inst.mInst || inst.mObj.IsNull()) { inst.ResetInstance(); +#ifdef VCMP_ENABLE_OFFICIAL + // Discard legacy wrapper instance + if (IsOfficial()) + { + LgVehicleSetID(inst.mLgInst, -1); + inst.mLgObj.Release(); + inst.mLgInst = nullptr; + } +#endif + // Make sure that if an instance was created, it points to nothing + if (inst.mInst) + { + inst.mInst->m_ID = -1; + } + // Make sure that if an object was created, it is released + if (!inst.mObj.IsNull()) + { + inst.mObj.Release(); + } // Now we can throw the error STHROWF("Unable to create a vehicle instance for: {}", id); } @@ -1732,6 +1957,33 @@ void Core::ConnectPlayer(int32_t id, int32_t header, LightObj & payload) { return; // Nothing to allocate! } +#ifdef VCMP_ENABLE_OFFICIAL + // Do we need to support legacy API? + if (IsOfficial()) + { + // Create the legacy wrapper object + inst.mLgObj = LgPlayerObj(m_VM, id); + // Obtain the legacy wrapper instance + inst.mLgInst = inst.mLgObj.CastI< LgPlayer >(); + // Make sure that both the instance and script object could be created + if (!inst.mLgInst || inst.mLgObj.IsNull()) + { + inst.ResetInstance(); + // Make sure that if an instance was created, it points to nothing + if (inst.mLgInst) + { + LgPlayerSetID(inst.mLgInst, -1); + } + // Make sure that if an object was created, it is released + if (!inst.mLgObj.IsNull()) + { + inst.mLgObj.Release(); + } + // Now we can throw the error + STHROWF("Unable to create a player wrapper instance for: {}", id); + } + } +#endif // Instantiate the entity manager DeleteGuard< CPlayer > dg(new CPlayer(id)); // Create the script object @@ -1744,6 +1996,26 @@ void Core::ConnectPlayer(int32_t id, int32_t header, LightObj & payload) if (!inst.mInst || inst.mObj.IsNull()) { inst.ResetInstance(); +#ifdef VCMP_ENABLE_OFFICIAL + // Discard legacy wrapper instance + if (IsOfficial()) + { + LgPlayerSetID(inst.mLgInst, -1); + inst.mLgObj.Release(); + inst.mLgInst = nullptr; + } +#endif + // Make sure that if an instance was created, it points to nothing + if (inst.mInst) + { + inst.mInst->m_ID = -1; + } + // Make sure that if an object was created, it is released + if (!inst.mObj.IsNull()) + { + inst.mObj.Release(); + } + // Now we can throw the error STHROWF("Unable to create a player instance for: {}", id); } // Assign the specified entity identifier diff --git a/module/Core.hpp b/module/Core.hpp index de35276e..cecba339 100644 --- a/module/Core.hpp +++ b/module/Core.hpp @@ -61,6 +61,9 @@ private: // -------------------------------------------------------------------------------------------- int32_t m_State; // Current plug-in state. +#ifdef VCMP_ENABLE_OFFICIAL + bool m_Official; // Whether official support is enabked. +#endif HSQUIRRELVM m_VM; // Script virtual machine. Scripts m_Scripts; // Loaded scripts objects. Scripts m_PendingScripts; // Pending scripts objects. @@ -181,6 +184,16 @@ public: return m_State; } +#ifdef VCMP_ENABLE_OFFICIAL + /* -------------------------------------------------------------------------------------------- + * See whether official support option was enabled in the plug-in. + */ + SQMOD_NODISCARD bool IsOfficial() const + { + return m_Official; + } +#endif + /* -------------------------------------------------------------------------------------------- * See whether debugging option was enabled in the plug-in. */ @@ -471,6 +484,7 @@ public: SQMOD_NODISCARD BlipInst & GetBlip(int32_t id) { return m_Blips.at(static_cast< size_t >(id)); } SQMOD_NODISCARD CheckpointInst & GetCheckpoint(int32_t id) { return m_Checkpoints.at(static_cast< size_t >(id)); } SQMOD_NODISCARD KeyBindInst & GetKeyBind(int32_t id) { return m_KeyBinds.at(static_cast< size_t >(id)); } + // Windows API is retarded. That's why this isn't named `GetObject` like the others SQMOD_NODISCARD ObjectInst & GetObj(int32_t id) { return m_Objects.at(static_cast< size_t >(id)); } SQMOD_NODISCARD PickupInst & GetPickup(int32_t id) { return m_Pickups.at(static_cast< size_t >(id)); } SQMOD_NODISCARD PlayerInst & GetPlayer(int32_t id) { return m_Players.at(static_cast< size_t >(id)); } @@ -556,7 +570,7 @@ public: void EmitPlayerRequestClass(int32_t player_id, int32_t offset); void EmitPlayerRequestSpawn(int32_t player_id); void EmitPlayerSpawn(int32_t player_id); - void EmitPlayerWasted(int32_t player_id, int32_t reason); + void EmitPlayerWasted(int32_t player_id, int32_t reason, vcmpBodyPart body_part); void EmitPlayerKilled(int32_t player_id, int32_t killer_id, int32_t reason, vcmpBodyPart body_part, bool team_kill); void EmitPlayerEmbarking(int32_t player_id, int32_t vehicle_id, int32_t slot_index); void EmitPlayerEmbarked(int32_t player_id, int32_t vehicle_id, int32_t slot_index); diff --git a/module/Core/Entity.cpp b/module/Core/Entity.cpp index 21b1bcf8..302c6b69 100644 --- a/module/Core/Entity.cpp +++ b/module/Core/Entity.cpp @@ -32,6 +32,15 @@ namespace SqMod { // ------------------------------------------------------------------------------------------------ extern void CleanupTasks(int32_t id, int32_t type); +// ------------------------------------------------------------------------------------------------ +#ifdef VCMP_ENABLE_OFFICIAL + extern void LgCheckpointSetID(LgCheckpoint * inst, int32_t id); + extern void LgObjectSetID(LgObject * inst, int32_t id); + extern void LgPickupSetID(LgPickup * inst, int32_t id); + extern void LgPlayerSetID(LgPlayer * inst, int32_t id); + extern void LgVehicleSetID(LgVehicle * inst, int32_t id); +#endif + // ------------------------------------------------------------------------------------------------ BlipInst::~BlipInst() { @@ -161,6 +170,18 @@ void CheckpointInst::Destroy(bool destroy, int32_t header, LightObj & payload) mInst = nullptr; // Release the script object, if any mObj.Release(); +#ifdef VCMP_ENABLE_OFFICIAL + // Is there a manager instance associated with this entity? + if (mLgInst) + { + // Prevent further use of this entity + LgCheckpointSetID(mLgInst, -1); + } + // Prevent further use of the manager instance + mLgInst = nullptr; + // Release the script object, if any + mLgObj.Release(); +#endif // Release tasks, if any CleanupTasks(mID, ENT_CHECKPOINT); // Are we supposed to clean up this entity? (only at reload) @@ -243,6 +264,18 @@ void ObjectInst::Destroy(bool destroy, int32_t header, LightObj & payload) mInst = nullptr; // Release the script object, if any mObj.Release(); +#ifdef VCMP_ENABLE_OFFICIAL + // Is there a manager instance associated with this entity? + if (mLgInst) + { + // Prevent further use of this entity + LgObjectSetID(mLgInst, -1); + } + // Prevent further use of the manager instance + mLgInst = nullptr; + // Release the script object, if any + mLgObj.Release(); +#endif // Release tasks, if any CleanupTasks(mID, ENT_OBJECT); // Are we supposed to clean up this entity? (only at reload) @@ -284,6 +317,18 @@ void PickupInst::Destroy(bool destroy, int32_t header, LightObj & payload) mInst = nullptr; // Release the script object, if any mObj.Release(); +#ifdef VCMP_ENABLE_OFFICIAL + // Is there a manager instance associated with this entity? + if (mLgInst) + { + // Prevent further use of this entity + LgPickupSetID(mLgInst, -1); + } + // Prevent further use of the manager instance + mLgInst = nullptr; + // Release the script object, if any + mLgObj.Release(); +#endif // Release tasks, if any CleanupTasks(mID, ENT_PICKUP); // Are we supposed to clean up this entity? (only at reload) @@ -327,6 +372,18 @@ void PlayerInst::Destroy(bool /*destroy*/, int32_t header, LightObj & payload) mInst = nullptr; // Release the script object, if any mObj.Release(); +#ifdef VCMP_ENABLE_OFFICIAL + // Is there a manager instance associated with this entity? + if (mLgInst) + { + // Prevent further use of this entity + LgPlayerSetID(mLgInst, -1); + } + // Prevent further use of the manager instance + mLgInst = nullptr; + // Release the script object, if any + mLgObj.Release(); +#endif // Release tasks, if any CleanupTasks(mID, ENT_PLAYER); // Reset the instance to it's initial state @@ -360,6 +417,18 @@ void VehicleInst::Destroy(bool destroy, int32_t header, LightObj & payload) mInst = nullptr; // Release the script object, if any mObj.Release(); +#ifdef VCMP_ENABLE_OFFICIAL + // Is there a manager instance associated with this entity? + if (mLgInst) + { + // Prevent further use of this entity + LgVehicleSetID(mLgInst, -1); + } + // Prevent further use of the manager instance + mLgInst = nullptr; + // Release the script object, if any + mLgObj.Release(); +#endif // Release tasks, if any CleanupTasks(mID, ENT_VEHICLE); // Are we supposed to clean up this entity? (only at reload) diff --git a/module/Core/Entity.hpp b/module/Core/Entity.hpp index 6eb6394b..7fa486e4 100644 --- a/module/Core/Entity.hpp +++ b/module/Core/Entity.hpp @@ -15,6 +15,15 @@ namespace SqMod { // -------------------------------------------------------------------------------------------- typedef std::vector< std::pair< Area *, LightObj > > AreaList; // List of collided areas. +// -------------------------------------------------------------------------------------------- +#ifdef VCMP_ENABLE_OFFICIAL + struct LgCheckpoint; + struct LgObject; + struct LgPickup; + struct LgPlayer; + struct LgVehicle; +#endif + /* -------------------------------------------------------------------------------------------- * Helper structure used to identify a blip entity instance on the server. */ @@ -118,6 +127,12 @@ struct CheckpointInst // ---------------------------------------------------------------------------------------- LightObj mEvents{}; // Table containing the emitted entity events. + // ---------------------------------------------------------------------------------------- +#ifdef VCMP_ENABLE_OFFICIAL + LgCheckpoint * mLgInst{nullptr}; // Pointer to the actual instance used to interact this entity. + LightObj mLgObj{}; // Script object of the instance used to interact this entity. +#endif + // ---------------------------------------------------------------------------------------- SignalPair mOnDestroyed{}; SignalPair mOnCustom{}; @@ -234,6 +249,12 @@ struct ObjectInst // ---------------------------------------------------------------------------------------- LightObj mEvents{}; // Table containing the emitted entity events. + // ---------------------------------------------------------------------------------------- +#ifdef VCMP_ENABLE_OFFICIAL + LgObject * mLgInst{nullptr}; // Pointer to the actual instance used to interact this entity. + LightObj mLgObj{}; // Script object of the instance used to interact this entity. +#endif + // ---------------------------------------------------------------------------------------- SignalPair mOnDestroyed{}; SignalPair mOnCustom{}; @@ -292,6 +313,12 @@ struct PickupInst // ---------------------------------------------------------------------------------------- LightObj mEvents{}; // Table containing the emitted entity events. + // ---------------------------------------------------------------------------------------- +#ifdef VCMP_ENABLE_OFFICIAL + LgPickup * mLgInst{nullptr}; // Pointer to the actual instance used to interact this entity. + LightObj mLgObj{}; // Script object of the instance used to interact this entity. +#endif + // ---------------------------------------------------------------------------------------- SignalPair mOnDestroyed{}; SignalPair mOnCustom{}; @@ -379,6 +406,12 @@ struct PlayerInst // ---------------------------------------------------------------------------------------- LightObj mEvents{}; // Table containing the emitted entity events. + // ---------------------------------------------------------------------------------------- +#ifdef VCMP_ENABLE_OFFICIAL + LgPlayer * mLgInst{nullptr}; // Pointer to the actual instance used to interact this entity. + LightObj mLgObj{}; // Script object of the instance used to interact this entity. +#endif + // ---------------------------------------------------------------------------------------- SignalPair mOnDestroyed{}; SignalPair mOnCustom{}; @@ -523,6 +556,12 @@ struct VehicleInst // ---------------------------------------------------------------------------------------- LightObj mEvents{}; // Table containing the emitted entity events. + // ---------------------------------------------------------------------------------------- +#ifdef VCMP_ENABLE_OFFICIAL + LgVehicle * mLgInst{nullptr}; // Pointer to the actual instance used to interact this entity. + LightObj mLgObj{}; // Script object of the instance used to interact this entity. +#endif + // ---------------------------------------------------------------------------------------- SignalPair mOnDestroyed{}; SignalPair mOnCustom{}; diff --git a/module/Core/Events.inc b/module/Core/Events.inc index d0f08fc5..51d0ce5e 100644 --- a/module/Core/Events.inc +++ b/module/Core/Events.inc @@ -4,6 +4,47 @@ namespace SqMod { // ------------------------------------------------------------------------------------------------ #define NULL_SQOBJ_(o) (o.IsNull() ? "NULL" : "OBJ") +// ------------------------------------------------------------------------------------------------ +#ifdef VCMP_ENABLE_OFFICIAL +// ------------------------------------------------------------------------------------------------ +// Invoke a script function from the root table with no return value +template < class... Args > static void ExecuteLegacyEvent(HSQUIRRELVM vm, const SQChar * name, Args &&... args) +{ + StackGuard sqsg(vm); + // Push the root table on the stack + sq_pushroottable(vm); + // Grab the function from the table + Function fn(vm, sq_gettop(vm), name); + // Was there a callback with that name? + if (fn.IsNull()) + { + return; // Nothing to invoke + } + // Forward the call to the function + fn.Execute(std::forward< Args >(args)...); +} +// ------------------------------------------------------------------------------------------------ +// Invoke a script function from the root table with a return value +template < class... Args > static LightObj EvaluateLegacyEvent(HSQUIRRELVM vm, const SQChar * name, Args &&... args) +{ + StackGuard sqsg(vm); + // Push the root table on the stack + sq_pushroottable(vm); + // Grab the function from the table + Function fn(vm, sq_gettop(vm), name); + // Was there a callback with that name? + if (fn.IsNull()) + { + return LightObj{}; // Nothing to invoke + } + // Forward the call to the function + return fn.Eval(std::forward< Args >(args)...); +} +// ------------------------------------------------------------------------------------------------ +static int32_t g_LastHour = 0; +static int32_t g_LastMinute = 0; +#endif + // ------------------------------------------------------------------------------------------------ void Core::EmitCustomEvent(int32_t group, int32_t header, LightObj & payload) const { @@ -58,6 +99,12 @@ void Core::EmitPlayerCreated(int32_t player, int32_t header, LightObj & payload) SQMOD_CO_EV_TRACEBACK("[TRACE<] Core::PlayerCreated(%d, %d, %s)", player, header, NULL_SQOBJ_(payload)) (*mOnPlayerCreated.first)(m_Players.at(static_cast< size_t >(player)).mObj, header, payload); SQMOD_CO_EV_TRACEBACK("[TRACE>] Core::PlayerCreated") +#ifdef VCMP_ENABLE_OFFICIAL + if (IsOfficial()) + { + ExecuteLegacyEvent(m_VM, _SC("onPlayerJoin"), m_Players.at(static_cast< size_t >(player)).mLgObj); + } +#endif } // ------------------------------------------------------------------------------------------------ @@ -126,6 +173,12 @@ void Core::EmitPlayerDestroyed(int32_t player, int32_t header, LightObj & payloa (*_player.mOnDestroyed.first)(header, payload); (*mOnPlayerDestroyed.first)(_player.mObj, header, payload); SQMOD_CO_EV_TRACEBACK("[TRACE>] Core::PlayerDestroyed") +#ifdef VCMP_ENABLE_OFFICIAL + if (IsOfficial()) + { + ExecuteLegacyEvent(m_VM, _SC("onPlayerPart"), _player.mLgObj); + } +#endif } // ------------------------------------------------------------------------------------------------ @@ -214,6 +267,12 @@ void Core::EmitServerStartup() const SQMOD_CO_EV_TRACEBACK("[TRACE<] Core::ServerStartup()") (*mOnServerStartup.first)(); SQMOD_CO_EV_TRACEBACK("[TRACE>] Core::ServerStartup") +#ifdef VCMP_ENABLE_OFFICIAL + if (IsOfficial()) + { + ExecuteLegacyEvent(m_VM, _SC("onServerStart")); + } +#endif } // ------------------------------------------------------------------------------------------------ @@ -222,6 +281,13 @@ void Core::EmitServerShutdown() const SQMOD_CO_EV_TRACEBACK("[TRACE<] Core::ServerShutdown()") (*mOnServerShutdown.first)(); SQMOD_CO_EV_TRACEBACK("[TRACE>] Core::ServerShutdown") +#ifdef VCMP_ENABLE_OFFICIAL + if (IsOfficial()) + { + ExecuteLegacyEvent(m_VM, _SC("onServerStop")); + ExecuteLegacyEvent(m_VM, _SC("onScriptUnload")); + } +#endif } // ------------------------------------------------------------------------------------------------ @@ -230,6 +296,20 @@ void Core::EmitServerFrame(float elapsed_time) const //SQMOD_CO_EV_TRACEBACK("[TRACE<] Core::ServerFrame(%f)", elapsed_time) (*mOnServerFrame.first)(elapsed_time); //SQMOD_CO_EV_TRACEBACK("[TRACE>] Core::ServerFrame") +#ifdef VCMP_ENABLE_OFFICIAL + if (IsOfficial()) + { + const int32_t hour = _Func->GetHour(), minute = _Func->GetMinute(); + // Check for onTimeChange triggers + if(g_LastHour != hour || g_LastMinute != minute) + { + ExecuteLegacyEvent(m_VM, _SC("onTimeChange"), g_LastHour, g_LastMinute, hour, minute); + // Update values + g_LastHour = hour; + g_LastMinute = minute; + } + } +#endif } // ------------------------------------------------------------------------------------------------ @@ -253,11 +333,14 @@ void Core::EmitIncomingConnection(char * player_name, size_t name_buffer_size, c // Save the buffer information so that we can write to it from the string m_IncomingNameBuffer = player_name; m_IncomingNameCapacity = name_buffer_size; + // Create reusable objects from parameters + LightObj player_name_obj(player_name, -1); + LightObj user_password_obj(user_password, -1); + LightObj ip_address_obj(ip_address, -1); // Attempt to forward the event to the script callback try { - (*mOnIncomingConnection.first)(LightObj(player_name, -1), name_buffer_size, - LightObj(user_password, -1), LightObj(ip_address, -1)); + (*mOnIncomingConnection.first)(player_name_obj, name_buffer_size, user_password_obj, ip_address_obj); } catch (...) { @@ -271,6 +354,13 @@ void Core::EmitIncomingConnection(char * player_name, size_t name_buffer_size, c m_IncomingNameBuffer = nullptr; m_IncomingNameCapacity = 0; SQMOD_CO_EV_TRACEBACK("[TRACE>] Core::IncomingConnection") +#ifdef VCMP_ENABLE_OFFICIAL + if (IsOfficial()) + { + LightObj r = EvaluateLegacyEvent(m_VM, _SC("onLoginAttempt"), player_name_obj, user_password_obj, ip_address_obj); + SetState(r.IsNull() ? 1 : r.Cast< int32_t >()); + } +#endif } // ------------------------------------------------------------------------------------------------ @@ -281,6 +371,14 @@ void Core::EmitPlayerRequestClass(int32_t player_id, int32_t offset) (*_player.mOnRequestClass.first)(offset); (*mOnPlayerRequestClass.first)(_player.mObj, offset); SQMOD_CO_EV_TRACEBACK("[TRACE>] Core::PlayerRequestClass") +#ifdef VCMP_ENABLE_OFFICIAL + if (IsOfficial()) + { + LightObj r = EvaluateLegacyEvent(m_VM, _SC("onPlayerRequestClass"), + _player.mLgObj, offset, _Func->GetPlayerTeam(player_id), _Func->GetPlayerSkin(player_id)); + SetState(r.IsNull() ? 1 : r.Cast< int32_t >()); + } +#endif } // ------------------------------------------------------------------------------------------------ @@ -291,6 +389,12 @@ void Core::EmitPlayerRequestSpawn(int32_t player_id) (*_player.mOnRequestSpawn.first)(); (*mOnPlayerRequestSpawn.first)(_player.mObj); SQMOD_CO_EV_TRACEBACK("[TRACE>] Core::PlayerRequestSpawn") +#ifdef VCMP_ENABLE_OFFICIAL + if (IsOfficial()) + { + ExecuteLegacyEvent(m_VM, _SC("onPlayerRequestSpawn"), _player.mLgObj); + } +#endif } // ------------------------------------------------------------------------------------------------ @@ -301,16 +405,31 @@ void Core::EmitPlayerSpawn(int32_t player_id) (*_player.mOnSpawn.first)(); (*mOnPlayerSpawn.first)(_player.mObj); SQMOD_CO_EV_TRACEBACK("[TRACE>] Core::PlayerSpawn") +#ifdef VCMP_ENABLE_OFFICIAL + if (IsOfficial()) + { + ExecuteLegacyEvent(m_VM, _SC("onPlayerSpawn"), _player.mLgObj); + } +#endif } // ------------------------------------------------------------------------------------------------ -void Core::EmitPlayerWasted(int32_t player_id, int32_t reason) +void Core::EmitPlayerWasted(int32_t player_id, int32_t reason, vcmpBodyPart SQ_UNUSED_ARG(body_part)) { SQMOD_CO_EV_TRACEBACK("[TRACE<] Core::PlayerWasted(%d, %d)", player_id, reason) PlayerInst & _player = m_Players.at(static_cast< size_t >(player_id)); (*_player.mOnWasted.first)(reason); (*mOnPlayerWasted.first)(_player.mObj, reason); SQMOD_CO_EV_TRACEBACK("[TRACE>] Core::PlayerWasted") +#ifdef VCMP_ENABLE_OFFICIAL + if (IsOfficial()) + { + if (reason == 43 || reason == 50) reason = 43; // drowned + else if (reason == 39 && body_part == 7) reason = 39; // car crash + else if (reason == 39 || reason == 40 || reason == 44) reason = 44; // fell + ExecuteLegacyEvent(m_VM, _SC("onPlayerDeath"), _player.mLgObj, reason); + } +#endif } // ------------------------------------------------------------------------------------------------ @@ -322,6 +441,19 @@ void Core::EmitPlayerKilled(int32_t player_id, int32_t killer_id, int32_t reason (*_player.mOnKilled.first)(_killer.mObj, reason, static_cast< int32_t >(body_part), team_kill); (*mOnPlayerKilled.first)(_player.mObj, _killer.mObj, reason, static_cast< int32_t >(body_part), team_kill); SQMOD_CO_EV_TRACEBACK("[TRACE>] Core::PlayerKilled") +#ifdef VCMP_ENABLE_OFFICIAL + if (IsOfficial()) + { + if (!team_kill) + { + ExecuteLegacyEvent(m_VM, _SC("onPlayerTeamKill"), _killer.mLgObj, _player.mLgObj, reason, static_cast< int32_t >(body_part)); + } + else + { + ExecuteLegacyEvent(m_VM, _SC("onPlayerKill"), _killer.mLgObj, _player.mLgObj, reason, static_cast< int32_t >(body_part)); + } + } +#endif } // ------------------------------------------------------------------------------------------------ @@ -334,6 +466,14 @@ void Core::EmitPlayerEmbarking(int32_t player_id, int32_t vehicle_id, int32_t sl (*_vehicle.mOnEmbarking.first)(_player.mObj, slot_index); (*mOnPlayerEmbarking.first)(_player.mObj, _vehicle.mObj, slot_index); SQMOD_CO_EV_TRACEBACK("[TRACE>] Core::PlayerEmbarking") +#ifdef VCMP_ENABLE_OFFICIAL + if (IsOfficial()) + { + LightObj r = EvaluateLegacyEvent(m_VM, _SC("onPlayerEnteringVehicle"), + _player.mLgObj, _vehicle.mLgObj, slot_index); + SetState(r.IsNull() ? 1 : r.Cast< int32_t >()); + } +#endif } // ------------------------------------------------------------------------------------------------ @@ -346,6 +486,12 @@ void Core::EmitPlayerEmbarked(int32_t player_id, int32_t vehicle_id, int32_t slo (*_vehicle.mOnEmbarked.first)(_player.mObj, slot_index); (*mOnPlayerEmbarked.first)(_player.mObj, _vehicle.mObj, slot_index); SQMOD_CO_EV_TRACEBACK("[TRACE>] Core::PlayerEmbarked") +#ifdef VCMP_ENABLE_OFFICIAL + if (IsOfficial()) + { + ExecuteLegacyEvent(m_VM, _SC("onPlayerEnterVehicle"), _player.mLgObj, _vehicle.mLgObj, slot_index); + } +#endif } // ------------------------------------------------------------------------------------------------ @@ -358,6 +504,12 @@ void Core::EmitPlayerDisembark(int32_t player_id, int32_t vehicle_id) (*_vehicle.mOnDisembark.first)(_player.mObj); (*mOnPlayerDisembark.first)(_player.mObj, _vehicle.mObj); SQMOD_CO_EV_TRACEBACK("[TRACE>] Core::PlayerDisembark") +#ifdef VCMP_ENABLE_OFFICIAL + if (IsOfficial()) + { + ExecuteLegacyEvent(m_VM, _SC("onPlayerExitVehicle"), _player.mLgObj, _vehicle.mLgObj); + } +#endif } // ------------------------------------------------------------------------------------------------ @@ -369,6 +521,12 @@ void Core::EmitPlayerRename(int32_t player_id, const char * old_name, const char (*_player.mOnRename.first)(oname, nname); (*mOnPlayerRename.first)(_player.mObj, oname, nname); SQMOD_CO_EV_TRACEBACK("[TRACE>] Core::PlayerRename") +#ifdef VCMP_ENABLE_OFFICIAL + if (IsOfficial()) + { + ExecuteLegacyEvent(m_VM, _SC("onPlayerNameChange"), _player.mLgObj, oname, nname); + } +#endif } // ------------------------------------------------------------------------------------------------ @@ -379,6 +537,12 @@ void Core::EmitPlayerState(int32_t player_id, int32_t old_state, int32_t new_sta (*_player.mOnState.first)(old_state, new_state); (*mOnPlayerState.first)(_player.mObj, old_state, new_state); SQMOD_CO_EV_TRACEBACK("[TRACE>] Core::PlayerState") +#ifdef VCMP_ENABLE_OFFICIAL + if (IsOfficial()) + { + ExecuteLegacyEvent(m_VM, _SC("onPlayerActionChange"), _player.mLgObj, old_state, new_state); + } +#endif } // ------------------------------------------------------------------------------------------------ @@ -479,6 +643,12 @@ void Core::EmitPlayerAction(int32_t player_id, int32_t old_action, int32_t new_a (*_player.mOnAction.first)(old_action, new_action); (*mOnPlayerAction.first)(_player.mObj, old_action, new_action); SQMOD_CO_EV_TRACEBACK("[TRACE>] Core::PlayerAction") +#ifdef VCMP_ENABLE_OFFICIAL + if (IsOfficial()) + { + ExecuteLegacyEvent(m_VM, _SC("onPlayerActionChange"), _player.mLgObj, old_action, new_action); + } +#endif } // ------------------------------------------------------------------------------------------------ @@ -619,6 +789,12 @@ void Core::EmitPlayerBurning(int32_t player_id, bool is_on_fire) (*_player.mOnBurning.first)(is_on_fire); (*mOnPlayerBurning.first)(_player.mObj, is_on_fire); SQMOD_CO_EV_TRACEBACK("[TRACE>] Core::PlayerBurning") +#ifdef VCMP_ENABLE_OFFICIAL + if (IsOfficial()) + { + ExecuteLegacyEvent(m_VM, _SC("onPlayerOnFireChange"), _player.mLgObj, is_on_fire); + } +#endif } // ------------------------------------------------------------------------------------------------ @@ -629,6 +805,12 @@ void Core::EmitPlayerCrouching(int32_t player_id, bool is_crouching) (*_player.mOnCrouching.first)(is_crouching); (*mOnPlayerCrouching.first)(_player.mObj, is_crouching); SQMOD_CO_EV_TRACEBACK("[TRACE>] Core::PlayerCrouching") +#ifdef VCMP_ENABLE_OFFICIAL + if (IsOfficial()) + { + ExecuteLegacyEvent(m_VM, _SC("onPlayerCrouchChange"), _player.mLgObj, is_crouching); + } +#endif } // ------------------------------------------------------------------------------------------------ @@ -639,6 +821,12 @@ void Core::EmitPlayerGameKeys(int32_t player_id, uint32_t old_keys, uint32_t new (*_player.mOnGameKeys.first)(old_keys, new_keys); (*mOnPlayerGameKeys.first)(_player.mObj, old_keys, new_keys); SQMOD_CO_EV_TRACEBACK("[TRACE>] Core::PlayerGameKeys") +#ifdef VCMP_ENABLE_OFFICIAL + if (IsOfficial()) + { + ExecuteLegacyEvent(m_VM, _SC("onPlayerGameKeysChange"), _player.mLgObj, old_keys, new_keys); + } +#endif } // ------------------------------------------------------------------------------------------------ @@ -649,6 +837,12 @@ void Core::EmitPlayerStartTyping(int32_t player_id) (*_player.mOnStartTyping.first)(); (*mOnPlayerStartTyping.first)(_player.mObj); SQMOD_CO_EV_TRACEBACK("[TRACE>] Core::PlayerStartTyping") +#ifdef VCMP_ENABLE_OFFICIAL + if (IsOfficial()) + { + ExecuteLegacyEvent(m_VM, _SC("onPlayerBeginTyping"), _player.mLgObj); + } +#endif } // ------------------------------------------------------------------------------------------------ @@ -659,6 +853,12 @@ void Core::EmitPlayerStopTyping(int32_t player_id) (*_player.mOnStopTyping.first)(); (*mOnPlayerStopTyping.first)(_player.mObj); SQMOD_CO_EV_TRACEBACK("[TRACE>] Core::PlayerStopTyping") +#ifdef VCMP_ENABLE_OFFICIAL + if (IsOfficial()) + { + ExecuteLegacyEvent(m_VM, _SC("onPlayerEndTyping"), _player.mLgObj); + } +#endif } // ------------------------------------------------------------------------------------------------ @@ -669,6 +869,12 @@ void Core::EmitPlayerAway(int32_t player_id, bool is_away) (*_player.mOnAway.first)(is_away); (*mOnPlayerAway.first)(_player.mObj, is_away); SQMOD_CO_EV_TRACEBACK("[TRACE>] Core::PlayerAway") +#ifdef VCMP_ENABLE_OFFICIAL + if (IsOfficial()) + { + ExecuteLegacyEvent(m_VM, _SC("onPlayerAwayChange"), _player.mLgObj, is_away); + } +#endif } // ------------------------------------------------------------------------------------------------ @@ -680,6 +886,13 @@ void Core::EmitPlayerMessage(int32_t player_id, const char * message) (*_player.mOnMessage.first)(msg); (*mOnPlayerMessage.first)(_player.mObj, msg); SQMOD_CO_EV_TRACEBACK("[TRACE>] Core::PlayerMessage") +#ifdef VCMP_ENABLE_OFFICIAL + if (IsOfficial()) + { + LightObj r = EvaluateLegacyEvent(m_VM, _SC("onPlayerChat"), _player.mLgObj, msg); + SetState(r.IsNull() ? 1 : r.Cast< int32_t >()); + } +#endif } // ------------------------------------------------------------------------------------------------ @@ -691,6 +904,31 @@ void Core::EmitPlayerCommand(int32_t player_id, const char * message) (*_player.mOnCommand.first)(msg); (*mOnPlayerCommand.first)(_player.mObj, msg); SQMOD_CO_EV_TRACEBACK("[TRACE>] Core::PlayerCommand") +#ifdef VCMP_ENABLE_OFFICIAL + if (IsOfficial()) + { + LightObj text, args; + // Find the first space character + const char * split = std::strchr(message, ' '); + // Do we need to split the command from arguments? + if (split) + { + // Create a string object for the command (don't include the space character) + text = LightObj(message, static_cast< SQInteger >(split - message) - 1); + // Do we need to create a script object for arguments? + if (std::strlen(split + 1) > 0) + { + args = LightObj(split + 1, -1); // Skip the space character + } + } + else + { + text = std::move(msg); // Use the existing message object as is + } + LightObj r = EvaluateLegacyEvent(m_VM, _SC("onPlayerCommand"), _player.mLgObj, text, args); + SetState(r.IsNull() ? 1 : r.Cast< int32_t >()); + } +#endif } // ------------------------------------------------------------------------------------------------ @@ -703,6 +941,13 @@ void Core::EmitPlayerPrivateMessage(int32_t player_id, int32_t target_player_id, (*_player.mOnMessage.first)(_receiver.mObj, msg); (*mOnPlayerPrivateMessage.first)(_player.mObj, _receiver.mObj, msg); SQMOD_CO_EV_TRACEBACK("[TRACE>] Core::PlayerPrivateMessage") +#ifdef VCMP_ENABLE_OFFICIAL + if (IsOfficial()) + { + LightObj r = EvaluateLegacyEvent(m_VM, _SC("onPlayerPM"), _player.mLgObj, _receiver.mLgObj, msg); + SetState(r.IsNull() ? 1 : r.Cast< int32_t >()); + } +#endif } // ------------------------------------------------------------------------------------------------ @@ -715,6 +960,12 @@ void Core::EmitPlayerKeyPress(int32_t player_id, int32_t bind_id) (*_keybind.mOnKeyPress.first)(_player.mObj); (*mOnPlayerKeyPress.first)(_player.mObj, _keybind.mObj); SQMOD_CO_EV_TRACEBACK("[TRACE>] Core::PlayerKeyPress") +#ifdef VCMP_ENABLE_OFFICIAL + if (IsOfficial()) + { + ExecuteLegacyEvent(m_VM, _SC("onKeyDown"), _player.mLgObj, bind_id); + } +#endif } // ------------------------------------------------------------------------------------------------ @@ -727,6 +978,12 @@ void Core::EmitPlayerKeyRelease(int32_t player_id, int32_t bind_id) (*_player.mOnKeyRelease.first)(_keybind.mObj); (*mOnPlayerKeyRelease.first)(_player.mObj, _keybind.mObj); SQMOD_CO_EV_TRACEBACK("[TRACE>] Core::PlayerKeyRelease") +#ifdef VCMP_ENABLE_OFFICIAL + if (IsOfficial()) + { + ExecuteLegacyEvent(m_VM, _SC("onKeyUp"), _player.mLgObj, bind_id); + } +#endif } // ------------------------------------------------------------------------------------------------ @@ -738,6 +995,12 @@ void Core::EmitPlayerSpectate(int32_t player_id, int32_t target_player_id) (*_player.mOnSpectate.first)(_target.mObj); (*mOnPlayerSpectate.first)(_player.mObj, _target.mObj); SQMOD_CO_EV_TRACEBACK("[TRACE>] Core::PlayerSpectate") +#ifdef VCMP_ENABLE_OFFICIAL + if (IsOfficial()) + { + ExecuteLegacyEvent(m_VM, _SC("onPlayerSpectate"), _player.mLgObj, _target.mLgObj); + } +#endif } // ------------------------------------------------------------------------------------------------ @@ -755,10 +1018,16 @@ void Core::EmitPlayerCrashReport(int32_t player_id, const char * report) { SQMOD_CO_EV_TRACEBACK("[TRACE<] Core::PlayerCrashreport(%d, %s)", player_id, report) PlayerInst & _player = m_Players.at(static_cast< size_t >(player_id)); - LightObj rep(report, -1); - (*_player.mOnCrashReport.first)(rep); - (*mOnPlayerCrashReport.first)(_player.mObj, rep); + LightObj report_obj(report, -1); + (*_player.mOnCrashReport.first)(report_obj); + (*mOnPlayerCrashReport.first)(_player.mObj, report_obj); SQMOD_CO_EV_TRACEBACK("[TRACE>] Core::PlayerCrashreport") +#ifdef VCMP_ENABLE_OFFICIAL + if (IsOfficial()) + { + ExecuteLegacyEvent(m_VM, _SC("onPlayerCrashDump"), _player.mLgObj, report_obj); + } +#endif } // ------------------------------------------------------------------------------------------------ @@ -766,10 +1035,16 @@ void Core::EmitPlayerModuleList(int32_t player_id, const char * list) { SQMOD_CO_EV_TRACEBACK("[TRACE<] Core::PlayerModuleList(%d, %s)", player_id, list) PlayerInst & _player = m_Players.at(static_cast< size_t >(player_id)); - LightObj rep(list, -1); - (*_player.mOnModuleList.first)(rep); - (*mOnPlayerModuleList.first)(_player.mObj, rep); + LightObj list_obj(list, -1); + (*_player.mOnModuleList.first)(list_obj); + (*mOnPlayerModuleList.first)(_player.mObj, list_obj); SQMOD_CO_EV_TRACEBACK("[TRACE>] Core::PlayerModuleList") +#ifdef VCMP_ENABLE_OFFICIAL + if (IsOfficial()) + { + ExecuteLegacyEvent(m_VM, _SC("onPlayerModuleList"), _player.mLgObj, list_obj); + } +#endif } // ------------------------------------------------------------------------------------------------ @@ -780,6 +1055,12 @@ void Core::EmitVehicleExplode(int32_t vehicle_id) (*_vehicle.mOnExplode.first)(); (*mOnVehicleExplode.first)(_vehicle.mObj); SQMOD_CO_EV_TRACEBACK("[TRACE>] Core::VehicleExplode") +#ifdef VCMP_ENABLE_OFFICIAL + if (IsOfficial()) + { + ExecuteLegacyEvent(m_VM, _SC("onVehicleExplode"), _vehicle.mLgObj); + } +#endif } // ------------------------------------------------------------------------------------------------ @@ -790,6 +1071,12 @@ void Core::EmitVehicleRespawn(int32_t vehicle_id) (*_vehicle.mOnRespawn.first)(); (*mOnVehicleRespawn.first)(_vehicle.mObj); SQMOD_CO_EV_TRACEBACK("[TRACE>] Core::VehicleRespawn") +#ifdef VCMP_ENABLE_OFFICIAL + if (IsOfficial()) + { + ExecuteLegacyEvent(m_VM, _SC("onVehicleRespawn"), _vehicle.mLgObj); + } +#endif } // ------------------------------------------------------------------------------------------------ @@ -802,6 +1089,12 @@ void Core::EmitObjectShot(int32_t object_id, int32_t player_id, int32_t weapon_i (*_player.mOnObjectShot.first)(_object.mObj, weapon_id); (*mOnObjectShot.first)(_player.mObj, _object.mObj, weapon_id); SQMOD_CO_EV_TRACEBACK("[TRACE>] Core::ObjectShot") +#ifdef VCMP_ENABLE_OFFICIAL + if (IsOfficial()) + { + ExecuteLegacyEvent(m_VM, _SC("onObjectShot"), _object.mLgObj, _player.mLgObj, weapon_id); + } +#endif } // ------------------------------------------------------------------------------------------------ @@ -814,6 +1107,12 @@ void Core::EmitObjectTouched(int32_t object_id, int32_t player_id) (*_player.mOnObjectTouched.first)(_object.mObj); (*mOnObjectTouched.first)(_player.mObj, _object.mObj); SQMOD_CO_EV_TRACEBACK("[TRACE>] Core::ObjectTouched") +#ifdef VCMP_ENABLE_OFFICIAL + if (IsOfficial()) + { + ExecuteLegacyEvent(m_VM, _SC("onObjectBump"), _object.mLgObj, _player.mLgObj); + } +#endif } // ------------------------------------------------------------------------------------------------ @@ -826,6 +1125,13 @@ void Core::EmitPickupClaimed(int32_t pickup_id, int32_t player_id) (*_player.mOnPickupClaimed.first)(_pickup.mObj); (*mOnPickupClaimed.first)(_player.mObj, _pickup.mObj); SQMOD_CO_EV_TRACEBACK("[TRACE>] Core::PickupClaimed") +#ifdef VCMP_ENABLE_OFFICIAL + if (IsOfficial()) + { + LightObj r = EvaluateLegacyEvent(m_VM, _SC("onPickupClaimPicked"), _player.mLgObj, _pickup.mLgObj); + SetState(r.IsNull() ? 1 : r.Cast< int32_t >()); + } +#endif } // ------------------------------------------------------------------------------------------------ @@ -838,6 +1144,12 @@ void Core::EmitPickupCollected(int32_t pickup_id, int32_t player_id) (*_player.mOnPickupCollected.first)(_pickup.mObj); (*mOnPickupCollected.first)(_player.mObj, _pickup.mObj); SQMOD_CO_EV_TRACEBACK("[TRACE>] Core::PickupCollected") +#ifdef VCMP_ENABLE_OFFICIAL + if (IsOfficial()) + { + ExecuteLegacyEvent(m_VM, _SC("onPickupPickedUp"), _player.mLgObj, _pickup.mLgObj); + } +#endif } // ------------------------------------------------------------------------------------------------ @@ -848,6 +1160,12 @@ void Core::EmitPickupRespawn(int32_t pickup_id) (*_pickup.mOnRespawn.first)(); (*mOnPickupRespawn.first)(_pickup.mObj); SQMOD_CO_EV_TRACEBACK("[TRACE>] Core::PickupRespawn") +#ifdef VCMP_ENABLE_OFFICIAL + if (IsOfficial()) + { + ExecuteLegacyEvent(m_VM, _SC("onPickupRespawn"), _pickup.mLgObj); + } +#endif } // ------------------------------------------------------------------------------------------------ @@ -860,6 +1178,12 @@ void Core::EmitCheckpointEntered(int32_t checkpoint_id, int32_t player_id) (*_player.mOnCheckpointEntered.first)(_checkpoint.mObj); (*mOnCheckpointEntered.first)(_player.mObj, _checkpoint.mObj); SQMOD_CO_EV_TRACEBACK("[TRACE>] Core::CheckpointEntered") +#ifdef VCMP_ENABLE_OFFICIAL + if (IsOfficial()) + { + ExecuteLegacyEvent(m_VM, _SC("onCheckpointEntered"), _player.mLgObj, _checkpoint.mLgObj); + } +#endif } // ------------------------------------------------------------------------------------------------ @@ -872,6 +1196,12 @@ void Core::EmitCheckpointExited(int32_t checkpoint_id, int32_t player_id) (*_player.mOnCheckpointExited.first)(_checkpoint.mObj); (*mOnCheckpointExited.first)(_player.mObj, _checkpoint.mObj); SQMOD_CO_EV_TRACEBACK("[TRACE>] Core::CheckpointExited") +#ifdef VCMP_ENABLE_OFFICIAL + if (IsOfficial()) + { + ExecuteLegacyEvent(m_VM, _SC("onCheckpointExited"), _player.mLgObj, _checkpoint.mLgObj); + } +#endif } // ------------------------------------------------------------------------------------------------ @@ -983,6 +1313,12 @@ void Core::EmitPlayerHealth(int32_t player_id, float old_health, float new_healt (*_player.mOnHealth.first)(old_health, new_health); (*mOnPlayerHealth.first)(_player.mObj, old_health, new_health); SQMOD_CO_EV_TRACEBACK("[TRACE>] Core::PlayerHealth") +#ifdef VCMP_ENABLE_OFFICIAL + if (IsOfficial()) + { + ExecuteLegacyEvent(m_VM, _SC("onPlayerHealthChange"), _player.mLgObj, old_health, new_health); + } +#endif } // ------------------------------------------------------------------------------------------------ @@ -993,6 +1329,12 @@ void Core::EmitPlayerArmour(int32_t player_id, float old_armour, float new_armou (*_player.mOnArmour.first)(old_armour, new_armour); (*mOnPlayerArmour.first)(_player.mObj, old_armour, new_armour); SQMOD_CO_EV_TRACEBACK("[TRACE>] Core::PlayerArmour") +#ifdef VCMP_ENABLE_OFFICIAL + if (IsOfficial()) + { + ExecuteLegacyEvent(m_VM, _SC("onPlayerArmourChange"), _player.mLgObj, old_armour, new_armour); + } +#endif } // ------------------------------------------------------------------------------------------------ @@ -1003,6 +1345,12 @@ void Core::EmitPlayerWeapon(int32_t player_id, int32_t old_weapon, int32_t new_w (*_player.mOnWeapon.first)(old_weapon, new_weapon); (*mOnPlayerWeapon.first)(_player.mObj, old_weapon, new_weapon); SQMOD_CO_EV_TRACEBACK("[TRACE>] Core::PlayerWeapon") +#ifdef VCMP_ENABLE_OFFICIAL + if (IsOfficial()) + { + ExecuteLegacyEvent(m_VM, _SC("onPlayerWeaponChange"), _player.mLgObj, old_weapon, new_weapon); + } +#endif } // ------------------------------------------------------------------------------------------------ @@ -1023,6 +1371,16 @@ void Core::EmitPlayerPosition(int32_t player_id) (*_player.mOnPosition.first)(_player.mTrackPositionHeader, _player.mTrackPositionPayload); (*mOnPlayerPosition.first)(_player.mObj, _player.mTrackPositionHeader, _player.mTrackPositionPayload); SQMOD_CO_EV_TRACEBACK("[TRACE>] Core::PlayerPosition") +#ifdef VCMP_ENABLE_OFFICIAL + if (IsOfficial()) + { + Vector3 pos; + _Func->GetPlayerPosition(player_id, &pos.x, &pos.y, &pos.z); + ExecuteLegacyEvent(m_VM, _SC("onPlayerMove"), _player.mLgObj + , _player.mLastPosition.x, _player.mLastPosition.y, _player.mLastPosition.z + , pos.x, pos.y, pos.z); + } +#endif } // ------------------------------------------------------------------------------------------------ @@ -1164,6 +1522,12 @@ void Core::EmitVehicleHealth(int32_t vehicle_id, float old_health, float new_hea (*_vehicle.mOnHealth.first)(old_health, new_health); (*mOnVehicleHealth.first)(_vehicle.mObj, old_health, new_health); SQMOD_CO_EV_TRACEBACK("[TRACE>] Core::VehicleHealth") +#ifdef VCMP_ENABLE_OFFICIAL + if (IsOfficial()) + { + ExecuteLegacyEvent(m_VM, _SC("onVehicleHealthChange"), _vehicle.mLgObj, old_health, new_health); + } +#endif } // ------------------------------------------------------------------------------------------------ @@ -1174,6 +1538,16 @@ void Core::EmitVehiclePosition(int32_t vehicle_id) (*_vehicle.mOnPosition.first)(); (*mOnVehiclePosition.first)(_vehicle.mObj); SQMOD_CO_EV_TRACEBACK("[TRACE>] Core::VehiclePosition") +#ifdef VCMP_ENABLE_OFFICIAL + if (IsOfficial()) + { + Vector3 pos; + _Func->GetVehiclePosition(vehicle_id, &pos.x, &pos.y, &pos.z); + ExecuteLegacyEvent(m_VM, _SC("onVehicleMove"), _vehicle.mLgObj + , _vehicle.mLastPosition.x, _vehicle.mLastPosition.y, _vehicle.mLastPosition.z + , pos.x, pos.y, pos.z); + } +#endif } // ------------------------------------------------------------------------------------------------ @@ -1875,6 +2249,12 @@ void Core::EmitClientScriptData(int32_t player_id, const uint8_t * data, size_t (*_player.mOnClientScriptData.first)(o, size); (*mOnClientScriptData.first)(_player.mObj, o, size); SQMOD_CO_EV_TRACEBACK("[TRACE>] Core::ClientScriptData") +#ifdef VCMP_ENABLE_OFFICIAL + if (IsOfficial()) + { + ExecuteLegacyEvent(m_VM, _SC("onClientScriptData"), _player.mLgObj); + } +#endif } #undef NULL_SQOBJ_ // don't need this anymore diff --git a/module/Main.cpp b/module/Main.cpp index 0d4e6cb7..26c03295 100644 --- a/module/Main.cpp +++ b/module/Main.cpp @@ -329,7 +329,7 @@ static void OnPlayerDeath(int32_t player_id, int32_t killer_id, int32_t reason, } else { - Core::Get().EmitPlayerWasted(player_id, reason); + Core::Get().EmitPlayerWasted(player_id, reason, body_part); } SQMOD_SV_EV_TRACEBACK("[TRACE>] OnPlayerDeath") } @@ -605,7 +605,7 @@ static void OnPlayerAwayChange(int32_t player_id, uint8_t is_away) try { SQMOD_SV_EV_TRACEBACK("[TRACE<] OnPlayerAwayChange") - Core::Get().EmitPlayerAway(player_id, is_away); + Core::Get().EmitPlayerAway(player_id, is_away >= 1); SQMOD_SV_EV_TRACEBACK("[TRACE>] OnPlayerAwayChange") } SQMOD_CATCH_EVENT_EXCEPTION(OnPlayerAwayChange) diff --git a/module/Misc/Official.cpp b/module/Misc/Official.cpp new file mode 100644 index 00000000..197945e2 --- /dev/null +++ b/module/Misc/Official.cpp @@ -0,0 +1,1222 @@ +// ------------------------------------------------------------------------------------------------ +#include "Misc/Official.hpp" +#include "Base/Vector2.hpp" +#include "Core/Utility.hpp" +// ------------------------------------------------------------------------------------------------ +#include "Core/Entity.hpp" +#include "Core.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/Vehicle.hpp" + +// ------------------------------------------------------------------------------------------------ +namespace SqMod { + +// ------------------------------------------------------------------------------------------------ +SQMOD_DECL_TYPENAME(RGBTn, _SC("RGB")) +SQMOD_DECL_TYPENAME(EntityRGBTn, _SC("LgEntityRGB")) +SQMOD_DECL_TYPENAME(RGBATn, _SC("RGBA")) +SQMOD_DECL_TYPENAME(ARGBTn, _SC("ARGB")) +SQMOD_DECL_TYPENAME(VectorTn, _SC("Vector")) +SQMOD_DECL_TYPENAME(QuaternionTn, _SC("Quaternion")) +SQMOD_DECL_TYPENAME(EntityVectorTn, _SC("LgEntityVector")) +SQMOD_DECL_TYPENAME(EntityQuaternionTn, _SC("LgEntityQuaternion")) +SQMOD_DECL_TYPENAME(BoundsTn, _SC("Bounds")) +SQMOD_DECL_TYPENAME(WastedSettingsTn, _SC("WastedSettings")) + +// ------------------------------------------------------------------------------------------------ +SQMOD_DECL_TYPENAME(CCheckpointTn, _SC("CCheckpoint_INTERNAL")) +SQMOD_DECL_TYPENAME(CObjectTn, _SC("CObject_INTERNAL")) +SQMOD_DECL_TYPENAME(CPickupTn, _SC("CPickup_INTERNAL")) +SQMOD_DECL_TYPENAME(CPlayerTn, _SC("CPlayer_INTERNAL")) +SQMOD_DECL_TYPENAME(CVehicleTn, _SC("CVehicle_INTERNAL")) + +/* ------------------------------------------------------------------------------------------------ + * Entity type enumeration. +*/ +struct LgEntityType +{ + enum Type + { + Player = 0, + Vehicle, + Pickup, + Object, + Checkpoint, + Unknown + }; +}; + +/* ------------------------------------------------------------------------------------------------ + * Player vector flag enumeration. +*/ +struct LgPlayerVectorFlag +{ + enum Type + { + Pos = 0, + Speed, + Unknown + }; +}; + +/* ------------------------------------------------------------------------------------------------ + * Vehicle vector flag enumeration. +*/ +struct LgVehicleVectorFlag +{ + enum Type + { + Pos = 0, + SpawnPos, + Angle, + SpawnAngle, + Speed, + RelSpeed, + TurnSpeed, + RelTurnSpeed, + Unknown + }; +}; + +/* ------------------------------------------------------------------------------------------------ + * Object vector flag enumeration. +*/ +struct LgObjectVectorFlag +{ + enum Type + { + Pos = 0, + Rotation, + Unknown + }; +}; + +/* ------------------------------------------------------------------------------------------------ + * Vehicle quaternion flag enumeration. +*/ +struct LgVehicleQuaternionFlag +{ + enum Type + { + Angle = 0, + SpawnAngle, + Unknown + }; +}; + +// ------------------------------------------------------------------------------------------------ +static SQInteger VectorToString(HSQUIRRELVM vm) +{ + try + { + Var< LgVector * > v(SqVM(), 1); + // Validate the instance, just to be sure + if (!v.value) + { + return sq_throwerror(vm, "Invalid Vector instance"); + } + // Generate the formatted string + auto s = fmt::format("({}, {}, {})", v.value->x, v.value->y, v.value->z); + // Push it on the stack + sq_pushstring(vm, s.c_str(), static_cast< SQInteger >(s.size())); + // Specify that we have a value to return + return 1; + } + catch (const std::exception & e) + { + return sq_throwerror(vm, e.what()); + } + SQ_UNREACHABLE +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger QuaternionToString(HSQUIRRELVM vm) +{ + try + { + Var< LgQuaternion * > v(SqVM(), 1); + // Validate the instance, just to be sure + if (!v.value) + { + return sq_throwerror(vm, "Invalid Quaternion instance"); + } + // Generate the formatted string + auto s = fmt::format("({}, {}, {}, {})", v.value->x, v.value->y, v.value->z, v.value->w); + // Push it on the stack + sq_pushstring(vm, s.c_str(), static_cast< SQInteger >(s.size())); + // Specify that we have a value to return + return 1; + } + catch (const std::exception & e) + { + return sq_throwerror(vm, e.what()); + } + SQ_UNREACHABLE +} + +// ------------------------------------------------------------------------------------------------ +void LgEntityVector::Set() +{ + switch (mType) + { + case LgEntityType::Player: + switch (mFlag) + { + case LgPlayerVectorFlag::Pos: + _Func->SetPlayerPosition(mID, x, y, z); + break; + case LgPlayerVectorFlag::Speed: + _Func->SetPlayerSpeed(mID, x, y, z); + break; + default: break; + } break; + case LgEntityType::Vehicle: + switch (mFlag) + { + case LgVehicleVectorFlag::Pos: + _Func->SetVehiclePosition(mID, x, y, z, 0); + break; + case LgVehicleVectorFlag::SpawnPos: + _Func->SetVehicleSpawnPosition(mID, x, y, z); + break; + case LgVehicleVectorFlag::Angle: + _Func->SetVehicleRotationEuler(mID, x, y, z); + break; + case LgVehicleVectorFlag::SpawnAngle: + _Func->SetVehicleSpawnRotationEuler(mID, x, y, z); + break; + case LgVehicleVectorFlag::Speed: + _Func->SetVehicleSpeed(mID, x, y, z, false, false); + break; + case LgVehicleVectorFlag::RelSpeed: + _Func->SetVehicleSpeed(mID, x, y, z, false, true); + break; + case LgVehicleVectorFlag::TurnSpeed: + _Func->SetVehicleTurnSpeed(mID, x, y, z, false, false); + break; + case LgVehicleVectorFlag::RelTurnSpeed: + _Func->SetVehicleTurnSpeed(mID, x, y, z, false, true); + break; + default: break; + } break; + case LgEntityType::Pickup: + _Func->SetPickupPosition(mID, x, y, z); + break; + case LgEntityType::Object: + switch (mFlag) + { + case LgObjectVectorFlag::Pos: + _Func->SetObjectPosition(mID, x, y, z); + break; + case LgObjectVectorFlag::Rotation: + _Func->RotateObjectToEuler(mID, x, y, z, 0); + break; + default: break; + } break; + case LgEntityType::Checkpoint: + _Func->SetCheckPointPosition(mID, x, y, z); + break; + default: break; + } +} + +// ------------------------------------------------------------------------------------------------ +void LgEntityQuaternion::Set() +{ + switch (mType) + { + case LgEntityType::Vehicle: + switch (mFlag) + { + case LgVehicleVectorFlag::Angle: + _Func->SetVehicleRotation(mID, x, y, z, w); + break; + case LgVehicleVectorFlag::SpawnAngle: + _Func->SetVehicleSpawnRotation(mID, x, y, z, w); + break; + default: break; + } break; + case LgEntityType::Object: + _Func->RotateObjectTo(mID, x, y, z, w, 0); + break; + default: break; + } +} + +// ------------------------------------------------------------------------------------------------ +void LgEntityRGB::Set() +{ + if (mType == LgEntityType::Player) + { + _Func->SetPlayerColour(mID, GetRGB()); + } +} + +// ------------------------------------------------------------------------------------------------ +void Register_Official_Entity(HSQUIRRELVM vm); + +// ================================================================================================ +void Register_Official(HSQUIRRELVM vm) +{ + // See if official support is allowed + if (!Core::Get().IsOfficial()) + { + return; // Do nothing + } + // -------------------------------------------------------------------------------------------- + RootTable(vm).Bind(VectorTn::Str, + DerivedClass< LgVector, Vector3 >(vm, VectorTn::Str) + // Constructors + .Ctor< Vector3::Value, Vector3::Value, Vector3::Value >() + // Member Methods + .Func(_SC("Distance"), &LgVector::GetDistanceTo) + // Global Member Methods + .SquirrelFunc(_SC("_tostring"), &VectorToString) + ); + // -------------------------------------------------------------------------------------------- + RootTable(vm).Bind(EntityVectorTn::Str, + DerivedClass< LgEntityVector, LgVector >(vm, EntityVectorTn::Str) + // Constructors + .Ctor< int, int, int, Vector3::Value, Vector3::Value, Vector3::Value >() + // Properties + .Prop(_SC("x"), &LgEntityVector::GetX, &LgEntityVector::SetX) + .Prop(_SC("y"), &LgEntityVector::GetY, &LgEntityVector::SetY) + .Prop(_SC("z"), &LgEntityVector::GetZ, &LgEntityVector::SetZ) + ); + // -------------------------------------------------------------------------------------------- + RootTable(vm).Bind(QuaternionTn::Str, + DerivedClass< LgQuaternion, Quaternion >(vm, QuaternionTn::Str) + // Constructors + .Ctor< Quaternion::Value, Quaternion::Value, Quaternion::Value >() + // Global Member Methods + .SquirrelFunc(_SC("_tostring"), &QuaternionToString) + ); + // -------------------------------------------------------------------------------------------- + RootTable(vm).Bind(EntityQuaternionTn::Str, + DerivedClass< LgEntityQuaternion, LgQuaternion >(vm, EntityQuaternionTn::Str) + // Constructors + .Ctor< int, int, int, Quaternion::Value, Quaternion::Value, Quaternion::Value, Quaternion::Value >() + // Properties + .Prop(_SC("x"), &LgEntityQuaternion::GetX, &LgEntityQuaternion::SetX) + .Prop(_SC("y"), &LgEntityQuaternion::GetY, &LgEntityQuaternion::SetY) + .Prop(_SC("z"), &LgEntityQuaternion::GetZ, &LgEntityQuaternion::SetZ) + .Prop(_SC("w"), &LgEntityQuaternion::GetW, &LgEntityQuaternion::SetW) + ); + // -------------------------------------------------------------------------------------------- + RootTable(vm).Bind(RGBTn::Str, + DerivedClass< LgRGB, Color3 >(vm, RGBTn::Str) + // Constructors + .Ctor< LgRGB::Value, LgRGB::Value, LgRGB::Value >() + ); + // -------------------------------------------------------------------------------------------- + RootTable(vm).Bind(RGBATn::Str, + DerivedClass< LgRGBA, Color4 >(vm, RGBATn::Str) + // Constructors + .Ctor< LgRGBA::Value, LgRGBA::Value, LgRGBA::Value >() + ); + // -------------------------------------------------------------------------------------------- + RootTable(vm).Bind(ARGBTn::Str, + Class< LgARGB >(vm, ARGBTn::Str) + // Constructors + .Ctor< LgARGB::Value, LgARGB::Value, LgARGB::Value, LgARGB::Value >() + // Member Variables + .Var(_SC("a"), &LgARGB::a) + .Var(_SC("r"), &LgARGB::r) + .Var(_SC("g"), &LgARGB::g) + .Var(_SC("b"), &LgARGB::b) + ); + // -------------------------------------------------------------------------------------------- + RootTable(vm).Bind(EntityRGBTn::Str, + DerivedClass< LgEntityRGB, Color3 >(vm, EntityRGBTn::Str) + // Constructors + .Ctor< int, int, int, Color3::Value, Color3::Value, Color3::Value >() + // Properties + .Prop(_SC("r"), &LgEntityRGB::GetR, &LgEntityRGB::SetR) + .Prop(_SC("g"), &LgEntityRGB::GetG, &LgEntityRGB::SetG) + .Prop(_SC("b"), &LgEntityRGB::GetB, &LgEntityRGB::SetB) + ); + // -------------------------------------------------------------------------------------------- + RootTable(vm).Bind(BoundsTn::Str, + Class< LgBounds >(vm, BoundsTn::Str) + // Constructors + .Ctor< LgBounds::Value, LgBounds::Value, LgBounds::Value, LgBounds::Value >() + // Member Variables + .Var(_SC("MaxX"), &LgBounds::max_x) + .Var(_SC("MinX"), &LgBounds::min_x) + .Var(_SC("MaxY"), &LgBounds::max_y) + .Var(_SC("MinY"), &LgBounds::min_y) + ); + // -------------------------------------------------------------------------------------------- + RootTable(vm).Bind(WastedSettingsTn::Str, + Class< LgWastedSettings >(vm, WastedSettingsTn::Str) + // Constructors + .Ctor< uint32_t, uint32_t, float, float, LgRGB, uint32_t, uint32_t >() + // Member Variables + .Var(_SC("DeathTime"), &LgWastedSettings::mDeathTime) + .Var(_SC("FadeTime"), &LgWastedSettings::mFadeTime) + .Var(_SC("FadeInSpeed"), &LgWastedSettings::mFadeInSpeed) + .Var(_SC("FadeOutSpeed"), &LgWastedSettings::mFadeOutSpeed) + .Var(_SC("FadeColour"), &LgWastedSettings::mFadeColour) + .Var(_SC("CorpseFadeDelay"), &LgWastedSettings::mCorpseFadeDelay) + .Var(_SC("CorpseFadeTime"), &LgWastedSettings::mCorpseFadeTime) + ); + // -------------------------------------------------------------------------------------------- + Register_Official_Entity(vm); +} + +/* ------------------------------------------------------------------------------------------------ + * Checkpoint entity proxy. +*/ +struct LgCheckpoint +{ + int32_t mID; + /* -------------------------------------------------------------------------------------------- + * Base constructor. + */ + explicit LgCheckpoint(int32_t id) + : mID(id) + { + } + /* -------------------------------------------------------------------------------------------- + * Retrieve the a valid entity identifier, otherwise throw an exception. + */ + SQMOD_NODISCARD int32_t GetIdentifier() const + { + // Validate the associated identifier + if (INVALID_ENTITY(mID)) + { + STHROWF("Invalid checkpoint reference"); + } + // Return it + return mID; + } + /* -------------------------------------------------------------------------------------------- + * Retrieve the native implementation of the associated entity, otherwise throw an exception. + */ + SQMOD_NODISCARD CCheckpoint & Get() const + { + // Retrieve the associated instance + CCheckpoint * p = Core::Get().GetCheckpoint(GetIdentifier()).mInst; + // Validate the associated instance + if (!p) + { + STHROWF("Invalid checkpoint instance"); + } + // This is valid so we can return it + return *p; + } + /* -------------------------------------------------------------------------------------------- + * Retrieve entity instance which is native to the plug-in. + */ + SQMOD_NODISCARD LightObj & GetNative() const + { + return Core::Get().GetCheckpoint(GetIdentifier()).mObj; + } + // -------------------------------------------------------------------------------------------- + void SetWorld(int world) const { Get().SetWorld(world); } + void SetColor(const LgARGB & c) const { Get().SetColorEx4(c.r, c.g, c.b, c.a); } + void SetPos(const Vector3 & pos) const { Get().SetPosition(pos); } + void SetRadius(float radius) const { Get().SetRadius(radius); } + // -------------------------------------------------------------------------------------------- + SQMOD_NODISCARD int GetWorld() const { return Get().GetWorld(); } + SQMOD_NODISCARD LgARGB GetColor() const { const Color4 c = Get().GetColor(); return LgARGB(c.a, c.r, c.g, c.b); } + SQMOD_NODISCARD LgEntityVector GetPos() const + { return LgEntityVector(mID, LgEntityType::Checkpoint, 0, Get().GetPosition()); } + SQMOD_NODISCARD float GetRadius() const { return Get().GetRadius(); } + SQMOD_NODISCARD int GetID() const { return mID; } + SQMOD_NODISCARD LgPlayer * GetOwner() const + { const int id = Get().GetOwnerID(); return VALID_ENTITYEX(id, SQMOD_PLAYER_POOL) ? Core::Get().GetPlayer(id).mLgInst : nullptr; } + // -------------------------------------------------------------------------------------------- + void Delete() const { _Func->DeleteCheckPoint(GetIdentifier()); } + SQMOD_NODISCARD bool StreamedToPlayer(LgPlayer & player) const; +}; + +/* ------------------------------------------------------------------------------------------------ + * Object entity proxy. +*/ +struct LgObject +{ + int32_t mID; + /* -------------------------------------------------------------------------------------------- + * Base constructor. + */ + explicit LgObject(int32_t id) + : mID(id) + { + } + /* -------------------------------------------------------------------------------------------- + * Retrieve the a valid entity identifier, otherwise throw an exception. + */ + SQMOD_NODISCARD int32_t GetIdentifier() const + { + // Validate the associated identifier + if (INVALID_ENTITY(mID)) + { + STHROWF("Invalid object reference"); + } + // Return it + return mID; + } + /* -------------------------------------------------------------------------------------------- + * Retrieve the native implementation of the associated entity, otherwise throw an exception. + */ + SQMOD_NODISCARD CObject & Get() const + { + // Retrieve the associated instance + CObject * p = Core::Get().GetObj(GetIdentifier()).mInst; + // Validate the associated instance + if (!p) + { + STHROWF("Invalid object instance"); + } + // This is valid so we can return it + return *p; + } + /* -------------------------------------------------------------------------------------------- + * Retrieve entity instance which is native to the plug-in. + */ + SQMOD_NODISCARD LightObj & GetNative() const + { + return Core::Get().GetObj(GetIdentifier()).mObj; + } + // -------------------------------------------------------------------------------------------- + void SetWorld(int world) const { Get().SetWorld(world); } + void SetPos(const Vector3 & pos) const { Get().SetPosition(pos); } + void SetReportingShots(bool toggle) const { Get().SetShotReport(toggle); } + void SetReportingBumps(bool toggle) const { Get().SetTouchedReport(toggle); } + // -------------------------------------------------------------------------------------------- + SQMOD_NODISCARD int GetModel() const { return Get().GetModel(); } + SQMOD_NODISCARD int GetAlpha() const { return Get().GetAlpha(); } + SQMOD_NODISCARD int GetWorld() const { return Get().GetWorld(); } + SQMOD_NODISCARD LgEntityVector GetPos() const + { return LgEntityVector(mID, LgEntityType::Object, LgObjectVectorFlag::Pos, Get().GetPosition()); } + SQMOD_NODISCARD LgEntityQuaternion GetRotation() const + { return LgEntityQuaternion(mID, LgEntityType::Object, 0, Get().GetRotation()); } + SQMOD_NODISCARD LgEntityVector GetRotationEuler() const + { return LgEntityVector(mID, LgEntityType::Object, LgObjectVectorFlag::Rotation, Get().GetRotationEuler()); } + SQMOD_NODISCARD int GetID() const { return mID; } + SQMOD_NODISCARD bool GetReportingShots() const { return Get().GetShotReport(); } + SQMOD_NODISCARD bool GetReportingBumps() const { return Get().GetTouchedReport(); } + // -------------------------------------------------------------------------------------------- + void Delete() const { _Func->DeleteObject(GetIdentifier()); } + void MoveTo(const Vector3 & pos, int time) const { Get().MoveTo(pos, time); } + void MoveBy(const Vector3 & offset, int time) const { Get().MoveBy(offset, time); } + void RotateTo(const Quaternion & rotation, int time) const { Get().RotateTo(rotation, time); } + void RotateBy(const Quaternion & rotOffset, int time) const { Get().RotateBy(rotOffset, time); } + void RotateToEuler(const Vector3 & rotation, int time) const { Get().RotateToEuler(rotation, time); } + void RotateByEuler(const Vector3 & rotOffset, int time) const { Get().RotateByEuler(rotOffset, time); } + void SetAlpha(int alpha, int fadeTime) const { Get().SetAlphaEx(alpha, fadeTime); } + SQMOD_NODISCARD bool StreamedToPlayer(LgPlayer & player) const; +}; + +/* ------------------------------------------------------------------------------------------------ + * Pickup entity proxy. +*/ +struct LgPickup +{ + int32_t mID; + /* -------------------------------------------------------------------------------------------- + * Base constructor. + */ + explicit LgPickup(int32_t id) + : mID(id) + { + } + /* -------------------------------------------------------------------------------------------- + * Retrieve the a valid entity identifier, otherwise throw an exception. + */ + SQMOD_NODISCARD int32_t GetIdentifier() const + { + // Validate the associated identifier + if (INVALID_ENTITY(mID)) + { + STHROWF("Invalid pickup reference"); + } + // Return it + return mID; + } + /* -------------------------------------------------------------------------------------------- + * Retrieve the native implementation of the associated entity, otherwise throw an exception. + */ + SQMOD_NODISCARD CPickup & Get() const + { + // Retrieve the associated instance + CPickup * p = Core::Get().GetPickup(GetIdentifier()).mInst; + // Validate the associated instance + if (!p) + { + STHROWF("Invalid pickup instance"); + } + // This is valid so we can return it + return *p; + } + /* -------------------------------------------------------------------------------------------- + * Retrieve entity instance which is native to the plug-in. + */ + SQMOD_NODISCARD LightObj & GetNative() const + { + return Core::Get().GetPickup(GetIdentifier()).mObj; + } + // -------------------------------------------------------------------------------------------- + void SetWorld(int world) const { Get().SetWorld(world); } + void SetAlpha(int alpha) const { Get().SetAlpha(alpha); } + void SetAuto(bool toggle) const { Get().SetAutomatic(toggle); } + void SetAutoTimer(int timer) const { Get().SetAutoTimer(timer); } + void SetPos(const Vector3 & pos) const { Get().SetPosition(pos); } + void SetSingleUse(bool toggle) const { _Func->SetPickupOption(GetIdentifier(), vcmpPickupOptionSingleUse, toggle); } + // -------------------------------------------------------------------------------------------- + SQMOD_NODISCARD int GetWorld() const { return Get().GetWorld(); } + SQMOD_NODISCARD int GetAlpha() const { return Get().GetAlpha(); } + SQMOD_NODISCARD bool GetAuto() const { return Get().GetAutomatic(); } + SQMOD_NODISCARD int GetAutoTimer() const { return Get().GetAutoTimer(); } + SQMOD_NODISCARD LgEntityVector GetPos() const + { return LgEntityVector(mID, LgEntityType::Pickup, 0, Get().GetPosition()); } + SQMOD_NODISCARD int GetModel() const { return Get().GetModel(); } + SQMOD_NODISCARD int GetQuantity() const { return Get().GetQuantity(); } + SQMOD_NODISCARD int GetID() const { return mID; } + SQMOD_NODISCARD bool GetSingleUse() const { return _Func->GetPickupOption(GetIdentifier(), vcmpPickupOptionSingleUse) >= 1; } + // -------------------------------------------------------------------------------------------- + void Delete() const { _Func->DeletePickup(GetIdentifier()); } + void Respawn() const { Get().Refresh(); } + SQMOD_NODISCARD bool StreamedToPlayer(LgPlayer & player) const; +}; + +/* ------------------------------------------------------------------------------------------------ + * Player entity proxy. +*/ +struct LgPlayer +{ + int32_t mID; + /* -------------------------------------------------------------------------------------------- + * Base constructor. + */ + explicit LgPlayer(int32_t id) + : mID(id) + { + } + /* -------------------------------------------------------------------------------------------- + * Retrieve the a valid entity identifier, otherwise throw an exception. + */ + SQMOD_NODISCARD int32_t GetIdentifier() const + { + // Validate the associated identifier + if (INVALID_ENTITY(mID)) + { + STHROWF("Invalid player reference"); + } + // Return it + return mID; + } + /* -------------------------------------------------------------------------------------------- + * Retrieve the native implementation of the associated entity, otherwise throw an exception. + */ + SQMOD_NODISCARD CPlayer & Get() const + { + // Retrieve the associated instance + CPlayer * p = Core::Get().GetPlayer(GetIdentifier()).mInst; + // Validate the associated instance + if (!p) + { + STHROWF("Invalid player instance"); + } + // This is valid so we can return it + return *p; + } + /* -------------------------------------------------------------------------------------------- + * Retrieve entity instance which is native to the plug-in. + */ + SQMOD_NODISCARD LightObj & GetNative() const + { + return Core::Get().GetPlayer(GetIdentifier()).mObj; + } + // -------------------------------------------------------------------------------------------- + SQMOD_NODISCARD const SQChar * ToString() const { return INVALID_ENTITY(mID) ? Get().GetName() : _SC(""); } + // -------------------------------------------------------------------------------------------- + void SetName(StackStrF & name) const { Get().SetName(name); } + void SetPosition(const Vector3 & pos) const { Get().SetPosition(pos); } + void SetHealth(float health) const { Get().SetHealth(health); } + void SetArmour(float armour) const { Get().SetArmor(armour); } + void SetAdmin(bool toggle) const { Get().SetAdmin(toggle); } + void SetWorld(int world) const { Get().SetWorld(world); } + void SetSecWorld(int world) const { Get().SetSecondaryWorld(world); } + void SetTeam(int team) const { Get().SetTeam(team); } + void SetSkin(int skin) const { Get().SetSkin(skin); } + void SetColour(const LgRGB & colour) const { Get().SetColor(colour); } + void SetMoney(int money) const { Get().SetMoney(money); } + void SetScore(int score) const { Get().SetScore(score); } + void SetImmunity(uint32_t immunity) const { Get().SetImmunity(immunity); } + void SetHeading(float heading) const { Get().SetHeading(heading); } + void SetVehicle(LgVehicle & vehicle) const; + void SetFrozen(bool toggle) const { _Func->SetPlayerOption(GetIdentifier(), vcmpPlayerOptionControllable, !toggle); } + void SetDriveByEnabled(bool toggle) const { _Func->SetPlayerOption(GetIdentifier(), vcmpPlayerOptionDriveBy, toggle); } + void SetWhiteScanLines(bool toggle) const { _Func->SetPlayerOption(GetIdentifier(), vcmpPlayerOptionWhiteScanlines, toggle); } + void SetGreenScanLines(bool toggle) const { _Func->SetPlayerOption(GetIdentifier(), vcmpPlayerOptionGreenScanlines, toggle); } + void SetWidescreen(bool toggle) const { _Func->SetPlayerOption(GetIdentifier(), vcmpPlayerOptionWidescreen, toggle); } + void SetOnRadar(bool toggle) const { _Func->SetPlayerOption(GetIdentifier(), vcmpPlayerOptionHasMarker, toggle); } + void SetCanAttack(bool toggle) const { _Func->SetPlayerOption(GetIdentifier(), vcmpPlayerOptionCanAttack, toggle); } + void SetWeaponSlot(int slot) const { Get().SetWeaponSlot(slot); } + void ShowMarkers(bool toggle) const { _Func->SetPlayerOption(GetIdentifier(), vcmpPlayerOptionShowMarkers, toggle); } + void SetSpectateTarget(LgPlayer & player) const { Get().SetSpectator(player.Get()); } + void SetMarkerVisible(bool toggle) const { _Func->SetPlayerOption(GetIdentifier(), vcmpPlayerOptionHasMarker, toggle); } + void SetCanUseColors(bool toggle) const { _Func->SetPlayerOption(GetIdentifier(), vcmpPlayerOptionChatTagsEnabled, toggle); } + void SetDrunkStatus(bool toggle) const { _Func->SetPlayerOption(GetIdentifier(), vcmpPlayerOptionDrunkEffects, toggle); } + void SetWantedLevel(int level) const { Get().SetWantedLevel(level); } + // -------------------------------------------------------------------------------------------- + SQMOD_NODISCARD LgEntityVector GetPosition() const + { return LgEntityVector(mID, LgEntityType::Player, LgPlayerVectorFlag::Pos, Get().GetPosition()); } + SQMOD_NODISCARD int GetClass() const { return Get().GetClass(); } + SQMOD_NODISCARD bool GetAdmin() const { return Get().GetAdmin(); } + SQMOD_NODISCARD const SQChar * GetIP() const { return Get().GetIP(); } + SQMOD_NODISCARD bool GetSpawned() const { return Get().IsSpawned(); } + SQMOD_NODISCARD int GetWorld() const { return Get().GetWorld(); } + SQMOD_NODISCARD int GetSecWorld() const { return Get().GetSecondaryWorld(); } + SQMOD_NODISCARD int GetUniqueWorld() const { return Get().GetUniqueWorld(); } + SQMOD_NODISCARD int GetState() const { return Get().GetState(); } + SQMOD_NODISCARD const SQChar * GetName() const { return Get().GetName(); } + SQMOD_NODISCARD int GetTeam() const { return Get().GetTeam(); } + SQMOD_NODISCARD int GetSkin() const { return Get().GetSkin(); } + SQMOD_NODISCARD LgEntityRGB GetColour() const { return LgEntityRGB(mID, LgEntityType::Player, 0, Get().GetColor()); } + SQMOD_NODISCARD int GetMoney() const { return Get().GetMoney(); } + SQMOD_NODISCARD int GetScore() const { return Get().GetScore(); } + SQMOD_NODISCARD int GetPing() const { return Get().GetPing(); } + SQMOD_NODISCARD float GetHealth() const { return Get().GetHealth(); } + SQMOD_NODISCARD float GetArmour() const { return Get().GetArmor(); } + SQMOD_NODISCARD int32_t GetImmunity() const { return Get().GetImmunity(); } + SQMOD_NODISCARD float GetHeading() const { return Get().GetHeading(); } + SQMOD_NODISCARD LgVehicle * GetVehicle() const + { const int id = _Func->GetPlayerVehicleId(GetIdentifier()); return VALID_ENTITYEX(id, SQMOD_VEHICLE_POOL) ? Core::Get().GetVehicle(id).mLgInst : nullptr; } + SQMOD_NODISCARD bool GetFrozen() const { return _Func->GetPlayerOption(GetIdentifier(), vcmpPlayerOptionControllable) <= 0; } + SQMOD_NODISCARD bool GetDriveByEnabled() const { return _Func->GetPlayerOption(GetIdentifier(), vcmpPlayerOptionDriveBy) >= 1; } + SQMOD_NODISCARD bool GetWhiteScanLines() const { return _Func->GetPlayerOption(GetIdentifier(), vcmpPlayerOptionWhiteScanlines) >= 1; } + SQMOD_NODISCARD bool GetGreenScanLines() const { return _Func->GetPlayerOption(GetIdentifier(), vcmpPlayerOptionGreenScanlines) >= 1; } + SQMOD_NODISCARD bool GetWidescreen() const { return _Func->GetPlayerOption(GetIdentifier(), vcmpPlayerOptionWidescreen) >= 1; } + SQMOD_NODISCARD bool GetOnRadar() const { return _Func->GetPlayerOption(GetIdentifier(), vcmpPlayerOptionHasMarker) >= 1; } + SQMOD_NODISCARD bool GetCanAttack() const { return _Func->GetPlayerOption(GetIdentifier(), vcmpPlayerOptionCanAttack) >= 1; } + SQMOD_NODISCARD int GetVehicleSlot() const { return Get().GetVehicleSlot(); } + SQMOD_NODISCARD int GetVehicleStatus() const { return Get().GetVehicleStatus(); } + SQMOD_NODISCARD int GetWeaponSlot() const { return Get().GetWeaponSlot(); } + SQMOD_NODISCARD int GetWeapon() const { return Get().GetWeapon(); } + SQMOD_NODISCARD int GetWeaponAmmo() const { return Get().GetAmmo(); } + SQMOD_NODISCARD int GetAlpha() const { return Get().GetAlpha(); } + SQMOD_NODISCARD int GetID() const { return mID; } + SQMOD_NODISCARD bool Typing() const { return Get().IsTyping(); } + SQMOD_NODISCARD bool ShowingMarkers() const { return _Func->GetPlayerOption(GetIdentifier(), vcmpPlayerOptionShowMarkers) >= 1; } + SQMOD_NODISCARD bool GetCameraLocked() const { return Get().IsCameraLocked(); } + SQMOD_NODISCARD int GetKey() const { return Get().GetKey(); } + SQMOD_NODISCARD bool GetAwayStatus() const { return Get().IsAway(); } + SQMOD_NODISCARD LgPlayer * GetSpectateTarget() const + { const int id = _Func->GetPlayerSpectateTarget(GetIdentifier()); return VALID_ENTITYEX(id, SQMOD_PLAYER_POOL) ? Core::Get().GetPlayer(id).mLgInst : nullptr; } + SQMOD_NODISCARD LgEntityVector GetSpeed() const + { return LgEntityVector(mID, LgEntityType::Player, LgPlayerVectorFlag::Speed, Get().GetSpeed()); } + SQMOD_NODISCARD bool GetCanUseColors() const { return _Func->GetPlayerOption(GetIdentifier(), vcmpPlayerOptionChatTagsEnabled) >= 1; } + SQMOD_NODISCARD bool GetMarkerVisible() const { return _Func->GetPlayerOption(GetIdentifier(), vcmpPlayerOptionHasMarker) >= 1; } + SQMOD_NODISCARD bool GetDrunkStatus() const { return _Func->GetPlayerOption(GetIdentifier(), vcmpPlayerOptionDrunkEffects) >= 1; } + SQMOD_NODISCARD double GetFPS() const { return Get().GetFPS(); } + SQMOD_NODISCARD const SQChar * GetUniqueID() const { return Get().GetUID(); } + SQMOD_NODISCARD const SQChar * GetUniqueID2() const { return Get().GetUID2(); } + SQMOD_NODISCARD bool GetPlayerOnFireStatus() const { return Get().IsBurning(); } + SQMOD_NODISCARD bool GetPlayerCrouchStatus() const { return Get().IsCrouched(); } + SQMOD_NODISCARD int GetPlayerAction() const { return Get().GetAction(); } + SQMOD_NODISCARD int GetPlayerGameKeys() const { return Get().GetGameKeys(); } + SQMOD_NODISCARD LgVector GetPlayerAimPos() const { return LgVector(Get().GetAimPosition()); } + SQMOD_NODISCARD LgVector GetPlayerAimDir() const { return LgVector(Get().GetAimDirection()); } + SQMOD_NODISCARD int GetWantedLevel() const { return Get().GetWantedLevel(); } + // -------------------------------------------------------------------------------------------- + void PlaySound(int sound) const { Get().PlaySound(sound); } + void Kick() const { Get().Kick(); } + void Ban() const { Get().Ban(); } + void Spawn() const { Get().ForceSpawn(); } + void GiveMoney(int money) const { Get().GiveMoney(money); } + void AddSpeed(const Vector3 & speed) const { Get().AddSpeed(speed); } + void SetSpeed(const Vector3 & speed) const { Get().SetSpeed(speed); } + void Eject() const { Get().Disembark(); } + void SetCameraPos(const Vector3 & pos, const Vector3 & look) const { Get().SetCameraPosition(pos, look); } + void Disarm() const { Get().StripWeapons(); } + void CompatAnimation(int anim) const { Get().SetAnimation(anim); } + void Animation(int group, int anim) const { Get().SetAnimationEx(anim, group); } + SQMOD_NODISCARD LgVehicle * StandingOnVehicle() const + { const int id = _Func->GetPlayerStandingOnVehicle(GetIdentifier()); return VALID_ENTITYEX(id, SQMOD_VEHICLE_POOL) ? Core::Get().GetVehicle(id).mLgInst : nullptr; } + SQMOD_NODISCARD LgObject * StandingOnObject() const + { const int id = _Func->GetPlayerStandingOnObject(GetIdentifier()); return VALID_ENTITYEX(id, SQMOD_OBJECT_POOL) ? Core::Get().GetObj(id).mLgInst : nullptr; } + void GiveWeapon(int weapon, int ammo) const { Get().GiveWeapon(weapon, ammo); } + void SetWeapon(int weapon, int ammo) const { Get().SetWeaponEx(weapon, ammo); } + void RemoveWeapon(int weapon) const { Get().RemoveWeapon(weapon); } + SQMOD_NODISCARD int GetWeaponAtSlot(int slot) const { return Get().GetWeaponAtSlot(slot); } + SQMOD_NODISCARD int GetAmmoAtSlot(int slot) const { return Get().GetAmmoAtSlot(slot); } + void SetAlpha(int alpha, int fadeTime) const { Get().SetAlphaEx(alpha, fadeTime); } + SQMOD_NODISCARD bool StreamedToPlayer(const LgPlayer & player) const { return Get().IsStreamedFor(player.Get()); } + void SetVehicleSlot(const LgVehicle & vehicle, int slot) const; + void Select() const { Get().ForceSelect(); } + void RestoreCamera() const { Get().RestoreCamera(); } + void RemoveMarker() const { _Func->SetPlayerOption(GetIdentifier(), vcmpPlayerOptionHasMarker, 0); } + void SetMarker(int toggle) const { _Func->SetPlayerOption(GetIdentifier(), vcmpPlayerOptionShowMarkers, toggle); } + void SetDrunkLevel(int visuals, int handling) const { + if (visuals <= 0 && handling <= 0) _Func->SetPlayerOption(GetIdentifier(), vcmpPlayerOptionDrunkEffects, 0); + else _Func->SetPlayerOption(GetIdentifier(), vcmpPlayerOptionDrunkEffects, 1); + } + void RedirectPlayerToServer(StackStrF & ip, unsigned int port, StackStrF & nick, StackStrF & spass, StackStrF & upass) const + { Get().Redirect(ip, port, nick, spass, upass); } + void RequestModuleList() const { Get().GetModuleList(); } +}; + +/* ------------------------------------------------------------------------------------------------ + * Vehicle entity proxy. +*/ +struct LgVehicle +{ + int32_t mID; + /* -------------------------------------------------------------------------------------------- + * Base constructor. + */ + explicit LgVehicle(int32_t id) + : mID(id) + { + } + /* -------------------------------------------------------------------------------------------- + * Retrieve the a valid entity identifier, otherwise throw an exception. + */ + SQMOD_NODISCARD int32_t GetIdentifier() const + { + // Validate the associated identifier + if (INVALID_ENTITY(mID)) + { + STHROWF("Invalid vehicle reference"); + } + // Return it + return mID; + } + /* -------------------------------------------------------------------------------------------- + * Retrieve the native implementation of the associated entity, otherwise throw an exception. + */ + SQMOD_NODISCARD CVehicle & Get() const + { + // Retrieve the associated instance + CVehicle * p = Core::Get().GetVehicle(GetIdentifier()).mInst; + // Validate the associated instance + if (!p) + { + STHROWF("Invalid vehicle instance"); + } + // This is valid so we can return it + return *p; + } + /* -------------------------------------------------------------------------------------------- + * Retrieve entity instance which is native to the plug-in. + */ + SQMOD_NODISCARD LightObj & GetNative() const + { + return Core::Get().GetVehicle(GetIdentifier()).mObj; + } + // -------------------------------------------------------------------------------------------- + SQMOD_NODISCARD static int32_t GetDriverID(int32_t id) { + for(int i = 0, n = _Func->GetMaxPlayers(); i < n; ++i) { + if(_Func->IsPlayerConnected(i)) { + if(_Func->GetPlayerVehicleId(i) == id && _Func->GetPlayerInVehicleSlot(i) == 0) return i; + } + } + return -1; + } + // -------------------------------------------------------------------------------------------- + void SetWorld(int world) const { Get().SetWorld(world); } + void SetImmunity(int immunity) const { Get().SetImmunity(immunity); } + void SetPosition(const Vector3 & pos) const { Get().SetPosition(pos); } + void SetSpawnPos(const Vector3 & pos) const { Get().SetSpawnPosition(pos); } + void SetSpawnAngle(const Quaternion & angle) const { Get().SetSpawnRotation(angle); } + void SetSpawnAngleEuler(const Vector3 & angle) const { Get().SetSpawnRotationEuler(angle); } + void SetIdleRespawnTimer(uint32_t time) const { Get().SetIdleRespawnTimer(time); } + void SetHealth(float health) const { Get().SetHealth(health); } + void SetColour1(int colour1) const { Get().SetPrimaryColor(colour1); } + void SetColour2(int colour2) const { Get().SetSecondaryColor(colour2); } + void SetLocked(bool toggle) const { _Func->SetVehicleOption(GetIdentifier(), vcmpVehicleOptionDoorsLocked, toggle); } + void SetDamage(uint32_t damage) const { Get().SetDamageData(damage); } + void SetLightFlags(uint32_t flags) const { Get().SetLightsData(flags); } + void SetAlarm(bool toggle) const { _Func->SetVehicleOption(GetIdentifier(), vcmpVehicleOptionAlarm, toggle ); } + void SetSiren(bool toggle) const { _Func->SetVehicleOption(GetIdentifier(), vcmpVehicleOptionSiren, toggle); } + void SetLights(bool toggle) const { _Func->SetVehicleOption(GetIdentifier(), vcmpVehicleOptionLights, toggle ); } + void SetRotation(const Quaternion & rotation) const { Get().SetRotation(rotation); } + void SetEulerRotation(const Vector3 & angle) const { Get().SetRotationEuler(angle); } + void SetSpeed(const Vector3 & speed) const { Get().SetSpeed(speed); } + void SetRelativeSpeed(const Vector3 & speed) const { Get().SetRelativeSpeed(speed); } + void SetTurnSpeed(const Vector3 & speed) const { Get().SetTurnSpeed(speed); } + void SetRelativeTurnSpeed(const Vector3 & speed) const { Get().SetRelativeTurnSpeed(speed); } + void SetRadio(int id) const { Get().SetRadio(id); } + void SetRadioLocked(bool toggle) const { _Func->SetVehicleOption(GetIdentifier(), vcmpVehicleOptionRadioLocked, toggle); } + void SetGhost(bool toggle) const { _Func->SetVehicleOption(GetIdentifier(), vcmpVehicleOptionGhost, toggle); } + void SetSingleUse(bool toggle) const { _Func->SetVehicleOption(GetIdentifier(), vcmpVehicleOptionSingleUse, toggle); } + void SetTaxiLight(bool toggle) const { + if (toggle == (GetTaxiLight() != 0)) return; + uint32_t data = _Func->GetVehicleLightsData(GetIdentifier()); + if (toggle) data |= (1 << 8); + else data &= ~(1 << 8); + _Func->SetVehicleLightsData(GetIdentifier(), data); + } + // -------------------------------------------------------------------------------------------- + SQMOD_NODISCARD int GetWorld() const { return Get().GetWorld(); } + SQMOD_NODISCARD int GetModel() const { return Get().GetModel(); } + SQMOD_NODISCARD int GetImmunity() const { return Get().GetImmunity(); } + SQMOD_NODISCARD LgEntityVector GetPosition() const + { return LgEntityVector(mID, LgEntityType::Vehicle, LgVehicleVectorFlag::Pos, Get().GetPosition()); } + SQMOD_NODISCARD LgEntityVector GetSpawnPos() const + { return LgEntityVector(mID, LgEntityType::Vehicle, LgVehicleVectorFlag::SpawnPos, Get().GetSpawnPosition()); } + SQMOD_NODISCARD LgEntityQuaternion GetSpawnAngle() const + { return LgEntityQuaternion(mID, LgEntityType::Vehicle, LgVehicleQuaternionFlag::SpawnAngle, Get().GetSpawnRotation()); } + SQMOD_NODISCARD LgEntityVector GetSpawnAngleEuler() const + { return LgEntityVector(mID, LgEntityType::Vehicle, LgVehicleVectorFlag::SpawnAngle, Get().GetSpawnRotationEuler()); } + SQMOD_NODISCARD uint32_t GetIdleRespawnTimer() const { return Get().GetIdleRespawnTimer(); } + SQMOD_NODISCARD float GetHealth() const { return Get().GetHealth(); } + SQMOD_NODISCARD int GetColour1() const { return Get().GetPrimaryColor(); } + SQMOD_NODISCARD int GetColour2() const { return Get().GetSecondaryColor(); } + SQMOD_NODISCARD bool GetLocked() const { return _Func->GetVehicleOption(GetIdentifier(), vcmpVehicleOptionDoorsLocked) >= 1; } + SQMOD_NODISCARD uint32_t GetDamage() const { return Get().GetDamageData(); } + SQMOD_NODISCARD uint32_t GetLightFlags() const { return Get().GetLightsData(); } + SQMOD_NODISCARD bool GetAlarm() const { return _Func->GetVehicleOption(GetIdentifier(), vcmpVehicleOptionAlarm) >= 1; } + SQMOD_NODISCARD bool GetSiren() const { return _Func->GetVehicleOption(GetIdentifier(), vcmpVehicleOptionSiren) >= 1; } + SQMOD_NODISCARD bool GetLights() const { return _Func->GetVehicleOption(GetIdentifier(), vcmpVehicleOptionLights) >= 1; } + SQMOD_NODISCARD LgPlayer * GetDriver() const + { const int id = GetDriverID(GetIdentifier()); return VALID_ENTITYEX(id, SQMOD_PLAYER_POOL) ? Core::Get().GetPlayer(id).mLgInst : nullptr; } + SQMOD_NODISCARD int GetID() const { return mID; } + SQMOD_NODISCARD int GetSyncSource() const { return Get().GetSyncSource(); } + SQMOD_NODISCARD int GetSyncType() const { return Get().GetSyncType(); } + SQMOD_NODISCARD bool GetWrecked() const { return Get().IsWrecked(); } + SQMOD_NODISCARD LgEntityQuaternion GetRotation() const + { return LgEntityQuaternion(mID, LgEntityType::Vehicle, LgVehicleQuaternionFlag::Angle, Get().GetRotation()); } + SQMOD_NODISCARD LgEntityVector GetEulerRotation() const + { return LgEntityVector(mID, LgEntityType::Vehicle, LgVehicleVectorFlag::Angle, Get().GetRotationEuler()); } + SQMOD_NODISCARD LgEntityVector GetSpeed() const + { return LgEntityVector(mID, LgEntityType::Vehicle, LgVehicleVectorFlag::Speed, Get().GetSpeed()); } + SQMOD_NODISCARD LgEntityVector GetRelativeSpeed() const + { return LgEntityVector(mID, LgEntityType::Vehicle, LgVehicleVectorFlag::RelSpeed, Get().GetRelativeSpeed()); } + SQMOD_NODISCARD LgEntityVector GetTurnSpeed() const + { return LgEntityVector(mID, LgEntityType::Vehicle, LgVehicleVectorFlag::TurnSpeed, Get().GetTurnSpeed()); } + SQMOD_NODISCARD LgEntityVector GetRelativeTurnSpeed() const + { return LgEntityVector(mID, LgEntityType::Vehicle, LgVehicleVectorFlag::RelTurnSpeed, Get().GetRelativeTurnSpeed()); } + SQMOD_NODISCARD int GetRadio() const { return Get().GetRadio(); } + SQMOD_NODISCARD bool GetRadioLockStatus() const { return _Func->GetVehicleOption(GetIdentifier(), vcmpVehicleOptionRadioLocked) >= 1; } + SQMOD_NODISCARD bool GetGhost() const { return _Func->GetVehicleOption(GetIdentifier(), vcmpVehicleOptionGhost) >= 1; } + SQMOD_NODISCARD LgVector GetTurretRotation() const { const Vector2 v = Get().GetTurretRotation(); return LgVector(v.x, v.y, 0); } + SQMOD_NODISCARD bool GetSingleUse() const { return _Func->GetVehicleOption(GetIdentifier(), vcmpVehicleOptionSingleUse) >= 1; } + SQMOD_NODISCARD bool GetTaxiLight() const { return (_Func->GetVehicleLightsData(GetIdentifier()) & (1 << 8)) != 0; } + // -------------------------------------------------------------------------------------------- + void Delete() const { _Func->DeleteVehicle(GetIdentifier()); } + void Fix() const { Get().Fix(); } + void Respawn() const { Get().Respawn(); } + void Kill() const { Get().Explode(); } + void SetFlatTyres(bool toggle) const { Get().FlattenTyres(toggle); } + SQMOD_NODISCARD int GetPartStatus(int part) const { return Get().GetPartStatus(part); } + void SetPartStatus(int part, int status) const { Get().SetPartStatus(part, status); } + SQMOD_NODISCARD int GetTyreStatus(int tyre) const { return Get().GetTyreStatus(tyre); } + void SetTyreStatus(int part, int status) const { Get().SetTyreStatus(part, status); } + SQMOD_NODISCARD bool GetStreamedForPlayer(LgPlayer & player) const { return Get().IsStreamedFor(player.Get()); } + SQMOD_NODISCARD LgPlayer * GetOccupant(int slot) const + { const int id = _Func->GetVehicleOccupant(GetIdentifier(), slot); return VALID_ENTITYEX(id, SQMOD_PLAYER_POOL) ? Core::Get().GetPlayer(id).mLgInst : nullptr; } + void SetHandlingData(int rule, float value) const { Get().SetHandlingRule(rule, value); } + SQMOD_NODISCARD double GetHandlingData(int rule) const { return Get().GetHandlingRule(rule); } + void ResetHandlingData(int rule) const { Get().ResetHandlingRule(rule); } + void ResetAllHandling() const { Get().ResetHandlings(); } + SQMOD_NODISCARD bool IsHandlingSet(int rule) const { return Get().ExistsHandlingRule(rule); } + // -------------------------------------------------------------------------------------------- + void AddVehicleSpeed(const Vector3 & speed) const { Get().SetSpeed(speed); } + void AddVehicleRelSpeed(const Vector3 & speed) const { Get().SetRelativeSpeed(speed); } + void AddVehicleTurnSpeed(const Vector3 & speed) const { Get().SetTurnSpeed(speed); } + void AddVehicleRelTurnSpeed(const Vector3 & speed) const { Get().SetRelativeTurnSpeed(speed); } +}; + +// ------------------------------------------------------------------------------------------------ +inline bool LgCheckpoint::StreamedToPlayer(LgPlayer & player) const { return Get().IsStreamedFor(player.Get()); } +inline bool LgObject::StreamedToPlayer(LgPlayer & player) const { return Get().IsStreamedFor(player.Get()); } +inline bool LgPickup::StreamedToPlayer(LgPlayer & player) const { return Get().IsStreamedFor(player.Get()); } +inline void LgPlayer::SetVehicle(LgVehicle & vehicle) const { Get().Embark(vehicle.Get()); } +inline void LgPlayer::SetVehicleSlot(const LgVehicle & vehicle, int slot) const { Get().EmbarkEx(vehicle.Get(), slot, true, false); } + +// ------------------------------------------------------------------------------------------------ +void LgCheckpointSetID(LgCheckpoint * inst, int32_t id) { assert(inst); if (inst) inst->mID = id; } +void LgObjectSetID(LgObject * inst, int32_t id) { assert(inst); if (inst) inst->mID = id; } +void LgPickupSetID(LgPickup * inst, int32_t id) { assert(inst); if (inst) inst->mID = id; } +void LgPlayerSetID(LgPlayer * inst, int32_t id) { assert(inst); if (inst) inst->mID = id; } +void LgVehicleSetID(LgVehicle * inst, int32_t id) { assert(inst); if (inst) inst->mID = id; } + +// ------------------------------------------------------------------------------------------------ +LightObj LgCheckpointObj(HSQUIRRELVM vm, int32_t id) { return LightObj(SqTypeIdentity< LgCheckpoint >{}, vm, id); } +LightObj LgObjectObj(HSQUIRRELVM vm, int32_t id) { return LightObj(SqTypeIdentity< LgObject >{}, vm, id); } +LightObj LgPickupObj(HSQUIRRELVM vm, int32_t id) { return LightObj(SqTypeIdentity< LgPickup >{}, vm, id); } +LightObj LgPlayerObj(HSQUIRRELVM vm, int32_t id) { return LightObj(SqTypeIdentity< LgPlayer >{}, vm, id); } +LightObj LgVehicleObj(HSQUIRRELVM vm, int32_t id) { return LightObj(SqTypeIdentity< LgVehicle >{}, vm, id); } + +// ================================================================================================ +void Register_Official_Entity(HSQUIRRELVM vm) +{ + // -------------------------------------------------------------------------------------------- + Class< LgCheckpoint, NoConstructor< LgCheckpoint > > checkpoint(vm, "CCheckpoint_INTERNAL"); + // Read-write properties + checkpoint + .Prop(_SC("World"), &LgCheckpoint::GetWorld, &LgCheckpoint::SetWorld) + .Prop(_SC("Color"), &LgCheckpoint::GetColor, &LgCheckpoint::SetColor) + .Prop(_SC("Radius"), &LgCheckpoint::GetRadius, &LgCheckpoint::SetRadius) + .Prop(_SC("Pos"), &LgCheckpoint::GetPos, &LgCheckpoint::SetPos) + ; + // Read-only properties + checkpoint + .Prop(_SC("Native"), &LgCheckpoint::GetNative) + .Prop(_SC("ID"), &LgCheckpoint::GetID) + .Prop(_SC("Owner"), &LgCheckpoint::GetOwner) + ; + // Functions + checkpoint + .SquirrelFunc(_SC("_typename"), &CCheckpointTn::Fn) + .Func(_SC("Remove"), &LgCheckpoint::Delete) + .Func(_SC("StreamedToPlayer"), &LgCheckpoint::StreamedToPlayer) + ; + RootTable(vm).Bind(_SC("CCheckpoint"), checkpoint); + // -------------------------------------------------------------------------------------------- + Class< LgObject, NoConstructor< LgObject > > object(vm, "CObject_INTERNAL"); + // Read-write properties + object + .Prop(_SC("World"), &LgObject::GetWorld, &LgObject::SetWorld) + .Prop(_SC("Pos"), &LgObject::GetPos, &LgObject::SetPos) + .Prop(_SC("TrackingShots"), &LgObject::GetReportingShots, &LgObject::SetReportingShots) + .Prop(_SC("TrackingBumps"), &LgObject::GetReportingBumps, &LgObject::SetReportingBumps) + ; + // Read-only properties + object + .Prop(_SC("Native"), &LgObject::GetNative) + .Prop(_SC("Alpha"), &LgObject::GetAlpha) + .Prop(_SC("Model"), &LgObject::GetModel) + .Prop(_SC("Rotation"), &LgObject::GetRotation) + .Prop(_SC("RotationEuler"), &LgObject::GetRotationEuler) + .Prop(_SC("ID"), &LgObject::GetID) + ; + // Functions + object + .SquirrelFunc(_SC("_typename"), &CObjectTn::Fn) + .Func(_SC("Delete"), &LgObject::Delete) + .Func(_SC("MoveTo"), &LgObject::MoveTo) + .Func(_SC("MoveBy"), &LgObject::MoveBy) + .Func(_SC("RotateTo"), &LgObject::RotateTo) + .Func(_SC("RotateBy"), &LgObject::RotateBy) + .Func(_SC("RotateToEuler"), &LgObject::RotateToEuler) + .Func(_SC("RotateByEuler"), &LgObject::RotateByEuler) + .Func(_SC("SetAlpha"), &LgObject::SetAlpha) + .Func(_SC("StreamedToPlayer"), &LgObject::StreamedToPlayer) + ; + RootTable(vm).Bind(_SC("CObject"), object); + // -------------------------------------------------------------------------------------------- + Class< LgPickup, NoConstructor< LgPickup > > pickup(vm, "CPickup_INTERNAL"); + // Read-write properties + pickup + .Prop(_SC("World"), &LgPickup::GetWorld, &LgPickup::SetWorld) + .Prop(_SC("Alpha"), &LgPickup::GetAlpha, &LgPickup::SetAlpha) + .Prop(_SC("Automatic"), &LgPickup::GetAuto, &LgPickup::SetAuto) + .Prop(_SC("Timer"), &LgPickup::GetAutoTimer, &LgPickup::SetAutoTimer) + .Prop(_SC("RespawnTime"), &LgPickup::GetAutoTimer, &LgPickup::SetAutoTimer) + .Prop(_SC("Pos"), &LgPickup::GetPos, &LgPickup::SetPos) + .Prop(_SC("SingleUse"), &LgPickup::GetSingleUse, &LgPickup::SetSingleUse) + ; + // Read-only properties + pickup + .Prop(_SC("Native"), &LgPickup::GetNative) + .Prop(_SC("Model"), &LgPickup::GetModel) + .Prop(_SC("Quantity"), &LgPickup::GetQuantity) + .Prop(_SC("ID"), &LgPickup::GetID) + ; + // Functions + pickup + .SquirrelFunc(_SC("_typename"), &CPickupTn::Fn) + .Func(_SC("Remove"), &LgPickup::Delete) + .Func(_SC("Respawn"), &LgPickup::Respawn) + .Func(_SC("StreamedToPlayer"), &LgPickup::StreamedToPlayer) + ; + RootTable(vm).Bind(_SC("CPickup"), pickup); + // -------------------------------------------------------------------------------------------- + Class< LgPlayer, NoConstructor< LgPlayer > > player(vm, "CPlayer_INTERNAL"); + // Read-write properties + player + .Prop(_SC("Admin"), &LgPlayer::GetAdmin, &LgPlayer::SetAdmin) + .Prop(_SC("Angle"), &LgPlayer::GetHeading, &LgPlayer::SetHeading) + .Prop(_SC("Armor"), &LgPlayer::GetArmour, &LgPlayer::SetArmour) + .Prop(_SC("Armour"), &LgPlayer::GetArmour, &LgPlayer::SetArmour) + .Prop(_SC("CanAttack"), &LgPlayer::GetCanAttack, &LgPlayer::SetCanAttack) + .Prop(_SC("CanDriveby"), &LgPlayer::GetDriveByEnabled, &LgPlayer::SetDriveByEnabled) + .Prop(_SC("Cash"), &LgPlayer::GetMoney, &LgPlayer::SetMoney) + .Prop(_SC("Color"), &LgPlayer::GetColour, &LgPlayer::SetColour) + .Prop(_SC("Colour"), &LgPlayer::GetColour, &LgPlayer::SetColour) + .Prop(_SC("DrivebyAbility"), &LgPlayer::GetDriveByEnabled, &LgPlayer::SetDriveByEnabled) + .Prop(_SC("Frozen"), &LgPlayer::GetFrozen, &LgPlayer::SetFrozen) + .Prop(_SC("GreenScanlines"), &LgPlayer::GetGreenScanLines, &LgPlayer::SetGreenScanLines) + .Prop(_SC("HasChatTags"), &LgPlayer::GetCanUseColors, &LgPlayer::SetCanUseColors) + .Prop(_SC("HasMarker"), &LgPlayer::GetMarkerVisible, &LgPlayer::SetMarkerVisible) + .Prop(_SC("Heading"), &LgPlayer::GetHeading, &LgPlayer::SetHeading) + .Prop(_SC("Health"), &LgPlayer::GetHealth, &LgPlayer::SetHealth) + .Prop(_SC("Immunity"), &LgPlayer::GetImmunity, &LgPlayer::SetImmunity) + .Prop(_SC("IsAdmin"), &LgPlayer::GetAdmin, &LgPlayer::SetAdmin) + .Prop(_SC("IsDrunk"), &LgPlayer::GetDrunkStatus, &LgPlayer::SetDrunkStatus) + .Prop(_SC("IsFrozen"), &LgPlayer::GetFrozen, &LgPlayer::SetFrozen) + .Prop(_SC("IsOnRadar"), &LgPlayer::GetOnRadar, &LgPlayer::SetOnRadar) + .Prop(_SC("IsWeaponSyncBlocked"), &LgPlayer::GetCanAttack, &LgPlayer::SetCanAttack) + .Prop(_SC("Money"), &LgPlayer::GetMoney, &LgPlayer::SetMoney) + .Prop(_SC("Name"), &LgPlayer::GetName, &LgPlayer::SetName) + .Prop(_SC("Pos"), &LgPlayer::GetPosition, &LgPlayer::SetPosition) + .Prop(_SC("Score"), &LgPlayer::GetScore, &LgPlayer::SetScore) + .Prop(_SC("SecWorld"), &LgPlayer::GetSecWorld, &LgPlayer::SetSecWorld) + .Prop(_SC("ShowMarkers"), &LgPlayer::ShowingMarkers, &LgPlayer::ShowMarkers) + .Prop(_SC("Slot"), &LgPlayer::GetWeaponSlot, &LgPlayer::SetWeaponSlot) + .Prop(_SC("Skin"), &LgPlayer::GetSkin, &LgPlayer::SetSkin) + .Prop(_SC("SpectateTarget"), &LgPlayer::GetSpectateTarget, &LgPlayer::SetSpectateTarget) + .Prop(_SC("Speed"), &LgPlayer::GetSpeed, &LgPlayer::SetSpeed ) + .Prop(_SC("Team"), &LgPlayer::GetTeam, &LgPlayer::SetTeam) + .Prop(_SC("Vehicle"), &LgPlayer::GetVehicle, &LgPlayer::SetVehicle) + .Prop(_SC("WantedLevel"), &LgPlayer::GetWantedLevel, &LgPlayer::SetWantedLevel) + .Prop(_SC("WhiteScanlines"), &LgPlayer::GetWhiteScanLines, &LgPlayer::SetWhiteScanLines) + .Prop(_SC("Widescreen"), &LgPlayer::GetWidescreen, &LgPlayer::SetWidescreen) + .Prop(_SC("World"), &LgPlayer::GetWorld, &LgPlayer::SetWorld) + ; + // Read-only properties + player + .Prop(_SC("Native"), &LgPlayer::GetNative) + .Prop(_SC("Action"), &LgPlayer::GetPlayerAction) + .Prop(_SC("AimDir"), &LgPlayer::GetPlayerAimDir) + .Prop(_SC("AimPos"), &LgPlayer::GetPlayerAimPos) + .Prop(_SC("Alpha"), &LgPlayer::GetAlpha) + .Prop(_SC("Ammo"), &LgPlayer::GetWeaponAmmo) + .Prop(_SC("Away"), &LgPlayer::GetAwayStatus) + .Prop(_SC("CameraLocked"), &LgPlayer::GetCameraLocked) + .Prop(_SC("Class"), &LgPlayer::GetClass) + .Prop(_SC("FPS"), &LgPlayer::GetFPS) + .Prop(_SC("GameKeys"), &LgPlayer::GetPlayerGameKeys) + .Prop(_SC("ID"), &LgPlayer::GetID) + .Prop(_SC("IP"), &LgPlayer::GetIP) + .Prop(_SC("IsCrouching"), &LgPlayer::GetPlayerCrouchStatus) + .Prop(_SC("IsOnFire"), &LgPlayer::GetPlayerOnFireStatus) + .Prop(_SC("IsSpawned"), &LgPlayer::GetSpawned) + .Prop(_SC("Key"), &LgPlayer::GetKey) + .Prop(_SC("Ping"), &LgPlayer::GetPing) + .Prop(_SC("Spawned"), &LgPlayer::GetSpawned) + .Prop(_SC("StandingOnObject"), &LgPlayer::StandingOnObject) + .Prop(_SC("StandingOnVehicle"), &LgPlayer::StandingOnVehicle) + .Prop(_SC("State"), &LgPlayer::GetState) + .Prop(_SC("Typing"), &LgPlayer::Typing) + .Prop(_SC("UniqueWorld"), &LgPlayer::GetUniqueWorld) + .Prop(_SC("UniqueID"), &LgPlayer::GetUniqueID) + .Prop(_SC("UID"), &LgPlayer::GetUniqueID) + .Prop(_SC("UniqueID2"), &LgPlayer::GetUniqueID2) + .Prop(_SC("UID2"), &LgPlayer::GetUniqueID2) + .Prop(_SC("VehicleSlot"), &LgPlayer::GetVehicleSlot) + .Prop(_SC("VehicleStatus"), &LgPlayer::GetVehicleStatus) + .Prop(_SC("Weapon"), &LgPlayer::GetWeapon) + ; + // Functions + player + .SquirrelFunc(_SC("_typename"), &CPlayerTn::Fn) + .Func(_SC("_tostring"), &LgPlayer::ToString) + .Func(_SC("AddSpeed"), &LgPlayer::AddSpeed) + .Func(_SC("Ban"), &LgPlayer::Ban) + .Func(_SC("Disarm"), &LgPlayer::Disarm) + .Func(_SC("Eject"), &LgPlayer::Eject) + .Func(_SC("GetAmmoAtSlot"), &LgPlayer::GetAmmoAtSlot) + .Func(_SC("GetWeaponAtSlot"), &LgPlayer::GetWeaponAtSlot) + .Func(_SC("GiveMoney"), &LgPlayer::GiveMoney) + .Func(_SC("GiveWeapon"), &LgPlayer::GiveWeapon) + .Func(_SC("Kick"), &LgPlayer::Kick) + .Func(_SC("PlaySound"), &LgPlayer::PlaySound) + .Func(_SC("Redirect"), &LgPlayer::RedirectPlayerToServer) + .Func(_SC("RemoveWeapon"), &LgPlayer::RemoveWeapon) + .Func(_SC("RemoveMarker"), &LgPlayer::RemoveMarker) + .Func(_SC("RestoreCamera"), &LgPlayer::RestoreCamera) + .Func(_SC("Select"), &LgPlayer::Select) + .Func(_SC("SetAlpha"), &LgPlayer::SetAlpha) + .Overload(_SC("SetAnim"), &LgPlayer::Animation) + .Overload(_SC("SetAnim"), &LgPlayer::CompatAnimation) + .Func(_SC("SetCameraPos"), &LgPlayer::SetCameraPos) + .Func(_SC("SetDrunkLevel"), &LgPlayer::SetDrunkLevel) + .Func(_SC("SetMarker"), &LgPlayer::SetMarker) + .Func(_SC("SetWantedLevel"), &LgPlayer::SetWantedLevel) + .Func(_SC("SetWeapon"), &LgPlayer::SetWeapon) + .Func(_SC("Spawn"), &LgPlayer::Spawn) + .Func(_SC("StreamedToPlayer"), &LgPlayer::StreamedToPlayer) + .Func(_SC("PutInVehicleSlot"), &LgPlayer::SetVehicleSlot) + .Func(_SC("RequestModuleList"), &LgPlayer::RequestModuleList) + ; + RootTable(vm).Bind(_SC("CPlayer"), player); + // -------------------------------------------------------------------------------------------- + Class< LgVehicle, NoConstructor< LgVehicle > > vehicle(vm, "CVehicle_INTERNAL"); + // Read-write properties + vehicle + .Prop(_SC("Immunity"), &LgVehicle::GetImmunity, &LgVehicle::SetImmunity) + .Prop(_SC("Pos"), &LgVehicle::GetPosition, &LgVehicle::SetPosition) + .Prop(_SC("World"), &LgVehicle::GetWorld, &LgVehicle::SetWorld) + .Prop(_SC("SpawnPos"), &LgVehicle::GetSpawnPos, &LgVehicle::SetSpawnPos) + .Prop(_SC("EulerSpawnAngle"), &LgVehicle::GetSpawnAngleEuler, &LgVehicle::SetSpawnAngleEuler) + .Prop(_SC("SpawnAngle"), &LgVehicle::GetSpawnAngle, &LgVehicle::SetSpawnAngle) + .Prop(_SC("RespawnTimer"), &LgVehicle::GetIdleRespawnTimer, &LgVehicle::SetIdleRespawnTimer) + .Prop(_SC("Health"), &LgVehicle::GetHealth, &LgVehicle::SetHealth) + .Prop(_SC("Colour1"), &LgVehicle::GetColour1, &LgVehicle::SetColour1) + .Prop(_SC("Colour2"), &LgVehicle::GetColour2, &LgVehicle::SetColour2) + .Prop(_SC("Locked"), &LgVehicle::GetLocked, &LgVehicle::SetLocked) + .Prop(_SC("LightFlags"), &LgVehicle::GetLightFlags, &LgVehicle::SetLightFlags) + .Prop(_SC("TaxiLight"), &LgVehicle::GetTaxiLight, &LgVehicle::SetTaxiLight) + .Prop(_SC("Damage"), &LgVehicle::GetDamage, &LgVehicle::SetDamage) + .Prop(_SC("Alarm"), &LgVehicle::GetAlarm, &LgVehicle::SetAlarm) + .Prop(_SC("Siren"), &LgVehicle::GetSiren, &LgVehicle::SetSiren) + .Prop(_SC("Lights"), &LgVehicle::GetLights, &LgVehicle::SetLights) + .Prop(_SC("Angle"), &LgVehicle::GetRotation, &LgVehicle::SetRotation) + .Prop(_SC("Rotation"), &LgVehicle::GetRotation, &LgVehicle::SetRotation) + .Prop(_SC("EulerAngle"), &LgVehicle::GetEulerRotation, &LgVehicle::SetEulerRotation) + .Prop(_SC("EulerRotation"), &LgVehicle::GetEulerRotation, &LgVehicle::SetEulerRotation) + .Prop(_SC("Speed"), &LgVehicle::GetSpeed, &LgVehicle::SetSpeed) + .Prop(_SC("RelativeSpeed"), &LgVehicle::GetRelativeSpeed, &LgVehicle::SetRelativeSpeed) + .Prop(_SC("TurnSpeed"), &LgVehicle::GetTurnSpeed, &LgVehicle::SetTurnSpeed) + .Prop(_SC("RelativeTurnSpeed"), &LgVehicle::GetRelativeTurnSpeed, &LgVehicle::SetRelativeTurnSpeed) + .Prop(_SC("Radio"), &LgVehicle::GetRadio, &LgVehicle::SetRadio) + .Prop(_SC("RadioLocked"), &LgVehicle::GetRadioLockStatus, &LgVehicle::SetRadioLocked) + .Prop(_SC("IsGhost"), &LgVehicle::GetGhost, &LgVehicle::SetGhost) + .Prop(_SC("SingleUse"), &LgVehicle::GetSingleUse, &LgVehicle::SetSingleUse) + ; + // Read-only properties + vehicle + .Prop(_SC("Native"), &LgVehicle::GetNative) + .Prop(_SC("Model"), &LgVehicle::GetModel) + .Prop(_SC("Driver"), &LgVehicle::GetDriver) + .Prop(_SC("ID"), &LgVehicle::GetID) + .Prop(_SC("SyncSource"), &LgVehicle::GetSyncSource) + .Prop(_SC("SyncType"), &LgVehicle::GetSyncType) + .Prop(_SC("TurretRotation"), &LgVehicle::GetTurretRotation) + .Prop(_SC("Wrecked"), &LgVehicle::GetWrecked) + ; + // Functions + vehicle + .SquirrelFunc(_SC("_typename"), &CVehicleTn::Fn) + .Func( _SC("Delete"), &LgVehicle::Delete) + .Func( _SC("Remove"), &LgVehicle::Delete) + .Func( _SC("Respawn"), &LgVehicle::Respawn) + .Func( _SC("Kill"), &LgVehicle::Kill) + .Func( _SC("KillEngine"), &LgVehicle::Kill) + .Func( _SC("Fix"), &LgVehicle::Fix) + .Func( _SC("GetPart"), &LgVehicle::GetPartStatus) + .Func( _SC("SetPart"), &LgVehicle::SetPartStatus) + .Func( _SC("GetTyre"), &LgVehicle::GetTyreStatus) + .Func( _SC("SetTyre"), &LgVehicle::SetTyreStatus) + .Func( _SC("GetTire"), &LgVehicle::GetTyreStatus) + .Func( _SC("SetTire"), &LgVehicle::SetTyreStatus) + .Func( _SC("SetFlatTyres"), &LgVehicle::SetFlatTyres) + .Func( _SC("StreamedForPlayer"), &LgVehicle::GetStreamedForPlayer) + .Func( _SC("GetOccupant"), &LgVehicle::GetOccupant) + .Func( _SC("SetHandlingData"), &LgVehicle::SetHandlingData) + .Func( _SC("GetHandlingData"), &LgVehicle::GetHandlingData) + .Func( _SC("ResetHandlingData"), &LgVehicle::ResetHandlingData) + .Func( _SC("ResetAllHandling"), &LgVehicle::ResetAllHandling) + .Func( _SC("IsHandlingSet"), &LgVehicle::IsHandlingSet) + .Func( _SC("AddSpeed"), &LgVehicle::AddVehicleSpeed) + .Func( _SC("AddRelSpeed"), &LgVehicle::AddVehicleRelSpeed) + .Func( _SC("AddTurnSpeed"), &LgVehicle::AddVehicleTurnSpeed) + .Func( _SC("AddRelTurnSpeed"), &LgVehicle::AddVehicleRelTurnSpeed) + ; + RootTable(vm).Bind(_SC("CVehicle"), vehicle); +} + +} // Namespace:: SqMod diff --git a/module/Misc/Official.hpp b/module/Misc/Official.hpp new file mode 100644 index 00000000..ec6c08bf --- /dev/null +++ b/module/Misc/Official.hpp @@ -0,0 +1,447 @@ +#pragma once + +// ------------------------------------------------------------------------------------------------ +#include "Base/Color3.hpp" +#include "Base/Color4.hpp" +#include "Base/Vector3.hpp" +#include "Base/Quaternion.hpp" + +// ------------------------------------------------------------------------------------------------ +namespace SqMod { + +/* ------------------------------------------------------------------------------------------------ + * Class used to represent a transparent ARGB color. +*/ +struct LgARGB +{ + /* -------------------------------------------------------------------------------------------- + * The type of value used by components of type. + */ + typedef unsigned char Value; + + /* -------------------------------------------------------------------------------------------- + * The alpha, red, green and blue components of this type. + */ + Value a{0}, r{0}, g{0}, b{0}; + + /* -------------------------------------------------------------------------------------------- + * Construct with individually specified alpha, red, green and blue colors. + */ + LgARGB(Value av, Value rv, Value gv, Value bv) noexcept + : a(av), r(rv), g(gv), b(bv) + { + } +}; + +/* ------------------------------------------------------------------------------------------------ + * Entity vector. +*/ +struct LgVector : public Vector3 +{ + /* -------------------------------------------------------------------------------------------- + * Copy constructor. + */ + LgVector(const Vector3 & v) + : Vector3(v) + { + } + /* -------------------------------------------------------------------------------------------- + * Import from base class. + */ + using Vector3::Vector3; + using Vector3::operator =; +}; + +/* ------------------------------------------------------------------------------------------------ + * Entity vector. +*/ +struct LgEntityVector : public LgVector +{ + /* -------------------------------------------------------------------------------------------- + * Entity identifier. + */ + int16_t mID; + + /* -------------------------------------------------------------------------------------------- + * Entity type. + */ + uint8_t mType; + + /* -------------------------------------------------------------------------------------------- + * Vector flag. + */ + uint8_t mFlag; + + /* -------------------------------------------------------------------------------------------- + * Base constructor. + */ + LgEntityVector(int id, int type, int flag, Value x, Value y, Value z) + : LgVector(x, y, z) + , mID(static_cast< int16_t >(id)) + , mType(static_cast< uint8_t >(type)) + , mFlag(static_cast< uint8_t >(flag)) + { + } + + /* -------------------------------------------------------------------------------------------- + * Base constructor. + */ + LgEntityVector(int id, int type, int flag, const Vector3 & v) + : LgVector(v) + , mID(static_cast< int16_t >(id)) + , mType(static_cast< uint8_t >(type)) + , mFlag(static_cast< uint8_t >(flag)) + { + } + + /* -------------------------------------------------------------------------------------------- + * Retrieve the X component of the vector. + */ + SQMOD_NODISCARD Value GetX() const { return LgVector::x; } + + /* -------------------------------------------------------------------------------------------- + * Retrieve the Y component of the vector. + */ + SQMOD_NODISCARD Value GetY() const { return LgVector::y; } + + /* -------------------------------------------------------------------------------------------- + * Retrieve the Z component of the vector. + */ + SQMOD_NODISCARD Value GetZ() const { return LgVector::z; } + + /* -------------------------------------------------------------------------------------------- + * Modify the X component of the vector. + */ + void SetX(Value v) { LgVector::x = v; Set(); } + + /* -------------------------------------------------------------------------------------------- + * Modify the Y component of the vector. + */ + void SetY(Value v) { LgVector::y = v; Set(); } + + /* -------------------------------------------------------------------------------------------- + * Modify the Z component of the vector. + */ + void SetZ(Value v) { LgVector::z = v; Set(); } + + /* -------------------------------------------------------------------------------------------- + * Modify the X, Y and Z component of the vector. + */ + void Set(); + + /* -------------------------------------------------------------------------------------------- + * Import from base class. + */ + using LgVector::LgVector; + using LgVector::operator =; +}; + +/* ------------------------------------------------------------------------------------------------ + * Entity quaternion. +*/ +struct LgQuaternion : public Quaternion +{ + /* -------------------------------------------------------------------------------------------- + * Copy constructor. + */ + LgQuaternion(const Quaternion & q) + : Quaternion(q) + { + } + /* -------------------------------------------------------------------------------------------- + * Import from base class. + */ + using Quaternion::Quaternion; + using Quaternion::operator =; +}; + +/* ------------------------------------------------------------------------------------------------ + * Entity quaternion. +*/ +struct LgEntityQuaternion : public LgQuaternion +{ + /* -------------------------------------------------------------------------------------------- + * Entity identifier. + */ + int16_t mID; + + /* -------------------------------------------------------------------------------------------- + * Entity type. + */ + uint8_t mType; + + /* -------------------------------------------------------------------------------------------- + * Quaternion flag. + */ + uint8_t mFlag; + + /* -------------------------------------------------------------------------------------------- + * Base constructor. + */ + LgEntityQuaternion(int id, int type, int flag, Value x, Value y, Value z, Value w) + : LgQuaternion(x, y, z, w) + , mID(static_cast< int16_t >(id)) + , mType(static_cast< uint8_t >(type)) + , mFlag(static_cast< uint8_t >(flag)) + { + } + + /* -------------------------------------------------------------------------------------------- + * Base constructor. + */ + LgEntityQuaternion(int id, int type, int flag, const Quaternion & q) + : LgQuaternion(q) + , mID(static_cast< int16_t >(id)) + , mType(static_cast< uint8_t >(type)) + , mFlag(static_cast< uint8_t >(flag)) + { + } + + /* -------------------------------------------------------------------------------------------- + * Retrieve the X component of the quaternion. + */ + SQMOD_NODISCARD Value GetX() const { return LgQuaternion::x; } + + /* -------------------------------------------------------------------------------------------- + * Retrieve the Y component of the quaternion. + */ + SQMOD_NODISCARD Value GetY() const { return LgQuaternion::y; } + + /* -------------------------------------------------------------------------------------------- + * Retrieve the Z component of the quaternion. + */ + SQMOD_NODISCARD Value GetZ() const { return LgQuaternion::z; } + + /* -------------------------------------------------------------------------------------------- + * Retrieve the W component of the quaternion. + */ + SQMOD_NODISCARD Value GetW() const { return LgQuaternion::w; } + + /* -------------------------------------------------------------------------------------------- + * Modify the X component of the quaternion. + */ + void SetX(Value v) { LgQuaternion::x = v; Set(); } + + /* -------------------------------------------------------------------------------------------- + * Modify the Y component of the quaternion. + */ + void SetY(Value v) { LgQuaternion::y = v; Set(); } + + /* -------------------------------------------------------------------------------------------- + * Modify the Z component of the quaternion. + */ + void SetZ(Value v) { LgQuaternion::z = v; Set(); } + + /* -------------------------------------------------------------------------------------------- + * Modify the W component of the quaternion. + */ + void SetW(Value v) { LgQuaternion::w = v; Set(); } + + /* -------------------------------------------------------------------------------------------- + * Modify the X, Y, Z and W component of the quaternion. + */ + void Set(); + + /* -------------------------------------------------------------------------------------------- + * Import from base class. + */ + using LgQuaternion::LgQuaternion; + using LgQuaternion::operator =; +}; + +/* ------------------------------------------------------------------------------------------------ + * Class used to represent a transparent RGB color. +*/ +struct LgRGB : public Color3 +{ + /* -------------------------------------------------------------------------------------------- + * Copy constructor. + */ + LgRGB(const Color3 & c) + : Color3(c) + { + } + /* -------------------------------------------------------------------------------------------- + * Import from base class. + */ + using Color3::Color3; + using Color3::operator =; +}; + +/* ------------------------------------------------------------------------------------------------ + * Class used to represent a transparent RGBA color. +*/ +struct LgRGBA : public Color4 +{ + /* -------------------------------------------------------------------------------------------- + * Import from base class. + */ + using Color4::Color4; + using Color4::operator =; +}; + +/* ------------------------------------------------------------------------------------------------ + * Entity color. +*/ +struct LgEntityRGB : public LgRGB +{ + /* -------------------------------------------------------------------------------------------- + * Entity identifier. + */ + int16_t mID; + + /* -------------------------------------------------------------------------------------------- + * Entity type. + */ + uint8_t mType; + + /* -------------------------------------------------------------------------------------------- + * Color flag. + */ + uint8_t mFlag; + + /* -------------------------------------------------------------------------------------------- + * Base constructor. + */ + LgEntityRGB(int id, int type, int flag, Value r, Value g, Value b) + : LgRGB(r, g, b) + , mID(static_cast< int16_t >(id)) + , mType(static_cast< uint8_t >(type)) + , mFlag(static_cast< uint8_t >(flag)) + { + } + + /* -------------------------------------------------------------------------------------------- + * Base constructor. + */ + LgEntityRGB(int id, int type, int flag, const Color3 & c) + : LgRGB(c) + , mID(static_cast< int16_t >(id)) + , mType(static_cast< uint8_t >(type)) + , mFlag(static_cast< uint8_t >(flag)) + { + } + + /* -------------------------------------------------------------------------------------------- + * Retrieve the Red component of the color. + */ + SQMOD_NODISCARD Value GetR() const { return LgRGB::r; } + + /* -------------------------------------------------------------------------------------------- + * Retrieve the Green component of the color. + */ + SQMOD_NODISCARD Value GetG() const { return LgRGB::g; } + + /* -------------------------------------------------------------------------------------------- + * Retrieve the Blue component of the color. + */ + SQMOD_NODISCARD Value GetB() const { return LgRGB::b; } + + /* -------------------------------------------------------------------------------------------- + * Modify the Red component of the color. + */ + void SetR(Value v) { LgRGB::r = v; Set(); } + + /* -------------------------------------------------------------------------------------------- + * Modify the Green component of the color. + */ + void SetG(Value v) { LgRGB::g = v; Set(); } + + /* -------------------------------------------------------------------------------------------- + * Modify the Blue component of the color. + */ + void SetB(Value v) { LgRGB::b = v; Set(); } + + /* -------------------------------------------------------------------------------------------- + * Modify the red, Green and Blue component of the color. + */ + void Set(); + + /* -------------------------------------------------------------------------------------------- + * Import from base class. + */ + using LgRGB::LgRGB; + using LgRGB::operator =; +}; + +/* ------------------------------------------------------------------------------------------------ + * Class used to represent 2D area boundaries. +*/ +struct LgBounds +{ + /* -------------------------------------------------------------------------------------------- + * The type of value used by components of type. + */ + typedef unsigned char Value; + + /* -------------------------------------------------------------------------------------------- + * Upper and lower bounds of the area. + */ + Value max_x; + Value min_x; + Value max_y; + Value min_y; + + /* -------------------------------------------------------------------------------------------- + * Construct with default (empty/zero) bounds. + */ + LgBounds() + : max_x(0), min_x(0), max_y(0), min_y(0) + { + } + /* -------------------------------------------------------------------------------------------- + * Construct with individually specified bounds. + */ + LgBounds(Value xmax, Value xmin, Value ymax, Value ymin) + : max_x(xmax), min_x(xmin), max_y(ymax), min_y(ymin) + { + } +}; + +/* ------------------------------------------------------------------------------------------------ + * Class used to represent wasted settings. +*/ +struct LgWastedSettings +{ + /* -------------------------------------------------------------------------------------------- + * Settings values. + */ + uint32_t mDeathTime; + uint32_t mFadeTime; + float mFadeInSpeed; + float mFadeOutSpeed; + LgRGB mFadeColour; + uint32_t mCorpseFadeDelay; + uint32_t mCorpseFadeTime; + + /* -------------------------------------------------------------------------------------------- + * Construct with default settings. + */ + LgWastedSettings() + : mDeathTime(0) + , mFadeTime(0) + , mFadeInSpeed(0.0f) + , mFadeOutSpeed(0.0f) + , mFadeColour(0) + , mCorpseFadeDelay(0) + , mCorpseFadeTime(0) + { + } + + /* -------------------------------------------------------------------------------------------- + * Construct with individually specified settings. + */ + LgWastedSettings(uint32_t death_time, uint32_t fade_time, float fade_in_speed, float fade_out_speed, + LgRGB fade_colour, uint32_t corpse_fade_delay, uint32_t corpse_fade_time) + : mDeathTime(death_time) + , mFadeTime(fade_time) + , mFadeInSpeed(fade_in_speed) + , mFadeOutSpeed(fade_out_speed) + , mFadeColour(fade_colour) + , mCorpseFadeDelay(corpse_fade_delay) + , mCorpseFadeTime(corpse_fade_time) + { + } +}; + +} // Namespace:: SqMod diff --git a/module/Register.cpp b/module/Register.cpp index 3971b628..5ed371fa 100644 --- a/module/Register.cpp +++ b/module/Register.cpp @@ -56,6 +56,9 @@ extern void Register_Tasks(HSQUIRRELVM vm); extern void Register_Misc(HSQUIRRELVM vm); extern void Register_Areas(HSQUIRRELVM vm); extern void Register_Signal(HSQUIRRELVM vm); +#ifdef VCMP_ENABLE_OFFICIAL + extern void Register_Official(HSQUIRRELVM vm); +#endif // ------------------------------------------------------------------------------------------------ bool RegisterAPI(HSQUIRRELVM vm) @@ -103,6 +106,9 @@ bool RegisterAPI(HSQUIRRELVM vm) Register_Misc(vm); Register_Areas(vm); Register_Signal(vm); +#ifdef VCMP_ENABLE_OFFICIAL + Register_Official(vm); +#endif return true; } diff --git a/module/SqBase.hpp b/module/SqBase.hpp index 6a3f130c..0f791941 100644 --- a/module/SqBase.hpp +++ b/module/SqBase.hpp @@ -88,6 +88,21 @@ #define SQMOD_SDK_LEAST(MJR, MNR) ((PLUGIN_API_MAJOR >= (MJR)) && (PLUGIN_API_MINOR >= (MNR))) #define SQMOD_SDK_PRIOR(MJR, MNR) ((PLUGIN_API_MAJOR < (MJR)) && (PLUGIN_API_MINOR < (MNR))) +/* ------------------------------------------------------------------------------------------------ + * VCMP OFFICIAL SUPPORT. +*/ +#ifdef VCMP_ENABLE_OFFICIAL + #define SQMOD_OFFICIAL_ONLY(EXPR) EXPR + #define SQMOD_EXCEPT_OFFICIAL(EXPR) +#else + #define SQMOD_OFFICIAL_ONLY(EXPR) + #define SQMOD_EXCEPT_OFFICIAL(EXPR) EXPR +#endif +// -------------------------------------------------------------------------------------------------------------------- +// Select the value according to the selected option. +#define SQMOD_OFFICIAL_OR(XV, OV) SQMOD_OFFICIAL_ONLY(XV) SQMOD_EXCEPT_OFFICIAL(OV) +#define SQMOD_NON_OFFICIAL_OR(XV, OV) SQMOD_EXCEPT_OFFICIAL(XV) SQMOD_OFFICIAL_ONLY(OV) + /* ------------------------------------------------------------------------------------------------ * API EXPORT. */ @@ -476,9 +491,9 @@ enum EntityType * ATTRIBUTES */ #if defined(__GNUC__) && __GNUC__ >= 7 - #define SQ_FALL_THROUGH __attribute__ ((fallthrough)) + #define SQ_FALL_THROUGH __attribute__ ((fallthrough)) #else - #define SQ_FALL_THROUGH ((void)0) + #define SQ_FALL_THROUGH ((void)0) #endif // __GNUC__ >= 7 /* ------------------------------------------------------------------------------------------------