#include "Playerbots.h" #include "ForgeOfSoulsActions.h" #include "ForgeOfSoulsStrategy.h" #include "SharedDefines.h" bool MoveFromBronjahmAction::Execute(Event event) { Unit* boss = AI_VALUE2(Unit*, "find target", "bronjahm"); if (!boss) return false; if (bot->GetExactDist2d(boss) < 10.0f) return FleePosition(boss->GetPosition(), 15.0f, 2000U); else return true; return false; } bool AttackCorruptedSoulFragmentAction::Execute(Event event) { Unit* currentTarget = AI_VALUE(Unit*, "current target"); GuidVector targets = AI_VALUE(GuidVector, "possible targets"); // If no valid skull target, search for corrupted soul fragment Unit* empoweredPrince = nullptr; for (auto i = targets.begin(); i != targets.end(); ++i) { Unit* unit = botAI->GetUnit(*i); if (!unit || !unit->IsAlive()) continue; if (unit->GetEntry() == NPC_CORRUPTED_SOUL_FRAGMENT) { empoweredPrince = unit; // Mark corrupted soul fragment with skull if in group and not already marked if (Group* group = bot->GetGroup()) { ObjectGuid currentSkullGuid = group->GetTargetIcon(7); if (currentSkullGuid.IsEmpty() || currentSkullGuid != unit->GetGUID()) { group->SetTargetIcon(7, bot->GetGUID(), unit->GetGUID()); // 7 = skull } } break; } } return false; } bool BronjahmGroupPositionAction::Execute(Event event) { Unit* boss = AI_VALUE2(Unit*, "find target", "bronjahm"); if (!boss) return false; Aura* aura = botAI->GetAura("soulstorm", boss); bool hasAura = aura; Unit* corruptedSoul = bot->FindNearestCreature(NPC_CORRUPTED_SOUL_FRAGMENT, 50.0f); bool activeSoulExists = corruptedSoul && corruptedSoul->IsAlive(); if (botAI->IsTank(bot) && botAI->HasAggro(boss)) { // If any corrupted soul exists, handle positioning carefully if (activeSoulExists) { GuidVector npcs = AI_VALUE(GuidVector, "nearest hostile npcs"); for (auto& npc : npcs) { Unit* unit = botAI->GetUnit(npc); if (unit && unit->GetEntry() == NPC_CORRUPTED_SOUL_FRAGMENT) { // Soul exists - check positions float soulToBossDist = unit->GetExactDist2d(boss); float tankToBossDist = bot->GetExactDist2d(boss); float soulToTankDist = unit->GetExactDist2d(bot); // Handle edge case: if soul is between tank and boss // This happens when: (tankToBossDist > soulToBossDist) AND (soulToTankDist < tankToBossDist) if (tankToBossDist > soulToBossDist && soulToTankDist < tankToBossDist) { // Calculate position 5 yards behind boss from the soul's perspective float angle = boss->GetAngle(unit); // Angle from boss to soul float oppositeAngle = Position::NormalizeOrientation(angle + M_PI); // Opposite direction // Calculate position 5 yards behind boss float x = boss->GetPositionX() + 5.0f * cos(oppositeAngle); float y = boss->GetPositionY() + 5.0f * sin(oppositeAngle); float z = boss->GetPositionZ(); return MoveTo(bot->GetMapId(), x, y, z, false, false, false, true, MovementPriority::MOVEMENT_NORMAL); } // If soul is near boss, flee from boss if (soulToBossDist < 10.0f) return FleePosition(unit->GetPosition(), 13.0f, 1000U); // If soul exists but none of the above conditions, don't move to tank position yet bot->SetFacingToObject(boss); return true; } } } else { // No souls exist, safe to move to tank position if (bot->GetExactDist2d(BRONJAHM_TANK_POSITION) > 5.0f) { return MoveTo(bot->GetMapId(), BRONJAHM_TANK_POSITION.GetPositionX(), BRONJAHM_TANK_POSITION.GetPositionY(), BRONJAHM_TANK_POSITION.GetPositionZ(), false, false, false, true, MovementPriority::MOVEMENT_NORMAL); } } } else { float maxMovement = 10.0f; if (bot->GetExactDist2d(boss) > maxMovement && !activeSoulExists && (hasAura || boss->FindCurrentSpellBySpellId(SPELL_SOULSTORM_VISUAL) || boss->FindCurrentSpellBySpellId(SPELL_SOULSTORM_VISUAL2))) { if (botAI->IsRanged(bot)) { return Move(bot->GetAngle(boss), fmin(bot->GetExactDist2d(boss) - 6.5f, maxMovement)); } else { return Move(bot->GetAngle(boss), fmin(bot->GetExactDist2d(boss) - 2.0f, maxMovement)); } } else return false; } return false; } bool BronjahmGroupPositionAction::isUseful() { return true; } bool DevourerOfSoulsAction::Execute(Event event) { Unit* boss = AI_VALUE2(Unit*, "find target", "devourer of souls"); if (!boss) return false; Aura* aura = botAI->GetAura("mirrored soul", boss); bool hasAura = aura; if (!botAI->IsTank(bot) && !botAI->IsHeal(bot) && hasAura) { // Calculate the opposite direction float angle = bot->GetAngle(boss); float newAngle = Position::NormalizeOrientation(angle + M_PI); // Add 180 degrees (PI radians) // Set the bot's orientation to face away from DoS = no attacks bot->SetFacingTo(newAngle); return true; } return false; }