From 1ddf7d1f94e2d6bb41fab226f7fc0a96b8de1283 Mon Sep 17 00:00:00 2001 From: Jacob Hofer Date: Sun, 2 Jan 2022 20:37:03 +0000 Subject: [PATCH] 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.