mirror of
https://github.com/DarkflameUniverse/DarkflameServer
synced 2024-08-30 18:43:58 +00:00
chore: Move Player ghosting functionality to GhostComponent (#1413)
* Moving and organizing Player code - Move code to CharacterComponent - Remove extraneous interfaces - Simplify some code greatly - Change some types to return and take in const ref (only structs larger than 8 bytes benefit from this change.) - Update code to use CharacterComponent for sending to zone instead of Player*. * Moving and organizing Player code - Move code to CharacterComponent - Remove extraneous interfaces - Simplify some code greatly - Change some types to return and take in const ref (only structs larger than 8 bytes benefit from this change.) - Update code to use CharacterComponent for sending to zone instead of Player*. - Remove static storage container (static containers can be destroyed before exit/terminate handler executes) * remove player cast * Remove extra includes * Add a player manager Used for the static Player functions. Further removes stuff from the Player class/file. * chore: Move ghosting functionality to component Tested that ghosting still works and players are still firing off the OnPlayerLeave and relevant handlers. * move to unordered_set
This commit is contained in:
parent
0a30430c4f
commit
c83ec8228c
@ -2135,9 +2135,9 @@ void Entity::ProcessPositionUpdate(PositionUpdate& update) {
|
|||||||
controllablePhysicsComponent->SetAngularVelocity(update.angularVelocity);
|
controllablePhysicsComponent->SetAngularVelocity(update.angularVelocity);
|
||||||
controllablePhysicsComponent->SetDirtyAngularVelocity(update.angularVelocity != NiPoint3::ZERO);
|
controllablePhysicsComponent->SetDirtyAngularVelocity(update.angularVelocity != NiPoint3::ZERO);
|
||||||
|
|
||||||
auto* player = static_cast<Player*>(this);
|
auto* ghostComponent = GetComponent<GhostComponent>();
|
||||||
player->SetGhostReferencePoint(update.position);
|
if (ghostComponent) ghostComponent->SetGhostReferencePoint(update.position);
|
||||||
Game::entityManager->QueueGhostUpdate(player->GetObjectID());
|
Game::entityManager->QueueGhostUpdate(GetObjectID());
|
||||||
|
|
||||||
if (updateChar) Game::entityManager->SerializeEntity(this);
|
if (updateChar) Game::entityManager->SerializeEntity(this);
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include "eReplicaComponentType.h"
|
#include "eReplicaComponentType.h"
|
||||||
#include "eReplicaPacketType.h"
|
#include "eReplicaPacketType.h"
|
||||||
#include "PlayerManager.h"
|
#include "PlayerManager.h"
|
||||||
|
#include "GhostComponent.h"
|
||||||
|
|
||||||
// Configure which zones have ghosting disabled, mostly small worlds.
|
// Configure which zones have ghosting disabled, mostly small worlds.
|
||||||
std::vector<LWOMAPID> EntityManager::m_GhostingExcludedZones = {
|
std::vector<LWOMAPID> EntityManager::m_GhostingExcludedZones = {
|
||||||
@ -189,7 +190,8 @@ void EntityManager::SerializeEntities() {
|
|||||||
|
|
||||||
if (entity->GetIsGhostingCandidate()) {
|
if (entity->GetIsGhostingCandidate()) {
|
||||||
for (auto* player : PlayerManager::GetAllPlayers()) {
|
for (auto* player : PlayerManager::GetAllPlayers()) {
|
||||||
if (player->IsObserved(toSerialize)) {
|
auto* ghostComponent = player->GetComponent<GhostComponent>();
|
||||||
|
if (ghostComponent && ghostComponent->IsObserved(toSerialize)) {
|
||||||
Game::server->Send(&stream, player->GetSystemAddress(), false);
|
Game::server->Send(&stream, player->GetSystemAddress(), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -381,7 +383,8 @@ void EntityManager::ConstructEntity(Entity* entity, const SystemAddress& sysAddr
|
|||||||
if (player->GetPlayerReadyForUpdates()) {
|
if (player->GetPlayerReadyForUpdates()) {
|
||||||
Game::server->Send(&stream, player->GetSystemAddress(), false);
|
Game::server->Send(&stream, player->GetSystemAddress(), false);
|
||||||
} else {
|
} else {
|
||||||
player->AddLimboConstruction(entity->GetObjectID());
|
auto* ghostComponent = player->GetComponent<GhostComponent>();
|
||||||
|
if (ghostComponent) ghostComponent->AddLimboConstruction(entity->GetObjectID());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -421,7 +424,8 @@ void EntityManager::DestructEntity(Entity* entity, const SystemAddress& sysAddr)
|
|||||||
|
|
||||||
for (auto* player : PlayerManager::GetAllPlayers()) {
|
for (auto* player : PlayerManager::GetAllPlayers()) {
|
||||||
if (!player->GetPlayerReadyForUpdates()) {
|
if (!player->GetPlayerReadyForUpdates()) {
|
||||||
player->RemoveLimboConstruction(entity->GetObjectID());
|
auto* ghostComponent = player->GetComponent<GhostComponent>();
|
||||||
|
if (ghostComponent) ghostComponent->RemoveLimboConstruction(entity->GetObjectID());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -484,13 +488,14 @@ void EntityManager::UpdateGhosting(Player* player) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto* missionComponent = player->GetComponent<MissionComponent>();
|
auto* missionComponent = player->GetComponent<MissionComponent>();
|
||||||
|
auto* ghostComponent = player->GetComponent<GhostComponent>();
|
||||||
|
|
||||||
if (missionComponent == nullptr) {
|
if (missionComponent == nullptr || !ghostComponent) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& referencePoint = player->GetGhostReferencePoint();
|
const auto& referencePoint = ghostComponent->GetGhostReferencePoint();
|
||||||
const auto isOverride = player->GetGhostOverride();
|
const auto isOverride = ghostComponent->GetGhostOverride();
|
||||||
|
|
||||||
for (auto* entity : m_EntitiesToGhost) {
|
for (auto* entity : m_EntitiesToGhost) {
|
||||||
const auto isAudioEmitter = entity->GetLOT() == 6368;
|
const auto isAudioEmitter = entity->GetLOT() == 6368;
|
||||||
@ -499,7 +504,7 @@ void EntityManager::UpdateGhosting(Player* player) {
|
|||||||
|
|
||||||
const int32_t id = entity->GetObjectID();
|
const int32_t id = entity->GetObjectID();
|
||||||
|
|
||||||
const auto observed = player->IsObserved(id);
|
const auto observed = ghostComponent->IsObserved(id);
|
||||||
|
|
||||||
const auto distance = NiPoint3::DistanceSquared(referencePoint, entityPoint);
|
const auto distance = NiPoint3::DistanceSquared(referencePoint, entityPoint);
|
||||||
|
|
||||||
@ -511,7 +516,7 @@ void EntityManager::UpdateGhosting(Player* player) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (observed && distance > ghostingDistanceMax && !isOverride) {
|
if (observed && distance > ghostingDistanceMax && !isOverride) {
|
||||||
player->GhostEntity(id);
|
ghostComponent->GhostEntity(id);
|
||||||
|
|
||||||
DestructEntity(entity, player->GetSystemAddress());
|
DestructEntity(entity, player->GetSystemAddress());
|
||||||
|
|
||||||
@ -528,7 +533,7 @@ void EntityManager::UpdateGhosting(Player* player) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
player->ObserveEntity(id);
|
ghostComponent->ObserveEntity(id);
|
||||||
|
|
||||||
ConstructEntity(entity, player->GetSystemAddress());
|
ConstructEntity(entity, player->GetSystemAddress());
|
||||||
|
|
||||||
@ -550,22 +555,25 @@ void EntityManager::CheckGhosting(Entity* entity) {
|
|||||||
const auto isAudioEmitter = entity->GetLOT() == 6368;
|
const auto isAudioEmitter = entity->GetLOT() == 6368;
|
||||||
|
|
||||||
for (auto* player : PlayerManager::GetAllPlayers()) {
|
for (auto* player : PlayerManager::GetAllPlayers()) {
|
||||||
const auto& entityPoint = player->GetGhostReferencePoint();
|
auto* ghostComponent = player->GetComponent<GhostComponent>();
|
||||||
|
if (!ghostComponent) continue;
|
||||||
|
|
||||||
|
const auto& entityPoint = ghostComponent->GetGhostReferencePoint();
|
||||||
|
|
||||||
const int32_t id = entity->GetObjectID();
|
const int32_t id = entity->GetObjectID();
|
||||||
|
|
||||||
const auto observed = player->IsObserved(id);
|
const auto observed = ghostComponent->IsObserved(id);
|
||||||
|
|
||||||
const auto distance = NiPoint3::DistanceSquared(referencePoint, entityPoint);
|
const auto distance = NiPoint3::DistanceSquared(referencePoint, entityPoint);
|
||||||
|
|
||||||
if (observed && distance > ghostingDistanceMax) {
|
if (observed && distance > ghostingDistanceMax) {
|
||||||
player->GhostEntity(id);
|
ghostComponent->GhostEntity(id);
|
||||||
|
|
||||||
DestructEntity(entity, player->GetSystemAddress());
|
DestructEntity(entity, player->GetSystemAddress());
|
||||||
|
|
||||||
entity->SetObservers(entity->GetObservers() - 1);
|
entity->SetObservers(entity->GetObservers() - 1);
|
||||||
} else if (!observed && ghostingDistanceMin > distance) {
|
} else if (!observed && ghostingDistanceMin > distance) {
|
||||||
player->ObserveEntity(id);
|
ghostComponent->ObserveEntity(id);
|
||||||
|
|
||||||
ConstructEntity(entity, player->GetSystemAddress());
|
ConstructEntity(entity, player->GetSystemAddress());
|
||||||
|
|
||||||
|
@ -14,14 +14,6 @@
|
|||||||
#include "eReplicaComponentType.h"
|
#include "eReplicaComponentType.h"
|
||||||
#include "PlayerManager.h"
|
#include "PlayerManager.h"
|
||||||
|
|
||||||
void Player::SetGhostReferencePoint(const NiPoint3& value) {
|
|
||||||
m_GhostReferencePoint = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Player::SetGhostOverridePoint(const NiPoint3& value) {
|
|
||||||
m_GhostOverridePoint = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Player::SetRespawnPos(const NiPoint3& position) {
|
void Player::SetRespawnPos(const NiPoint3& position) {
|
||||||
if (!m_Character) return;
|
if (!m_Character) return;
|
||||||
|
|
||||||
@ -47,85 +39,16 @@ Player::Player(const LWOOBJID& objectID, const EntityInfo info, User* user, Enti
|
|||||||
m_SystemAddress = m_ParentUser->GetSystemAddress();
|
m_SystemAddress = m_ParentUser->GetSystemAddress();
|
||||||
m_DroppedCoins = 0;
|
m_DroppedCoins = 0;
|
||||||
|
|
||||||
m_GhostReferencePoint = NiPoint3::ZERO;
|
|
||||||
m_GhostOverridePoint = NiPoint3::ZERO;
|
|
||||||
m_GhostOverride = false;
|
|
||||||
|
|
||||||
int32_t initialObservedEntitiesCapacity = 256;
|
|
||||||
m_ObservedEntities.resize(initialObservedEntitiesCapacity);
|
|
||||||
|
|
||||||
m_Character->SetEntity(this);
|
m_Character->SetEntity(this);
|
||||||
|
|
||||||
PlayerManager::AddPlayer(this);
|
PlayerManager::AddPlayer(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::AddLimboConstruction(LWOOBJID objectId) {
|
|
||||||
const auto iter = std::find(m_LimboConstructions.begin(), m_LimboConstructions.end(), objectId);
|
|
||||||
if (iter == m_LimboConstructions.end()) {
|
|
||||||
m_LimboConstructions.push_back(objectId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Player::RemoveLimboConstruction(LWOOBJID objectId) {
|
|
||||||
const auto iter = std::find(m_LimboConstructions.begin(), m_LimboConstructions.end(), objectId);
|
|
||||||
if (iter != m_LimboConstructions.end()) {
|
|
||||||
m_LimboConstructions.erase(iter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Player::ConstructLimboEntities() {
|
|
||||||
for (const auto& objectId : m_LimboConstructions) {
|
|
||||||
auto* entity = Game::entityManager->GetEntity(objectId);
|
|
||||||
if (!entity) continue;
|
|
||||||
|
|
||||||
Game::entityManager->ConstructEntity(entity, m_SystemAddress);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_LimboConstructions.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Player::ObserveEntity(int32_t id) {
|
|
||||||
for (auto& observedEntity : m_ObservedEntities) {
|
|
||||||
if (observedEntity == 0 || observedEntity == id) {
|
|
||||||
observedEntity = id;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_ObservedEntities.reserve(m_ObservedEntities.size() + 1);
|
|
||||||
|
|
||||||
m_ObservedEntities.push_back(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Player::IsObserved(int32_t id) {
|
|
||||||
return std::find(m_ObservedEntities.begin(), m_ObservedEntities.end(), id) != m_ObservedEntities.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Player::GhostEntity(int32_t id) {
|
|
||||||
for (auto& observedEntity : m_ObservedEntities) {
|
|
||||||
if (observedEntity == id) {
|
|
||||||
observedEntity = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Player::~Player() {
|
Player::~Player() {
|
||||||
LOG("Deleted player");
|
LOG("Deleted player");
|
||||||
|
|
||||||
for (auto& observedEntity : m_ObservedEntities) {
|
|
||||||
if (observedEntity == 0) continue;
|
|
||||||
|
|
||||||
auto* entity = Game::entityManager->GetGhostCandidate(observedEntity);
|
|
||||||
if (!entity) continue;
|
|
||||||
|
|
||||||
entity->SetObservers(entity->GetObservers() - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_LimboConstructions.clear();
|
|
||||||
|
|
||||||
// Make sure the player exists first. Remove afterwards to prevent the OnPlayerExist functions from not being able to find the player.
|
// Make sure the player exists first. Remove afterwards to prevent the OnPlayerExist functions from not being able to find the player.
|
||||||
if (!PlayerManager::GetPlayer(GetObjectID())) {
|
if (!PlayerManager::RemovePlayer(this)) {
|
||||||
LOG("Unable to find player to remove from manager.");
|
LOG("Unable to find player to remove from manager.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -145,6 +68,4 @@ Player::~Player() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PlayerManager::RemovePlayer(this);
|
|
||||||
}
|
}
|
||||||
|
@ -26,14 +26,6 @@ public:
|
|||||||
|
|
||||||
const NiQuaternion& GetRespawnRotation() const override { return m_respawnRot; };
|
const NiQuaternion& GetRespawnRotation() const override { return m_respawnRot; };
|
||||||
|
|
||||||
const NiPoint3& GetGhostReferencePoint() const { return m_GhostOverride ? m_GhostOverridePoint : m_GhostReferencePoint; };
|
|
||||||
|
|
||||||
const NiPoint3& GetOriginGhostReferencePoint() const { return m_GhostReferencePoint; };
|
|
||||||
|
|
||||||
const NiPoint3& GetGhostOverridePoint() const { return m_GhostOverridePoint; };
|
|
||||||
|
|
||||||
bool GetGhostOverride() const { return m_GhostOverride; };
|
|
||||||
|
|
||||||
std::map<LWOOBJID, Loot::Info>& GetDroppedLoot() { return m_DroppedLoot; };
|
std::map<LWOOBJID, Loot::Info>& GetDroppedLoot() { return m_DroppedLoot; };
|
||||||
|
|
||||||
uint64_t GetDroppedCoins() const { return m_DroppedCoins; };
|
uint64_t GetDroppedCoins() const { return m_DroppedCoins; };
|
||||||
@ -42,8 +34,6 @@ public:
|
|||||||
* Setters
|
* Setters
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void SetGhostOverride(bool value) { m_GhostOverride = value; };
|
|
||||||
|
|
||||||
void SetDroppedCoins(const uint64_t value) { m_DroppedCoins = value; };
|
void SetDroppedCoins(const uint64_t value) { m_DroppedCoins = value; };
|
||||||
|
|
||||||
void SetSystemAddress(const SystemAddress& value) override;
|
void SetSystemAddress(const SystemAddress& value) override;
|
||||||
@ -52,26 +42,10 @@ public:
|
|||||||
|
|
||||||
void SetRespawnRot(const NiQuaternion& rotation) override;
|
void SetRespawnRot(const NiQuaternion& rotation) override;
|
||||||
|
|
||||||
void SetGhostReferencePoint(const NiPoint3& value);
|
|
||||||
|
|
||||||
void SetGhostOverridePoint(const NiPoint3& value);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ghosting
|
* Ghosting
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void AddLimboConstruction(LWOOBJID objectId);
|
|
||||||
|
|
||||||
void RemoveLimboConstruction(LWOOBJID objectId);
|
|
||||||
|
|
||||||
void ConstructLimboEntities();
|
|
||||||
|
|
||||||
void ObserveEntity(const int32_t id);
|
|
||||||
|
|
||||||
bool IsObserved(const int32_t id);
|
|
||||||
|
|
||||||
void GhostEntity(const int32_t id);
|
|
||||||
|
|
||||||
~Player() override;
|
~Player() override;
|
||||||
private:
|
private:
|
||||||
SystemAddress m_SystemAddress;
|
SystemAddress m_SystemAddress;
|
||||||
@ -82,16 +56,6 @@ private:
|
|||||||
|
|
||||||
User* m_ParentUser;
|
User* m_ParentUser;
|
||||||
|
|
||||||
NiPoint3 m_GhostReferencePoint;
|
|
||||||
|
|
||||||
NiPoint3 m_GhostOverridePoint;
|
|
||||||
|
|
||||||
bool m_GhostOverride;
|
|
||||||
|
|
||||||
std::vector<int32_t> m_ObservedEntities;
|
|
||||||
|
|
||||||
std::vector<LWOOBJID> m_LimboConstructions;
|
|
||||||
|
|
||||||
std::map<LWOOBJID, Loot::Info> m_DroppedLoot;
|
std::map<LWOOBJID, Loot::Info> m_DroppedLoot;
|
||||||
|
|
||||||
uint64_t m_DroppedCoins;
|
uint64_t m_DroppedCoins;
|
||||||
|
@ -22,12 +22,15 @@ void PlayerManager::AddPlayer(Player* player) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlayerManager::RemovePlayer(Player* player) {
|
bool PlayerManager::RemovePlayer(Player* 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()) {
|
const bool toReturn = iter != m_Players.end();
|
||||||
|
if (toReturn) {
|
||||||
m_Players.erase(iter);
|
m_Players.erase(iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return toReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
Player* PlayerManager::GetPlayer(const SystemAddress& sysAddr) {
|
Player* PlayerManager::GetPlayer(const SystemAddress& sysAddr) {
|
||||||
|
@ -11,7 +11,7 @@ struct SystemAddress;
|
|||||||
namespace PlayerManager {
|
namespace PlayerManager {
|
||||||
void AddPlayer(Player* player);
|
void AddPlayer(Player* player);
|
||||||
|
|
||||||
void RemovePlayer(Player* player);
|
bool RemovePlayer(Player* player);
|
||||||
|
|
||||||
Player* GetPlayer(const SystemAddress& sysAddr);
|
Player* GetPlayer(const SystemAddress& sysAddr);
|
||||||
|
|
||||||
|
@ -1,4 +1,57 @@
|
|||||||
#include "GhostComponent.h"
|
#include "GhostComponent.h"
|
||||||
|
|
||||||
// TODO Move ghosting related code from Player to here
|
GhostComponent::GhostComponent(Entity* parent) : Component(parent) {
|
||||||
GhostComponent::GhostComponent(Entity* parent) : Component(parent) {}
|
m_GhostReferencePoint = NiPoint3::ZERO;
|
||||||
|
m_GhostOverridePoint = NiPoint3::ZERO;
|
||||||
|
m_GhostOverride = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
GhostComponent::~GhostComponent() {
|
||||||
|
for (auto& observedEntity : m_ObservedEntities) {
|
||||||
|
if (observedEntity == 0) continue;
|
||||||
|
|
||||||
|
auto* entity = Game::entityManager->GetGhostCandidate(observedEntity);
|
||||||
|
if (!entity) continue;
|
||||||
|
|
||||||
|
entity->SetObservers(entity->GetObservers() - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GhostComponent::SetGhostReferencePoint(const NiPoint3& value) {
|
||||||
|
m_GhostReferencePoint = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GhostComponent::SetGhostOverridePoint(const NiPoint3& value) {
|
||||||
|
m_GhostOverridePoint = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GhostComponent::AddLimboConstruction(LWOOBJID objectId) {
|
||||||
|
m_LimboConstructions.insert(objectId);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GhostComponent::RemoveLimboConstruction(LWOOBJID objectId) {
|
||||||
|
m_LimboConstructions.erase(objectId);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GhostComponent::ConstructLimboEntities() {
|
||||||
|
for (const auto& objectId : m_LimboConstructions) {
|
||||||
|
auto* entity = Game::entityManager->GetEntity(objectId);
|
||||||
|
if (!entity) continue;
|
||||||
|
|
||||||
|
Game::entityManager->ConstructEntity(entity, m_Parent->GetSystemAddress());
|
||||||
|
}
|
||||||
|
|
||||||
|
m_LimboConstructions.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GhostComponent::ObserveEntity(int32_t id) {
|
||||||
|
m_ObservedEntities.insert(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GhostComponent::IsObserved(int32_t id) {
|
||||||
|
return m_ObservedEntities.contains(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GhostComponent::GhostEntity(int32_t id) {
|
||||||
|
m_ObservedEntities.erase(id);
|
||||||
|
}
|
||||||
|
@ -3,11 +3,52 @@
|
|||||||
|
|
||||||
#include "Component.h"
|
#include "Component.h"
|
||||||
#include "eReplicaComponentType.h"
|
#include "eReplicaComponentType.h"
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
|
class NiPoint3;
|
||||||
|
|
||||||
class GhostComponent : public Component {
|
class GhostComponent : public Component {
|
||||||
public:
|
public:
|
||||||
static inline const eReplicaComponentType ComponentType = eReplicaComponentType::GHOST;
|
static inline const eReplicaComponentType ComponentType = eReplicaComponentType::GHOST;
|
||||||
GhostComponent(Entity* parent);
|
GhostComponent(Entity* parent);
|
||||||
|
~GhostComponent() override;
|
||||||
|
|
||||||
|
void SetGhostOverride(bool value) { m_GhostOverride = value; };
|
||||||
|
|
||||||
|
const NiPoint3& GetGhostReferencePoint() const { return m_GhostOverride ? m_GhostOverridePoint : m_GhostReferencePoint; };
|
||||||
|
|
||||||
|
const NiPoint3& GetOriginGhostReferencePoint() const { return m_GhostReferencePoint; };
|
||||||
|
|
||||||
|
const NiPoint3& GetGhostOverridePoint() const { return m_GhostOverridePoint; };
|
||||||
|
|
||||||
|
bool GetGhostOverride() const { return m_GhostOverride; };
|
||||||
|
|
||||||
|
void SetGhostReferencePoint(const NiPoint3& value);
|
||||||
|
|
||||||
|
void SetGhostOverridePoint(const NiPoint3& value);
|
||||||
|
|
||||||
|
void AddLimboConstruction(const LWOOBJID objectId);
|
||||||
|
|
||||||
|
void RemoveLimboConstruction(const LWOOBJID objectId);
|
||||||
|
|
||||||
|
void ConstructLimboEntities();
|
||||||
|
|
||||||
|
void ObserveEntity(const int32_t id);
|
||||||
|
|
||||||
|
bool IsObserved(const int32_t id);
|
||||||
|
|
||||||
|
void GhostEntity(const int32_t id);
|
||||||
|
|
||||||
|
private:
|
||||||
|
NiPoint3 m_GhostReferencePoint;
|
||||||
|
|
||||||
|
NiPoint3 m_GhostOverridePoint;
|
||||||
|
|
||||||
|
std::unordered_set<int32_t> m_ObservedEntities;
|
||||||
|
|
||||||
|
std::unordered_set<LWOOBJID> m_LimboConstructions;
|
||||||
|
|
||||||
|
bool m_GhostOverride;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //!__GHOSTCOMPONENT__H__
|
#endif //!__GHOSTCOMPONENT__H__
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
#include "eGameMessageType.h"
|
#include "eGameMessageType.h"
|
||||||
#include "ePlayerFlag.h"
|
#include "ePlayerFlag.h"
|
||||||
#include "dConfig.h"
|
#include "dConfig.h"
|
||||||
|
#include "GhostComponent.h"
|
||||||
#include "StringifiedEnum.h"
|
#include "StringifiedEnum.h"
|
||||||
|
|
||||||
void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const SystemAddress& sysAddr, LWOOBJID objectID, eGameMessageType messageID) {
|
void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const SystemAddress& sysAddr, LWOOBJID objectID, eGameMessageType messageID) {
|
||||||
@ -108,9 +109,9 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System
|
|||||||
GameMessages::SendRestoreToPostLoadStats(entity, sysAddr);
|
GameMessages::SendRestoreToPostLoadStats(entity, sysAddr);
|
||||||
entity->SetPlayerReadyForUpdates();
|
entity->SetPlayerReadyForUpdates();
|
||||||
|
|
||||||
auto* player = dynamic_cast<Player*>(entity);
|
auto* ghostComponent = entity->GetComponent<GhostComponent>();
|
||||||
if (player != nullptr) {
|
if (ghostComponent != nullptr) {
|
||||||
player->ConstructLimboEntities();
|
ghostComponent->ConstructLimboEntities();
|
||||||
}
|
}
|
||||||
|
|
||||||
InventoryComponent* inv = entity->GetComponent<InventoryComponent>();
|
InventoryComponent* inv = entity->GetComponent<InventoryComponent>();
|
||||||
@ -137,14 +138,14 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System
|
|||||||
|
|
||||||
Entity* zoneControl = Game::entityManager->GetZoneControlEntity();
|
Entity* zoneControl = Game::entityManager->GetZoneControlEntity();
|
||||||
for (CppScripts::Script* script : CppScripts::GetEntityScripts(zoneControl)) {
|
for (CppScripts::Script* script : CppScripts::GetEntityScripts(zoneControl)) {
|
||||||
script->OnPlayerLoaded(zoneControl, player);
|
script->OnPlayerLoaded(zoneControl, entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Entity*> scriptedActs = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::SCRIPT);
|
std::vector<Entity*> scriptedActs = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::SCRIPT);
|
||||||
for (Entity* scriptEntity : scriptedActs) {
|
for (Entity* scriptEntity : scriptedActs) {
|
||||||
if (scriptEntity->GetObjectID() != zoneControl->GetObjectID()) { // Don't want to trigger twice on instance worlds
|
if (scriptEntity->GetObjectID() != zoneControl->GetObjectID()) { // Don't want to trigger twice on instance worlds
|
||||||
for (CppScripts::Script* script : CppScripts::GetEntityScripts(scriptEntity)) {
|
for (CppScripts::Script* script : CppScripts::GetEntityScripts(scriptEntity)) {
|
||||||
script->OnPlayerLoaded(scriptEntity, player);
|
script->OnPlayerLoaded(scriptEntity, entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -78,6 +78,7 @@
|
|||||||
#include "RailActivatorComponent.h"
|
#include "RailActivatorComponent.h"
|
||||||
#include "LevelProgressionComponent.h"
|
#include "LevelProgressionComponent.h"
|
||||||
#include "DonationVendorComponent.h"
|
#include "DonationVendorComponent.h"
|
||||||
|
#include "GhostComponent.h"
|
||||||
|
|
||||||
// Message includes:
|
// Message includes:
|
||||||
#include "dZoneManager.h"
|
#include "dZoneManager.h"
|
||||||
@ -4605,7 +4606,8 @@ void GameMessages::HandleToggleGhostReferenceOverride(RakNet::BitStream* inStrea
|
|||||||
auto* player = PlayerManager::GetPlayer(sysAddr);
|
auto* player = PlayerManager::GetPlayer(sysAddr);
|
||||||
|
|
||||||
if (player != nullptr) {
|
if (player != nullptr) {
|
||||||
player->SetGhostOverride(bOverride);
|
auto* ghostComponent = entity->GetComponent<GhostComponent>();
|
||||||
|
if (ghostComponent) ghostComponent->SetGhostOverride(bOverride);
|
||||||
|
|
||||||
Game::entityManager->UpdateGhosting(player);
|
Game::entityManager->UpdateGhosting(player);
|
||||||
}
|
}
|
||||||
@ -4620,7 +4622,8 @@ void GameMessages::HandleSetGhostReferencePosition(RakNet::BitStream* inStream,
|
|||||||
auto* player = PlayerManager::GetPlayer(sysAddr);
|
auto* player = PlayerManager::GetPlayer(sysAddr);
|
||||||
|
|
||||||
if (player != nullptr) {
|
if (player != nullptr) {
|
||||||
player->SetGhostOverridePoint(position);
|
auto* ghostComponent = entity->GetComponent<GhostComponent>();
|
||||||
|
if (ghostComponent) ghostComponent->SetGhostOverridePoint(position);
|
||||||
|
|
||||||
Game::entityManager->UpdateGhosting(player);
|
Game::entityManager->UpdateGhosting(player);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user