mirror of
				https://github.com/DarkflameUniverse/DarkflameServer.git
				synced 2025-10-31 20:52:01 +00:00 
			
		
		
		
	Merge branch 'DarkflameUniverse:main' into MSVCCompilerFlags
This commit is contained in:
		| @@ -2,7 +2,6 @@ set(DGAME_SOURCES "Character.cpp" | ||||
| 		"Entity.cpp" | ||||
| 		"EntityManager.cpp" | ||||
| 		"LeaderboardManager.cpp" | ||||
| 		"Player.cpp" | ||||
| 		"PlayerManager.cpp" | ||||
| 		"TeamManager.cpp" | ||||
| 		"TradingManager.cpp" | ||||
|   | ||||
| @@ -457,6 +457,8 @@ public: | ||||
|  | ||||
| 	void SetBillboardVisible(bool visible); | ||||
|  | ||||
| 	User* GetParentUser() const { return m_ParentUser; } | ||||
|  | ||||
| private: | ||||
| 	void UpdateInfoFromDatabase(); | ||||
| 	/** | ||||
|   | ||||
							
								
								
									
										118
									
								
								dGame/Entity.cpp
									
									
									
									
									
								
							
							
						
						
									
										118
									
								
								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<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) { | ||||
| 		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<MissionComponent>()->LoadFromXml(m_Character->GetXMLDoc()); | ||||
| 	} | ||||
|  | ||||
| @@ -437,7 +470,8 @@ void Entity::Initialize() { | ||||
|  | ||||
| 		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>(); | ||||
| 	} | ||||
| @@ -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<const Player*>(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<CharacterComponent>(); | ||||
| 	if (!characterComponent) return; | ||||
|  | ||||
| 	CharacterComponent* character = GetComponent<CharacterComponent>(); | ||||
| 	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<Player*>(this)->GetDroppedLoot(); | ||||
|  | ||||
| 	auto* characterComponent = GetComponent<CharacterComponent>(); | ||||
| 	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<InventoryComponent>(); | ||||
| 	if (!inv) return; | ||||
| 	auto* characterComponent = GetComponent<CharacterComponent>(); | ||||
| 	if (!inv || !characterComponent) return; | ||||
|  | ||||
| 	CDObjectsTable* objectsTable = CDClientManager::Instance().GetTable<CDObjectsTable>(); | ||||
|  | ||||
| 	auto& droppedLoot = static_cast<Player*>(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<Player*>(this); | ||||
| 	auto droppedCoins = player->GetDroppedCoins(); | ||||
|  | ||||
| 	auto* characterComponent = GetComponent<CharacterComponent>(); | ||||
| 	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<Player*>(this); | ||||
| 	auto droppedCoins = player->GetDroppedCoins(); | ||||
|  | ||||
| 	auto* characterComponent = GetComponent<CharacterComponent>(); | ||||
| 	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<LWOOBJID> 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<LWOOBJID> 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<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); | ||||
| } | ||||
|   | ||||
| @@ -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(); | ||||
|   | ||||
| @@ -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; | ||||
| 	} | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -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); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| @@ -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; | ||||
| }; | ||||
| @@ -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<Player*> m_Players; | ||||
| 	std::vector<Entity*> m_Players; | ||||
| }; | ||||
|  | ||||
| const std::vector<Player*>& PlayerManager::GetAllPlayers() { | ||||
| const std::vector<Entity*>& 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<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); | ||||
|  | ||||
| 	Player* player = nullptr; | ||||
| 	Entity* player = nullptr; | ||||
| 	for (auto* character : characters) { | ||||
| 		if (!character->IsPlayer()) continue; | ||||
| 		 | ||||
| 		if (GeneralUtils::CaseInsensitiveStringCompare(name, character->GetCharacter()->GetName())) { | ||||
| 			player = dynamic_cast<Player*>(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; | ||||
|   | ||||
| @@ -5,21 +5,21 @@ | ||||
|  | ||||
| #include <string> | ||||
|  | ||||
| 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<Player*>& GetAllPlayers(); | ||||
| 	const std::vector<Entity*>& GetAllPlayers(); | ||||
| }; | ||||
|  | ||||
| #endif  //!__PLAYERMANAGER__H__ | ||||
|   | ||||
| @@ -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" | ||||
|   | ||||
| @@ -24,7 +24,7 @@ | ||||
| #include "WorldPackets.h" | ||||
| #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_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; | ||||
| } | ||||
|   | ||||
| @@ -11,6 +11,7 @@ | ||||
| #include "tinyxml2.h" | ||||
| #include "eReplicaComponentType.h" | ||||
| #include <array> | ||||
| #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<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. | ||||
| 	 */ | ||||
| @@ -579,6 +596,16 @@ private: | ||||
| 	std::array<uint64_t, 4> m_ClaimCodes{}; | ||||
|  | ||||
| 	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 | ||||
|   | ||||
| @@ -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<CharacterComponent>(); | ||||
| 		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<CharacterComponent>(); | ||||
| 		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<CharacterComponent>(); | ||||
| 		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); | ||||
| } | ||||
|   | ||||
| @@ -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" | ||||
|   | ||||
| @@ -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; | ||||
|  | ||||
|   | ||||
| @@ -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" | ||||
|   | ||||
| @@ -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" | ||||
|   | ||||
| @@ -18,7 +18,6 @@ | ||||
| #include "Character.h" | ||||
| #include "ControllablePhysicsComponent.h" | ||||
| #include "dZoneManager.h" | ||||
| #include "Player.h" | ||||
| #include "CppScripts.h" | ||||
|  | ||||
| #include "CDClientDatabase.h" | ||||
|   | ||||
| @@ -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) { | ||||
|   | ||||
| @@ -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<InventoryComponent>(); | ||||
| 	auto* levelComponent = entity->GetComponent<LevelProgressionComponent>(); | ||||
| @@ -599,8 +600,10 @@ void Mission::SetMissionState(const eMissionState state, const bool sendingRewar | ||||
| 	if (entity == nullptr) { | ||||
| 		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) { | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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<CharacterComponent>(); | ||||
| 		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") { | ||||
|   | ||||
| @@ -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.", | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -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; | ||||
| } | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -2,13 +2,17 @@ | ||||
|  | ||||
| #include <cstdint> | ||||
| #include <vector> | ||||
| #include <map> | ||||
| #include <string> | ||||
| #include <cstring> | ||||
|  | ||||
| #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<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: | ||||
| 	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; | ||||
| }; | ||||
|   | ||||
| @@ -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()); | ||||
|  | ||||
|   | ||||
| @@ -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<std::forward_list<dpEntity*>>()); | ||||
| 	} | ||||
|  | ||||
| 	//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<dpEntity*>()); | ||||
| 		} | ||||
| 	} | ||||
| 	m_Cells.resize(NUM_CELLS, std::vector<std::vector<dpEntity*>>(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] | ||||
| 	cellX = std::clamp(cellX, 0, NUM_CELLS - 1); | ||||
| 	cellZ = 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] | ||||
| 	cellX = std::clamp(cellX, 0, NUM_CELLS - 1); | ||||
| 	cellZ = 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; | ||||
| 	oldCellX = std::clamp(oldCellX, 0, NUM_CELLS - 1); | ||||
| 	oldCellZ = 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] | ||||
| 	oldCellX = std::clamp(oldCellX, 0, NUM_CELLS - 1); | ||||
| 	oldCellZ = 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); | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -1,8 +1,7 @@ | ||||
| #pragma once | ||||
| #include <vector> | ||||
| #include <list> | ||||
| #include <forward_list> | ||||
| #include <map> | ||||
| #include <vector> | ||||
|  | ||||
| #include "dCommonVars.h" | ||||
|  | ||||
| class dpEntity; | ||||
| @@ -30,7 +29,8 @@ public: | ||||
| 	 */ | ||||
| 	void SetDeleteGrid(bool value) { this->m_DeleteGrid = value; }; | ||||
|  | ||||
| 	std::vector<std::vector<std::forward_list<dpEntity*>>> GetCells() { return this->m_Cells; }; | ||||
| 	// Intentional copy since this is only used when we delete this class to re-create it. | ||||
| 	std::vector<std::vector<std::vector<dpEntity*>>> 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<std::vector<std::forward_list<dpEntity*>>> m_Cells; | ||||
| 	std::vector<std::vector<std::vector<dpEntity*>>> m_Cells; | ||||
| 	std::map<LWOOBJID, dpEntity*> m_GargantuanObjects; | ||||
| 	bool m_DeleteGrid = true; | ||||
| }; | ||||
|   | ||||
| @@ -81,7 +81,7 @@ void dpWorld::Shutdown() { | ||||
| } | ||||
|  | ||||
| bool dpWorld::IsLoaded() { | ||||
| 	return m_NavMesh->GetdtNavMesh() != nullptr; | ||||
| 	return m_NavMesh->IsNavmeshLoaded(); | ||||
| } | ||||
|  | ||||
| void dpWorld::StepWorld(float deltaTime) { | ||||
|   | ||||
| @@ -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(); | ||||
|   | ||||
| @@ -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" | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 jadebenn
					jadebenn