From 7fdcf7efc01d1f2403e7e8ddc4245f4304773e8b Mon Sep 17 00:00:00 2001 From: Sandu Liviu Catalin Date: Sun, 2 Jun 2019 00:39:06 +0300 Subject: [PATCH] Implement new API changes. Initial implementation of entity streaming events, 3D arrows, drunk effects., camera interpolation, entity options and whatnot. Not yet tested! --- include/vcmp.h | 56 ++++++++++++++++--- source/Core.hpp | 24 ++++++++ source/Core/Events.inc | 112 ++++++++++++++++++++++++++++++++++++++ source/Core/Inst.inc | 13 +++++ source/Core/Utils.inc | 12 ++++ source/Entity/Player.cpp | 107 ++++++++++++++++++++++++++++++++++++ source/Entity/Player.hpp | 55 +++++++++++++++++++ source/Entity/Vehicle.cpp | 40 ++++++++++++++ source/Entity/Vehicle.hpp | 20 +++++++ source/Main.cpp | 14 +++++ source/Misc/Constants.cpp | 11 +++- 11 files changed, 452 insertions(+), 12 deletions(-) diff --git a/include/vcmp.h b/include/vcmp.h index 8a9e99df..e5149e32 100644 --- a/include/vcmp.h +++ b/include/vcmp.h @@ -2,7 +2,7 @@ Project: Vice City Multiplayer 0.4 Server / Plugin Kit File: plugin.h - Copyright 2011-2016 Ago Allikmaa (maxorator) + Copyright 2011-2019 Ago Allikmaa (maxorator) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -31,7 +31,7 @@ typedef struct { } ServerSettings; #define PLUGIN_API_MAJOR 2 -#define PLUGIN_API_MINOR 0 +#define PLUGIN_API_MINOR 1 typedef struct { uint32_t structSize; @@ -60,6 +60,8 @@ typedef enum { vcmpEntityPoolObject = 2, vcmpEntityPoolPickup = 3, vcmpEntityPoolRadio = 4, + vcmpEntityPoolPlayer = 5, + vcmpEntityReserved1 = 6, vcmpEntityPoolBlip = 7, vcmpEntityPoolCheckPoint = 8, forceSizeVcmpEntityPool = INT32_MAX @@ -156,6 +158,7 @@ typedef enum { vcmpServerOptionWallGlitch = 19, vcmpServerOptionDisableBackfaceCulling = 20, vcmpServerOptionDisableHeliBladeDamage = 21, + vcmpServerOptionDisableCrouch = 22, forceSizeVcmpServerOption = INT32_MAX } vcmpServerOption; @@ -169,7 +172,8 @@ typedef enum { vcmpPlayerOptionCanAttack = 6, vcmpPlayerOptionHasMarker = 7, vcmpPlayerOptionChatTagsEnabled = 8, - vcmpPlayerOptionDrunkEffects = 9, + vcmpPlayerOptionDrunkEffectsDeprecated = 9, + vcmpPlayerOptionBleeding = 10, forceSizeVcmpPlayerOption = INT32_MAX } vcmpPlayerOption; @@ -181,6 +185,8 @@ typedef enum { vcmpVehicleOptionGhost = 4, vcmpVehicleOptionSiren = 5, vcmpVehicleOptionSingleUse = 6, + vcmpVehicleOptionEngineDisabled = 7, + vcmpVehicleOptionBootOpen = 8, forceSizeVcmpVehicleOption = INT32_MAX } vcmpVehicleOption; @@ -889,7 +895,8 @@ typedef struct { /* GetLastError: vcmpErrorNoSuchEntity */ uint8_t (*IsObjectTouchedReportEnabled) (int32_t objectId); - // TODO: MOVE LATER + /* 04rel005 SDK functions */ + /* ---------------------------------------------------------- */ vcmpError (*GetPlayerModuleList) (int32_t playerId); /* vcmpErrorNoSuchEntity, vcmpErrorArgumentOutOfBounds */ @@ -903,9 +910,35 @@ typedef struct { uint16_t (*GetFallTimer) (void); /* vcmpErrorNoSuchEntity */ - vcmpError(*SetVehicleLightsData) (int32_t vehicleId, uint32_t lightsData); + vcmpError (*SetVehicleLightsData) (int32_t vehicleId, uint32_t lightsData); /* GetLastError: vcmpErrorNoSuchEntity */ - uint32_t(*GetVehicleLightsData) (int32_t vehicleId); + uint32_t (*GetVehicleLightsData) (int32_t vehicleId); + + /* 04rel007 SDK functions */ + /* ---------------------------------------------------------- */ + /* vcmpErrorNoSuchEntity */ + vcmpError (*KillPlayer) (int32_t playerId); + + /* vcmpErrorNoSuchEntity */ + vcmpError (*SetVehicle3DArrowForPlayer) (int32_t nVehicleId, int32_t nTargetPlayerId, uint8_t bEnabled); + /* GetLastError: vcmpErrorNoSuchEntity */ + uint8_t (*GetVehicle3DArrowForPlayer) (int32_t nVehicleId, int32_t nTargetPlayerId); + /* vcmpErrorNoSuchEntity */ + vcmpError (*SetPlayer3DArrowForPlayer) (int32_t nPlayerId, int32_t nTargetPlayerId, uint8_t bEnabled); + /* GetLastError: vcmpErrorNoSuchEntity */ + uint8_t (*GetPlayer3DArrowForPlayer) (int32_t nPlayerId, int32_t nTargetPlayerId); + + /* vcmpErrorNoSuchEntity */ + vcmpError (*SetPlayerDrunkHandling) (int32_t nPlayerId, uint32_t dwDrunkLevel); + /* GetLastError: vcmpErrorNoSuchEntity */ + uint32_t (*GetPlayerDrunkHandling) (int32_t nPlayerId); + /* vcmpErrorNoSuchEntity */ + vcmpError (*SetPlayerDrunkVisuals) (int32_t nPlayerId, uint8_t byteDrunkLevel); + /* GetLastError: vcmpErrorNoSuchEntity */ + uint8_t (*GetPlayerDrunkVisuals) (int32_t nPlayerId); + + /* vcmpErrorNoSuchEntity, vcmpErrorRequestDenied */ + vcmpError (*InterpolateCameraLookAt) (int32_t playerId, float lookX, float lookY, float lookZ, uint32_t dwInterpTimeMS); } PluginFuncs; @@ -969,7 +1002,12 @@ typedef struct { void (*OnEntityPoolChange) (vcmpEntityPool entityType, int32_t entityId, uint8_t isDeleted); void (*OnServerPerformanceReport) (size_t entryCount, const char** descriptions, uint64_t* times); - // TODO: MOVE LATER - void(*OnPlayerModuleList) (int32_t playerId, const char* list); + /* 04rel005 SDK functions */ + /* ---------------------------------------------------------- */ + void (*OnPlayerModuleList) (int32_t playerId, const char* list); -} PluginCallbacks; \ No newline at end of file + /* 04rel007 SDK functions */ + /* ---------------------------------------------------------- */ + void (*OnEntityStreamingChange) (int32_t playerId, int32_t entityId, vcmpEntityPool entityType, uint8_t isDeleted); + +} PluginCallbacks; diff --git a/source/Core.hpp b/source/Core.hpp index d58357cd..763117fe 100644 --- a/source/Core.hpp +++ b/source/Core.hpp @@ -194,6 +194,7 @@ protected: // ---------------------------------------------------------------------------------------- SignalPair mOnDestroyed; SignalPair mOnCustom; + SignalPair mOnStream; // ---------------------------------------------------------------------------------------- SignalPair mOnEntered; @@ -264,6 +265,7 @@ protected: // ---------------------------------------------------------------------------------------- SignalPair mOnDestroyed; SignalPair mOnCustom; + SignalPair mOnStream; // ---------------------------------------------------------------------------------------- SignalPair mOnKeyPress; @@ -326,6 +328,7 @@ protected: // ---------------------------------------------------------------------------------------- SignalPair mOnDestroyed; SignalPair mOnCustom; + SignalPair mOnStream; // ---------------------------------------------------------------------------------------- SignalPair mOnShot; @@ -391,6 +394,7 @@ protected: // ---------------------------------------------------------------------------------------- SignalPair mOnDestroyed; SignalPair mOnCustom; + SignalPair mOnStream; // ---------------------------------------------------------------------------------------- SignalPair mOnRespawn; @@ -484,6 +488,7 @@ protected: // ---------------------------------------------------------------------------------------- SignalPair mOnDestroyed; SignalPair mOnCustom; + SignalPair mOnStream; // ---------------------------------------------------------------------------------------- SignalPair mOnRequestClass; @@ -541,6 +546,7 @@ protected: SignalPair mOnCheckpointEntered; SignalPair mOnCheckpointExited; SignalPair mOnClientScriptData; + SignalPair mOnEntityStream; SignalPair mOnUpdate; SignalPair mOnHealth; SignalPair mOnArmour; @@ -631,6 +637,7 @@ protected: // ---------------------------------------------------------------------------------------- SignalPair mOnDestroyed; SignalPair mOnCustom; + SignalPair mOnStream; // ---------------------------------------------------------------------------------------- SignalPair mOnEmbarking; @@ -1228,6 +1235,16 @@ public: */ void EmitEntityPool(vcmpEntityPool entity_type, Int32 entity_id, bool is_deleted); + /* -------------------------------------------------------------------------------------------- + * Entity streaming changes events. + */ + void EmitCheckpointStream(int32_t player_id, int32_t entity_id, bool is_deleted); + void EmitObjectStream(int32_t player_id, int32_t entity_id, bool is_deleted); + void EmitPickupStream(int32_t player_id, int32_t entity_id, bool is_deleted); + void EmitVehicleStream(int32_t player_id, int32_t entity_id, bool is_deleted); + void EmitPlayerStream(int32_t player_id, int32_t entity_id, bool is_deleted); + void EmitEntityStreaming(int32_t player_id, int32_t entity_id, vcmpEntityPool entity_type, bool is_deleted); + /* -------------------------------------------------------------------------------------------- * Entity update events. */ @@ -1273,6 +1290,11 @@ public: SignalPair mOnPickupCustom; SignalPair mOnPlayerCustom; SignalPair mOnVehicleCustom; + SignalPair mOnCheckpointStream; + SignalPair mOnObjectStream; + SignalPair mOnPickupStream; + SignalPair mOnPlayerStream; + SignalPair mOnVehicleStream; SignalPair mOnServerStartup; SignalPair mOnServerShutdown; SignalPair mOnServerFrame; @@ -1346,6 +1368,7 @@ public: SignalPair mOnCheckpointRadius; SignalPair mOnEntityPool; SignalPair mOnClientScriptData; + SignalPair mOnPlayerStreamChange; SignalPair mOnPlayerUpdate; SignalPair mOnVehicleUpdate; SignalPair mOnPlayerHealth; @@ -1379,6 +1402,7 @@ public: SignalPair mOnVehicleHandlingRule; SignalPair mOnVehicleEnterArea; SignalPair mOnVehicleLeaveArea; + SignalPair mOnEntityStream; SignalPair mOnServerOption; SignalPair mOnScriptReload; SignalPair mOnScriptLoaded; diff --git a/source/Core/Events.inc b/source/Core/Events.inc index 11e79c51..c59be805 100644 --- a/source/Core/Events.inc +++ b/source/Core/Events.inc @@ -1277,6 +1277,118 @@ void Core::EmitPlayerUpdate(Int32 player_id, vcmpPlayerUpdate update_type) (*mOnPlayerUpdate.first)(inst.mObj, static_cast< Int32 >(update_type)); } +// ------------------------------------------------------------------------------------------------ +void Core::EmitCheckpointStream(int32_t player_id, int32_t entity_id, bool is_deleted) +{ + CheckpointInst & _checkpoint = m_Checkpoints.at(entity_id); + PlayerInst & _client = m_Players.at(player_id); + (*_checkpoint.mOnStream.first)(_client.mObj, is_deleted); + (*_client.mOnEntityStream.first)(_checkpoint.mObj, static_cast< Int32 >(vcmpEntityPoolCheckPoint), is_deleted); + (*mOnCheckpointStream.first)(_client.mObj, _checkpoint.mObj, is_deleted); + (*mOnEntityStream.first)(_client.mObj, _checkpoint.mObj, static_cast< Int32 >(vcmpEntityPoolCheckPoint), is_deleted); +} +// ------------------------------------------------------------------------------------------------ +void Core::EmitObjectStream(int32_t player_id, int32_t entity_id, bool is_deleted) +{ + ObjectInst & _object = m_Objects.at(entity_id); + PlayerInst & _client = m_Players.at(player_id); + (*_object.mOnStream.first)(_client.mObj, is_deleted); + (*_client.mOnEntityStream.first)(_object.mObj, static_cast< Int32 >(vcmpEntityPoolObject), is_deleted); + (*mOnObjectStream.first)(_client.mObj, _object.mObj, is_deleted); + (*mOnEntityStream.first)(_client.mObj, _object.mObj, static_cast< Int32 >(vcmpEntityPoolObject), is_deleted); +} +// ------------------------------------------------------------------------------------------------ +void Core::EmitPickupStream(int32_t player_id, int32_t entity_id, bool is_deleted) +{ + PickupInst & _pickup = m_Pickups.at(entity_id); + PlayerInst & _client = m_Players.at(player_id); + (*_pickup.mOnStream.first)(_client.mObj, is_deleted); + (*_client.mOnEntityStream.first)(_pickup.mObj, static_cast< Int32 >(vcmpEntityPoolPickup), is_deleted); + (*mOnPickupStream.first)(_client.mObj, _pickup.mObj, is_deleted); + (*mOnEntityStream.first)(_client.mObj, _pickup.mObj, static_cast< Int32 >(vcmpEntityPoolPickup), is_deleted); +} +// ------------------------------------------------------------------------------------------------ +void Core::EmitVehicleStream(int32_t player_id, int32_t entity_id, bool is_deleted) +{ + VehicleInst & _vehicle = m_Vehicles.at(entity_id); + PlayerInst & _client = m_Players.at(player_id); + (*_vehicle.mOnStream.first)(_client.mObj, is_deleted); + (*_client.mOnEntityStream.first)(_vehicle.mObj, static_cast< Int32 >(vcmpEntityPoolVehicle), is_deleted); + (*mOnVehicleStream.first)(_client.mObj, _vehicle.mObj, is_deleted); + (*mOnEntityStream.first)(_client.mObj, _vehicle.mObj, static_cast< Int32 >(vcmpEntityPoolVehicle), is_deleted); +} +// ------------------------------------------------------------------------------------------------ +void Core::EmitPlayerStream(int32_t player_id, int32_t entity_id, bool is_deleted) +{ + PlayerInst & _player = m_Players.at(entity_id); + PlayerInst & _client = m_Players.at(player_id); + (*_player.mOnStream.first)(_client.mObj, is_deleted); + (*_client.mOnEntityStream.first)(_player.mObj, static_cast< Int32 >(vcmpEntityPoolPlayer), is_deleted); + (*mOnPlayerStream.first)(_client.mObj, _player.mObj, is_deleted); + (*mOnEntityStream.first)(_client.mObj, _player.mObj, static_cast< Int32 >(vcmpEntityPoolPlayer), is_deleted); +} + +// ------------------------------------------------------------------------------------------------ +void Core::EmitEntityStreaming(int32_t player_id, int32_t entity_id, vcmpEntityPool entity_type, bool is_deleted) +{ + // Make sure that the specified entity identifier is valid + if (INVALID_ENTITYEX(player_id, SQMOD_PLAYER_POOL)) + { + STHROWF("Cannot notify player with invalid identifier about streaming: %d", player_id); + } + // See what type of entity changed + switch (entity_type) + { + case vcmpEntityPoolVehicle: { + // Make sure that the specified entity identifier is valid + if (INVALID_ENTITYEX(entity_id, SQMOD_VEHICLE_POOL)) + { + STHROWF("Cannot stream vehicle with invalid identifier: %d", entity_id); + } + // Forward the event to the dedicated handler + EmitVehicleStream(player_id, entity_id, is_deleted); + } break; + case vcmpEntityPoolObject: { + // Make sure that the specified entity identifier is valid + if (INVALID_ENTITYEX(entity_id, SQMOD_OBJECT_POOL)) + { + STHROWF("Cannot stream object with invalid identifier: %d", entity_id); + } + // Forward the event to the dedicated handler + EmitObjectStream(player_id, entity_id, is_deleted); + } break; + case vcmpEntityPoolPickup: { + // Make sure that the specified entity identifier is valid + if (INVALID_ENTITYEX(entity_id, SQMOD_PICKUP_POOL)) + { + STHROWF("Cannot stream pickup with invalid identifier: %d", entity_id); + } + // Forward the event to the dedicated handler + EmitPickupStream(player_id, entity_id, is_deleted); + } break; + case vcmpEntityPoolPlayer: { + // Make sure that the specified entity identifier is valid + if (INVALID_ENTITYEX(entity_id, SQMOD_PLAYER_POOL)) + { + STHROWF("Cannot stream player with invalid identifier: %d", entity_id); + } + // Forward the event to the dedicated handler + EmitPlayerStream(player_id, entity_id, is_deleted); + } break; + case vcmpEntityPoolCheckPoint: { + // Make sure that the specified entity identifier is valid + if (INVALID_ENTITYEX(entity_id, SQMOD_CHECKPOINT_POOL)) + { + STHROWF("Cannot stream checkpoint with invalid identifier: %d", entity_id); + } + // Forward the event to the dedicated handler + EmitCheckpointStream(player_id, entity_id, is_deleted); + } break; + default: + LogErr("Unknown change in entity streaming: client %d > type %d > entity %d", player_id, entity_type, entity_id); + } +} + // ------------------------------------------------------------------------------------------------ void Core::EmitVehicleUpdate(Int32 vehicle_id, vcmpVehicleUpdate update_type) { diff --git a/source/Core/Inst.inc b/source/Core/Inst.inc index f9cdd3bd..783eb831 100644 --- a/source/Core/Inst.inc +++ b/source/Core/Inst.inc @@ -417,6 +417,7 @@ void Core::CheckpointInst::InitEvents() // Proceed to initializing the events InitSignalPair(mOnDestroyed, mEvents, "Destroyed"); InitSignalPair(mOnCustom, mEvents, "Custom"); + InitSignalPair(mOnStream, mEvents, "Stream"); InitSignalPair(mOnEntered, mEvents, "Entered"); InitSignalPair(mOnExited, mEvents, "Exited"); InitSignalPair(mOnWorld, mEvents, "World"); @@ -428,6 +429,7 @@ void Core::CheckpointInst::DropEvents() { ResetSignalPair(mOnDestroyed); ResetSignalPair(mOnCustom); + ResetSignalPair(mOnStream); ResetSignalPair(mOnEntered); ResetSignalPair(mOnExited); ResetSignalPair(mOnWorld); @@ -452,6 +454,7 @@ void Core::KeybindInst::InitEvents() // Proceed to initializing the events InitSignalPair(mOnDestroyed, mEvents, "Destroyed"); InitSignalPair(mOnCustom, mEvents, "Custom"); + InitSignalPair(mOnStream, mEvents, "Stream"); InitSignalPair(mOnKeyPress, mEvents, "KeyPress"); InitSignalPair(mOnKeyRelease, mEvents, "KeyRelease"); } @@ -483,6 +486,7 @@ void Core::ObjectInst::InitEvents() // Proceed to initializing the events InitSignalPair(mOnDestroyed, mEvents, "Destroyed"); InitSignalPair(mOnCustom, mEvents, "Custom"); + InitSignalPair(mOnStream, mEvents, "Stream"); InitSignalPair(mOnShot, mEvents, "Shot"); InitSignalPair(mOnTouched, mEvents, "Touched"); InitSignalPair(mOnWorld, mEvents, "World"); @@ -495,6 +499,7 @@ void Core::ObjectInst::DropEvents() { ResetSignalPair(mOnDestroyed); ResetSignalPair(mOnCustom); + ResetSignalPair(mOnStream); ResetSignalPair(mOnShot); ResetSignalPair(mOnTouched); ResetSignalPair(mOnWorld); @@ -520,6 +525,7 @@ void Core::PickupInst::InitEvents() // Proceed to initializing the events InitSignalPair(mOnDestroyed, mEvents, "Destroyed"); InitSignalPair(mOnCustom, mEvents, "Custom"); + InitSignalPair(mOnStream, mEvents, "Stream"); InitSignalPair(mOnRespawn, mEvents, "Respawn"); InitSignalPair(mOnClaimed, mEvents, "Claimed"); InitSignalPair(mOnCollected, mEvents, "Collected"); @@ -535,6 +541,7 @@ void Core::PickupInst::DropEvents() { ResetSignalPair(mOnDestroyed); ResetSignalPair(mOnCustom); + ResetSignalPair(mOnStream); ResetSignalPair(mOnRespawn); ResetSignalPair(mOnClaimed); ResetSignalPair(mOnCollected); @@ -563,6 +570,7 @@ void Core::PlayerInst::InitEvents() // Proceed to initializing the events InitSignalPair(mOnDestroyed, mEvents, "Destroyed"); InitSignalPair(mOnCustom, mEvents, "Custom"); + InitSignalPair(mOnStream, mEvents, "Stream"); InitSignalPair(mOnRequestClass, mEvents, "RequestClass"); InitSignalPair(mOnRequestSpawn, mEvents, "RequestSpawn"); InitSignalPair(mOnSpawn, mEvents, "Spawn"); @@ -618,6 +626,7 @@ void Core::PlayerInst::InitEvents() InitSignalPair(mOnCheckpointEntered, mEvents, "CheckpointEntered"); InitSignalPair(mOnCheckpointExited, mEvents, "CheckpointExited"); InitSignalPair(mOnClientScriptData, mEvents, "ClientScriptData"); + InitSignalPair(mOnEntityStream, mEvents, "EntityStream"); InitSignalPair(mOnUpdate, mEvents, "Update"); InitSignalPair(mOnHealth, mEvents, "Health"); InitSignalPair(mOnArmour, mEvents, "Armour"); @@ -643,6 +652,7 @@ void Core::PlayerInst::DropEvents() { ResetSignalPair(mOnDestroyed); ResetSignalPair(mOnCustom); + ResetSignalPair(mOnStream); ResetSignalPair(mOnRequestClass); ResetSignalPair(mOnRequestSpawn); ResetSignalPair(mOnSpawn); @@ -698,6 +708,7 @@ void Core::PlayerInst::DropEvents() ResetSignalPair(mOnCheckpointEntered); ResetSignalPair(mOnCheckpointExited); ResetSignalPair(mOnClientScriptData); + ResetSignalPair(mOnEntityStream); ResetSignalPair(mOnUpdate); ResetSignalPair(mOnHealth); ResetSignalPair(mOnArmour); @@ -736,6 +747,7 @@ void Core::VehicleInst::InitEvents() // Proceed to initializing the events InitSignalPair(mOnDestroyed, mEvents, "Destroyed"); InitSignalPair(mOnCustom, mEvents, "Custom"); + InitSignalPair(mOnStream, mEvents, "Stream"); InitSignalPair(mOnEmbarking, mEvents, "Embarking"); InitSignalPair(mOnEmbarked, mEvents, "Embarked"); InitSignalPair(mOnDisembark, mEvents, "Disembark"); @@ -763,6 +775,7 @@ void Core::VehicleInst::DropEvents() { ResetSignalPair(mOnDestroyed); ResetSignalPair(mOnCustom); + ResetSignalPair(mOnStream); ResetSignalPair(mOnEmbarking); ResetSignalPair(mOnEmbarked); ResetSignalPair(mOnDisembark); diff --git a/source/Core/Utils.inc b/source/Core/Utils.inc index 5778d86f..f4d10c7b 100644 --- a/source/Core/Utils.inc +++ b/source/Core/Utils.inc @@ -75,6 +75,11 @@ void Core::InitEvents() InitSignalPair(mOnPickupCustom, m_Events, "PickupCustom"); InitSignalPair(mOnPlayerCustom, m_Events, "PlayerCustom"); InitSignalPair(mOnVehicleCustom, m_Events, "VehicleCustom"); + InitSignalPair(mOnCheckpointStream, m_Events, "CheckpointStream"); + InitSignalPair(mOnObjectStream, m_Events, "ObjectStream"); + InitSignalPair(mOnPickupStream, m_Events, "PickupStream"); + InitSignalPair(mOnPlayerStream, m_Events, "PlayerStream"); + InitSignalPair(mOnVehicleStream, m_Events, "VehicleStream"); InitSignalPair(mOnServerStartup, m_Events, "ServerStartup"); InitSignalPair(mOnServerShutdown, m_Events, "ServerShutdown"); InitSignalPair(mOnServerFrame, m_Events, "ServerFrame"); @@ -181,6 +186,7 @@ void Core::InitEvents() InitSignalPair(mOnVehicleHandlingRule, m_Events, "VehicleHandlingRule"); InitSignalPair(mOnVehicleEnterArea, m_Events, "VehicleEnterArea"); InitSignalPair(mOnVehicleLeaveArea, m_Events, "VehicleLeaveArea"); + InitSignalPair(mOnEntityStream, m_Events, "EntityStream"); InitSignalPair(mOnServerOption, m_Events, "ServerOption"); InitSignalPair(mOnScriptReload, m_Events, "ScriptReload"); InitSignalPair(mOnScriptLoaded, m_Events, "ScriptLoaded"); @@ -210,6 +216,11 @@ void Core::DropEvents() ResetSignalPair(mOnPickupCustom); ResetSignalPair(mOnPlayerCustom); ResetSignalPair(mOnVehicleCustom); + ResetSignalPair(mOnCheckpointStream); + ResetSignalPair(mOnObjectStream); + ResetSignalPair(mOnPickupStream); + ResetSignalPair(mOnPlayerStream); + ResetSignalPair(mOnVehicleStream); ResetSignalPair(mOnServerStartup); ResetSignalPair(mOnServerShutdown); ResetSignalPair(mOnServerFrame); @@ -316,6 +327,7 @@ void Core::DropEvents() ResetSignalPair(mOnVehicleHandlingRule); ResetSignalPair(mOnVehicleEnterArea); ResetSignalPair(mOnVehicleLeaveArea); + ResetSignalPair(mOnEntityStream); ResetSignalPair(mOnServerOption); ResetSignalPair(mOnScriptReload); ResetSignalPair(mOnScriptLoaded); diff --git a/source/Entity/Player.cpp b/source/Entity/Player.cpp index 682f2493..d055ca31 100644 --- a/source/Entity/Player.cpp +++ b/source/Entity/Player.cpp @@ -240,6 +240,15 @@ CSStr CPlayer::GetUID2() const return s_Buffer; } +// ------------------------------------------------------------------------------------------------ +void CPlayer::Kill() const +{ + // Validate the managed identifier + Validate(); + // Perform the requested operation + _Func->KillPlayer(m_ID); +} + // ------------------------------------------------------------------------------------------------ void CPlayer::Kick() const { @@ -1377,6 +1386,59 @@ void CPlayer::Unspectate() const _Func->SetPlayerSpectateTarget(m_ID, -1); } +// ------------------------------------------------------------------------------------------------ +void CPlayer::SetPlayer3DArrow(CPlayer & target, bool toggle) const +{ + // Validate the managed identifier + Validate(); + // Spectate the given target + _Func->SetPlayer3DArrowForPlayer(m_ID, target.GetID(), toggle); +} + +// ------------------------------------------------------------------------------------------------ +bool CPlayer::GetPlayer3DArrow(CPlayer & target) const +{ + // Validate the managed identifier + Validate(); + // Spectate the given target + return _Func->GetPlayer3DArrowForPlayer(m_ID, target.GetID()); +} + +// ------------------------------------------------------------------------------------------------ +void CPlayer::SetPlayer3DArrowID(SQInteger id, bool toggle) const +{ + // Validate the managed identifier + Validate(); + // Spectate the given target + _Func->SetPlayer3DArrowForPlayer(m_ID, id, toggle); +} + +// ------------------------------------------------------------------------------------------------ +bool CPlayer::GetPlayer3DArrowID(SQInteger id) const +{ + // Validate the managed identifier + Validate(); + // Spectate the given target + return _Func->GetPlayer3DArrowForPlayer(m_ID, id); +} +// ------------------------------------------------------------------------------------------------ +bool CPlayer::InterpolateCameraLookAt(const Vector3 & pos, Uint32 ms) const +{ + // Validate the managed identifier + Validate(); + // Perform the requested operation + return _Func->InterpolateCameraLookAt(m_ID, pos.x, pos.y, pos.z, ms) != vcmpErrorRequestDenied; +} + +// ------------------------------------------------------------------------------------------------ +bool CPlayer::InterpolateCameraLookAtEx(Float32 x, Float32 y, Float32 z, Uint32 ms) const +{ + // Validate the managed identifier + Validate(); + // Perform the requested operation + return _Func->InterpolateCameraLookAt(m_ID, x, y, z, ms) != vcmpErrorRequestDenied; +} + // ------------------------------------------------------------------------------------------------ void CPlayer::Redirect(StackStrF & ip, Uint32 port, StackStrF & nick, StackStrF & server_pass, StackStrF & user_pass) @@ -1409,6 +1471,42 @@ void CPlayer::PlaySound(Int32 sound_id) const _Func->PlaySound(_Func->GetPlayerUniqueWorld(m_ID), sound_id, NAN, NAN, NAN); } +// ------------------------------------------------------------------------------------------------ +void CPlayer::SetDrunkHandling(SQInteger level) const +{ + // Validate the managed identifier + Validate(); + // Perform the requested operation + _Func->SetPlayerDrunkHandling(m_ID, static_cast< Uint32 >(level)); +} + +// ------------------------------------------------------------------------------------------------ +SQInteger CPlayer::GetDrunkHandling() const +{ + // Validate the managed identifier + Validate(); + // Perform the requested operation + return _Func->GetPlayerDrunkHandling(m_ID); +} + +// ------------------------------------------------------------------------------------------------ +void CPlayer::SetDrunkVisuals(SQInteger level) const +{ + // Validate the managed identifier + Validate(); + // Perform the requested operation + _Func->SetPlayerDrunkVisuals(m_ID, static_cast< Uint8 >(level)); +} + +// ------------------------------------------------------------------------------------------------ +SQInteger CPlayer::GetDrunkVisuals() const +{ + // Validate the managed identifier + Validate(); + // Perform the requested operation + return _Func->GetPlayerDrunkVisuals(m_ID); +} + // ------------------------------------------------------------------------------------------------ LightObj & CPlayer::CreateCheckpointEx(Int32 world, bool sphere, Float32 x, Float32 y, Float32 z, Uint8 r, Uint8 g, Uint8 b, Uint8 a, Float32 radius) const @@ -2673,6 +2771,8 @@ void Register_CPlayer(HSQUIRRELVM vm) .Prop(_SC("Away"), &CPlayer::IsAway) .Prop(_SC("Spec"), &CPlayer::GetSpectator, &CPlayer::SetSpectator) .Prop(_SC("SpecID"), &CPlayer::GetSpectatorID, &CPlayer::SetSpectatorID) + .Prop(_SC("DrunkHandling"), &CPlayer::GetDrunkHandling, &CPlayer::SetDrunkHandling) + .Prop(_SC("DrunkVisuals"), &CPlayer::GetDrunkVisuals, &CPlayer::SetDrunkVisuals) .Prop(_SC("CollideAreas"), &CPlayer::GetCollideAreas, &CPlayer::SetCollideAreas) .Prop(_SC("Authority"), &CPlayer::GetAuthority, &CPlayer::SetAuthority) .Prop(_SC("TrackPosition"), &CPlayer::GetTrackPosition, &CPlayer::SetTrackPosition) @@ -2693,6 +2793,7 @@ void Register_CPlayer(HSQUIRRELVM vm) .Prop(_SC("Blue"), &CPlayer::GetColorB, &CPlayer::SetColorB) // Member Methods .Func(_SC("StreamedFor"), &CPlayer::IsStreamedFor) + .Func(_SC("Kill"), &CPlayer::Kill) .Func(_SC("Kick"), &CPlayer::Kick) .Func(_SC("Ban"), &CPlayer::Ban) .Func(_SC("KickBecause"), &CPlayer::KickBecause) @@ -2722,6 +2823,12 @@ void Register_CPlayer(HSQUIRRELVM vm) .Func(_SC("Spectating"), &CPlayer::GetSpectator) .Func(_SC("Unspectate"), &CPlayer::Unspectate) .Func(_SC("Spectate"), &CPlayer::SetSpectator) + .Func(_SC("SetPlayer3DArrow"), &CPlayer::SetPlayer3DArrow) + .Func(_SC("GetPlayer3DArrow"), &CPlayer::GetPlayer3DArrow) + .Func(_SC("SetPlayer3DArrowID"), &CPlayer::SetPlayer3DArrowID) + .Func(_SC("GetPlayer3DArrowID"), &CPlayer::GetPlayer3DArrowID) + .Func(_SC("InterpolateCameraLookAt"), &CPlayer::InterpolateCameraLookAt) + .Func(_SC("InterpolateCameraLookAtEx"), &CPlayer::InterpolateCameraLookAtEx) .Func(_SC("Redirect"), &CPlayer::Redirect) .Func(_SC("GetModuleList"), &CPlayer::GetModuleList) .Func(_SC("PlaySound"), &CPlayer::PlaySound) diff --git a/source/Entity/Player.hpp b/source/Entity/Player.hpp index 2779a605..3f0bdd3f 100644 --- a/source/Entity/Player.hpp +++ b/source/Entity/Player.hpp @@ -265,6 +265,11 @@ public: */ CSStr GetUID2() const; + /* -------------------------------------------------------------------------------------------- + * Set player's health to 0 and reset the death reason. + */ + void Kill() const; + /* -------------------------------------------------------------------------------------------- * Kick the managed player entity from the server. */ @@ -740,6 +745,36 @@ public: */ void Unspectate() const; + /* -------------------------------------------------------------------------------------------- + * Set whether the target player will see an objective arrow over a player. + */ + void SetPlayer3DArrow(CPlayer & target, bool toggle) const; + + /* -------------------------------------------------------------------------------------------- + * See whether the target player sees an objective arrow over a player. + */ + bool GetPlayer3DArrow(CPlayer & target) const; + + /* -------------------------------------------------------------------------------------------- + * Set whether the target player will see an objective arrow over a player. + */ + void SetPlayer3DArrowID(SQInteger id, bool toggle) const; + + /* -------------------------------------------------------------------------------------------- + * See whether the target player sees an objective arrow over a player. + */ + bool GetPlayer3DArrowID(SQInteger id) const; + + /* -------------------------------------------------------------------------------------------- + * Smoothly pivots the camera angle. + */ + bool InterpolateCameraLookAt(const Vector3 & pos, Uint32 ms) const; + + /* -------------------------------------------------------------------------------------------- + * Smoothly pivots the camera angle. + */ + bool InterpolateCameraLookAtEx(Float32 x, Float32 y, Float32 z, Uint32 ms) const; + /* -------------------------------------------------------------------------------------------- * Redirect the managed player entity to the specified server. */ @@ -756,6 +791,26 @@ public: */ void PlaySound(Int32 sound_id) const; + /* -------------------------------------------------------------------------------------------- + * Set how delayed a player's turn handling is when in a vehicle. + */ + void SetDrunkHandling(SQInteger level) const; + + /* -------------------------------------------------------------------------------------------- + * Retrieve how delayed a player's turn handling is when in a vehicle. + */ + SQInteger GetDrunkHandling() const; + + /* -------------------------------------------------------------------------------------------- + * Set how intense the drunk blur overlay is for a player. + */ + void SetDrunkVisuals(SQInteger level) const; + + /* -------------------------------------------------------------------------------------------- + * Retrieve how intense the drunk blur overlay is for a player. + */ + SQInteger GetDrunkVisuals() const; + /* -------------------------------------------------------------------------------------------- * Create a checkpoint or sphere for this player. */ diff --git a/source/Entity/Vehicle.cpp b/source/Entity/Vehicle.cpp index 56ccfbf3..dcc0d4d5 100644 --- a/source/Entity/Vehicle.cpp +++ b/source/Entity/Vehicle.cpp @@ -1148,6 +1148,42 @@ bool CVehicle::Embark(CPlayer & player, Int32 slot, bool allocate, bool warp) co != vcmpErrorRequestDenied); } +// ------------------------------------------------------------------------------------------------ +void CVehicle::SetPlayer3DArrow(CPlayer & target, bool toggle) const +{ + // Validate the managed identifier + Validate(); + // Spectate the given target + _Func->SetVehicle3DArrowForPlayer(m_ID, target.GetID(), toggle); +} + +// ------------------------------------------------------------------------------------------------ +bool CVehicle::GetPlayer3DArrow(CPlayer & target) const +{ + // Validate the managed identifier + Validate(); + // Spectate the given target + return _Func->GetVehicle3DArrowForPlayer(m_ID, target.GetID()); +} + +// ------------------------------------------------------------------------------------------------ +void CVehicle::SetPlayer3DArrowID(SQInteger id, bool toggle) const +{ + // Validate the managed identifier + Validate(); + // Spectate the given target + _Func->SetVehicle3DArrowForPlayer(m_ID, id, toggle); +} + +// ------------------------------------------------------------------------------------------------ +bool CVehicle::GetPlayer3DArrowID(SQInteger id) const +{ + // Validate the managed identifier + Validate(); + // Spectate the given target + return _Func->GetVehicle3DArrowForPlayer(m_ID, id); +} + // ------------------------------------------------------------------------------------------------ bool CVehicle::GetCollideAreas() const { @@ -2038,6 +2074,10 @@ void Register_CVehicle(HSQUIRRELVM vm) .Func(_SC("SetHandlingRule"), &CVehicle::SetHandlingRule) .Func(_SC("ResetHandlingRule"), &CVehicle::ResetHandlingRule) .Func(_SC("ResetHandlings"), &CVehicle::ResetHandlings) + .Func(_SC("SetPlayer3DArrow"), &CVehicle::SetPlayer3DArrow) + .Func(_SC("GetPlayer3DArrow"), &CVehicle::GetPlayer3DArrow) + .Func(_SC("SetPlayer3DArrowID"), &CVehicle::SetPlayer3DArrowID) + .Func(_SC("GetPlayer3DArrowID"), &CVehicle::GetPlayer3DArrowID) .Func(_SC("AreasCollide"), &CVehicle::SetAreasCollide) // Member Overloads .Overload< void (CVehicle::*)(const Vector3 &, bool) const > diff --git a/source/Entity/Vehicle.hpp b/source/Entity/Vehicle.hpp index 01487f18..86331a3d 100644 --- a/source/Entity/Vehicle.hpp +++ b/source/Entity/Vehicle.hpp @@ -622,6 +622,26 @@ public: */ bool Embark(CPlayer & player, Int32 slot, bool allocate, bool warp) const; + /* -------------------------------------------------------------------------------------------- + * Set whether the target player will see an objective arrow over a vehicle. + */ + void SetPlayer3DArrow(CPlayer & target, bool toggle) const; + + /* -------------------------------------------------------------------------------------------- + * See whether the target player sees an objective arrow over a vehicle. + */ + bool GetPlayer3DArrow(CPlayer & target) const; + + /* -------------------------------------------------------------------------------------------- + * Set whether the target player will see an objective arrow over a vehicle. + */ + void SetPlayer3DArrowID(SQInteger id, bool toggle) const; + + /* -------------------------------------------------------------------------------------------- + * See whether the target player sees an objective arrow over a vehicle. + */ + bool GetPlayer3DArrowID(SQInteger id) const; + /* -------------------------------------------------------------------------------------------- * See whether the managed vehicle entity collides with user defined areas. */ diff --git a/source/Main.cpp b/source/Main.cpp index bb2b1900..32ba4383 100644 --- a/source/Main.cpp +++ b/source/Main.cpp @@ -867,6 +867,19 @@ static void OnEntityPoolChange(vcmpEntityPool entity_type, int32_t entity_id, ui SQMOD_RELOAD_CHECK(false) } +// ------------------------------------------------------------------------------------------------ +static void OnEntityStreamingChange(int32_t player_id, int32_t entity_id, vcmpEntityPool entity_type, uint8_t is_deleted) +{ + // Attempt to forward the event + try + { + Core::Get().EmitEntityStreaming(player_id, entity_id, entity_type, is_deleted); + } + SQMOD_CATCH_EVENT_EXCEPTION(OnEntityStreamingChange) + // See if a reload was requested + SQMOD_RELOAD_CHECK(false) +} + // ------------------------------------------------------------------------------------------------ static void OnServerPerformanceReport(size_t /*entry_count*/, CCStr * /*descriptions*/, uint64_t * /*times*/) { @@ -973,6 +986,7 @@ SQMOD_API_EXPORT unsigned int VcmpPluginInit(PluginFuncs * funcs, PluginCallback _Clbk->OnEntityPoolChange = OnEntityPoolChange; _Clbk->OnServerPerformanceReport = OnServerPerformanceReport; _Clbk->OnPlayerModuleList = OnPlayerModuleList; + _Clbk->OnEntityStreamingChange = OnEntityStreamingChange; // Attempt to initialize the plug-in exports InitExports(); // Dummy spacing diff --git a/source/Misc/Constants.cpp b/source/Misc/Constants.cpp index de57e0f0..a3962c2b 100644 --- a/source/Misc/Constants.cpp +++ b/source/Misc/Constants.cpp @@ -245,6 +245,7 @@ static const EnumElement g_EntityPoolEnum[] = { {_SC("Object"), vcmpEntityPoolObject}, {_SC("Pickup"), vcmpEntityPoolPickup}, {_SC("Radio"), vcmpEntityPoolRadio}, + {_SC("Player"), vcmpEntityPoolPlayer}, {_SC("Blip"), vcmpEntityPoolBlip}, {_SC("Checkpoint"), vcmpEntityPoolCheckPoint}, {_SC("Max"), vcmpEntityPoolCheckPoint} @@ -330,7 +331,8 @@ static const EnumElement g_ServerOptionEnum[] = { {_SC("WallGlitch"), vcmpServerOptionWallGlitch}, {_SC("DisableBackfaceCulling"), vcmpServerOptionDisableBackfaceCulling}, {_SC("DisableHeliBladeDamage"), vcmpServerOptionDisableHeliBladeDamage}, - {_SC("Max"), vcmpServerOptionDisableHeliBladeDamage} + {_SC("DisableCrouch "), vcmpServerOptionDisableCrouch}, + {_SC("Max"), vcmpServerOptionDisableCrouch} }; // ------------------------------------------------------------------------------------------------ @@ -345,8 +347,8 @@ static const EnumElement g_PlayerOptionEnum[] = { {_SC("CanAttack"), vcmpPlayerOptionCanAttack}, {_SC("HasMarker"), vcmpPlayerOptionHasMarker}, {_SC("ChatTagsEnabled"), vcmpPlayerOptionChatTagsEnabled}, - {_SC("DrunkEffects"), vcmpPlayerOptionDrunkEffects}, - {_SC("Max"), vcmpPlayerOptionDrunkEffects} + {_SC("DrunkEffects"), vcmpPlayerOptionBleeding}, + {_SC("Max"), vcmpPlayerOptionBleeding} }; // ------------------------------------------------------------------------------------------------ @@ -358,6 +360,9 @@ static const EnumElement g_VehicleOptionEnum[] = { {_SC("RadioLocked"), vcmpVehicleOptionRadioLocked}, {_SC("Ghost"), vcmpVehicleOptionGhost}, {_SC("Siren"), vcmpVehicleOptionSiren}, + {_SC("SingleUse "), vcmpVehicleOptionSingleUse}, + {_SC("EngineDisabled "), vcmpVehicleOptionEngineDisabled}, + {_SC("BootOpen "), vcmpVehicleOptionBootOpen}, {_SC("Max"), vcmpVehicleOptionSiren} };