fix: mission offering (#1359)

fixes an issue where NPCs would offer the incorrect missions which caused odd blocks.  Consolidated logic for mission offering and removed redundant code.
This commit is contained in:
David Markowitz 2023-12-26 15:45:10 -08:00 committed by GitHub
parent ffa2f9986c
commit 46ac039a3b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 14 additions and 45 deletions

View File

@ -55,54 +55,39 @@ MissionOfferComponent::MissionOfferComponent(Entity* parent, const LOT parentLot
}); });
for (auto& mission : missions) { for (auto& mission : missions) {
auto* offeredMission = new OfferedMission(mission.missionID, mission.offersMission, mission.acceptsMission); this->offeredMissions.emplace_back(mission.missionID, mission.offersMission, mission.acceptsMission);
this->offeredMissions.push_back(offeredMission);
} }
} }
} }
MissionOfferComponent::~MissionOfferComponent() {
for (auto* mission : this->offeredMissions) {
if (mission) {
delete mission;
mission = nullptr;
}
}
offeredMissions.clear();
}
void MissionOfferComponent::OnUse(Entity* originator) { void MissionOfferComponent::OnUse(Entity* originator) {
OfferMissions(originator); OfferMissions(originator);
} }
void MissionOfferComponent::OfferMissions(Entity* entity, const uint32_t specifiedMissionId) { void MissionOfferComponent::OfferMissions(Entity* entity, const uint32_t specifiedMissionId) {
// First, get the entity's MissionComponent. If there is not one, then we cannot offer missions to this entity. // First, get the entity's MissionComponent. If there is not one, then we cannot offer missions to this entity.
auto* missionComponent = static_cast<MissionComponent*>(entity->GetComponent(eReplicaComponentType::MISSION)); auto* missionComponent = entity->GetComponent<MissionComponent>();
if (!missionComponent) { if (!missionComponent) {
LOG("Unable to get mission component for Entity %llu", entity->GetObjectID()); LOG("Unable to get mission component for Entity %llu", entity->GetObjectID());
return; return;
} }
std::vector<uint32_t> offered{};
CDMissions info{}; CDMissions info{};
if (specifiedMissionId > 0 && !Mission::IsValidMission(specifiedMissionId, info)) { if (specifiedMissionId > 0 && !Mission::IsValidMission(specifiedMissionId, info)) {
return; return;
} }
for (auto* offeredMission : this->offeredMissions) { for (const auto offeredMission : this->offeredMissions) {
if (specifiedMissionId > 0) { if (specifiedMissionId > 0) {
if (offeredMission->GetMissionId() != specifiedMissionId && !info.isRandom) { if (offeredMission.GetMissionId() != specifiedMissionId && !info.isRandom) {
continue; continue;
} }
} }
// First, check if we already have the mission // First, check if we already have the mission
const auto missionId = offeredMission->GetMissionId(); const auto missionId = offeredMission.GetMissionId();
auto* mission = missionComponent->GetMission(missionId); auto* mission = missionComponent->GetMission(missionId);
@ -118,8 +103,6 @@ void MissionOfferComponent::OfferMissions(Entity* entity, const uint32_t specifi
if (mission->IsActive() || mission->IsReadyToComplete()) { if (mission->IsActive() || mission->IsReadyToComplete()) {
GameMessages::SendOfferMission(entity->GetObjectID(), entity->GetSystemAddress(), missionId, m_Parent->GetObjectID()); GameMessages::SendOfferMission(entity->GetObjectID(), entity->GetSystemAddress(), missionId, m_Parent->GetObjectID());
offered.push_back(missionId);
continue; continue;
} }
} }
@ -127,20 +110,13 @@ void MissionOfferComponent::OfferMissions(Entity* entity, const uint32_t specifi
const auto canAccept = MissionPrerequisites::CanAccept(missionId, missionComponent->GetMissions()); const auto canAccept = MissionPrerequisites::CanAccept(missionId, missionComponent->GetMissions());
// Mission has not yet been accepted - check the prereqs // Mission has not yet been accepted - check the prereqs
if (!canAccept) if (!canAccept || !Mission::IsValidMission(missionId, info)) continue;
continue;
if (!Mission::IsValidMission(missionId, info)) {
continue;
}
const auto& randomPool = info.randomPool; const auto& randomPool = info.randomPool;
const auto isRandom = info.isRandom; const auto isRandom = info.isRandom;
if (isRandom && randomPool.empty()) // This means the mission is part of a random pool of missions. // This means the mission is part of a random pool of missions.
{ if (isRandom && randomPool.empty()) continue;
continue;
}
if (isRandom && !randomPool.empty()) { if (isRandom && !randomPool.empty()) {
std::istringstream stream(randomPool); std::istringstream stream(randomPool);
@ -180,9 +156,7 @@ void MissionOfferComponent::OfferMissions(Entity* entity, const uint32_t specifi
sample == specifiedMissionId) { sample == specifiedMissionId) {
mission = missionComponent->GetMission(sample); mission = missionComponent->GetMission(sample);
if (mission == nullptr || mission->IsAchievement()) { if (mission == nullptr || mission->IsAchievement()) continue;
continue;
}
GameMessages::SendOfferMission(entity->GetObjectID(), entity->GetSystemAddress(), sample, m_Parent->GetObjectID()); GameMessages::SendOfferMission(entity->GetObjectID(), entity->GetSystemAddress(), sample, m_Parent->GetObjectID());
@ -191,22 +165,18 @@ void MissionOfferComponent::OfferMissions(Entity* entity, const uint32_t specifi
break; break;
} }
if (std::find(offered.begin(), offered.end(), sample) == offered.end() && MissionPrerequisites::CanAccept(sample, missionComponent->GetMissions())) { if (MissionPrerequisites::CanAccept(sample, missionComponent->GetMissions())) {
canAcceptPool.push_back(sample); canAcceptPool.push_back(sample);
} }
} }
// If the mission is already active or we already completed one of them today // If the mission is already active or we already completed one of them today
if (canAcceptPool.empty()) if (canAcceptPool.empty()) continue;
continue;
const auto selected = canAcceptPool[GeneralUtils::GenerateRandomNumber<int>(0, canAcceptPool.size() - 1)]; const auto selected = canAcceptPool[GeneralUtils::GenerateRandomNumber<int>(0, canAcceptPool.size() - 1)];
GameMessages::SendOfferMission(entity->GetObjectID(), entity->GetSystemAddress(), selected, m_Parent->GetObjectID()); GameMessages::SendOfferMission(entity->GetObjectID(), entity->GetSystemAddress(), selected, m_Parent->GetObjectID());
} else if ( } else if (offeredMission.GetOffersMission()) {
std::find(offered.begin(), offered.end(), missionId) == offered.end()
&&
(offeredMission->GetOffersMission() || offeredMission->GetAcceptsMission())) {
GameMessages::SendOfferMission(entity->GetObjectID(), entity->GetSystemAddress(), missionId, m_Parent->GetObjectID()); GameMessages::SendOfferMission(entity->GetObjectID(), entity->GetSystemAddress(), missionId, m_Parent->GetObjectID());
} }
} }

