From f2e7d2eaacfa54ce4541dd270fb5a419cb4d9383 Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Sun, 4 Feb 2024 06:10:07 -0800 Subject: [PATCH 1/5] Use vector instead of forward_list for dpGrid also swap contains in for find != end on an associative container since we are in c++20 now :) --- dPhysics/dpEntity.cpp | 2 +- dPhysics/dpGrid.cpp | 80 ++++++++++++++++++++----------------------- dPhysics/dpGrid.h | 10 +++--- 3 files changed, 44 insertions(+), 48 deletions(-) diff --git a/dPhysics/dpEntity.cpp b/dPhysics/dpEntity.cpp index 70bddb40..cbe3f5e8 100644 --- a/dPhysics/dpEntity.cpp +++ b/dPhysics/dpEntity.cpp @@ -76,7 +76,7 @@ void dpEntity::CheckCollision(dpEntity* other) { return; } - bool wasFound = (m_CurrentlyCollidingObjects.find(other->GetObjectID()) != m_CurrentlyCollidingObjects.end()); + bool wasFound = m_CurrentlyCollidingObjects.contains(other->GetObjectID()); bool isColliding = m_CollisionShape->IsColliding(other->GetShape()); diff --git a/dPhysics/dpGrid.cpp b/dPhysics/dpGrid.cpp index 1704e068..f498c491 100644 --- a/dPhysics/dpGrid.cpp +++ b/dPhysics/dpGrid.cpp @@ -8,24 +8,14 @@ dpGrid::dpGrid(int numCells, int cellSize) { CELL_SIZE = cellSize; m_DeleteGrid = true; - //fill x - for (int i = 0; i < NUM_CELLS; i++) { - m_Cells.push_back(std::vector>()); - } - - //fill z - for (int i = 0; i < NUM_CELLS; i++) { - for (int i = 0; i < NUM_CELLS; i++) { - m_Cells[i].push_back(std::forward_list()); - } - } + m_Cells.resize(NUM_CELLS, std::vector>(NUM_CELLS)); } dpGrid::~dpGrid() { if (!this->m_DeleteGrid) return; for (auto& x : m_Cells) { //x - for (auto& y : x) { //y - for (auto en : y) { + for (auto& z : x) { //y + for (auto en : z) { if (!en) continue; delete en; en = nullptr; @@ -39,13 +29,12 @@ void dpGrid::Add(dpEntity* entity) { int cellX = (int)std::round(entity->m_Position.x) / dpGrid::CELL_SIZE + NUM_CELLS / 2; int cellZ = (int)std::round(entity->m_Position.z) / dpGrid::CELL_SIZE + NUM_CELLS / 2; - if (cellX < 0) cellX = 0; - if (cellZ < 0) cellZ = 0; - if (cellX >= NUM_CELLS) cellX = NUM_CELLS - 1; - if (cellZ >= NUM_CELLS) cellZ = NUM_CELLS - 1; + // Clamp values to the range [0, NUM_CELLS - 1] + std::clamp(cellX, 0, NUM_CELLS - 1); + std::clamp(cellZ, 0, NUM_CELLS - 1); //Add to cell: - m_Cells[cellX][cellZ].push_front(entity); + m_Cells[cellX][cellZ].push_back(entity); //To verify that the object isn't gargantuan: if (entity->GetScale() >= CELL_SIZE * 2 || entity->GetIsGargantuan()) @@ -59,23 +48,27 @@ void dpGrid::Move(dpEntity* entity, float x, float z) { int cellX = (int)std::round(x) / dpGrid::CELL_SIZE + NUM_CELLS / 2; int cellZ = (int)std::round(z) / dpGrid::CELL_SIZE + NUM_CELLS / 2; - if (cellX < 0) cellX = 0; - if (cellZ < 0) cellZ = 0; - if (cellX >= NUM_CELLS) cellX = NUM_CELLS - 1; - if (cellZ >= NUM_CELLS) cellZ = NUM_CELLS - 1; + // Clamp values to the range [0, NUM_CELLS - 1] + std::clamp(cellX, 0, NUM_CELLS - 1); + std::clamp(cellZ, 0, NUM_CELLS - 1); - if (oldCellX < 0) oldCellX = 0; - if (oldCellZ < 0) oldCellZ = 0; - if (oldCellX >= NUM_CELLS) oldCellX = NUM_CELLS - 1; - if (oldCellZ >= NUM_CELLS) oldCellZ = NUM_CELLS - 1; + std::clamp(oldCellX, 0, NUM_CELLS - 1); + std::clamp(oldCellZ, 0, NUM_CELLS - 1); if (oldCellX == cellX && oldCellZ == cellZ) return; - //Remove from perv cell: - m_Cells[oldCellX][oldCellZ].remove(entity); + //Remove from prev cell: + auto& cell = m_Cells[oldCellX][oldCellZ]; + + // For speed, find the single match and swap it with the last element, then pop_back. + auto toRemove = std::find(cell.begin(), cell.end(), entity); + if (toRemove != cell.end()) { + *toRemove = cell.back(); + cell.pop_back(); + } //Add to the new cell - m_Cells[cellX][cellZ].push_front(entity); + m_Cells[cellX][cellZ].push_back(entity); } void dpGrid::Delete(dpEntity* entity) { @@ -83,15 +76,18 @@ void dpGrid::Delete(dpEntity* entity) { int oldCellX = (int)std::round(entity->m_Position.x) / dpGrid::CELL_SIZE + NUM_CELLS / 2; int oldCellZ = (int)std::round(entity->m_Position.z) / dpGrid::CELL_SIZE + NUM_CELLS / 2; - if (oldCellX < 0) oldCellX = 0; - if (oldCellZ < 0) oldCellZ = 0; - if (oldCellX >= NUM_CELLS) oldCellX = NUM_CELLS - 1; - if (oldCellZ >= NUM_CELLS) oldCellZ = NUM_CELLS - 1; + // Clamp values to the range [0, NUM_CELLS - 1] + std::clamp(oldCellX, 0, NUM_CELLS - 1); + std::clamp(oldCellZ, 0, NUM_CELLS - 1); - m_Cells[oldCellX][oldCellZ].remove(entity); + auto& cell = m_Cells[oldCellX][oldCellZ]; + auto toRemove = std::find(cell.begin(), cell.end(), entity); + if (toRemove != cell.end()) { + *toRemove = cell.back(); + cell.pop_back(); + } - if (m_GargantuanObjects.find(entity->m_ObjectID) != m_GargantuanObjects.end()) - m_GargantuanObjects.erase(entity->m_ObjectID); + m_GargantuanObjects.erase(entity->m_ObjectID); if (entity) delete entity; entity = nullptr; @@ -100,8 +96,8 @@ void dpGrid::Delete(dpEntity* entity) { void dpGrid::Update(float deltaTime) { //Pre-update: for (auto& x : m_Cells) { //x - for (auto& y : x) { //y - for (auto en : y) { + for (auto& z : x) { //y + for (auto en : z) { if (!en) continue; en->PreUpdate(); } @@ -110,8 +106,8 @@ void dpGrid::Update(float deltaTime) { //Actual collision detection update: for (int x = 0; x < NUM_CELLS; x++) { - for (int y = 0; y < NUM_CELLS; y++) { - HandleCell(x, y, deltaTime); + for (int z = 0; z < NUM_CELLS; z++) { + HandleCell(x, z, deltaTime); } } } @@ -157,7 +153,7 @@ void dpGrid::HandleCell(int x, int z, float deltaTime) { HandleEntity(en, other); } - for (auto other : m_GargantuanObjects) - HandleEntity(en, other.second); + for (auto& [id, entity] : m_GargantuanObjects) + HandleEntity(en, entity); } } diff --git a/dPhysics/dpGrid.h b/dPhysics/dpGrid.h index 229e7449..39a9cfe7 100644 --- a/dPhysics/dpGrid.h +++ b/dPhysics/dpGrid.h @@ -1,8 +1,7 @@ #pragma once -#include -#include -#include #include +#include + #include "dCommonVars.h" class dpEntity; @@ -30,7 +29,8 @@ public: */ void SetDeleteGrid(bool value) { this->m_DeleteGrid = value; }; - std::vector>> GetCells() { return this->m_Cells; }; + // Intentional copy since this is only used when we delete this class to re-create it. + std::vector>> GetCells() { return this->m_Cells; }; private: void HandleEntity(dpEntity* entity, dpEntity* other); @@ -38,7 +38,7 @@ private: private: //cells on X, cells on Y for that X, then another vector that contains the entities within that cell. - std::vector>> m_Cells; + std::vector>> m_Cells; std::map m_GargantuanObjects; bool m_DeleteGrid = true; }; From f0b6ad89d99fc7d502fc1f8845750ca4a009e8fc Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Sun, 4 Feb 2024 06:29:05 -0800 Subject: [PATCH 2/5] chore: Player class removal (#1445) * SystemAddress and destructor * move respawn logic to character comp Tested that respawn pos and rot can be set as per previously by crossing a respawn point and smashing to see if I would respawn at the new place. * Move loot cheat checking * Remove GetParentUser overload Tested completing missions control behaviors collecting life crate completing a bunch of missions using macros loading into worlds brick-by-brick placing models digging the x spot in gnarled forest can still ban and mute players cheat detection is still doing its thing flags are still set (checked with flag 45) claim codes still work (created new char, checked the lego club mail was there) * Move player constructor logic Its now at the bottom of Entity constructor. Time to remove Player * Remove Player class Removes the Player class. Tested that I can still login and see another player in Venture Explorer and logging out a few times still works as well as smashing enemies * store ptr * Update SlashCommandHandler.cpp --- dGame/CMakeLists.txt | 1 - dGame/Character.h | 2 + dGame/Entity.cpp | 118 +++++++++++++----- dGame/Entity.h | 20 ++- dGame/EntityManager.cpp | 12 +- dGame/EntityManager.h | 2 +- dGame/Player.cpp | 71 ----------- dGame/Player.h | 62 --------- dGame/PlayerManager.cpp | 23 ++-- dGame/PlayerManager.h | 14 +-- dGame/dComponents/ActivityComponent.cpp | 1 - dGame/dComponents/CharacterComponent.cpp | 24 +++- dGame/dComponents/CharacterComponent.h | 29 ++++- dGame/dComponents/DestroyableComponent.cpp | 15 ++- dGame/dComponents/InventoryComponent.cpp | 1 - .../PropertyManagementComponent.cpp | 3 - dGame/dComponents/RacingControlComponent.cpp | 1 - dGame/dComponents/TriggerComponent.cpp | 1 - dGame/dGameMessages/GameMessageHandler.cpp | 1 - dGame/dGameMessages/GameMessages.cpp | 13 +- dGame/dMission/Mission.cpp | 13 +- dGame/dMission/Mission.h | 3 +- dGame/dPropertyBehaviors/ControlBehaviors.cpp | 5 +- dGame/dUtilities/CheatDetection.cpp | 5 +- dGame/dUtilities/SlashCommandHandler.cpp | 15 ++- .../02_server/Map/General/PetDigServer.cpp | 2 +- .../ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp | 1 - dWorldServer/WorldServer.cpp | 17 +-- 28 files changed, 215 insertions(+), 260 deletions(-) delete mode 100644 dGame/Player.cpp delete mode 100644 dGame/Player.h diff --git a/dGame/CMakeLists.txt b/dGame/CMakeLists.txt index 4d9a3e50..627f163a 100644 --- a/dGame/CMakeLists.txt +++ b/dGame/CMakeLists.txt @@ -2,7 +2,6 @@ set(DGAME_SOURCES "Character.cpp" "Entity.cpp" "EntityManager.cpp" "LeaderboardManager.cpp" - "Player.cpp" "PlayerManager.cpp" "TeamManager.cpp" "TradingManager.cpp" diff --git a/dGame/Character.h b/dGame/Character.h index 6c8ead30..b994fb61 100644 --- a/dGame/Character.h +++ b/dGame/Character.h @@ -457,6 +457,8 @@ public: void SetBillboardVisible(bool visible); + User* GetParentUser() const { return m_ParentUser; } + private: void UpdateInfoFromDatabase(); /** diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index 89b925c6..50ef5df2 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -15,7 +15,6 @@ #include "Spawner.h" #include "UserManager.h" #include "dpWorld.h" -#include "Player.h" #include "LUTriggers.h" #include "User.h" #include "EntityTimer.h" @@ -26,6 +25,7 @@ #include "eObjectBits.h" #include "PositionUpdate.h" #include "eChatMessageType.h" +#include "PlayerManager.h" //Component includes: #include "Component.h" @@ -95,7 +95,7 @@ #include "CDSkillBehaviorTable.h" #include "CDZoneTableTable.h" -Entity::Entity(const LWOOBJID& objectID, EntityInfo info, Entity* parentEntity) { +Entity::Entity(const LWOOBJID& objectID, EntityInfo info, User* parentUser, Entity* parentEntity) { m_ObjectID = objectID; m_TemplateID = info.lot; m_ParentEntity = parentEntity; @@ -124,9 +124,42 @@ Entity::Entity(const LWOOBJID& objectID, EntityInfo info, Entity* parentEntity) m_SpawnerNodeID = info.spawnerNodeID; if (info.lot != 1) m_PlayerIsReadyForUpdates = true; + if (parentUser) { + m_Character = parentUser->GetLastUsedChar(); + parentUser->SetLoggedInChar(objectID); + m_GMLevel = m_Character->GetGMLevel(); + + m_Character->SetEntity(this); + + PlayerManager::AddPlayer(this); + } } Entity::~Entity() { + if (IsPlayer()) { + LOG("Deleted player"); + + // Make sure the player exists first. Remove afterwards to prevent the OnPlayerExist functions from not being able to find the player. + if (!PlayerManager::RemovePlayer(this)) { + LOG("Unable to find player to remove from manager."); + return; + } + + Entity* zoneControl = Game::entityManager->GetZoneControlEntity(); + for (CppScripts::Script* script : CppScripts::GetEntityScripts(zoneControl)) { + script->OnPlayerExit(zoneControl, this); + } + + std::vector scriptedActs = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::SCRIPTED_ACTIVITY); + for (Entity* scriptEntity : scriptedActs) { + if (scriptEntity->GetObjectID() != zoneControl->GetObjectID()) { // Don't want to trigger twice on instance worlds + for (CppScripts::Script* script : CppScripts::GetEntityScripts(scriptEntity)) { + script->OnPlayerExit(scriptEntity, this); + } + } + } + } + if (m_Character) { m_Character->SaveXMLToDatabase(); } @@ -212,7 +245,7 @@ void Entity::Initialize() { * Not all components are implemented. Some are represented by a nullptr, as they hold no data. */ - if (GetParentUser()) { + if (m_Character && m_Character->GetParentUser()) { AddComponent()->LoadFromXml(m_Character->GetXMLDoc()); } @@ -437,7 +470,8 @@ void Entity::Initialize() { AddComponent(); - AddComponent(m_Character)->LoadFromXml(m_Character->GetXMLDoc()); + auto& systemAddress = m_Character->GetParentUser() ? m_Character->GetParentUser()->GetSystemAddress() : UNASSIGNED_SYSTEM_ADDRESS; + AddComponent(m_Character, systemAddress)->LoadFromXml(m_Character->GetXMLDoc()); AddComponent(); } @@ -788,14 +822,6 @@ bool Entity::operator!=(const Entity& other) const { return other.m_ObjectID != m_ObjectID; } -User* Entity::GetParentUser() const { - if (!IsPlayer()) { - return nullptr; - } - - return static_cast(this)->GetParentUser(); -} - Component* Entity::GetComponent(eReplicaComponentType componentID) const { const auto& index = m_Components.find(componentID); @@ -850,17 +876,12 @@ void Entity::SetProximityRadius(dpEntity* entity, std::string name) { void Entity::SetGMLevel(eGameMasterLevel value) { m_GMLevel = value; - if (GetParentUser()) { - Character* character = GetParentUser()->GetLastUsedChar(); + if (m_Character) m_Character->SetGMLevel(value); - if (character) { - character->SetGMLevel(value); - } - } + auto* characterComponent = GetComponent(); + if (!characterComponent) return; - CharacterComponent* character = GetComponent(); - if (!character) return; - character->SetGMLevel(value); + characterComponent->SetGMLevel(value); GameMessages::SendGMLevelBroadcast(m_ObjectID, value); @@ -1630,18 +1651,23 @@ bool Entity::GetIsDead() const { void Entity::AddLootItem(const Loot::Info& info) { if (!IsPlayer()) return; - auto& droppedLoot = static_cast(this)->GetDroppedLoot(); + + auto* characterComponent = GetComponent(); + if (!characterComponent) return; + + auto& droppedLoot = characterComponent->GetDroppedLoot(); droppedLoot.insert(std::make_pair(info.id, info)); } void Entity::PickupItem(const LWOOBJID& objectID) { if (!IsPlayer()) return; InventoryComponent* inv = GetComponent(); - if (!inv) return; + auto* characterComponent = GetComponent(); + if (!inv || !characterComponent) return; CDObjectsTable* objectsTable = CDClientManager::Instance().GetTable(); - auto& droppedLoot = static_cast(this)->GetDroppedLoot(); + auto& droppedLoot = characterComponent->GetDroppedLoot(); for (const auto& p : droppedLoot) { if (p.first == objectID) { @@ -1677,22 +1703,28 @@ void Entity::PickupItem(const LWOOBJID& objectID) { bool Entity::CanPickupCoins(uint64_t count) { if (!IsPlayer()) return false; - auto* player = static_cast(this); - auto droppedCoins = player->GetDroppedCoins(); + + auto* characterComponent = GetComponent(); + if (!characterComponent) return false; + + auto droppedCoins = characterComponent->GetDroppedCoins(); if (count > droppedCoins) { return false; } else { - player->SetDroppedCoins(droppedCoins - count); + characterComponent->SetDroppedCoins(droppedCoins - count); return true; } } void Entity::RegisterCoinDrop(uint64_t count) { if (!IsPlayer()) return; - auto* player = static_cast(this); - auto droppedCoins = player->GetDroppedCoins(); + + auto* characterComponent = GetComponent(); + if (!characterComponent) return; + + auto droppedCoins = characterComponent->GetDroppedCoins(); droppedCoins += count; - player->SetDroppedCoins(droppedCoins); + characterComponent->SetDroppedCoins(droppedCoins); } void Entity::AddChild(Entity* child) { @@ -1990,7 +2022,7 @@ std::vector Entity::GetTargetsInPhantom() { // Clean up invalid targets, like disconnected players m_TargetsInPhantom.erase(std::remove_if(m_TargetsInPhantom.begin(), m_TargetsInPhantom.end(), [](const LWOOBJID id) { return !Game::entityManager->GetEntity(id); - }), m_TargetsInPhantom.end()); + }), m_TargetsInPhantom.end()); std::vector enemies; for (const auto id : m_TargetsInPhantom) { @@ -2133,3 +2165,27 @@ void Entity::ProcessPositionUpdate(PositionUpdate& update) { if (updateChar) Game::entityManager->SerializeEntity(this); } + +const SystemAddress& Entity::GetSystemAddress() const { + auto* characterComponent = GetComponent(); + return characterComponent ? characterComponent->GetSystemAddress() : UNASSIGNED_SYSTEM_ADDRESS; +} + +const NiPoint3& Entity::GetRespawnPosition() const { + auto* characterComponent = GetComponent(); + return characterComponent ? characterComponent->GetRespawnPosition() : NiPoint3Constant::ZERO; +} + +const NiQuaternion& Entity::GetRespawnRotation() const { + auto* characterComponent = GetComponent(); + return characterComponent ? characterComponent->GetRespawnRotation() : NiQuaternionConstant::IDENTITY; +} + +void Entity::SetRespawnPos(const NiPoint3& position) { + auto* characterComponent = GetComponent(); + if (characterComponent) characterComponent->SetRespawnPos(position); +} +void Entity::SetRespawnRot(const NiQuaternion& rotation) { + auto* characterComponent = GetComponent(); + if (characterComponent) characterComponent->SetRespawnRot(rotation); +} diff --git a/dGame/Entity.h b/dGame/Entity.h index 3074842a..eb6eb956 100644 --- a/dGame/Entity.h +++ b/dGame/Entity.h @@ -47,10 +47,10 @@ namespace CppScripts { */ class Entity { public: - explicit Entity(const LWOOBJID& objectID, EntityInfo info, Entity* parentEntity = nullptr); - virtual ~Entity(); + explicit Entity(const LWOOBJID& objectID, EntityInfo info, User* parentUser = nullptr, Entity* parentEntity = nullptr); + ~Entity(); - virtual void Initialize(); + void Initialize(); bool operator==(const Entity& other) const; bool operator!=(const Entity& other) const; @@ -104,9 +104,7 @@ public: const NiQuaternion& GetRotation() const; - virtual User* GetParentUser() const; - - virtual const SystemAddress& GetSystemAddress() const { return UNASSIGNED_SYSTEM_ADDRESS; }; + const SystemAddress& GetSystemAddress() const; /** * Setters @@ -128,11 +126,9 @@ public: void SetRotation(const NiQuaternion& rotation); - virtual void SetRespawnPos(const NiPoint3& position) {} + void SetRespawnPos(const NiPoint3& position); - virtual void SetRespawnRot(const NiQuaternion& rotation) {} - - virtual void SetSystemAddress(const SystemAddress& value) {}; + void SetRespawnRot(const NiQuaternion& rotation); /** * Component management @@ -229,8 +225,8 @@ public: void TriggerEvent(eTriggerEventType event, Entity* optionalTarget = nullptr); void ScheduleDestructionAfterUpdate() { m_ShouldDestroyAfterUpdate = true; } - virtual const NiPoint3& GetRespawnPosition() const { return NiPoint3Constant::ZERO; } - virtual const NiQuaternion& GetRespawnRotation() const { return NiQuaternionConstant::IDENTITY; } + const NiPoint3& GetRespawnPosition() const; + const NiQuaternion& GetRespawnRotation() const; void Sleep(); void Wake(); diff --git a/dGame/EntityManager.cpp b/dGame/EntityManager.cpp index 10655d25..e1f2f46e 100644 --- a/dGame/EntityManager.cpp +++ b/dGame/EntityManager.cpp @@ -7,7 +7,6 @@ #include "GeneralUtils.h" #include "dServer.h" #include "Spawner.h" -#include "Player.h" #include "SkillComponent.h" #include "SwitchComponent.h" #include "UserManager.h" @@ -118,14 +117,7 @@ Entity* EntityManager::CreateEntity(EntityInfo info, User* user, Entity* parentE info.id = id; - Entity* entity; - - // Check if the entitty if a player, in case use the extended player entity class - if (user != nullptr) { - entity = new Player(id, info, user, parentEntity); - } else { - entity = new Entity(id, info, parentEntity); - } + Entity* entity = new Entity(id, info, user, parentEntity); // Initialize the entity entity->Initialize(); @@ -482,7 +474,7 @@ void EntityManager::UpdateGhosting() { m_PlayersToUpdateGhosting.clear(); } -void EntityManager::UpdateGhosting(Player* player) { +void EntityManager::UpdateGhosting(Entity* player) { if (player == nullptr) { return; } diff --git a/dGame/EntityManager.h b/dGame/EntityManager.h index 33d7aaff..352b927b 100644 --- a/dGame/EntityManager.h +++ b/dGame/EntityManager.h @@ -55,7 +55,7 @@ public: float GetGhostDistanceMin() const; void QueueGhostUpdate(LWOOBJID playerID); void UpdateGhosting(); - void UpdateGhosting(Player* player); + void UpdateGhosting(Entity* player); void CheckGhosting(Entity* entity); Entity* GetGhostCandidate(int32_t id); bool GetGhostingEnabled() const; diff --git a/dGame/Player.cpp b/dGame/Player.cpp deleted file mode 100644 index 8f414b43..00000000 --- a/dGame/Player.cpp +++ /dev/null @@ -1,71 +0,0 @@ -#include "Player.h" - -#include - -#include "Character.h" -#include "UserManager.h" -#include "EntityManager.h" -#include "Game.h" -#include "Logger.h" -#include "dZoneManager.h" -#include "User.h" -#include "CppScripts.h" -#include "Loot.h" -#include "eReplicaComponentType.h" -#include "PlayerManager.h" - -void Player::SetRespawnPos(const NiPoint3& position) { - if (!m_Character) return; - - m_respawnPos = position; - - m_Character->SetRespawnPoint(Game::zoneManager->GetZone()->GetWorldID(), position); - -} - -void Player::SetRespawnRot(const NiQuaternion& rotation) { - m_respawnRot = rotation; -} - -void Player::SetSystemAddress(const SystemAddress& value) { - m_SystemAddress = value; -} - -Player::Player(const LWOOBJID& objectID, const EntityInfo info, User* user, Entity* parentEntity) : Entity(objectID, info, parentEntity) { - m_ParentUser = user; - m_Character = m_ParentUser->GetLastUsedChar(); - m_ParentUser->SetLoggedInChar(objectID); - m_GMLevel = m_Character->GetGMLevel(); - m_SystemAddress = m_ParentUser->GetSystemAddress(); - m_DroppedCoins = 0; - - m_Character->SetEntity(this); - - PlayerManager::AddPlayer(this); -} - -Player::~Player() { - LOG("Deleted player"); - - // Make sure the player exists first. Remove afterwards to prevent the OnPlayerExist functions from not being able to find the player. - if (!PlayerManager::RemovePlayer(this)) { - LOG("Unable to find player to remove from manager."); - return; - } - - if (IsPlayer()) { - Entity* zoneControl = Game::entityManager->GetZoneControlEntity(); - for (CppScripts::Script* script : CppScripts::GetEntityScripts(zoneControl)) { - script->OnPlayerExit(zoneControl, this); - } - - std::vector scriptedActs = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::SCRIPTED_ACTIVITY); - for (Entity* scriptEntity : scriptedActs) { - if (scriptEntity->GetObjectID() != zoneControl->GetObjectID()) { // Don't want to trigger twice on instance worlds - for (CppScripts::Script* script : CppScripts::GetEntityScripts(scriptEntity)) { - script->OnPlayerExit(scriptEntity, this); - } - } - } - } -} diff --git a/dGame/Player.h b/dGame/Player.h deleted file mode 100644 index dd8efd9c..00000000 --- a/dGame/Player.h +++ /dev/null @@ -1,62 +0,0 @@ -#pragma once - -#include "Entity.h" - -/** - * Extended Entity for player data and behavior. - * - * Contains properties only a player entity would require, like associated SystemAddress and User. - * - * Keeps track of which entities are observed by this user for ghosting. - */ -class Player final : public Entity -{ -public: - explicit Player(const LWOOBJID& objectID, EntityInfo info, User* user, Entity* parentEntity = nullptr); - - /** - * Getters - */ - - User* GetParentUser() const override { return m_ParentUser; }; - - const SystemAddress& GetSystemAddress() const override { return m_SystemAddress; }; - - const NiPoint3& GetRespawnPosition() const override { return m_respawnPos; }; - - const NiQuaternion& GetRespawnRotation() const override { return m_respawnRot; }; - - std::map& GetDroppedLoot() { return m_DroppedLoot; }; - - uint64_t GetDroppedCoins() const { return m_DroppedCoins; }; - - /** - * Setters - */ - - void SetDroppedCoins(const uint64_t value) { m_DroppedCoins = value; }; - - void SetSystemAddress(const SystemAddress& value) override; - - void SetRespawnPos(const NiPoint3& position) override; - - void SetRespawnRot(const NiQuaternion& rotation) override; - - /** - * Ghosting - */ - - ~Player() override; -private: - SystemAddress m_SystemAddress; - - NiPoint3 m_respawnPos; - - NiQuaternion m_respawnRot; - - User* m_ParentUser; - - std::map m_DroppedLoot; - - uint64_t m_DroppedCoins; -}; diff --git a/dGame/PlayerManager.cpp b/dGame/PlayerManager.cpp index e3017f05..61e2568d 100644 --- a/dGame/PlayerManager.cpp +++ b/dGame/PlayerManager.cpp @@ -1,20 +1,19 @@ #include "PlayerManager.h" #include "Character.h" -#include "Player.h" #include "User.h" #include "UserManager.h" #include "eReplicaComponentType.h" namespace { - std::vector m_Players; + std::vector m_Players; }; -const std::vector& PlayerManager::GetAllPlayers() { +const std::vector& PlayerManager::GetAllPlayers() { return m_Players; } -void PlayerManager::AddPlayer(Player* player) { +void PlayerManager::AddPlayer(Entity* player) { const auto& iter = std::find(m_Players.begin(), m_Players.end(), player); if (iter == m_Players.end()) { @@ -22,7 +21,7 @@ void PlayerManager::AddPlayer(Player* player) { } } -bool PlayerManager::RemovePlayer(Player* player) { +bool PlayerManager::RemovePlayer(Entity* player) { const auto iter = std::find(m_Players.begin(), m_Players.end(), player); const bool toReturn = iter != m_Players.end(); @@ -33,21 +32,21 @@ bool PlayerManager::RemovePlayer(Player* player) { return toReturn; } -Player* PlayerManager::GetPlayer(const SystemAddress& sysAddr) { +Entity* PlayerManager::GetPlayer(const SystemAddress& sysAddr) { auto* entity = UserManager::Instance()->GetUser(sysAddr)->GetLastUsedChar()->GetEntity(); - return static_cast(entity); + return entity; } -Player* PlayerManager::GetPlayer(const std::string& name) { +Entity* PlayerManager::GetPlayer(const std::string& name) { const auto characters = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::CHARACTER); - Player* player = nullptr; + Entity* player = nullptr; for (auto* character : characters) { if (!character->IsPlayer()) continue; if (GeneralUtils::CaseInsensitiveStringCompare(name, character->GetCharacter()->GetName())) { - player = dynamic_cast(character); + player = character; break; } } @@ -55,8 +54,8 @@ Player* PlayerManager::GetPlayer(const std::string& name) { return player; } -Player* PlayerManager::GetPlayer(LWOOBJID playerID) { - Player* playerToReturn = nullptr; +Entity* PlayerManager::GetPlayer(LWOOBJID playerID) { + Entity* playerToReturn = nullptr; for (auto* player : m_Players) { if (player->GetObjectID() == playerID) { playerToReturn = player; diff --git a/dGame/PlayerManager.h b/dGame/PlayerManager.h index bb54f83b..7f6be5ba 100644 --- a/dGame/PlayerManager.h +++ b/dGame/PlayerManager.h @@ -5,21 +5,21 @@ #include -class Player; +class Entity; struct SystemAddress; namespace PlayerManager { - void AddPlayer(Player* player); + void AddPlayer(Entity* player); - bool RemovePlayer(Player* player); + bool RemovePlayer(Entity* player); - Player* GetPlayer(const SystemAddress& sysAddr); + Entity* GetPlayer(const SystemAddress& sysAddr); - Player* GetPlayer(const std::string& name); + Entity* GetPlayer(const std::string& name); - Player* GetPlayer(LWOOBJID playerID); + Entity* GetPlayer(LWOOBJID playerID); - const std::vector& GetAllPlayers(); + const std::vector& GetAllPlayers(); }; #endif //!__PLAYERMANAGER__H__ diff --git a/dGame/dComponents/ActivityComponent.cpp b/dGame/dComponents/ActivityComponent.cpp index aa6a4604..60a95952 100644 --- a/dGame/dComponents/ActivityComponent.cpp +++ b/dGame/dComponents/ActivityComponent.cpp @@ -10,7 +10,6 @@ #include "WorldPackets.h" #include "EntityManager.h" #include "ChatPackets.h" -#include "Player.h" #include "BitStreamUtils.h" #include "dServer.h" #include "GeneralUtils.h" diff --git a/dGame/dComponents/CharacterComponent.cpp b/dGame/dComponents/CharacterComponent.cpp index 70eec0cf..61b744f1 100644 --- a/dGame/dComponents/CharacterComponent.cpp +++ b/dGame/dComponents/CharacterComponent.cpp @@ -24,7 +24,7 @@ #include "WorldPackets.h" #include -CharacterComponent::CharacterComponent(Entity* parent, Character* character) : Component(parent) { +CharacterComponent::CharacterComponent(Entity* parent, Character* character, const SystemAddress& systemAddress) : Component(parent) { m_Character = character; m_IsRacing = false; @@ -46,6 +46,7 @@ CharacterComponent::CharacterComponent(Entity* parent, Character* character) : C m_CurrentActivity = eGameActivity::NONE; m_CountryCode = 0; m_LastUpdateTimestamp = std::time(nullptr); + m_SystemAddress = systemAddress; } bool CharacterComponent::LandingAnimDisabled(int zoneID) { @@ -762,8 +763,8 @@ void CharacterComponent::UpdateClientMinimap(bool showFaction, std::string ventu } void CharacterComponent::AwardClaimCodes() { - if (!m_Parent) return; - auto* user = m_Parent->GetParentUser(); + if (!m_Parent || !m_Parent->GetCharacter()) return; + auto* user = m_Parent->GetCharacter()->GetParentUser(); if (!user) return; auto rewardCodes = Database::Get()->GetRewardCodesByAccountID(user->GetAccountID()); @@ -817,3 +818,20 @@ void CharacterComponent::SendToZone(LWOMAPID zoneId, LWOCLONEID cloneId) const { Game::entityManager->DestructEntity(entity); }); } + +const SystemAddress& CharacterComponent::GetSystemAddress() const { + return m_SystemAddress; +} + +void CharacterComponent::SetRespawnPos(const NiPoint3& position) { + if (!m_Character) return; + + m_respawnPos = position; + + m_Character->SetRespawnPoint(Game::zoneManager->GetZone()->GetWorldID(), position); + +} + +void CharacterComponent::SetRespawnRot(const NiQuaternion& rotation) { + m_respawnRot = rotation; +} diff --git a/dGame/dComponents/CharacterComponent.h b/dGame/dComponents/CharacterComponent.h index a44d359d..01c26f9a 100644 --- a/dGame/dComponents/CharacterComponent.h +++ b/dGame/dComponents/CharacterComponent.h @@ -11,6 +11,7 @@ #include "tinyxml2.h" #include "eReplicaComponentType.h" #include +#include "Loot.h" enum class eGameActivity : uint32_t; @@ -65,7 +66,7 @@ class CharacterComponent final : public Component { public: static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::CHARACTER; - CharacterComponent(Entity* parent, Character* character); + CharacterComponent(Entity* parent, Character* character, const SystemAddress& systemAddress); ~CharacterComponent() override; void LoadFromXml(tinyxml2::XMLDocument* doc) override; @@ -289,6 +290,22 @@ public: */ void SendToZone(LWOMAPID zoneId, LWOCLONEID cloneId = 0) const; + const SystemAddress& GetSystemAddress() const; + + const NiPoint3& GetRespawnPosition() const { return m_respawnPos; }; + + void SetRespawnPos(const NiPoint3& position); + + const NiQuaternion& GetRespawnRotation() const { return m_respawnRot; }; + + void SetRespawnRot(const NiQuaternion& rotation); + + std::map& GetDroppedLoot() { return m_DroppedLoot; }; + + uint64_t GetDroppedCoins() const { return m_DroppedCoins; }; + + void SetDroppedCoins(const uint64_t value) { m_DroppedCoins = value; }; + /** * Character info regarding this character, including clothing styles, etc. */ @@ -579,6 +596,16 @@ private: std::array m_ClaimCodes{}; void AwardClaimCodes(); + + SystemAddress m_SystemAddress; + + NiPoint3 m_respawnPos; + + NiQuaternion m_respawnRot; + + std::map m_DroppedLoot; + + uint64_t m_DroppedCoins = 0; }; #endif // CHARACTERCOMPONENT_H diff --git a/dGame/dComponents/DestroyableComponent.cpp b/dGame/dComponents/DestroyableComponent.cpp index 64dca4f1..fd89da4d 100644 --- a/dGame/dComponents/DestroyableComponent.cpp +++ b/dGame/dComponents/DestroyableComponent.cpp @@ -251,13 +251,14 @@ void DestroyableComponent::SetMaxHealth(float value, bool playAnim) { if (playAnim) { // Now update the player bar - if (!m_Parent->GetParentUser()) return; + auto* characterComponent = m_Parent->GetComponent(); + if (!characterComponent) return; AMFArrayValue args; args.Insert("amount", std::to_string(difference)); args.Insert("type", "health"); - GameMessages::SendUIMessageServerToSingleClient(m_Parent, m_Parent->GetParentUser()->GetSystemAddress(), "MaxPlayerBarUpdate", args); + GameMessages::SendUIMessageServerToSingleClient(m_Parent, characterComponent->GetSystemAddress(), "MaxPlayerBarUpdate", args); } Game::entityManager->SerializeEntity(m_Parent); @@ -292,13 +293,14 @@ void DestroyableComponent::SetMaxArmor(float value, bool playAnim) { if (playAnim) { // Now update the player bar - if (!m_Parent->GetParentUser()) return; + auto* characterComponent = m_Parent->GetComponent(); + if (!characterComponent) return; AMFArrayValue args; args.Insert("amount", std::to_string(value)); args.Insert("type", "armor"); - GameMessages::SendUIMessageServerToSingleClient(m_Parent, m_Parent->GetParentUser()->GetSystemAddress(), "MaxPlayerBarUpdate", args); + GameMessages::SendUIMessageServerToSingleClient(m_Parent, characterComponent->GetSystemAddress(), "MaxPlayerBarUpdate", args); } Game::entityManager->SerializeEntity(m_Parent); @@ -332,13 +334,14 @@ void DestroyableComponent::SetMaxImagination(float value, bool playAnim) { if (playAnim) { // Now update the player bar - if (!m_Parent->GetParentUser()) return; + auto* characterComponent = m_Parent->GetComponent(); + if (!characterComponent) return; AMFArrayValue args; args.Insert("amount", std::to_string(difference)); args.Insert("type", "imagination"); - GameMessages::SendUIMessageServerToSingleClient(m_Parent, m_Parent->GetParentUser()->GetSystemAddress(), "MaxPlayerBarUpdate", args); + GameMessages::SendUIMessageServerToSingleClient(m_Parent, characterComponent->GetSystemAddress(), "MaxPlayerBarUpdate", args); } Game::entityManager->SerializeEntity(m_Parent); } diff --git a/dGame/dComponents/InventoryComponent.cpp b/dGame/dComponents/InventoryComponent.cpp index 5e6af885..97c1198b 100644 --- a/dGame/dComponents/InventoryComponent.cpp +++ b/dGame/dComponents/InventoryComponent.cpp @@ -14,7 +14,6 @@ #include "Character.h" #include "EntityManager.h" #include "ItemSet.h" -#include "Player.h" #include "PetComponent.h" #include "PossessorComponent.h" #include "PossessableComponent.h" diff --git a/dGame/dComponents/PropertyManagementComponent.cpp b/dGame/dComponents/PropertyManagementComponent.cpp index 0f6eb5a8..0dfc04af 100644 --- a/dGame/dComponents/PropertyManagementComponent.cpp +++ b/dGame/dComponents/PropertyManagementComponent.cpp @@ -14,7 +14,6 @@ #include "Item.h" #include "Database.h" #include "ObjectIDManager.h" -#include "Player.h" #include "RocketLaunchpadControlComponent.h" #include "PropertyEntranceComponent.h" #include "InventoryComponent.h" @@ -177,8 +176,6 @@ bool PropertyManagementComponent::Claim(const LWOOBJID playerId) { auto* entity = Game::entityManager->GetEntity(playerId); - auto* user = entity->GetParentUser(); - auto character = entity->GetCharacter(); if (!character) return false; diff --git a/dGame/dComponents/RacingControlComponent.cpp b/dGame/dComponents/RacingControlComponent.cpp index 742563cc..824e7f36 100644 --- a/dGame/dComponents/RacingControlComponent.cpp +++ b/dGame/dComponents/RacingControlComponent.cpp @@ -12,7 +12,6 @@ #include "Item.h" #include "MissionComponent.h" #include "ModuleAssemblyComponent.h" -#include "Player.h" #include "PossessableComponent.h" #include "PossessorComponent.h" #include "eRacingTaskParam.h" diff --git a/dGame/dComponents/TriggerComponent.cpp b/dGame/dComponents/TriggerComponent.cpp index 6b83ae73..bb297dbc 100644 --- a/dGame/dComponents/TriggerComponent.cpp +++ b/dGame/dComponents/TriggerComponent.cpp @@ -9,7 +9,6 @@ #include "ControllablePhysicsComponent.h" #include "MissionComponent.h" #include "PhantomPhysicsComponent.h" -#include "Player.h" #include "QuickBuildComponent.h" #include "SkillComponent.h" #include "eEndBehavior.h" diff --git a/dGame/dGameMessages/GameMessageHandler.cpp b/dGame/dGameMessages/GameMessageHandler.cpp index fa11c086..07df3c60 100644 --- a/dGame/dGameMessages/GameMessageHandler.cpp +++ b/dGame/dGameMessages/GameMessageHandler.cpp @@ -18,7 +18,6 @@ #include "Character.h" #include "ControllablePhysicsComponent.h" #include "dZoneManager.h" -#include "Player.h" #include "CppScripts.h" #include "CDClientDatabase.h" diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index 1214c951..a81fec70 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -20,7 +20,6 @@ #include "WorldPackets.h" #include "Item.h" #include "ZCompression.h" -#include "Player.h" #include "dConfig.h" #include "TeamManager.h" #include "ChatPackets.h" @@ -2584,6 +2583,7 @@ void GameMessages::HandleBBBSaveRequest(RakNet::BitStream* inStream, Entity* ent //We need to get a new ID for our model first: ObjectIDManager::RequestPersistentID([=](uint32_t newID) { + if (!entity || !entity->GetCharacter() || !entity->GetCharacter()->GetParentUser()) return; LWOOBJID newIDL = newID; GeneralUtils::SetBit(newIDL, eObjectBits::CHARACTER); GeneralUtils::SetBit(newIDL, eObjectBits::PERSISTENT); @@ -2606,7 +2606,7 @@ void GameMessages::HandleBBBSaveRequest(RakNet::BitStream* inStream, Entity* ent //Insert into ugc: std::string str(sd0Data.get(), sd0Size); std::istringstream sd0DataStream(str); - Database::Get()->InsertNewUgcModel(sd0DataStream, blueprintIDSmall, entity->GetParentUser()->GetAccountID(), entity->GetCharacter()->GetID()); + Database::Get()->InsertNewUgcModel(sd0DataStream, blueprintIDSmall, entity->GetCharacter()->GetParentUser()->GetAccountID(), entity->GetCharacter()->GetID()); //Insert into the db as a BBB model: IPropertyContents::Model model; @@ -5110,13 +5110,8 @@ void GameMessages::HandleSetFlag(RakNet::BitStream* inStream, Entity* entity) { inStream->Read(bFlag); inStream->Read(iFlagID); - auto user = entity->GetParentUser(); - if (user) { - auto character = user->GetLastUsedChar(); - if (!character) return; - - character->SetPlayerFlag(iFlagID, bFlag); - } + auto character = entity->GetCharacter(); + if (character) character->SetPlayerFlag(iFlagID, bFlag); } void GameMessages::HandleRespondToMission(RakNet::BitStream* inStream, Entity* entity) { diff --git a/dGame/dMission/Mission.cpp b/dGame/dMission/Mission.cpp index 6799b834..40ab0688 100644 --- a/dGame/dMission/Mission.cpp +++ b/dGame/dMission/Mission.cpp @@ -24,6 +24,7 @@ #include "eMissionTaskType.h" #include "eMissionLockState.h" #include "eReplicaComponentType.h" +#include "Character.h" #include "CDMissionEmailTable.h" @@ -208,8 +209,8 @@ Entity* Mission::GetAssociate() const { return m_MissionComponent->GetParent(); } -User* Mission::GetUser() const { - return GetAssociate()->GetParentUser(); +Character* Mission::GetCharacter() const { + return GetAssociate()->GetCharacter(); } uint32_t Mission::GetMissionId() const { @@ -390,7 +391,7 @@ void Mission::Catchup() { if (type == eMissionTaskType::PLAYER_FLAG) { for (int32_t target : task->GetAllTargets()) { - const auto flag = GetUser()->GetLastUsedChar()->GetPlayerFlag(target); + const auto flag = GetCharacter()->GetPlayerFlag(target); if (!flag) { continue; @@ -413,7 +414,7 @@ void Mission::YieldRewards() { return; } - auto* character = GetUser()->GetLastUsedChar(); + auto* character = GetCharacter(); auto* inventoryComponent = entity->GetComponent(); auto* levelComponent = entity->GetComponent(); @@ -599,8 +600,10 @@ void Mission::SetMissionState(const eMissionState state, const bool sendingRewar if (entity == nullptr) { return; } + auto* characterComponent = entity->GetComponent(); + if (!characterComponent) return; - GameMessages::SendNotifyMission(entity, entity->GetParentUser()->GetSystemAddress(), info.id, static_cast(state), sendingRewards); + GameMessages::SendNotifyMission(entity, characterComponent->GetSystemAddress(), info.id, static_cast(state), sendingRewards); } void Mission::SetMissionTypeState(eMissionLockState state, const std::string& type, const std::string& subType) { diff --git a/dGame/dMission/Mission.h b/dGame/dMission/Mission.h index f7c17003..d8c104e8 100644 --- a/dGame/dMission/Mission.h +++ b/dGame/dMission/Mission.h @@ -17,6 +17,7 @@ namespace tinyxml2 { enum class eMissionState : int; enum class eMissionLockState : int; class MissionComponent; +class Character; /** * A mission (or achievement) that a player may unlock, progress and complete. @@ -46,7 +47,7 @@ public: * Returns the account owns the entity that is currently progressing this mission * @return the account owns the entity that is currently progressing this mission */ - User* GetUser() const; + Character* GetCharacter() const; /** * Returns the current state of this mission diff --git a/dGame/dPropertyBehaviors/ControlBehaviors.cpp b/dGame/dPropertyBehaviors/ControlBehaviors.cpp index c541257c..5fee358d 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviors.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviors.cpp @@ -13,6 +13,7 @@ #include "User.h" #include "tinyxml2.h" #include "CDClientDatabase.h" +#include "CharacterComponent.h" // Message includes #include "Action.h" @@ -145,10 +146,12 @@ void ControlBehaviors::ProcessCommand(Entity* modelEntity, const SystemAddress& } else if (command == "moveToInventory") { MoveToInventoryMessage msg(arguments); context.modelComponent->MoveToInventory(msg); + auto* characterComponent = modelOwner->GetComponent(); + if (!characterComponent) return; AMFArrayValue args; args.Insert("BehaviorID", std::to_string(msg.GetBehaviorId())); - GameMessages::SendUIMessageServerToSingleClient(modelOwner, modelOwner->GetParentUser()->GetSystemAddress(), "BehaviorRemoved", args); + GameMessages::SendUIMessageServerToSingleClient(modelOwner, characterComponent->GetSystemAddress(), "BehaviorRemoved", args); SendBehaviorListToClient(context); } else if (command == "updateAction") { diff --git a/dGame/dUtilities/CheatDetection.cpp b/dGame/dUtilities/CheatDetection.cpp index bc50b2cc..a87157a1 100644 --- a/dGame/dUtilities/CheatDetection.cpp +++ b/dGame/dUtilities/CheatDetection.cpp @@ -2,7 +2,6 @@ #include "Database.h" #include "Entity.h" #include "PossessableComponent.h" -#include "Player.h" #include "Game.h" #include "EntityManager.h" #include "Character.h" @@ -59,13 +58,13 @@ void LogAndSaveFailedAntiCheatCheck(const LWOOBJID& id, const SystemAddress& sys player->GetCharacter()->GetName().c_str(), player->GetObjectID(), sysAddr.ToString(), entity->GetCharacter()->GetName().c_str(), entity->GetObjectID()); - toReport = player->GetParentUser(); + if (player->GetCharacter()) toReport = player->GetCharacter()->GetParentUser(); // In the case that the target entity id did not exist, just log the player info. } else if (player) { LOG("Player (%s) (%llu) at system address (%s) with sending player (%llu) does not match their own.", player->GetCharacter()->GetName().c_str(), player->GetObjectID(), sysAddr.ToString(), id); - toReport = player->GetParentUser(); + if (player->GetCharacter()) toReport = player->GetCharacter()->GetParentUser(); // In the rare case that the player does not exist, just log the system address and who the target id was. } else { LOG("Player at system address (%s) with sending player (%llu) does not match their own.", diff --git a/dGame/dUtilities/SlashCommandHandler.cpp b/dGame/dUtilities/SlashCommandHandler.cpp index 35c5f7a9..0b5133ff 100644 --- a/dGame/dUtilities/SlashCommandHandler.cpp +++ b/dGame/dUtilities/SlashCommandHandler.cpp @@ -53,7 +53,6 @@ #include "Loot.h" #include "EntityInfo.h" #include "LUTriggers.h" -#include "Player.h" #include "PhantomPhysicsComponent.h" #include "ProximityMonitorComponent.h" #include "dpShapeSphere.h" @@ -1017,7 +1016,9 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } } else { - accountId = player->GetParentUser()->GetAccountID(); + auto* character = player->GetCharacter(); + auto* user = character != nullptr ? character->GetParentUser() : nullptr; + if (user) accountId = user->GetAccountID(); characterId = player->GetObjectID(); } @@ -1045,7 +1046,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit expire += 60 * 60 * hours; } - Database::Get()->UpdateAccountUnmuteTime(accountId, expire); + if (accountId != 0) Database::Get()->UpdateAccountUnmuteTime(accountId, expire); char buffer[32] = "brought up for review.\0"; @@ -1109,10 +1110,12 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } } else { - accountId = player->GetParentUser()->GetAccountID(); + auto* character = player->GetCharacter(); + auto* user = character != nullptr ? character->GetParentUser() : nullptr; + if (user) accountId = user->GetAccountID(); } - Database::Get()->UpdateAccountBan(accountId, true); + if (accountId != 0) Database::Get()->UpdateAccountBan(accountId, true); if (player != nullptr) { Game::server->Disconnect(player->GetSystemAddress(), eServerDisconnectIdentifiers::FREE_TRIAL_EXPIRED); @@ -1423,7 +1426,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit } // Allow for this on even while not a GM, as it sometimes toggles incorrrectly. - if (chatCommand == "gminvis" && entity->GetParentUser()->GetMaxGMLevel() >= eGameMasterLevel::DEVELOPER) { + if (chatCommand == "gminvis" && entity->GetCharacter()->GetParentUser()->GetMaxGMLevel() >= eGameMasterLevel::DEVELOPER) { GameMessages::SendToggleGMInvis(entity->GetObjectID(), true, UNASSIGNED_SYSTEM_ADDRESS); return; diff --git a/dScripts/02_server/Map/General/PetDigServer.cpp b/dScripts/02_server/Map/General/PetDigServer.cpp index 0ea78e4f..a55c2f29 100644 --- a/dScripts/02_server/Map/General/PetDigServer.cpp +++ b/dScripts/02_server/Map/General/PetDigServer.cpp @@ -107,7 +107,7 @@ void PetDigServer::HandleXBuildDig(const Entity* self, Entity* owner, Entity* pe return; auto* playerEntity = Game::entityManager->GetEntity(playerID); - if (!playerEntity || !playerEntity->GetParentUser() || !playerEntity->GetParentUser()->GetLastUsedChar()) + if (!playerEntity || !playerEntity->GetCharacter()) return; auto* player = playerEntity->GetCharacter(); diff --git a/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp b/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp index c8563b53..1952831a 100644 --- a/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp +++ b/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp @@ -2,7 +2,6 @@ #include "EntityManager.h" #include "GameMessages.h" #include "dZoneManager.h" -#include "Player.h" #include "Character.h" #include "ShootingGalleryComponent.h" #include "PossessorComponent.h" diff --git a/dWorldServer/WorldServer.cpp b/dWorldServer/WorldServer.cpp index 6a8ed074..550fc7ee 100644 --- a/dWorldServer/WorldServer.cpp +++ b/dWorldServer/WorldServer.cpp @@ -56,7 +56,6 @@ #include "DestroyableComponent.h" #include "Game.h" #include "MasterPackets.h" -#include "Player.h" #include "PropertyManagementComponent.h" #include "AssetManager.h" #include "LevelProgressionComponent.h" @@ -607,9 +606,10 @@ void HandlePacketChat(Packet* packet) { inStream.Read(expire); auto* entity = Game::entityManager->GetEntity(playerId); - - if (entity != nullptr) { - entity->GetParentUser()->SetMuteExpire(expire); + auto* character = entity != nullptr ? entity->GetCharacter() : nullptr; + auto* user = character != nullptr ? character->GetParentUser() : nullptr; + if (user) { + user->SetMuteExpire(expire); entity->GetCharacter()->SendMuteNotice(); } @@ -1127,9 +1127,10 @@ void HandlePacket(Packet* packet) { //Mail::HandleNotificationRequest(packet->systemAddress, player->GetObjectID()); //Notify chat that a player has loaded: - { - const auto& playerName = player->GetCharacter()->GetName(); - //RakNet::RakString playerName(player->GetCharacter()->GetName().c_str()); + auto* character = player->GetCharacter(); + auto* user = character != nullptr ? character->GetParentUser() : nullptr; + if (user) { + const auto& playerName = character->GetName(); CBITSTREAM; BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::PLAYER_ADDED_NOTIFICATION); @@ -1143,7 +1144,7 @@ void HandlePacket(Packet* packet) { bitStream.Write(zone.GetMapID()); bitStream.Write(zone.GetInstanceID()); bitStream.Write(zone.GetCloneID()); - bitStream.Write(player->GetParentUser()->GetMuteExpire()); + bitStream.Write(user->GetMuteExpire()); bitStream.Write(player->GetGMLevel()); Game::chatServer->Send(&bitStream, SYSTEM_PRIORITY, RELIABLE, 0, Game::chatSysAddr, false); From 8e2914813740edff09f39e2c42281b1df7b0e245 Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Sun, 4 Feb 2024 16:39:00 -0800 Subject: [PATCH 3/5] actually use clamped value --- dPhysics/dpGrid.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/dPhysics/dpGrid.cpp b/dPhysics/dpGrid.cpp index f498c491..6e38be92 100644 --- a/dPhysics/dpGrid.cpp +++ b/dPhysics/dpGrid.cpp @@ -30,8 +30,8 @@ void dpGrid::Add(dpEntity* entity) { int cellZ = (int)std::round(entity->m_Position.z) / dpGrid::CELL_SIZE + NUM_CELLS / 2; // Clamp values to the range [0, NUM_CELLS - 1] - std::clamp(cellX, 0, NUM_CELLS - 1); - std::clamp(cellZ, 0, NUM_CELLS - 1); + cellX = std::clamp(cellX, 0, NUM_CELLS - 1); + cellZ = std::clamp(cellZ, 0, NUM_CELLS - 1); //Add to cell: m_Cells[cellX][cellZ].push_back(entity); @@ -49,11 +49,11 @@ void dpGrid::Move(dpEntity* entity, float x, float z) { int cellZ = (int)std::round(z) / dpGrid::CELL_SIZE + NUM_CELLS / 2; // Clamp values to the range [0, NUM_CELLS - 1] - std::clamp(cellX, 0, NUM_CELLS - 1); - std::clamp(cellZ, 0, NUM_CELLS - 1); + cellX = std::clamp(cellX, 0, NUM_CELLS - 1); + cellZ = std::clamp(cellZ, 0, NUM_CELLS - 1); - std::clamp(oldCellX, 0, NUM_CELLS - 1); - std::clamp(oldCellZ, 0, NUM_CELLS - 1); + oldCellX = std::clamp(oldCellX, 0, NUM_CELLS - 1); + oldCellZ = std::clamp(oldCellZ, 0, NUM_CELLS - 1); if (oldCellX == cellX && oldCellZ == cellZ) return; @@ -77,8 +77,8 @@ void dpGrid::Delete(dpEntity* entity) { int oldCellZ = (int)std::round(entity->m_Position.z) / dpGrid::CELL_SIZE + NUM_CELLS / 2; // Clamp values to the range [0, NUM_CELLS - 1] - std::clamp(oldCellX, 0, NUM_CELLS - 1); - std::clamp(oldCellZ, 0, NUM_CELLS - 1); + cellX = std::clamp(oldCellX, 0, NUM_CELLS - 1); + cellZ = std::clamp(oldCellZ, 0, NUM_CELLS - 1); auto& cell = m_Cells[oldCellX][oldCellZ]; auto toRemove = std::find(cell.begin(), cell.end(), entity); From a88ef0c3250224bc585067d9cad9d8a7f449e25c Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Sun, 4 Feb 2024 16:44:40 -0800 Subject: [PATCH 4/5] Update dpGrid.cpp --- dPhysics/dpGrid.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dPhysics/dpGrid.cpp b/dPhysics/dpGrid.cpp index 6e38be92..8ec944fd 100644 --- a/dPhysics/dpGrid.cpp +++ b/dPhysics/dpGrid.cpp @@ -77,8 +77,8 @@ void dpGrid::Delete(dpEntity* entity) { int oldCellZ = (int)std::round(entity->m_Position.z) / dpGrid::CELL_SIZE + NUM_CELLS / 2; // Clamp values to the range [0, NUM_CELLS - 1] - cellX = std::clamp(oldCellX, 0, NUM_CELLS - 1); - cellZ = std::clamp(oldCellZ, 0, NUM_CELLS - 1); + oldCellX = std::clamp(oldCellX, 0, NUM_CELLS - 1); + oldCellZ = std::clamp(oldCellZ, 0, NUM_CELLS - 1); auto& cell = m_Cells[oldCellX][oldCellZ]; auto toRemove = std::find(cell.begin(), cell.end(), entity); From 395e5c1c6660bb10e9f33c5e63cb9b33b919b53c Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Tue, 6 Feb 2024 06:53:51 -0800 Subject: [PATCH 5/5] Remove transitive include for Detour (#1450) Moves it to the 1 cpp file that uses it and locks down its header. Still compiles and links. --- dNavigation/dNavMesh.cpp | 9 +-------- dNavigation/dNavMesh.h | 30 ++++++++++++------------------ dPhysics/dpWorld.cpp | 2 +- 3 files changed, 14 insertions(+), 27 deletions(-) diff --git a/dNavigation/dNavMesh.cpp b/dNavigation/dNavMesh.cpp index ab9ed2d5..f49dd31e 100644 --- a/dNavigation/dNavMesh.cpp +++ b/dNavigation/dNavMesh.cpp @@ -11,6 +11,7 @@ #include "dZoneManager.h" #include "DluAssert.h" +#include "DetourExtensions.h" dNavMesh::dNavMesh(uint32_t zoneId) { m_ZoneId = zoneId; @@ -30,16 +31,8 @@ dNavMesh::dNavMesh(uint32_t zoneId) { dNavMesh::~dNavMesh() { // Clean up Recast information - if(m_Solid) rcFreeHeightField(m_Solid); - if (m_CHF) rcFreeCompactHeightfield(m_CHF); - if (m_CSet) rcFreeContourSet(m_CSet); - if (m_PMesh) rcFreePolyMesh(m_PMesh); - if (m_PMDMesh) rcFreePolyMeshDetail(m_PMDMesh); if (m_NavMesh) dtFreeNavMesh(m_NavMesh); if (m_NavQuery) dtFreeNavMeshQuery(m_NavQuery); - - if (m_Ctx) delete m_Ctx; - if (m_Triareas) delete[] m_Triareas; } diff --git a/dNavigation/dNavMesh.h b/dNavigation/dNavMesh.h index 600b8b86..8a55c649 100644 --- a/dNavigation/dNavMesh.h +++ b/dNavigation/dNavMesh.h @@ -2,13 +2,17 @@ #include #include -#include -#include -#include - -#include "DetourExtensions.h" class NiPoint3; +class rcHeightfield; +class rcCompactHeightfield; +class rcContourSet; +class rcPolyMesh; +class rcPolyMeshDetail; +class InputGeom; +class dtNavMesh; +class dtNavMeshQuery; +class rcContext; class dNavMesh { public: @@ -26,24 +30,14 @@ public: float GetHeightAtPoint(const NiPoint3& location, const float halfExtentsHeight = 32.0f) const; std::vector GetPath(const NiPoint3& startPos, const NiPoint3& endPos, float speed = 10.0f); - class dtNavMesh* GetdtNavMesh() { return m_NavMesh; } + bool IsNavmeshLoaded() { return m_NavMesh != nullptr; } private: void LoadNavmesh(); uint32_t m_ZoneId; - uint8_t* m_Triareas = nullptr; - rcHeightfield* m_Solid = nullptr; - rcCompactHeightfield* m_CHF = nullptr; - rcContourSet* m_CSet = nullptr; - rcPolyMesh* m_PMesh = nullptr; - rcConfig m_Config; - rcPolyMeshDetail* m_PMDMesh = nullptr; - - class InputGeom* m_Geometry = nullptr; - class dtNavMesh* m_NavMesh = nullptr; - class dtNavMeshQuery* m_NavQuery = nullptr; + dtNavMesh* m_NavMesh = nullptr; + dtNavMeshQuery* m_NavQuery = nullptr; uint8_t m_NavMeshDrawFlags; - rcContext* m_Ctx = nullptr; }; diff --git a/dPhysics/dpWorld.cpp b/dPhysics/dpWorld.cpp index e820eac2..4ed54858 100644 --- a/dPhysics/dpWorld.cpp +++ b/dPhysics/dpWorld.cpp @@ -81,7 +81,7 @@ void dpWorld::Shutdown() { } bool dpWorld::IsLoaded() { - return m_NavMesh->GetdtNavMesh() != nullptr; + return m_NavMesh->IsNavmeshLoaded(); } void dpWorld::StepWorld(float deltaTime) {