mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2024-12-25 23:13:35 +00:00
d8ac148cee
* Re-write AOE behavior for new filter targets Update Tacarc to use new filter targets Added dev commands for skill and attack debugging * Get all entities by detroyable rather than controllable physics Since destroyables are what can be hit * Re-work filter targets to be 100% live accurate reduce memory usage by only using one vector and removing invalid entries get entities in the proximity rather than all entities with des comps in the instance, as was done in live * remove debuging longs and remove oopsie * address feedback * make log more useful * make filter more flat * Add some more checks to filter targets add pvp checks to isenemy * fix typing * Add filter target to TacArc and update filter target * fix double declaration * Some debugging logs * Update TacArc reading * make log clearer * logs * Update TacArcBehavior.cpp * banana * fix max targets * remove extreanous parenthesesuuesdsds * make behavior slot use a real type --------- Co-authored-by: David Markowitz <EmosewaMC@gmail.com>
134 lines
4.4 KiB
C++
134 lines
4.4 KiB
C++
#include "AreaOfEffectBehavior.h"
|
|
|
|
#include <vector>
|
|
|
|
#include "EntityManager.h"
|
|
#include "Game.h"
|
|
#include "dLogger.h"
|
|
#include "BehaviorBranchContext.h"
|
|
#include "BehaviorContext.h"
|
|
#include "RebuildComponent.h"
|
|
#include "DestroyableComponent.h"
|
|
#include "Game.h"
|
|
#include "dLogger.h"
|
|
|
|
void AreaOfEffectBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
|
|
uint32_t targetCount{};
|
|
|
|
if (!bitStream->Read(targetCount)) {
|
|
Game::logger->Log("AreaOfEffectBehavior", "Unable to read targetCount from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits());
|
|
return;
|
|
}
|
|
|
|
if (this->m_useTargetPosition && branch.target == LWOOBJID_EMPTY) return;
|
|
|
|
if (targetCount == 0){
|
|
PlayFx(u"miss", context->originator);
|
|
return;
|
|
}
|
|
|
|
if (targetCount > this->m_maxTargets) {
|
|
Game::logger->Log("AreaOfEffectBehavior", "Serialized size is greater than max targets! Size: %i, Max: %i", targetCount, this->m_maxTargets);
|
|
return;
|
|
}
|
|
|
|
auto caster = context->caster;
|
|
if (this->m_useTargetAsCaster) context->caster = branch.target;
|
|
|
|
std::vector<LWOOBJID> targets;
|
|
targets.reserve(targetCount);
|
|
|
|
for (auto i = 0u; i < targetCount; ++i) {
|
|
LWOOBJID target{};
|
|
if (!bitStream->Read(target)) {
|
|
Game::logger->Log("AreaOfEffectBehavior", "failed to read in target %i from bitStream, aborting target Handle!", i);
|
|
};
|
|
targets.push_back(target);
|
|
}
|
|
|
|
for (auto target : targets) {
|
|
branch.target = target;
|
|
this->m_action->Handle(context, bitStream, branch);
|
|
}
|
|
context->caster = caster;
|
|
PlayFx(u"cast", context->originator);
|
|
}
|
|
|
|
void AreaOfEffectBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
|
|
auto* caster = Game::entityManager->GetEntity(context->caster);
|
|
if (!caster) return;
|
|
|
|
// determine the position we are casting the AOE from
|
|
auto reference = branch.isProjectile ? branch.referencePosition : caster->GetPosition();
|
|
if (this->m_useTargetPosition) {
|
|
if (branch.target == LWOOBJID_EMPTY) return;
|
|
auto branchTarget = Game::entityManager->GetEntity(branch.target);
|
|
if (branchTarget) reference = branchTarget->GetPosition();
|
|
}
|
|
|
|
reference += this->m_offset;
|
|
|
|
std::vector<Entity*> targets {};
|
|
targets = Game::entityManager->GetEntitiesByProximity(reference, this->m_radius);
|
|
context->FilterTargets(targets, this->m_ignoreFactionList, this->m_includeFactionList, this->m_targetSelf, this->m_targetEnemy, this->m_targetFriend, this->m_targetTeam);
|
|
|
|
// sort by distance
|
|
std::sort(targets.begin(), targets.end(), [reference](Entity* a, Entity* b) {
|
|
const auto aDistance = NiPoint3::Distance(a->GetPosition(), reference);
|
|
const auto bDistance = NiPoint3::Distance(b->GetPosition(), reference);
|
|
return aDistance < bDistance;
|
|
}
|
|
);
|
|
|
|
// resize if we have more than max targets allows
|
|
if (targets.size() > this->m_maxTargets) targets.resize(this->m_maxTargets);
|
|
|
|
bitStream->Write<uint32_t>(targets.size());
|
|
|
|
if (targets.size() == 0) {
|
|
PlayFx(u"miss", context->originator);
|
|
return;
|
|
} else {
|
|
context->foundTarget = true;
|
|
// write all the targets to the bitstream
|
|
for (auto* target : targets) {
|
|
bitStream->Write(target->GetObjectID());
|
|
}
|
|
|
|
// then cast all the actions
|
|
for (auto* target : targets) {
|
|
branch.target = target->GetObjectID();
|
|
this->m_action->Calculate(context, bitStream, branch);
|
|
}
|
|
PlayFx(u"cast", context->originator);
|
|
}
|
|
}
|
|
|
|
void AreaOfEffectBehavior::Load() {
|
|
this->m_action = GetAction("action"); // required
|
|
this->m_radius = GetFloat("radius", 0.0f); // required
|
|
this->m_maxTargets = GetInt("max targets", 100);
|
|
if (this->m_maxTargets == 0) this->m_maxTargets = 100;
|
|
this->m_useTargetPosition = GetBoolean("use_target_position", false);
|
|
this->m_useTargetAsCaster = GetBoolean("use_target_as_caster", false);
|
|
this->m_offset = NiPoint3(
|
|
GetFloat("offset_x", 0.0f),
|
|
GetFloat("offset_y", 0.0f),
|
|
GetFloat("offset_z", 0.0f)
|
|
);
|
|
|
|
// params after this are needed for filter targets
|
|
const auto parameters = GetParameterNames();
|
|
for (const auto& parameter : parameters) {
|
|
if (parameter.first.rfind("include_faction", 0) == 0) {
|
|
this->m_includeFactionList.push_front(parameter.second);
|
|
} else if (parameter.first.rfind("ignore_faction", 0) == 0) {
|
|
this->m_ignoreFactionList.push_front(parameter.second);
|
|
}
|
|
}
|
|
this->m_targetSelf = GetBoolean("target_self", false);
|
|
this->m_targetEnemy = GetBoolean("target_enemy", false);
|
|
this->m_targetFriend = GetBoolean("target_friend", false);
|
|
this->m_targetTeam = GetBoolean("target_team", false);
|
|
}
|