View File

@ -64,7 +64,6 @@ public:
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::MISSION_OFFER; inline static const eReplicaComponentType ComponentType = eReplicaComponentType::MISSION_OFFER;
MissionOfferComponent(Entity* parent, LOT parentLot); MissionOfferComponent(Entity* parent, LOT parentLot);
~MissionOfferComponent() override;
/** /**
* Handles the OnUse event triggered by some entity, determines which missions to show based on what they may * Handles the OnUse event triggered by some entity, determines which missions to show based on what they may
@ -85,7 +84,7 @@ private:
/** /**
* The missions this entity has to offer * The missions this entity has to offer
*/ */
std::vector<OfferedMission*> offeredMissions; std::vector<OfferedMission> offeredMissions;
}; };
#endif // MISSIONOFFERCOMPONENT_H #endif // MISSIONOFFERCOMPONENT_H

View File

@ -257,7 +257,7 @@ bool Mission::IsComplete() const {
} }
bool Mission::IsActive() const { bool Mission::IsActive() const {
return m_State == eMissionState::ACTIVE || m_State == eMissionState::COMPLETE_AVAILABLE; return m_State == eMissionState::ACTIVE || m_State == eMissionState::COMPLETE_ACTIVE;
} }
void Mission::MakeActive() { void Mission::MakeActive() {