From 1ddf7d1f94e2d6bb41fab226f7fc0a96b8de1283 Mon Sep 17 00:00:00 2001 From: Jacob Hofer Date: Sun, 2 Jan 2022 20:37:03 +0000 Subject: [PATCH 1/4] Fix for Area of Affect Behaviors targeting incorrect entities --- dGame/dBehaviors/AreaOfEffectBehavior.cpp | 6 +++++- dGame/dBehaviors/AreaOfEffectBehavior.h | 4 ++++ dGame/dBehaviors/BehaviorContext.cpp | 4 ++-- dGame/dBehaviors/BehaviorContext.h | 2 +- dGame/dComponents/DestroyableComponent.cpp | 10 +++++++--- dGame/dComponents/DestroyableComponent.h | 2 +- 6 files changed, 20 insertions(+), 8 deletions(-) diff --git a/dGame/dBehaviors/AreaOfEffectBehavior.cpp b/dGame/dBehaviors/AreaOfEffectBehavior.cpp index b87c7c17..9e906c88 100644 --- a/dGame/dBehaviors/AreaOfEffectBehavior.cpp +++ b/dGame/dBehaviors/AreaOfEffectBehavior.cpp @@ -74,7 +74,7 @@ void AreaOfEffectBehavior::Calculate(BehaviorContext* context, RakNet::BitStream includeFaction = 1; } - for (auto validTarget : context->GetValidTargets(m_ignoreFaction , includeFaction, m_TargetSelf == 1)) + for (auto validTarget : context->GetValidTargets(m_ignoreFaction , includeFaction, m_TargetSelf == 1, m_targetEnemy == 1, m_targetFriend == 1)) { auto* entity = EntityManager::Instance()->GetEntity(validTarget); @@ -157,4 +157,8 @@ void AreaOfEffectBehavior::Load() this->m_includeFaction = GetInt("include_faction"); this->m_TargetSelf = GetInt("target_self"); + + this->m_targetEnemy = GetInt("target_enemy"); + + this->m_targetFriend = GetInt("target_friend"); } diff --git a/dGame/dBehaviors/AreaOfEffectBehavior.h b/dGame/dBehaviors/AreaOfEffectBehavior.h index 37313499..31367029 100644 --- a/dGame/dBehaviors/AreaOfEffectBehavior.h +++ b/dGame/dBehaviors/AreaOfEffectBehavior.h @@ -15,6 +15,10 @@ public: int32_t m_includeFaction; int32_t m_TargetSelf; + + int32_t m_targetEnemy; + + int32_t m_targetFriend; /* * Inherited diff --git a/dGame/dBehaviors/BehaviorContext.cpp b/dGame/dBehaviors/BehaviorContext.cpp index 2637aa61..fc67a82d 100644 --- a/dGame/dBehaviors/BehaviorContext.cpp +++ b/dGame/dBehaviors/BehaviorContext.cpp @@ -325,7 +325,7 @@ void BehaviorContext::Reset() this->scheduledUpdates.clear(); } -std::vector BehaviorContext::GetValidTargets(int32_t ignoreFaction, int32_t includeFaction, bool targetSelf) const +std::vector BehaviorContext::GetValidTargets(int32_t ignoreFaction, int32_t includeFaction, bool targetSelf, bool targetEnemy, bool targetFriend) const { auto* entity = EntityManager::Instance()->GetEntity(this->caster); @@ -366,7 +366,7 @@ std::vector BehaviorContext::GetValidTargets(int32_t ignoreFaction, in { const auto id = candidate->GetObjectID(); - if ((id != entity->GetObjectID() || targetSelf) && destroyableComponent->CheckValidity(id, ignoreFaction || includeFaction)) + if ((id != entity->GetObjectID() || targetSelf) && destroyableComponent->CheckValidity(id, ignoreFaction || includeFaction, targetEnemy, targetFriend)) { targets.push_back(id); } diff --git a/dGame/dBehaviors/BehaviorContext.h b/dGame/dBehaviors/BehaviorContext.h index 21b2e6e9..9f1d1621 100644 --- a/dGame/dBehaviors/BehaviorContext.h +++ b/dGame/dBehaviors/BehaviorContext.h @@ -102,7 +102,7 @@ struct BehaviorContext void Reset(); - std::vector GetValidTargets(int32_t ignoreFaction = 0, int32_t includeFaction = 0, const bool targetSelf = false) const; + std::vector GetValidTargets(int32_t ignoreFaction = 0, int32_t includeFaction = 0, const bool targetSelf = false, const bool targetEnemy = true, const bool targetFriend = false) const; explicit BehaviorContext(LWOOBJID originator, bool calculation = false); diff --git a/dGame/dComponents/DestroyableComponent.cpp b/dGame/dComponents/DestroyableComponent.cpp index 01beaa5f..9c651b7b 100644 --- a/dGame/dComponents/DestroyableComponent.cpp +++ b/dGame/dComponents/DestroyableComponent.cpp @@ -498,7 +498,7 @@ Entity* DestroyableComponent::GetKiller() const return EntityManager::Instance()->GetEntity(m_KillerID); } -bool DestroyableComponent::CheckValidity(const LWOOBJID target, const bool ignoreFactions) const +bool DestroyableComponent::CheckValidity(const LWOOBJID target, const bool ignoreFactions, const bool targetEnemy, const bool targetFriend) const { auto* entity = EntityManager::Instance()->GetEntity(target); @@ -537,15 +537,19 @@ bool DestroyableComponent::CheckValidity(const LWOOBJID target, const bool ignor auto candidateList = destroyable->GetFactionIDs(); + + bool isEnemy = false; + for (auto value : candidateList) { if (std::find(enemyList.begin(), enemyList.end(), value) != enemyList.end()) { - return true; + isEnemy = true; + break; } } - return false; + return (isEnemy && targetEnemy) || (!isEnemy && targetFriend); } diff --git a/dGame/dComponents/DestroyableComponent.h b/dGame/dComponents/DestroyableComponent.h index 6b81eccd..d702897c 100644 --- a/dGame/dComponents/DestroyableComponent.h +++ b/dGame/dComponents/DestroyableComponent.h @@ -371,7 +371,7 @@ public: * @param ignoreFactions whether or not check for the factions, e.g. just return true if the entity cannot be smashed * @return if the target ID is a valid enemy */ - bool CheckValidity(LWOOBJID target, bool ignoreFactions = false) const; + bool CheckValidity(LWOOBJID target, bool ignoreFactions = false, bool targetEnemy = true, bool targetFriend = false) const; /** * Attempt to damage this entity, handles everything from health and armor to absorption, immunity and callbacks. From 9f895205d4b66d2ceeb0623a7de79f2cf119bf6a Mon Sep 17 00:00:00 2001 From: CodeAX2 Date: Sun, 2 Jan 2022 14:00:01 -0700 Subject: [PATCH 2/4] Fix formatting and add comments --- dGame/dBehaviors/AreaOfEffectBehavior.cpp | 3 ++- dGame/dBehaviors/AreaOfEffectBehavior.h | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/dGame/dBehaviors/AreaOfEffectBehavior.cpp b/dGame/dBehaviors/AreaOfEffectBehavior.cpp index 9e906c88..6568f9b8 100644 --- a/dGame/dBehaviors/AreaOfEffectBehavior.cpp +++ b/dGame/dBehaviors/AreaOfEffectBehavior.cpp @@ -74,6 +74,7 @@ void AreaOfEffectBehavior::Calculate(BehaviorContext* context, RakNet::BitStream includeFaction = 1; } + // Gets all of the valid targets, passing in if should target enemies and friends for (auto validTarget : context->GetValidTargets(m_ignoreFaction , includeFaction, m_TargetSelf == 1, m_targetEnemy == 1, m_targetFriend == 1)) { auto* entity = EntityManager::Instance()->GetEntity(validTarget); @@ -156,7 +157,7 @@ void AreaOfEffectBehavior::Load() this->m_includeFaction = GetInt("include_faction"); - this->m_TargetSelf = GetInt("target_self"); + this->m_TargetSelf = GetInt("target_self"); this->m_targetEnemy = GetInt("target_enemy"); diff --git a/dGame/dBehaviors/AreaOfEffectBehavior.h b/dGame/dBehaviors/AreaOfEffectBehavior.h index 31367029..9a8b7290 100644 --- a/dGame/dBehaviors/AreaOfEffectBehavior.h +++ b/dGame/dBehaviors/AreaOfEffectBehavior.h @@ -14,7 +14,7 @@ public: int32_t m_includeFaction; - int32_t m_TargetSelf; + int32_t m_TargetSelf; int32_t m_targetEnemy; From d78b2404e29dd7ad64c53df0b1a717cdeae72ba7 Mon Sep 17 00:00:00 2001 From: CodeAX2 Date: Sun, 2 Jan 2022 14:01:29 -0700 Subject: [PATCH 3/4] Refactor CheckValidity - Change variables names to make it clear they are referring to the target - Change how the target is decided to be an enemy of friend to use the built-in method --- dGame/dComponents/DestroyableComponent.cpp | 34 +++++++--------------- 1 file changed, 11 insertions(+), 23 deletions(-) diff --git a/dGame/dComponents/DestroyableComponent.cpp b/dGame/dComponents/DestroyableComponent.cpp index 9c651b7b..e6f5ba02 100644 --- a/dGame/dComponents/DestroyableComponent.cpp +++ b/dGame/dComponents/DestroyableComponent.cpp @@ -500,27 +500,26 @@ Entity* DestroyableComponent::GetKiller() const bool DestroyableComponent::CheckValidity(const LWOOBJID target, const bool ignoreFactions, const bool targetEnemy, const bool targetFriend) const { - auto* entity = EntityManager::Instance()->GetEntity(target); + auto* targetEntity = EntityManager::Instance()->GetEntity(target); - if (entity == nullptr) + if (targetEntity == nullptr) { Game::logger->Log("DestroyableComponent", "Invalid entity for checking validity (%llu)!\n", target); - return false; } - auto* destroyable = entity->GetComponent(); + auto* targetDestroyable = targetEntity->GetComponent(); - if (destroyable == nullptr) + if (targetDestroyable == nullptr) { return false; } - auto* quickbuild = entity->GetComponent(); + auto* targetQuickbuild = targetEntity->GetComponent(); - if (quickbuild != nullptr) + if (targetQuickbuild != nullptr) { - const auto state = quickbuild->GetState(); + const auto state = targetQuickbuild->GetState(); if (state != REBUILD_COMPLETED) { @@ -533,22 +532,11 @@ bool DestroyableComponent::CheckValidity(const LWOOBJID target, const bool ignor return true; } - auto enemyList = GetEnemyFactionsIDs(); - - auto candidateList = destroyable->GetFactionIDs(); - - - bool isEnemy = false; - - for (auto value : candidateList) - { - if (std::find(enemyList.begin(), enemyList.end(), value) != enemyList.end()) - { - isEnemy = true; - break; - } - } + // Get if the target entity is an enemy + bool isEnemy = IsEnemy(targetEntity); + // Return true if the target type matches what we are targeting + // Friends are entities who are not enemies return (isEnemy && targetEnemy) || (!isEnemy && targetFriend); } From a19454f7aefd7f81eeaa97c53790ea1e56d549c3 Mon Sep 17 00:00:00 2001 From: CodeAX2 Date: Tue, 4 Jan 2022 11:11:23 -0700 Subject: [PATCH 4/4] Change destroyable component validator to properly check friends --- dGame/dComponents/DestroyableComponent.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dGame/dComponents/DestroyableComponent.cpp b/dGame/dComponents/DestroyableComponent.cpp index e6f5ba02..aca6c32a 100644 --- a/dGame/dComponents/DestroyableComponent.cpp +++ b/dGame/dComponents/DestroyableComponent.cpp @@ -532,12 +532,12 @@ bool DestroyableComponent::CheckValidity(const LWOOBJID target, const bool ignor return true; } - // Get if the target entity is an enemy + // Get if the target entity is an enemy and friend bool isEnemy = IsEnemy(targetEntity); + bool isFriend = IsFriend(targetEntity); // Return true if the target type matches what we are targeting - // Friends are entities who are not enemies - return (isEnemy && targetEnemy) || (!isEnemy && targetFriend); + return (isEnemy && targetEnemy) || (isFriend && targetFriend); }