diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index 16169887..269b4cc4 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -1682,9 +1682,9 @@ void Entity::PickupItem(const LWOOBJID& objectID) { std::vector skills = skillsTable->Query([=](CDObjectSkills entry) {return (entry.objectTemplate == p.second.lot); }); for (CDObjectSkills skill : skills) { CDSkillBehaviorTable* skillBehTable = CDClientManager::GetTable(); - CDSkillBehavior behaviorData = skillBehTable->GetSkillByID(skill.skillID); - SkillComponent::HandleUnmanaged(behaviorData.behaviorID, GetObjectID()); + auto* skillComponent = GetComponent(); + if (skillComponent) skillComponent->CastSkill(skill.skillID, GetObjectID(), GetObjectID()); auto* missionComponent = GetComponent(); diff --git a/dGame/EntityManager.cpp b/dGame/EntityManager.cpp index e1f2f46e..fc9fa0f0 100644 --- a/dGame/EntityManager.cpp +++ b/dGame/EntityManager.cpp @@ -24,6 +24,7 @@ #include "eReplicaPacketType.h" #include "PlayerManager.h" #include "GhostComponent.h" +#include // Configure which zones have ghosting disabled, mostly small worlds. std::vector EntityManager::m_GhostingExcludedZones = { @@ -165,8 +166,8 @@ void EntityManager::DestroyEntity(Entity* entity) { } void EntityManager::SerializeEntities() { - for (int32_t i = 0; i < m_EntitiesToSerialize.size(); i++) { - const LWOOBJID toSerialize = m_EntitiesToSerialize.at(i); + for (size_t i = 0; i < m_EntitiesToSerialize.size(); i++) { + const LWOOBJID toSerialize = m_EntitiesToSerialize[i]; auto* entity = GetEntity(toSerialize); if (!entity) continue; @@ -195,8 +196,8 @@ void EntityManager::SerializeEntities() { } void EntityManager::KillEntities() { - for (int32_t i = 0; i < m_EntitiesToKill.size(); i++) { - const LWOOBJID toKill = m_EntitiesToKill.at(i); + for (size_t i = 0; i < m_EntitiesToKill.size(); i++) { + const LWOOBJID toKill = m_EntitiesToKill[i]; auto* entity = GetEntity(toKill); if (!entity) { @@ -214,8 +215,8 @@ void EntityManager::KillEntities() { } void EntityManager::DeleteEntities() { - for (int32_t i = 0; i < m_EntitiesToDelete.size(); i++) { - const LWOOBJID toDelete = m_EntitiesToDelete.at(i); + for (size_t i = 0; i < m_EntitiesToDelete.size(); i++) { + const LWOOBJID toDelete = m_EntitiesToDelete[i]; auto entityToDelete = GetEntity(toDelete); if (entityToDelete) { // Get all this info first before we delete the player. @@ -238,8 +239,8 @@ void EntityManager::DeleteEntities() { } void EntityManager::UpdateEntities(const float deltaTime) { - for (const auto& e : m_Entities) { - e.second->Update(deltaTime); + for (auto* entity : m_Entities | std::views::values) { + entity->Update(deltaTime); } SerializeEntities(); @@ -259,10 +260,10 @@ Entity* EntityManager::GetEntity(const LWOOBJID& objectId) const { std::vector EntityManager::GetEntitiesInGroup(const std::string& group) { std::vector entitiesInGroup; - for (const auto& entity : m_Entities) { - for (const auto& entityGroup : entity.second->GetGroups()) { + for (auto* entity : m_Entities | std::views::values) { + for (const auto& entityGroup : entity->GetGroups()) { if (entityGroup == group) { - entitiesInGroup.push_back(entity.second); + entitiesInGroup.push_back(entity); } } } @@ -272,10 +273,12 @@ std::vector EntityManager::GetEntitiesInGroup(const std::string& group) std::vector EntityManager::GetEntitiesByComponent(const eReplicaComponentType componentType) const { std::vector withComp; - for (const auto& entity : m_Entities) { - if (componentType != eReplicaComponentType::INVALID && !entity.second->HasComponent(componentType)) continue; + if (componentType != eReplicaComponentType::INVALID) { + for (auto* entity : m_Entities | std::views::values) { + if (!entity->HasComponent(componentType)) continue; - withComp.push_back(entity.second); + withComp.push_back(entity); + } } return withComp; } @@ -283,19 +286,19 @@ std::vector EntityManager::GetEntitiesByComponent(const eReplicaCompone std::vector EntityManager::GetEntitiesByLOT(const LOT& lot) const { std::vector entities; - for (const auto& entity : m_Entities) { - if (entity.second->GetLOT() == lot) - entities.push_back(entity.second); + for (auto* entity : m_Entities | std::views::values) { + if (entity->GetLOT() == lot) entities.push_back(entity); } return entities; } -std::vector EntityManager::GetEntitiesByProximity(NiPoint3 reference, float radius) const{ - std::vector entities = {}; - if (radius > 1000.0f) return entities; - for (const auto& entity : m_Entities) { - if (NiPoint3::Distance(reference, entity.second->GetPosition()) <= radius) entities.push_back(entity.second); +std::vector EntityManager::GetEntitiesByProximity(NiPoint3 reference, float radius) const { + std::vector entities; + if (radius <= 1000.0f) { // The client has a 1000 unit limit on this same logic, so we'll use the same limit + for (auto* entity : m_Entities | std::views::values) { + if (NiPoint3::Distance(reference, entity->GetPosition()) <= radius) entities.push_back(entity); + } } return entities; } @@ -309,12 +312,8 @@ Entity* EntityManager::GetSpawnPointEntity(const std::string& spawnName) const { // Lookup the spawn point entity in the map const auto& spawnPoint = m_SpawnPoints.find(spawnName); - if (spawnPoint == m_SpawnPoints.end()) { - return nullptr; - } - // Check if the spawn point entity is valid just in case - return GetEntity(spawnPoint->second); + return spawnPoint == m_SpawnPoints.end() ? nullptr : GetEntity(spawnPoint->second); } const std::unordered_map& EntityManager::GetSpawnPointEntities() const { @@ -340,29 +339,25 @@ void EntityManager::ConstructEntity(Entity* entity, const SystemAddress& sysAddr entity->SetNetworkId(networkId); } - const auto checkGhosting = entity->GetIsGhostingCandidate(); - - if (checkGhosting) { - const auto& iter = std::find(m_EntitiesToGhost.begin(), m_EntitiesToGhost.end(), entity); - - if (iter == m_EntitiesToGhost.end()) { + if (entity->GetIsGhostingCandidate()) { + if (std::find(m_EntitiesToGhost.begin(), m_EntitiesToGhost.end(), entity) == m_EntitiesToGhost.end()) { m_EntitiesToGhost.push_back(entity); } - } - if (checkGhosting && sysAddr == UNASSIGNED_SYSTEM_ADDRESS) { - CheckGhosting(entity); + if (sysAddr == UNASSIGNED_SYSTEM_ADDRESS) { + CheckGhosting(entity); - return; + return; + } } m_SerializationCounter++; RakNet::BitStream stream; - stream.Write(ID_REPLICA_MANAGER_CONSTRUCTION); + stream.Write(ID_REPLICA_MANAGER_CONSTRUCTION); stream.Write(true); - stream.Write(entity->GetNetworkId()); + stream.Write(entity->GetNetworkId()); entity->WriteBaseReplicaData(&stream, eReplicaPacketType::CONSTRUCTION); entity->WriteComponents(&stream, eReplicaPacketType::CONSTRUCTION); @@ -395,9 +390,9 @@ void EntityManager::ConstructAllEntities(const SystemAddress& sysAddr) { //ZoneControl is special: ConstructEntity(m_ZoneControlEntity, sysAddr); - for (const auto& e : m_Entities) { - if (e.second && (e.second->GetSpawnerID() != 0 || e.second->GetLOT() == 1) && !e.second->GetIsGhostingCandidate()) { - ConstructEntity(e.second, sysAddr); + for (auto* entity : m_Entities | std::views::values) { + if (entity && (entity->GetSpawnerID() != 0 || entity->GetLOT() == 1) && !entity->GetIsGhostingCandidate()) { + ConstructEntity(entity, sysAddr); } } @@ -409,8 +404,8 @@ void EntityManager::DestructEntity(Entity* entity, const SystemAddress& sysAddr) RakNet::BitStream stream; - stream.Write(ID_REPLICA_MANAGER_DESTRUCTION); - stream.Write(entity->GetNetworkId()); + stream.Write(ID_REPLICA_MANAGER_DESTRUCTION); + stream.Write(entity->GetNetworkId()); Game::server->Send(&stream, sysAddr, sysAddr == UNASSIGNED_SYSTEM_ADDRESS); @@ -431,8 +426,8 @@ void EntityManager::SerializeEntity(Entity* entity) { } void EntityManager::DestructAllEntities(const SystemAddress& sysAddr) { - for (const auto& e : m_Entities) { - DestructEntity(e.second, sysAddr); + for (auto* entity : m_Entities | std::views::values) { + DestructEntity(entity, sysAddr); } } @@ -440,22 +435,12 @@ void EntityManager::SetGhostDistanceMax(float value) { m_GhostDistanceMaxSquared = value * value; } -float EntityManager::GetGhostDistanceMax() const { - return std::sqrt(m_GhostDistanceMaxSquared); -} - void EntityManager::SetGhostDistanceMin(float value) { m_GhostDistanceMinSqaured = value * value; } -float EntityManager::GetGhostDistanceMin() const { - return std::sqrt(m_GhostDistanceMinSqaured); -} - void EntityManager::QueueGhostUpdate(LWOOBJID playerID) { - const auto& iter = std::find(m_PlayersToUpdateGhosting.begin(), m_PlayersToUpdateGhosting.end(), playerID); - - if (iter == m_PlayersToUpdateGhosting.end()) { + if (std::find(m_PlayersToUpdateGhosting.begin(), m_PlayersToUpdateGhosting.end(), playerID) == m_PlayersToUpdateGhosting.end()) { m_PlayersToUpdateGhosting.push_back(playerID); } } @@ -475,26 +460,20 @@ void EntityManager::UpdateGhosting() { } void EntityManager::UpdateGhosting(Entity* player) { - if (player == nullptr) { - return; - } + if (!player) return; auto* missionComponent = player->GetComponent(); auto* ghostComponent = player->GetComponent(); - if (missionComponent == nullptr || !ghostComponent) { - return; - } + if (!missionComponent || !ghostComponent) return; const auto& referencePoint = ghostComponent->GetGhostReferencePoint(); const auto isOverride = ghostComponent->GetGhostOverride(); for (auto* entity : m_EntitiesToGhost) { - const auto isAudioEmitter = entity->GetLOT() == 6368; - const auto& entityPoint = entity->GetPosition(); - const int32_t id = entity->GetObjectID(); + const auto id = entity->GetObjectID(); const auto observed = ghostComponent->IsObserved(id); @@ -503,6 +482,7 @@ void EntityManager::UpdateGhosting(Entity* player) { auto ghostingDistanceMax = m_GhostDistanceMaxSquared; auto ghostingDistanceMin = m_GhostDistanceMinSqaured; + const auto isAudioEmitter = entity->GetLOT() == 6368; // https://explorer.lu/objects/6368 if (isAudioEmitter) { ghostingDistanceMax = ghostingDistanceMin; } @@ -541,30 +521,25 @@ void EntityManager::CheckGhosting(Entity* entity) { const auto& referencePoint = entity->GetPosition(); - auto ghostingDistanceMax = m_GhostDistanceMaxSquared; - auto ghostingDistanceMin = m_GhostDistanceMinSqaured; - - const auto isAudioEmitter = entity->GetLOT() == 6368; - for (auto* player : PlayerManager::GetAllPlayers()) { auto* ghostComponent = player->GetComponent(); if (!ghostComponent) continue; const auto& entityPoint = ghostComponent->GetGhostReferencePoint(); - const int32_t id = entity->GetObjectID(); + const auto id = entity->GetObjectID(); const auto observed = ghostComponent->IsObserved(id); const auto distance = NiPoint3::DistanceSquared(referencePoint, entityPoint); - if (observed && distance > ghostingDistanceMax) { + if (observed && distance > m_GhostDistanceMaxSquared) { ghostComponent->GhostEntity(id); DestructEntity(entity, player->GetSystemAddress()); entity->SetObservers(entity->GetObservers() - 1); - } else if (!observed && ghostingDistanceMin > distance) { + } else if (!observed && m_GhostDistanceMinSqaured > distance) { ghostComponent->ObserveEntity(id); ConstructEntity(entity, player->GetSystemAddress()); @@ -574,7 +549,7 @@ void EntityManager::CheckGhosting(Entity* entity) { } } -Entity* EntityManager::GetGhostCandidate(int32_t id) { +Entity* EntityManager::GetGhostCandidate(LWOOBJID id) const { for (auto* entity : m_EntitiesToGhost) { if (entity->GetObjectID() == id) { return entity; @@ -600,26 +575,22 @@ void EntityManager::ScheduleForKill(Entity* entity) { const auto objectId = entity->GetObjectID(); - if (std::count(m_EntitiesToKill.begin(), m_EntitiesToKill.end(), objectId)) { - return; + if (std::find(m_EntitiesToKill.begin(), m_EntitiesToKill.end(), objectId) != m_EntitiesToKill.end()) { + m_EntitiesToKill.push_back(objectId); } - - m_EntitiesToKill.push_back(objectId); } void EntityManager::ScheduleForDeletion(LWOOBJID entity) { - if (std::count(m_EntitiesToDelete.begin(), m_EntitiesToDelete.end(), entity)) { - return; + if (std::find(m_EntitiesToDelete.begin(), m_EntitiesToDelete.end(), entity) != m_EntitiesToDelete.end()) { + m_EntitiesToDelete.push_back(entity); } - - m_EntitiesToDelete.push_back(entity); } void EntityManager::FireEventServerSide(Entity* origin, std::string args) { - for (std::pair e : m_Entities) { - if (e.second) { - e.second->OnFireEventServerSide(origin, args); + for (const auto entity : m_Entities | std::views::values) { + if (entity) { + entity->OnFireEventServerSide(origin, args); } } } diff --git a/dGame/EntityManager.h b/dGame/EntityManager.h index 352b927b..abffe546 100644 --- a/dGame/EntityManager.h +++ b/dGame/EntityManager.h @@ -50,14 +50,12 @@ public: void DestructAllEntities(const SystemAddress& sysAddr); void SetGhostDistanceMax(float value); - float GetGhostDistanceMax() const; void SetGhostDistanceMin(float value); - float GetGhostDistanceMin() const; void QueueGhostUpdate(LWOOBJID playerID); void UpdateGhosting(); void UpdateGhosting(Entity* player); void CheckGhosting(Entity* entity); - Entity* GetGhostCandidate(int32_t id); + Entity* GetGhostCandidate(LWOOBJID id) const; bool GetGhostingEnabled() const; void ScheduleForKill(Entity* entity); diff --git a/dGame/TradingManager.cpp b/dGame/TradingManager.cpp index 3d9a209c..c7143354 100644 --- a/dGame/TradingManager.cpp +++ b/dGame/TradingManager.cpp @@ -104,7 +104,7 @@ void Trade::SetAccepted(LWOOBJID participant, bool value) { } Complete(); - TradingManager::Instance()->CancelTrade(m_TradeId); + TradingManager::Instance()->CancelTrade(LWOOBJID_EMPTY, m_TradeId, false); } } @@ -178,14 +178,14 @@ void Trade::Complete() { return; } -void Trade::Cancel() { +void Trade::Cancel(const LWOOBJID canceller) { auto* entityA = GetParticipantAEntity(); auto* entityB = GetParticipantBEntity(); if (entityA == nullptr || entityB == nullptr) return; - GameMessages::SendServerTradeCancel(entityA->GetObjectID(), entityA->GetSystemAddress()); - GameMessages::SendServerTradeCancel(entityB->GetObjectID(), entityB->GetSystemAddress()); + if (entityA->GetObjectID() != canceller || canceller == LWOOBJID_EMPTY) GameMessages::SendServerTradeCancel(entityA->GetObjectID(), entityA->GetSystemAddress()); + if (entityB->GetObjectID() != canceller || canceller == LWOOBJID_EMPTY) GameMessages::SendServerTradeCancel(entityB->GetObjectID(), entityB->GetSystemAddress()); } void Trade::SendUpdateToOther(LWOOBJID participant) { @@ -262,11 +262,13 @@ Trade* TradingManager::GetPlayerTrade(LWOOBJID playerId) const { return nullptr; } -void TradingManager::CancelTrade(LWOOBJID tradeId) { +void TradingManager::CancelTrade(const LWOOBJID canceller, LWOOBJID tradeId, const bool sendCancelMessage) { auto* trade = GetTrade(tradeId); if (trade == nullptr) return; + if (sendCancelMessage) trade->Cancel(canceller); + delete trade; trades.erase(tradeId); diff --git a/dGame/TradingManager.h b/dGame/TradingManager.h index ec0d332f..fa55aa9d 100644 --- a/dGame/TradingManager.h +++ b/dGame/TradingManager.h @@ -30,7 +30,7 @@ public: void SetAccepted(LWOOBJID participant, bool value); void Complete(); - void Cancel(); + void Cancel(const LWOOBJID canceller); void SendUpdateToOther(LWOOBJID participant); @@ -66,7 +66,7 @@ public: Trade* GetTrade(LWOOBJID tradeId) const; Trade* GetPlayerTrade(LWOOBJID playerId) const; - void CancelTrade(LWOOBJID tradeId); + void CancelTrade(const LWOOBJID canceller, LWOOBJID tradeId, const bool sendCancelMessage = true); Trade* NewTrade(LWOOBJID participantA, LWOOBJID participantB); private: diff --git a/dGame/UserManager.cpp b/dGame/UserManager.cpp index b98569eb..0fde2eb6 100644 --- a/dGame/UserManager.cpp +++ b/dGame/UserManager.cpp @@ -301,6 +301,7 @@ void UserManager::CreateCharacter(const SystemAddress& sysAddr, Packet* packet) const auto name = LUWStringName.GetAsString(); std::string predefinedName = GetPredefinedName(firstNameIndex, middleNameIndex, lastNameIndex); + LOT shirtLOT = FindCharShirtID(shirtColor, shirtStyle); LOT pantsLOT = FindCharPantsID(pantsColor); @@ -323,7 +324,7 @@ void UserManager::CreateCharacter(const SystemAddress& sysAddr, Packet* packet) } //Now that the name is ok, we can get an objectID from Master: - ObjectIDManager::RequestPersistentID([=, this](uint32_t objectID) { + ObjectIDManager::RequestPersistentID([=, this](uint32_t objectID) mutable { if (Database::Get()->GetCharacterInfo(objectID)) { LOG("Character object id unavailable, check object_id_tracker!"); WorldPackets::SendCharacterCreationResponse(sysAddr, eCharacterCreationResponse::OBJECT_ID_UNAVAILABLE); @@ -366,6 +367,14 @@ void UserManager::CreateCharacter(const SystemAddress& sysAddr, Packet* packet) bool nameOk = IsNamePreapproved(name); if (!nameOk && u->GetMaxGMLevel() > eGameMasterLevel::FORUM_MODERATOR) nameOk = true; + // If predefined name is invalid, change it to be their object id + // that way more than one player can create characters if the predefined name files are not provided + if (predefinedName == "INVALID") { + std::stringstream nameObjID; + nameObjID << "minifig" << objectID; + predefinedName = nameObjID.str(); + } + std::string_view nameToAssign = !name.empty() && nameOk ? name : predefinedName; std::string pendingName = !name.empty() && !nameOk ? name : ""; diff --git a/dGame/dComponents/GhostComponent.cpp b/dGame/dComponents/GhostComponent.cpp index db12ce4d..3aea329a 100644 --- a/dGame/dComponents/GhostComponent.cpp +++ b/dGame/dComponents/GhostComponent.cpp @@ -8,7 +8,7 @@ GhostComponent::GhostComponent(Entity* parent) : Component(parent) { GhostComponent::~GhostComponent() { for (auto& observedEntity : m_ObservedEntities) { - if (observedEntity == 0) continue; + if (observedEntity == LWOOBJID_EMPTY) continue; auto* entity = Game::entityManager->GetGhostCandidate(observedEntity); if (!entity) continue; @@ -44,14 +44,14 @@ void GhostComponent::ConstructLimboEntities() { m_LimboConstructions.clear(); } -void GhostComponent::ObserveEntity(int32_t id) { +void GhostComponent::ObserveEntity(LWOOBJID id) { m_ObservedEntities.insert(id); } -bool GhostComponent::IsObserved(int32_t id) { +bool GhostComponent::IsObserved(LWOOBJID id) { return m_ObservedEntities.contains(id); } -void GhostComponent::GhostEntity(int32_t id) { +void GhostComponent::GhostEntity(LWOOBJID id) { m_ObservedEntities.erase(id); } diff --git a/dGame/dComponents/GhostComponent.h b/dGame/dComponents/GhostComponent.h index bc4f158d..de0fb886 100644 --- a/dGame/dComponents/GhostComponent.h +++ b/dGame/dComponents/GhostComponent.h @@ -33,18 +33,18 @@ public: void ConstructLimboEntities(); - void ObserveEntity(const int32_t id); + void ObserveEntity(const LWOOBJID id); - bool IsObserved(const int32_t id); + bool IsObserved(const LWOOBJID id); - void GhostEntity(const int32_t id); + void GhostEntity(const LWOOBJID id); private: NiPoint3 m_GhostReferencePoint; NiPoint3 m_GhostOverridePoint; - std::unordered_set m_ObservedEntities; + std::unordered_set m_ObservedEntities; std::unordered_set m_LimboConstructions; diff --git a/dGame/dComponents/PhantomPhysicsComponent.cpp b/dGame/dComponents/PhantomPhysicsComponent.cpp index b3021415..592c2a6b 100644 --- a/dGame/dComponents/PhantomPhysicsComponent.cpp +++ b/dGame/dComponents/PhantomPhysicsComponent.cpp @@ -156,83 +156,42 @@ PhantomPhysicsComponent::PhantomPhysicsComponent(Entity* parent) : PhysicsCompon //temp test if (info->physicsAsset == "miscellaneous\\misc_phys_10x1x5.hkx") { m_dpEntity = new dpEntity(m_Parent->GetObjectID(), 10.0f, 5.0f, 1.0f); - - m_dpEntity->SetScale(m_Scale); - m_dpEntity->SetRotation(m_Rotation); - m_dpEntity->SetPosition(m_Position); - - dpWorld::AddEntity(m_dpEntity); } else if (info->physicsAsset == "miscellaneous\\misc_phys_640x640.hkx") { - // Move this down by 13.521004 units so it is still effectively at the same height as before - m_Position = m_Position - NiPoint3Constant::UNIT_Y * 13.521004f; // TODO Fix physics simulation to do simulation at high velocities due to bullet through paper problem... m_dpEntity = new dpEntity(m_Parent->GetObjectID(), 1638.4f, 13.521004f * 2.0f, 1638.4f); - m_dpEntity->SetScale(m_Scale); - m_dpEntity->SetRotation(m_Rotation); - m_dpEntity->SetPosition(m_Position); - - dpWorld::AddEntity(m_dpEntity); + // Move this down by 13.521004 units so it is still effectively at the same height as before + m_Position = m_Position - NiPoint3Constant::UNIT_Y * 13.521004f; } else if (info->physicsAsset == "env\\trigger_wall_tall.hkx") { m_dpEntity = new dpEntity(m_Parent->GetObjectID(), 10.0f, 25.0f, 1.0f); - m_dpEntity->SetScale(m_Scale); - m_dpEntity->SetRotation(m_Rotation); - m_dpEntity->SetPosition(m_Position); - dpWorld::AddEntity(m_dpEntity); } else if (info->physicsAsset == "env\\env_gen_placeholderphysics.hkx") { m_dpEntity = new dpEntity(m_Parent->GetObjectID(), 20.0f, 20.0f, 20.0f); - m_dpEntity->SetScale(m_Scale); - m_dpEntity->SetRotation(m_Rotation); - m_dpEntity->SetPosition(m_Position); - dpWorld::AddEntity(m_dpEntity); } else if (info->physicsAsset == "env\\POI_trigger_wall.hkx") { m_dpEntity = new dpEntity(m_Parent->GetObjectID(), 1.0f, 12.5f, 20.0f); // Not sure what the real size is - m_dpEntity->SetScale(m_Scale); - m_dpEntity->SetRotation(m_Rotation); - m_dpEntity->SetPosition(m_Position); - dpWorld::AddEntity(m_dpEntity); } else if (info->physicsAsset == "env\\NG_NinjaGo\\env_ng_gen_gate_chamber_puzzle_ceiling_tile_falling_phantom.hkx") { m_dpEntity = new dpEntity(m_Parent->GetObjectID(), 18.0f, 5.0f, 15.0f); - m_dpEntity->SetScale(m_Scale); - m_dpEntity->SetRotation(m_Rotation); - m_dpEntity->SetPosition(m_Position + m_Rotation.GetForwardVector() * 7.5f); - dpWorld::AddEntity(m_dpEntity); + m_Position += m_Rotation.GetForwardVector() * 7.5f; } else if (info->physicsAsset == "env\\NG_NinjaGo\\ng_flamejet_brick_phantom.HKX") { m_dpEntity = new dpEntity(m_Parent->GetObjectID(), 1.0f, 1.0f, 12.0f); - m_dpEntity->SetScale(m_Scale); - m_dpEntity->SetRotation(m_Rotation); - m_dpEntity->SetPosition(m_Position + m_Rotation.GetForwardVector() * 6.0f); - dpWorld::AddEntity(m_dpEntity); + m_Position += m_Rotation.GetForwardVector() * 6.0f; } else if (info->physicsAsset == "env\\Ring_Trigger.hkx") { m_dpEntity = new dpEntity(m_Parent->GetObjectID(), 6.0f, 6.0f, 6.0f); - m_dpEntity->SetScale(m_Scale); - m_dpEntity->SetRotation(m_Rotation); - m_dpEntity->SetPosition(m_Position); - dpWorld::AddEntity(m_dpEntity); } else if (info->physicsAsset == "env\\vfx_propertyImaginationBall.hkx") { m_dpEntity = new dpEntity(m_Parent->GetObjectID(), 4.5f); - m_dpEntity->SetScale(m_Scale); - m_dpEntity->SetRotation(m_Rotation); - m_dpEntity->SetPosition(m_Position); - dpWorld::AddEntity(m_dpEntity); } else if (info->physicsAsset == "env\\env_won_fv_gas-blocking-volume.hkx") { m_dpEntity = new dpEntity(m_Parent->GetObjectID(), 390.496826f, 111.467964f, 600.821534f, true); - m_dpEntity->SetScale(m_Scale); - m_dpEntity->SetRotation(m_Rotation); m_Position.y -= (111.467964f * m_Scale) / 2; - m_dpEntity->SetPosition(m_Position); - dpWorld::AddEntity(m_dpEntity); } else { - //LOG("This one is supposed to have %s", info->physicsAsset.c_str()); + // LOG_DEBUG("This one is supposed to have %s", info->physicsAsset.c_str()); //add fallback cube: m_dpEntity = new dpEntity(m_Parent->GetObjectID(), 2.0f, 2.0f, 2.0f); - m_dpEntity->SetScale(m_Scale); - m_dpEntity->SetRotation(m_Rotation); - m_dpEntity->SetPosition(m_Position); - dpWorld::AddEntity(m_dpEntity); } - + + m_dpEntity->SetScale(m_Scale); + m_dpEntity->SetRotation(m_Rotation); + m_dpEntity->SetPosition(m_Position); + dpWorld::AddEntity(m_dpEntity); } } diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index 8b4d1f05..3c42f4db 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -3270,7 +3270,7 @@ void GameMessages::HandleClientTradeRequest(RakNet::BitStream* inStream, Entity* if (trade != nullptr) { if (!trade->IsParticipant(i64Invitee)) { - TradingManager::Instance()->CancelTrade(trade->GetTradeId()); + TradingManager::Instance()->CancelTrade(entity->GetObjectID(), trade->GetTradeId()); TradingManager::Instance()->NewTrade(entity->GetObjectID(), i64Invitee); } @@ -3295,7 +3295,7 @@ void GameMessages::HandleClientTradeCancel(RakNet::BitStream* inStream, Entity* LOG("Trade canceled from (%llu)", entity->GetObjectID()); - TradingManager::Instance()->CancelTrade(trade->GetTradeId()); + TradingManager::Instance()->CancelTrade(entity->GetObjectID(), trade->GetTradeId()); } void GameMessages::HandleClientTradeAccept(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { diff --git a/dGame/dUtilities/SlashCommandHandler.cpp b/dGame/dUtilities/SlashCommandHandler.cpp index 169426ab..cd938bab 100644 --- a/dGame/dUtilities/SlashCommandHandler.cpp +++ b/dGame/dUtilities/SlashCommandHandler.cpp @@ -631,6 +631,9 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit if (infile.good()) { std::string line; while (std::getline(infile, line)) { + // Do this in two separate calls to catch both \n and \r\n + line.erase(std::remove(line.begin(), line.end(), '\n'), line.end()); + line.erase(std::remove(line.begin(), line.end(), '\r'), line.end()); SlashCommandHandler::HandleChatCommand(GeneralUtils::ASCIIToUTF16(line), entity, sysAddr); } } else { diff --git a/dScripts/02_server/Enemy/AG/BossSpiderQueenEnemyServer.cpp b/dScripts/02_server/Enemy/AG/BossSpiderQueenEnemyServer.cpp index a8edb14a..40b248f5 100644 --- a/dScripts/02_server/Enemy/AG/BossSpiderQueenEnemyServer.cpp +++ b/dScripts/02_server/Enemy/AG/BossSpiderQueenEnemyServer.cpp @@ -179,7 +179,7 @@ void BossSpiderQueenEnemyServer::SpiderWaveManager(Entity* self) { std::vector spiderEggs{}; - auto spooders = Game::entityManager->GetEntitiesInGroup("EGG"); + auto spooders = Game::entityManager->GetEntitiesInGroup("SpiderEggs"); for (auto spodder : spooders) { spiderEggs.push_back(spodder->GetObjectID()); } diff --git a/dScripts/02_server/Map/AG/NpcCowboyServer.cpp b/dScripts/02_server/Map/AG/NpcCowboyServer.cpp index 6dd212a4..996a99c2 100644 --- a/dScripts/02_server/Map/AG/NpcCowboyServer.cpp +++ b/dScripts/02_server/Map/AG/NpcCowboyServer.cpp @@ -1,6 +1,7 @@ #include "NpcCowboyServer.h" #include "eMissionState.h" #include "InventoryComponent.h" +#include "dZoneManager.h" void NpcCowboyServer::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, eMissionState missionState) { if (missionID != 1880) { @@ -23,4 +24,17 @@ void NpcCowboyServer::OnMissionDialogueOK(Entity* self, Entity* target, int miss } else if (missionState == eMissionState::READY_TO_COMPLETE || missionState == eMissionState::COMPLETE_READY_TO_COMPLETE) { inventoryComponent->RemoveItem(14378, 1); } + + // Next up hide or show the samples based on the mission state + int32_t visible = 1; + if (missionState == eMissionState::READY_TO_COMPLETE || missionState == eMissionState::COMPLETE_READY_TO_COMPLETE) { + visible = 0; + } + + auto spawners = Game::zoneManager->GetSpawnersByName("PlungerGunTargets"); + for (auto* spawner : spawners) { + for (const auto entity : spawner->GetSpawnedObjectIDs()) + GameMessages::SendNotifyClientObject(entity, u"SetVisibility", visible, 0, + target->GetObjectID(), "", target->GetSystemAddress()); + } } diff --git a/dScripts/02_server/Map/AG/NpcWispServer.cpp b/dScripts/02_server/Map/AG/NpcWispServer.cpp index e3b5398d..e087df24 100644 --- a/dScripts/02_server/Map/AG/NpcWispServer.cpp +++ b/dScripts/02_server/Map/AG/NpcWispServer.cpp @@ -1,9 +1,10 @@ #include "NpcWispServer.h" #include "InventoryComponent.h" -#include "EntityManager.h" +#include "dZoneManager.h" #include "Entity.h" #include "GameMessages.h" #include "eMissionState.h" +#include "Spawner.h" void NpcWispServer::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, eMissionState missionState) { if (missionID != 1849 && missionID != 1883) @@ -25,7 +26,7 @@ void NpcWispServer::OnMissionDialogueOK(Entity* self, Entity* target, int missio } // Next up hide or show the samples based on the mission state - auto visible = 1; + int32_t visible = 1; if (missionState == eMissionState::READY_TO_COMPLETE || missionState == eMissionState::COMPLETE_READY_TO_COMPLETE) { visible = 0; } @@ -35,9 +36,10 @@ void NpcWispServer::OnMissionDialogueOK(Entity* self, Entity* target, int missio : std::vector{ "MaelstromSamples", "MaelstromSamples2ndary1", "MaelstromSamples2ndary2" }; for (const auto& group : groups) { - auto samples = Game::entityManager->GetEntitiesInGroup(group); - for (auto* sample : samples) { - GameMessages::SendNotifyClientObject(sample->GetObjectID(), u"SetVisibility", visible, 0, + auto spawners = Game::zoneManager->GetSpawnersByName(group); + for (const auto* spawner : spawners) { + for (const auto objId : spawner->GetSpawnedObjectIDs()) + GameMessages::SendNotifyClientObject(objId, u"SetVisibility", visible, 0, target->GetObjectID(), "", target->GetSystemAddress()); } } diff --git a/dZoneManager/Spawner.cpp b/dZoneManager/Spawner.cpp index 31188907..3baf193f 100644 --- a/dZoneManager/Spawner.cpp +++ b/dZoneManager/Spawner.cpp @@ -25,16 +25,6 @@ Spawner::Spawner(const SpawnerInfo info) { m_Start = m_Info.noTimedSpawn; - //ssssh... - if (m_EntityInfo.lot == 14718) { //AG - MAELSTROM SAMPLE - m_Info.groups.emplace_back("MaelstromSamples"); - } - - if (m_EntityInfo.lot == 14375) //AG - SPIDER BOSS EGG - { - m_Info.groups.emplace_back("EGG"); - } - int timerCount = m_Info.amountMaintained; if (m_Info.amountMaintained > m_Info.nodes.size()) {