diff --git a/dGame/dBehaviors/AreaOfEffectBehavior.cpp b/dGame/dBehaviors/AreaOfEffectBehavior.cpp index b87c7c17..6568f9b8 100644 --- a/dGame/dBehaviors/AreaOfEffectBehavior.cpp +++ b/dGame/dBehaviors/AreaOfEffectBehavior.cpp @@ -74,7 +74,8 @@ void AreaOfEffectBehavior::Calculate(BehaviorContext* context, RakNet::BitStream includeFaction = 1; } - for (auto validTarget : context->GetValidTargets(m_ignoreFaction , includeFaction, m_TargetSelf == 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,5 +157,9 @@ 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"); + + this->m_targetFriend = GetInt("target_friend"); } diff --git a/dGame/dBehaviors/AreaOfEffectBehavior.h b/dGame/dBehaviors/AreaOfEffectBehavior.h index 37313499..9a8b7290 100644 --- a/dGame/dBehaviors/AreaOfEffectBehavior.h +++ b/dGame/dBehaviors/AreaOfEffectBehavior.h @@ -14,7 +14,11 @@ public: int32_t m_includeFaction; - int32_t m_TargetSelf; + 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 fb4dfe61..2199ff18 100644 --- a/dGame/dComponents/DestroyableComponent.cpp +++ b/dGame/dComponents/DestroyableComponent.cpp @@ -498,29 +498,28 @@ 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); + 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,19 +532,12 @@ bool DestroyableComponent::CheckValidity(const LWOOBJID target, const bool ignor return true; } - auto enemyList = GetEnemyFactionsIDs(); + // Get if the target entity is an enemy and friend + bool isEnemy = IsEnemy(targetEntity); + bool isFriend = IsFriend(targetEntity); - auto candidateList = destroyable->GetFactionIDs(); - - for (auto value : candidateList) - { - if (std::find(enemyList.begin(), enemyList.end(), value) != enemyList.end()) - { - return true; - } - } - - return false; + // Return true if the target type matches what we are targeting + return (isEnemy && targetEnemy) || (isFriend && 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.