Merge branch 'main' into md5-out-of-common

This commit is contained in:
David Markowitz 2024-02-08 03:55:22 -08:00
commit 186a5027ec
31 changed files with 229 additions and 287 deletions

View File

@ -2,7 +2,6 @@ set(DGAME_SOURCES "Character.cpp"
"Entity.cpp" "Entity.cpp"
"EntityManager.cpp" "EntityManager.cpp"
"LeaderboardManager.cpp" "LeaderboardManager.cpp"
"Player.cpp"
"PlayerManager.cpp" "PlayerManager.cpp"
"TeamManager.cpp" "TeamManager.cpp"
"TradingManager.cpp" "TradingManager.cpp"

View File

@ -457,6 +457,8 @@ public:
void SetBillboardVisible(bool visible); void SetBillboardVisible(bool visible);
User* GetParentUser() const { return m_ParentUser; }
private: private:
void UpdateInfoFromDatabase(); void UpdateInfoFromDatabase();
/** /**

View File

@ -15,7 +15,6 @@
#include "Spawner.h" #include "Spawner.h"
#include "UserManager.h" #include "UserManager.h"
#include "dpWorld.h" #include "dpWorld.h"
#include "Player.h"
#include "LUTriggers.h" #include "LUTriggers.h"
#include "User.h" #include "User.h"
#include "EntityTimer.h" #include "EntityTimer.h"
@ -26,6 +25,7 @@
#include "eObjectBits.h" #include "eObjectBits.h"
#include "PositionUpdate.h" #include "PositionUpdate.h"
#include "eChatMessageType.h" #include "eChatMessageType.h"
#include "PlayerManager.h"
//Component includes: //Component includes:
#include "Component.h" #include "Component.h"
@ -95,7 +95,7 @@
#include "CDSkillBehaviorTable.h" #include "CDSkillBehaviorTable.h"
#include "CDZoneTableTable.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_ObjectID = objectID;
m_TemplateID = info.lot; m_TemplateID = info.lot;
m_ParentEntity = parentEntity; m_ParentEntity = parentEntity;
@ -124,9 +124,42 @@ Entity::Entity(const LWOOBJID& objectID, EntityInfo info, Entity* parentEntity)
m_SpawnerNodeID = info.spawnerNodeID; m_SpawnerNodeID = info.spawnerNodeID;
if (info.lot != 1) m_PlayerIsReadyForUpdates = true; 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() { 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<Entity*> 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) { if (m_Character) {
m_Character->SaveXMLToDatabase(); 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. * 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<MissionComponent>()->LoadFromXml(m_Character->GetXMLDoc()); AddComponent<MissionComponent>()->LoadFromXml(m_Character->GetXMLDoc());
} }
@ -437,7 +470,8 @@ void Entity::Initialize() {
AddComponent<PlayerForcedMovementComponent>(); AddComponent<PlayerForcedMovementComponent>();
AddComponent<CharacterComponent>(m_Character)->LoadFromXml(m_Character->GetXMLDoc()); auto& systemAddress = m_Character->GetParentUser() ? m_Character->GetParentUser()->GetSystemAddress() : UNASSIGNED_SYSTEM_ADDRESS;
AddComponent<CharacterComponent>(m_Character, systemAddress)->LoadFromXml(m_Character->GetXMLDoc());
AddComponent<GhostComponent>(); AddComponent<GhostComponent>();
} }
@ -788,14 +822,6 @@ bool Entity::operator!=(const Entity& other) const {
return other.m_ObjectID != m_ObjectID; return other.m_ObjectID != m_ObjectID;
} }
User* Entity::GetParentUser() const {
if (!IsPlayer()) {
return nullptr;
}
return static_cast<const Player*>(this)->GetParentUser();
}
Component* Entity::GetComponent(eReplicaComponentType componentID) const { Component* Entity::GetComponent(eReplicaComponentType componentID) const {
const auto& index = m_Components.find(componentID); const auto& index = m_Components.find(componentID);
@ -850,17 +876,12 @@ void Entity::SetProximityRadius(dpEntity* entity, std::string name) {
void Entity::SetGMLevel(eGameMasterLevel value) { void Entity::SetGMLevel(eGameMasterLevel value) {
m_GMLevel = value; m_GMLevel = value;
if (GetParentUser()) { if (m_Character) m_Character->SetGMLevel(value);
Character* character = GetParentUser()->GetLastUsedChar();
if (character) { auto* characterComponent = GetComponent<CharacterComponent>();
character->SetGMLevel(value); if (!characterComponent) return;
}
}
CharacterComponent* character = GetComponent<CharacterComponent>(); characterComponent->SetGMLevel(value);
if (!character) return;
character->SetGMLevel(value);
GameMessages::SendGMLevelBroadcast(m_ObjectID, value); GameMessages::SendGMLevelBroadcast(m_ObjectID, value);
@ -1630,18 +1651,23 @@ bool Entity::GetIsDead() const {
void Entity::AddLootItem(const Loot::Info& info) { void Entity::AddLootItem(const Loot::Info& info) {
if (!IsPlayer()) return; if (!IsPlayer()) return;
auto& droppedLoot = static_cast<Player*>(this)->GetDroppedLoot();
auto* characterComponent = GetComponent<CharacterComponent>();
if (!characterComponent) return;
auto& droppedLoot = characterComponent->GetDroppedLoot();
droppedLoot.insert(std::make_pair(info.id, info)); droppedLoot.insert(std::make_pair(info.id, info));
} }
void Entity::PickupItem(const LWOOBJID& objectID) { void Entity::PickupItem(const LWOOBJID& objectID) {
if (!IsPlayer()) return; if (!IsPlayer()) return;
InventoryComponent* inv = GetComponent<InventoryComponent>(); InventoryComponent* inv = GetComponent<InventoryComponent>();
if (!inv) return; auto* characterComponent = GetComponent<CharacterComponent>();
if (!inv || !characterComponent) return;
CDObjectsTable* objectsTable = CDClientManager::Instance().GetTable<CDObjectsTable>(); CDObjectsTable* objectsTable = CDClientManager::Instance().GetTable<CDObjectsTable>();
auto& droppedLoot = static_cast<Player*>(this)->GetDroppedLoot(); auto& droppedLoot = characterComponent->GetDroppedLoot();
for (const auto& p : droppedLoot) { for (const auto& p : droppedLoot) {
if (p.first == objectID) { if (p.first == objectID) {
@ -1677,22 +1703,28 @@ void Entity::PickupItem(const LWOOBJID& objectID) {
bool Entity::CanPickupCoins(uint64_t count) { bool Entity::CanPickupCoins(uint64_t count) {
if (!IsPlayer()) return false; if (!IsPlayer()) return false;
auto* player = static_cast<Player*>(this);
auto droppedCoins = player->GetDroppedCoins(); auto* characterComponent = GetComponent<CharacterComponent>();
if (!characterComponent) return false;
auto droppedCoins = characterComponent->GetDroppedCoins();
if (count > droppedCoins) { if (count > droppedCoins) {
return false; return false;
} else { } else {
player->SetDroppedCoins(droppedCoins - count); characterComponent->SetDroppedCoins(droppedCoins - count);
return true; return true;
} }
} }
void Entity::RegisterCoinDrop(uint64_t count) { void Entity::RegisterCoinDrop(uint64_t count) {
if (!IsPlayer()) return; if (!IsPlayer()) return;
auto* player = static_cast<Player*>(this);
auto droppedCoins = player->GetDroppedCoins(); auto* characterComponent = GetComponent<CharacterComponent>();
if (!characterComponent) return;
auto droppedCoins = characterComponent->GetDroppedCoins();
droppedCoins += count; droppedCoins += count;
player->SetDroppedCoins(droppedCoins); characterComponent->SetDroppedCoins(droppedCoins);
} }
void Entity::AddChild(Entity* child) { void Entity::AddChild(Entity* child) {
@ -1990,7 +2022,7 @@ std::vector<LWOOBJID> Entity::GetTargetsInPhantom() {
// Clean up invalid targets, like disconnected players // Clean up invalid targets, like disconnected players
m_TargetsInPhantom.erase(std::remove_if(m_TargetsInPhantom.begin(), m_TargetsInPhantom.end(), [](const LWOOBJID id) { m_TargetsInPhantom.erase(std::remove_if(m_TargetsInPhantom.begin(), m_TargetsInPhantom.end(), [](const LWOOBJID id) {
return !Game::entityManager->GetEntity(id); return !Game::entityManager->GetEntity(id);
}), m_TargetsInPhantom.end()); }), m_TargetsInPhantom.end());
std::vector<LWOOBJID> enemies; std::vector<LWOOBJID> enemies;
for (const auto id : m_TargetsInPhantom) { for (const auto id : m_TargetsInPhantom) {
@ -2133,3 +2165,27 @@ void Entity::ProcessPositionUpdate(PositionUpdate& update) {
if (updateChar) Game::entityManager->SerializeEntity(this); if (updateChar) Game::entityManager->SerializeEntity(this);
} }
const SystemAddress& Entity::GetSystemAddress() const {
auto* characterComponent = GetComponent<CharacterComponent>();
return characterComponent ? characterComponent->GetSystemAddress() : UNASSIGNED_SYSTEM_ADDRESS;
}
const NiPoint3& Entity::GetRespawnPosition() const {
auto* characterComponent = GetComponent<CharacterComponent>();
return characterComponent ? characterComponent->GetRespawnPosition() : NiPoint3Constant::ZERO;
}
const NiQuaternion& Entity::GetRespawnRotation() const {
auto* characterComponent = GetComponent<CharacterComponent>();
return characterComponent ? characterComponent->GetRespawnRotation() : NiQuaternionConstant::IDENTITY;
}
void Entity::SetRespawnPos(const NiPoint3& position) {
auto* characterComponent = GetComponent<CharacterComponent>();
if (characterComponent) characterComponent->SetRespawnPos(position);
}
void Entity::SetRespawnRot(const NiQuaternion& rotation) {
auto* characterComponent = GetComponent<CharacterComponent>();
if (characterComponent) characterComponent->SetRespawnRot(rotation);
}

View File

@ -47,10 +47,10 @@ namespace CppScripts {
*/ */
class Entity { class Entity {
public: public:
explicit Entity(const LWOOBJID& objectID, EntityInfo info, Entity* parentEntity = nullptr); explicit Entity(const LWOOBJID& objectID, EntityInfo info, User* parentUser = nullptr, Entity* parentEntity = nullptr);
virtual ~Entity(); ~Entity();
virtual void Initialize(); void Initialize();
bool operator==(const Entity& other) const; bool operator==(const Entity& other) const;
bool operator!=(const Entity& other) const; bool operator!=(const Entity& other) const;
@ -104,9 +104,7 @@ public:
const NiQuaternion& GetRotation() const; const NiQuaternion& GetRotation() const;
virtual User* GetParentUser() const; const SystemAddress& GetSystemAddress() const;
virtual const SystemAddress& GetSystemAddress() const { return UNASSIGNED_SYSTEM_ADDRESS; };
/** /**
* Setters * Setters
@ -128,11 +126,9 @@ public:
void SetRotation(const NiQuaternion& rotation); void SetRotation(const NiQuaternion& rotation);
virtual void SetRespawnPos(const NiPoint3& position) {} void SetRespawnPos(const NiPoint3& position);
virtual void SetRespawnRot(const NiQuaternion& rotation) {} void SetRespawnRot(const NiQuaternion& rotation);
virtual void SetSystemAddress(const SystemAddress& value) {};
/** /**
* Component management * Component management
@ -229,8 +225,8 @@ public:
void TriggerEvent(eTriggerEventType event, Entity* optionalTarget = nullptr); void TriggerEvent(eTriggerEventType event, Entity* optionalTarget = nullptr);
void ScheduleDestructionAfterUpdate() { m_ShouldDestroyAfterUpdate = true; } void ScheduleDestructionAfterUpdate() { m_ShouldDestroyAfterUpdate = true; }
virtual const NiPoint3& GetRespawnPosition() const { return NiPoint3Constant::ZERO; } const NiPoint3& GetRespawnPosition() const;
virtual const NiQuaternion& GetRespawnRotation() const { return NiQuaternionConstant::IDENTITY; } const NiQuaternion& GetRespawnRotation() const;
void Sleep(); void Sleep();
void Wake(); void Wake();

View File

@ -7,7 +7,6 @@
#include "GeneralUtils.h" #include "GeneralUtils.h"
#include "dServer.h" #include "dServer.h"
#include "Spawner.h" #include "Spawner.h"
#include "Player.h"
#include "SkillComponent.h" #include "SkillComponent.h"
#include "SwitchComponent.h" #include "SwitchComponent.h"
#include "UserManager.h" #include "UserManager.h"
@ -118,14 +117,7 @@ Entity* EntityManager::CreateEntity(EntityInfo info, User* user, Entity* parentE
info.id = id; info.id = id;
Entity* entity; Entity* entity = new Entity(id, info, user, parentEntity);
// 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);
}
// Initialize the entity // Initialize the entity
entity->Initialize(); entity->Initialize();
@ -482,7 +474,7 @@ void EntityManager::UpdateGhosting() {
m_PlayersToUpdateGhosting.clear(); m_PlayersToUpdateGhosting.clear();
} }
void EntityManager::UpdateGhosting(Player* player) { void EntityManager::UpdateGhosting(Entity* player) {
if (player == nullptr) { if (player == nullptr) {
return; return;
} }

View File

@ -55,7 +55,7 @@ public:
float GetGhostDistanceMin() const; float GetGhostDistanceMin() const;
void QueueGhostUpdate(LWOOBJID playerID); void QueueGhostUpdate(LWOOBJID playerID);
void UpdateGhosting(); void UpdateGhosting();
void UpdateGhosting(Player* player); void UpdateGhosting(Entity* player);
void CheckGhosting(Entity* entity); void CheckGhosting(Entity* entity);
Entity* GetGhostCandidate(int32_t id); Entity* GetGhostCandidate(int32_t id);
bool GetGhostingEnabled() const; bool GetGhostingEnabled() const;

View File

@ -1,71 +0,0 @@
#include "Player.h"
#include <ctime>
#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<Entity*> 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);
}
}
}
}
}

View File

@ -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<LWOOBJID, Loot::Info>& 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<LWOOBJID, Loot::Info> m_DroppedLoot;
uint64_t m_DroppedCoins;
};

View File

@ -1,20 +1,19 @@
#include "PlayerManager.h" #include "PlayerManager.h"
#include "Character.h" #include "Character.h"
#include "Player.h"
#include "User.h" #include "User.h"
#include "UserManager.h" #include "UserManager.h"
#include "eReplicaComponentType.h" #include "eReplicaComponentType.h"
namespace { namespace {
std::vector<Player*> m_Players; std::vector<Entity*> m_Players;
}; };
const std::vector<Player*>& PlayerManager::GetAllPlayers() { const std::vector<Entity*>& PlayerManager::GetAllPlayers() {
return m_Players; 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); const auto& iter = std::find(m_Players.begin(), m_Players.end(), player);
if (iter == m_Players.end()) { 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 auto iter = std::find(m_Players.begin(), m_Players.end(), player);
const bool toReturn = iter != m_Players.end(); const bool toReturn = iter != m_Players.end();
@ -33,21 +32,21 @@ bool PlayerManager::RemovePlayer(Player* player) {
return toReturn; return toReturn;
} }
Player* PlayerManager::GetPlayer(const SystemAddress& sysAddr) { Entity* PlayerManager::GetPlayer(const SystemAddress& sysAddr) {
auto* entity = UserManager::Instance()->GetUser(sysAddr)->GetLastUsedChar()->GetEntity(); auto* entity = UserManager::Instance()->GetUser(sysAddr)->GetLastUsedChar()->GetEntity();
return static_cast<Player*>(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); const auto characters = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::CHARACTER);
Player* player = nullptr; Entity* player = nullptr;
for (auto* character : characters) { for (auto* character : characters) {
if (!character->IsPlayer()) continue; if (!character->IsPlayer()) continue;
if (GeneralUtils::CaseInsensitiveStringCompare(name, character->GetCharacter()->GetName())) { if (GeneralUtils::CaseInsensitiveStringCompare(name, character->GetCharacter()->GetName())) {
player = dynamic_cast<Player*>(character); player = character;
break; break;
} }
} }
@ -55,8 +54,8 @@ Player* PlayerManager::GetPlayer(const std::string& name) {
return player; return player;
} }
Player* PlayerManager::GetPlayer(LWOOBJID playerID) { Entity* PlayerManager::GetPlayer(LWOOBJID playerID) {
Player* playerToReturn = nullptr; Entity* playerToReturn = nullptr;
for (auto* player : m_Players) { for (auto* player : m_Players) {
if (player->GetObjectID() == playerID) { if (player->GetObjectID() == playerID) {
playerToReturn = player; playerToReturn = player;

View File

@ -5,21 +5,21 @@
#include <string> #include <string>
class Player; class Entity;
struct SystemAddress; struct SystemAddress;
namespace PlayerManager { 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<Player*>& GetAllPlayers(); const std::vector<Entity*>& GetAllPlayers();
}; };
#endif //!__PLAYERMANAGER__H__ #endif //!__PLAYERMANAGER__H__

View File

@ -10,7 +10,6 @@
#include "WorldPackets.h" #include "WorldPackets.h"
#include "EntityManager.h" #include "EntityManager.h"
#include "ChatPackets.h" #include "ChatPackets.h"
#include "Player.h"
#include "BitStreamUtils.h" #include "BitStreamUtils.h"
#include "dServer.h" #include "dServer.h"
#include "GeneralUtils.h" #include "GeneralUtils.h"

View File

@ -24,7 +24,7 @@
#include "WorldPackets.h" #include "WorldPackets.h"
#include <ctime> #include <ctime>
CharacterComponent::CharacterComponent(Entity* parent, Character* character) : Component(parent) { CharacterComponent::CharacterComponent(Entity* parent, Character* character, const SystemAddress& systemAddress) : Component(parent) {
m_Character = character; m_Character = character;
m_IsRacing = false; m_IsRacing = false;
@ -46,6 +46,7 @@ CharacterComponent::CharacterComponent(Entity* parent, Character* character) : C
m_CurrentActivity = eGameActivity::NONE; m_CurrentActivity = eGameActivity::NONE;
m_CountryCode = 0; m_CountryCode = 0;
m_LastUpdateTimestamp = std::time(nullptr); m_LastUpdateTimestamp = std::time(nullptr);
m_SystemAddress = systemAddress;
} }
bool CharacterComponent::LandingAnimDisabled(int zoneID) { bool CharacterComponent::LandingAnimDisabled(int zoneID) {
@ -762,8 +763,8 @@ void CharacterComponent::UpdateClientMinimap(bool showFaction, std::string ventu
} }
void CharacterComponent::AwardClaimCodes() { void CharacterComponent::AwardClaimCodes() {
if (!m_Parent) return; if (!m_Parent || !m_Parent->GetCharacter()) return;
auto* user = m_Parent->GetParentUser(); auto* user = m_Parent->GetCharacter()->GetParentUser();
if (!user) return; if (!user) return;
auto rewardCodes = Database::Get()->GetRewardCodesByAccountID(user->GetAccountID()); auto rewardCodes = Database::Get()->GetRewardCodesByAccountID(user->GetAccountID());
@ -817,3 +818,20 @@ void CharacterComponent::SendToZone(LWOMAPID zoneId, LWOCLONEID cloneId) const {
Game::entityManager->DestructEntity(entity); 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;
}

View File

@ -11,6 +11,7 @@
#include "tinyxml2.h" #include "tinyxml2.h"
#include "eReplicaComponentType.h" #include "eReplicaComponentType.h"
#include <array> #include <array>
#include "Loot.h"
enum class eGameActivity : uint32_t; enum class eGameActivity : uint32_t;
@ -65,7 +66,7 @@ class CharacterComponent final : public Component {
public: public:
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::CHARACTER; static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::CHARACTER;
CharacterComponent(Entity* parent, Character* character); CharacterComponent(Entity* parent, Character* character, const SystemAddress& systemAddress);
~CharacterComponent() override; ~CharacterComponent() override;
void LoadFromXml(tinyxml2::XMLDocument* doc) override; void LoadFromXml(tinyxml2::XMLDocument* doc) override;
@ -289,6 +290,22 @@ public:
*/ */
void SendToZone(LWOMAPID zoneId, LWOCLONEID cloneId = 0) const; 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<LWOOBJID, Loot::Info>& 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. * Character info regarding this character, including clothing styles, etc.
*/ */
@ -579,6 +596,16 @@ private:
std::array<uint64_t, 4> m_ClaimCodes{}; std::array<uint64_t, 4> m_ClaimCodes{};
void AwardClaimCodes(); void AwardClaimCodes();
SystemAddress m_SystemAddress;
NiPoint3 m_respawnPos;
NiQuaternion m_respawnRot;
std::map<LWOOBJID, Loot::Info> m_DroppedLoot;
uint64_t m_DroppedCoins = 0;
}; };
#endif // CHARACTERCOMPONENT_H #endif // CHARACTERCOMPONENT_H

View File

@ -251,13 +251,14 @@ void DestroyableComponent::SetMaxHealth(float value, bool playAnim) {
if (playAnim) { if (playAnim) {
// Now update the player bar // Now update the player bar
if (!m_Parent->GetParentUser()) return; auto* characterComponent = m_Parent->GetComponent<CharacterComponent>();
if (!characterComponent) return;
AMFArrayValue args; AMFArrayValue args;
args.Insert("amount", std::to_string(difference)); args.Insert("amount", std::to_string(difference));
args.Insert("type", "health"); 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); Game::entityManager->SerializeEntity(m_Parent);
@ -292,13 +293,14 @@ void DestroyableComponent::SetMaxArmor(float value, bool playAnim) {
if (playAnim) { if (playAnim) {
// Now update the player bar // Now update the player bar
if (!m_Parent->GetParentUser()) return; auto* characterComponent = m_Parent->GetComponent<CharacterComponent>();
if (!characterComponent) return;
AMFArrayValue args; AMFArrayValue args;
args.Insert("amount", std::to_string(value)); args.Insert("amount", std::to_string(value));
args.Insert("type", "armor"); 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); Game::entityManager->SerializeEntity(m_Parent);
@ -332,13 +334,14 @@ void DestroyableComponent::SetMaxImagination(float value, bool playAnim) {
if (playAnim) { if (playAnim) {
// Now update the player bar // Now update the player bar
if (!m_Parent->GetParentUser()) return; auto* characterComponent = m_Parent->GetComponent<CharacterComponent>();
if (!characterComponent) return;
AMFArrayValue args; AMFArrayValue args;
args.Insert("amount", std::to_string(difference)); args.Insert("amount", std::to_string(difference));
args.Insert("type", "imagination"); 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); Game::entityManager->SerializeEntity(m_Parent);
} }

View File

@ -14,7 +14,6 @@
#include "Character.h" #include "Character.h"
#include "EntityManager.h" #include "EntityManager.h"
#include "ItemSet.h" #include "ItemSet.h"
#include "Player.h"
#include "PetComponent.h" #include "PetComponent.h"
#include "PossessorComponent.h" #include "PossessorComponent.h"
#include "PossessableComponent.h" #include "PossessableComponent.h"

View File

@ -14,7 +14,6 @@
#include "Item.h" #include "Item.h"
#include "Database.h" #include "Database.h"
#include "ObjectIDManager.h" #include "ObjectIDManager.h"
#include "Player.h"
#include "RocketLaunchpadControlComponent.h" #include "RocketLaunchpadControlComponent.h"
#include "PropertyEntranceComponent.h" #include "PropertyEntranceComponent.h"
#include "InventoryComponent.h" #include "InventoryComponent.h"
@ -177,8 +176,6 @@ bool PropertyManagementComponent::Claim(const LWOOBJID playerId) {
auto* entity = Game::entityManager->GetEntity(playerId); auto* entity = Game::entityManager->GetEntity(playerId);
auto* user = entity->GetParentUser();
auto character = entity->GetCharacter(); auto character = entity->GetCharacter();
if (!character) return false; if (!character) return false;

View File

@ -12,7 +12,6 @@
#include "Item.h" #include "Item.h"
#include "MissionComponent.h" #include "MissionComponent.h"
#include "ModuleAssemblyComponent.h" #include "ModuleAssemblyComponent.h"
#include "Player.h"
#include "PossessableComponent.h" #include "PossessableComponent.h"
#include "PossessorComponent.h" #include "PossessorComponent.h"
#include "eRacingTaskParam.h" #include "eRacingTaskParam.h"

View File

@ -9,7 +9,6 @@
#include "ControllablePhysicsComponent.h" #include "ControllablePhysicsComponent.h"
#include "MissionComponent.h" #include "MissionComponent.h"
#include "PhantomPhysicsComponent.h" #include "PhantomPhysicsComponent.h"
#include "Player.h"
#include "QuickBuildComponent.h" #include "QuickBuildComponent.h"
#include "SkillComponent.h" #include "SkillComponent.h"
#include "eEndBehavior.h" #include "eEndBehavior.h"

View File

@ -18,7 +18,6 @@
#include "Character.h" #include "Character.h"
#include "ControllablePhysicsComponent.h" #include "ControllablePhysicsComponent.h"
#include "dZoneManager.h" #include "dZoneManager.h"
#include "Player.h"
#include "CppScripts.h" #include "CppScripts.h"
#include "CDClientDatabase.h" #include "CDClientDatabase.h"

View File

@ -20,7 +20,6 @@
#include "WorldPackets.h" #include "WorldPackets.h"
#include "Item.h" #include "Item.h"
#include "ZCompression.h" #include "ZCompression.h"
#include "Player.h"
#include "dConfig.h" #include "dConfig.h"
#include "TeamManager.h" #include "TeamManager.h"
#include "ChatPackets.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: //We need to get a new ID for our model first:
ObjectIDManager::RequestPersistentID([=](uint32_t newID) { ObjectIDManager::RequestPersistentID([=](uint32_t newID) {
if (!entity || !entity->GetCharacter() || !entity->GetCharacter()->GetParentUser()) return;
LWOOBJID newIDL = newID; LWOOBJID newIDL = newID;
GeneralUtils::SetBit(newIDL, eObjectBits::CHARACTER); GeneralUtils::SetBit(newIDL, eObjectBits::CHARACTER);
GeneralUtils::SetBit(newIDL, eObjectBits::PERSISTENT); GeneralUtils::SetBit(newIDL, eObjectBits::PERSISTENT);
@ -2606,7 +2606,7 @@ void GameMessages::HandleBBBSaveRequest(RakNet::BitStream* inStream, Entity* ent
//Insert into ugc: //Insert into ugc:
std::string str(sd0Data.get(), sd0Size); std::string str(sd0Data.get(), sd0Size);
std::istringstream sd0DataStream(str); 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: //Insert into the db as a BBB model:
IPropertyContents::Model model; IPropertyContents::Model model;
@ -5110,13 +5110,8 @@ void GameMessages::HandleSetFlag(RakNet::BitStream* inStream, Entity* entity) {
inStream->Read(bFlag); inStream->Read(bFlag);
inStream->Read(iFlagID); inStream->Read(iFlagID);
auto user = entity->GetParentUser(); auto character = entity->GetCharacter();
if (user) { if (character) character->SetPlayerFlag(iFlagID, bFlag);
auto character = user->GetLastUsedChar();
if (!character) return;
character->SetPlayerFlag(iFlagID, bFlag);
}
} }
void GameMessages::HandleRespondToMission(RakNet::BitStream* inStream, Entity* entity) { void GameMessages::HandleRespondToMission(RakNet::BitStream* inStream, Entity* entity) {

View File

@ -24,6 +24,7 @@
#include "eMissionTaskType.h" #include "eMissionTaskType.h"
#include "eMissionLockState.h" #include "eMissionLockState.h"
#include "eReplicaComponentType.h" #include "eReplicaComponentType.h"
#include "Character.h"
#include "CDMissionEmailTable.h" #include "CDMissionEmailTable.h"
@ -208,8 +209,8 @@ Entity* Mission::GetAssociate() const {
return m_MissionComponent->GetParent(); return m_MissionComponent->GetParent();
} }
User* Mission::GetUser() const { Character* Mission::GetCharacter() const {
return GetAssociate()->GetParentUser(); return GetAssociate()->GetCharacter();
} }
uint32_t Mission::GetMissionId() const { uint32_t Mission::GetMissionId() const {
@ -390,7 +391,7 @@ void Mission::Catchup() {
if (type == eMissionTaskType::PLAYER_FLAG) { if (type == eMissionTaskType::PLAYER_FLAG) {
for (int32_t target : task->GetAllTargets()) { for (int32_t target : task->GetAllTargets()) {
const auto flag = GetUser()->GetLastUsedChar()->GetPlayerFlag(target); const auto flag = GetCharacter()->GetPlayerFlag(target);
if (!flag) { if (!flag) {
continue; continue;
@ -413,7 +414,7 @@ void Mission::YieldRewards() {
return; return;
} }
auto* character = GetUser()->GetLastUsedChar(); auto* character = GetCharacter();
auto* inventoryComponent = entity->GetComponent<InventoryComponent>(); auto* inventoryComponent = entity->GetComponent<InventoryComponent>();
auto* levelComponent = entity->GetComponent<LevelProgressionComponent>(); auto* levelComponent = entity->GetComponent<LevelProgressionComponent>();
@ -599,8 +600,10 @@ void Mission::SetMissionState(const eMissionState state, const bool sendingRewar
if (entity == nullptr) { if (entity == nullptr) {
return; return;
} }
auto* characterComponent = entity->GetComponent<CharacterComponent>();
if (!characterComponent) return;
GameMessages::SendNotifyMission(entity, entity->GetParentUser()->GetSystemAddress(), info.id, static_cast<int>(state), sendingRewards); GameMessages::SendNotifyMission(entity, characterComponent->GetSystemAddress(), info.id, static_cast<int>(state), sendingRewards);
} }
void Mission::SetMissionTypeState(eMissionLockState state, const std::string& type, const std::string& subType) { void Mission::SetMissionTypeState(eMissionLockState state, const std::string& type, const std::string& subType) {

View File

@ -17,6 +17,7 @@ namespace tinyxml2 {
enum class eMissionState : int; enum class eMissionState : int;
enum class eMissionLockState : int; enum class eMissionLockState : int;
class MissionComponent; class MissionComponent;
class Character;
/** /**
* A mission (or achievement) that a player may unlock, progress and complete. * 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 * Returns the account owns the entity that is currently progressing this mission
* @return 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 * Returns the current state of this mission

View File

@ -13,6 +13,7 @@
#include "User.h" #include "User.h"
#include "tinyxml2.h" #include "tinyxml2.h"
#include "CDClientDatabase.h" #include "CDClientDatabase.h"
#include "CharacterComponent.h"
// Message includes // Message includes
#include "Action.h" #include "Action.h"
@ -145,10 +146,12 @@ void ControlBehaviors::ProcessCommand(Entity* modelEntity, const SystemAddress&
} else if (command == "moveToInventory") { } else if (command == "moveToInventory") {
MoveToInventoryMessage msg(arguments); MoveToInventoryMessage msg(arguments);
context.modelComponent->MoveToInventory(msg); context.modelComponent->MoveToInventory(msg);
auto* characterComponent = modelOwner->GetComponent<CharacterComponent>();
if (!characterComponent) return;
AMFArrayValue args; AMFArrayValue args;
args.Insert("BehaviorID", std::to_string(msg.GetBehaviorId())); 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); SendBehaviorListToClient(context);
} else if (command == "updateAction") { } else if (command == "updateAction") {

View File

@ -2,7 +2,6 @@
#include "Database.h" #include "Database.h"
#include "Entity.h" #include "Entity.h"
#include "PossessableComponent.h" #include "PossessableComponent.h"
#include "Player.h"
#include "Game.h" #include "Game.h"
#include "EntityManager.h" #include "EntityManager.h"
#include "Character.h" #include "Character.h"
@ -59,13 +58,13 @@ void LogAndSaveFailedAntiCheatCheck(const LWOOBJID& id, const SystemAddress& sys
player->GetCharacter()->GetName().c_str(), player->GetObjectID(), player->GetCharacter()->GetName().c_str(), player->GetObjectID(),
sysAddr.ToString(), sysAddr.ToString(),
entity->GetCharacter()->GetName().c_str(), entity->GetObjectID()); 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. // In the case that the target entity id did not exist, just log the player info.
} else if (player) { } else if (player) {
LOG("Player (%s) (%llu) at system address (%s) with sending player (%llu) does not match their own.", LOG("Player (%s) (%llu) at system address (%s) with sending player (%llu) does not match their own.",
player->GetCharacter()->GetName().c_str(), player->GetObjectID(), player->GetCharacter()->GetName().c_str(), player->GetObjectID(),
sysAddr.ToString(), id); 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. // In the rare case that the player does not exist, just log the system address and who the target id was.
} else { } else {
LOG("Player at system address (%s) with sending player (%llu) does not match their own.", LOG("Player at system address (%s) with sending player (%llu) does not match their own.",

View File

@ -53,7 +53,6 @@
#include "Loot.h" #include "Loot.h"
#include "EntityInfo.h" #include "EntityInfo.h"
#include "LUTriggers.h" #include "LUTriggers.h"
#include "Player.h"
#include "PhantomPhysicsComponent.h" #include "PhantomPhysicsComponent.h"
#include "ProximityMonitorComponent.h" #include "ProximityMonitorComponent.h"
#include "dpShapeSphere.h" #include "dpShapeSphere.h"
@ -1017,7 +1016,9 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
return; return;
} }
} else { } else {
accountId = player->GetParentUser()->GetAccountID(); auto* character = player->GetCharacter();
auto* user = character != nullptr ? character->GetParentUser() : nullptr;
if (user) accountId = user->GetAccountID();
characterId = player->GetObjectID(); characterId = player->GetObjectID();
} }
@ -1045,7 +1046,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
expire += 60 * 60 * hours; 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"; char buffer[32] = "brought up for review.\0";
@ -1109,10 +1110,12 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
return; return;
} }
} else { } 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) { if (player != nullptr) {
Game::server->Disconnect(player->GetSystemAddress(), eServerDisconnectIdentifiers::FREE_TRIAL_EXPIRED); 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. // 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); GameMessages::SendToggleGMInvis(entity->GetObjectID(), true, UNASSIGNED_SYSTEM_ADDRESS);
return; return;

View File

@ -11,6 +11,7 @@
#include "dZoneManager.h" #include "dZoneManager.h"
#include "DluAssert.h" #include "DluAssert.h"
#include "DetourExtensions.h"
dNavMesh::dNavMesh(uint32_t zoneId) { dNavMesh::dNavMesh(uint32_t zoneId) {
m_ZoneId = zoneId; m_ZoneId = zoneId;
@ -30,16 +31,8 @@ dNavMesh::dNavMesh(uint32_t zoneId) {
dNavMesh::~dNavMesh() { dNavMesh::~dNavMesh() {
// Clean up Recast information // 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_NavMesh) dtFreeNavMesh(m_NavMesh);
if (m_NavQuery) dtFreeNavMeshQuery(m_NavQuery); if (m_NavQuery) dtFreeNavMeshQuery(m_NavQuery);
if (m_Ctx) delete m_Ctx;
if (m_Triareas) delete[] m_Triareas;
} }

View File

@ -2,13 +2,17 @@
#include <cstdint> #include <cstdint>
#include <vector> #include <vector>
#include <map>
#include <string>
#include <cstring>
#include "DetourExtensions.h"
class NiPoint3; class NiPoint3;
class rcHeightfield;
class rcCompactHeightfield;
class rcContourSet;
class rcPolyMesh;
class rcPolyMeshDetail;
class InputGeom;
class dtNavMesh;
class dtNavMeshQuery;
class rcContext;
class dNavMesh { class dNavMesh {
public: public:
@ -26,24 +30,14 @@ public:
float GetHeightAtPoint(const NiPoint3& location, const float halfExtentsHeight = 32.0f) const; float GetHeightAtPoint(const NiPoint3& location, const float halfExtentsHeight = 32.0f) const;
std::vector<NiPoint3> GetPath(const NiPoint3& startPos, const NiPoint3& endPos, float speed = 10.0f); std::vector<NiPoint3> GetPath(const NiPoint3& startPos, const NiPoint3& endPos, float speed = 10.0f);
class dtNavMesh* GetdtNavMesh() { return m_NavMesh; } bool IsNavmeshLoaded() { return m_NavMesh != nullptr; }
private: private:
void LoadNavmesh(); void LoadNavmesh();
uint32_t m_ZoneId; uint32_t m_ZoneId;
uint8_t* m_Triareas = nullptr; dtNavMesh* m_NavMesh = nullptr;
rcHeightfield* m_Solid = nullptr; dtNavMeshQuery* m_NavQuery = 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;
uint8_t m_NavMeshDrawFlags; uint8_t m_NavMeshDrawFlags;
rcContext* m_Ctx = nullptr;
}; };

View File

@ -81,7 +81,7 @@ void dpWorld::Shutdown() {
} }
bool dpWorld::IsLoaded() { bool dpWorld::IsLoaded() {
return m_NavMesh->GetdtNavMesh() != nullptr; return m_NavMesh->IsNavmeshLoaded();
} }
void dpWorld::StepWorld(float deltaTime) { void dpWorld::StepWorld(float deltaTime) {

View File

@ -107,7 +107,7 @@ void PetDigServer::HandleXBuildDig(const Entity* self, Entity* owner, Entity* pe
return; return;
auto* playerEntity = Game::entityManager->GetEntity(playerID); auto* playerEntity = Game::entityManager->GetEntity(playerID);
if (!playerEntity || !playerEntity->GetParentUser() || !playerEntity->GetParentUser()->GetLastUsedChar()) if (!playerEntity || !playerEntity->GetCharacter())
return; return;
auto* player = playerEntity->GetCharacter(); auto* player = playerEntity->GetCharacter();

View File

@ -2,7 +2,6 @@
#include "EntityManager.h" #include "EntityManager.h"
#include "GameMessages.h" #include "GameMessages.h"
#include "dZoneManager.h" #include "dZoneManager.h"
#include "Player.h"
#include "Character.h" #include "Character.h"
#include "ShootingGalleryComponent.h" #include "ShootingGalleryComponent.h"
#include "PossessorComponent.h" #include "PossessorComponent.h"

View File

@ -56,7 +56,6 @@
#include "DestroyableComponent.h" #include "DestroyableComponent.h"
#include "Game.h" #include "Game.h"
#include "MasterPackets.h" #include "MasterPackets.h"
#include "Player.h"
#include "PropertyManagementComponent.h" #include "PropertyManagementComponent.h"
#include "AssetManager.h" #include "AssetManager.h"
#include "LevelProgressionComponent.h" #include "LevelProgressionComponent.h"
@ -607,9 +606,10 @@ void HandlePacketChat(Packet* packet) {
inStream.Read(expire); inStream.Read(expire);
auto* entity = Game::entityManager->GetEntity(playerId); auto* entity = Game::entityManager->GetEntity(playerId);
auto* character = entity != nullptr ? entity->GetCharacter() : nullptr;
if (entity != nullptr) { auto* user = character != nullptr ? character->GetParentUser() : nullptr;
entity->GetParentUser()->SetMuteExpire(expire); if (user) {
user->SetMuteExpire(expire);
entity->GetCharacter()->SendMuteNotice(); entity->GetCharacter()->SendMuteNotice();
} }
@ -1127,9 +1127,10 @@ void HandlePacket(Packet* packet) {
//Mail::HandleNotificationRequest(packet->systemAddress, player->GetObjectID()); //Mail::HandleNotificationRequest(packet->systemAddress, player->GetObjectID());
//Notify chat that a player has loaded: //Notify chat that a player has loaded:
{ auto* character = player->GetCharacter();
const auto& playerName = player->GetCharacter()->GetName(); auto* user = character != nullptr ? character->GetParentUser() : nullptr;
//RakNet::RakString playerName(player->GetCharacter()->GetName().c_str()); if (user) {
const auto& playerName = character->GetName();
CBITSTREAM; CBITSTREAM;
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::PLAYER_ADDED_NOTIFICATION); 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.GetMapID());
bitStream.Write(zone.GetInstanceID()); bitStream.Write(zone.GetInstanceID());
bitStream.Write(zone.GetCloneID()); bitStream.Write(zone.GetCloneID());
bitStream.Write(player->GetParentUser()->GetMuteExpire()); bitStream.Write(user->GetMuteExpire());
bitStream.Write(player->GetGMLevel()); bitStream.Write(player->GetGMLevel());
Game::chatServer->Send(&bitStream, SYSTEM_PRIORITY, RELIABLE, 0, Game::chatSysAddr, false); Game::chatServer->Send(&bitStream, SYSTEM_PRIORITY, RELIABLE, 0, Game::chatSysAddr, false);