mirror of
https://github.com/mod-playerbots/mod-playerbots
synced 2025-11-29 15:58:20 +08:00
ICC LM, LDW & DBS Improve (#1202)
* ICC PP WIP WIP * added mutated plague for PP * BPC added (kinetic and boss targeting need to be done by player) OT collects dark nucles, bots spread on vortex and other stuff they do ok on their own. Tested only on 10NM, should work on 25NM * Tank pos. correction * BQL, ranged spread, link, flame, bite, tanking tested 10NM to do (better fire spread, hc tacti, melee spread when in air) * LDW improved improved shadow logic, ranged spread for easier shadow handling * dbs update, fixed teleporting Bots should only go and teleport to the mage that is actually below zero now * DBS ranged fix Ranged should spread more quickly and freak out less * Festergut && DBS fixed ranged spread (both) fixed spore logic (fester) * Rotface fix Improved big ooze tanking (static pos, todo kiting) ooze explosion spread mechanic fix ooze pool fix Player needs to mark rotface with skull icon, oterwise bots try to attack oozes * BQL fixed for 25nm todo: better melee logic in air phase, better melee flame spread * VDW, Sister Svalna, Sindy update Sister Svalna, bots can pickup spears and throw at svalna when she has shield up VDW added healer strats to use portal and heal boss (atm druids are for raid healing only, so use druide + any other healer, ideally player should be healer) todo (focus on supressers, add healer rotations, atm they use quickest spell they can) Sindragosa Added tank boss manipulation (boss orientation and position) bots detect (buffet, unchained magic and chilled to the bone and act accordingly) bots detect frost beacon move to safe spot and los frost bombs around them, while dpsing tombs (todo stop dps if only one tomb is left, if we have frost bombs around, not a big deal atm since in nm they dont one shot) Last phase bots los behind tomb to loose buffet, tanks swap when they have hi buffet count. Player should tell bots with skull rti if they should kill tomb or focus boss. todo (dynamic tomb los in last phase so that healers can see tank but also hide behind tomb to break los from boss) Removed some debug messages, improved LM spike action (nearest bots also try to help kill it) Improved Lady Deathwshiper shade action (only targeted bots will run away instead of every bot that is near it) dbs improved tank switch I recommend to use 3 healers (just to be safe) and 2 paladin tanks (warr seems to struggle with agro) in 10 man 25 man 6-7 healers (just to be safe) Since most of the bosses are about survival and not dps * LK Update (doable) LK added Improved tank switching for all bosses Fixed PP gas cloud kiting Malleable goo todo (dont know how to detect it since its not object or npc) just summon ranged bots to safe position to bypass BPC fixed OT sometimes not tanking kele kinectic bombs todo (for now player should take care of them) Sindragosa fixed rare case when she is in air phase but tombs went to last phase position LK Bots can handle necrotic Bots can handle adds Bots should focus valkyre that actually grabbed someone (if unlucky and player just use attack command and summon bots to you if they are far away from you) if they grab bots you can either summon to make them useless or let bots cc them and do it legit way. Defile should be watched by player and once it was cast just summon bots to you Vile spirits for some reason go to the ground and get nuked by bots aoe spells so there is not much to be done **Player needs to be alive the whole LK fight since you will have to watch out for frost spehers (sometimes bots ignore them), summon bots when defile is up and summon ranged bots if they get stuck near shambling or raging spirits since their aoe will wipe you) all in all LK is doable both 10 and 25nm, player needs to have knowledge of lk fight and needs to know how to use multibot addon and make macros for eg summoning or commanding groups of bots or individual bots) Dont forget frost/shadow/nature resist auras in whole ICC since it will help alot I have done whole icc 10 and 25 with 2 pala tanks, 2/5 heals and rest dps, if you use +1 or +2 heals it should be easier (since I was testing I did close to 0 dmg in fights same with heals) * fixed changes made by mistake fix * Malleable fix (simple spread mechanic) Malleable mechanic added (simple spread for now) Gas cloud fixed (Bots sometimes got stuck between puddle and kite location) * Defile Update Bots detect and avoid defile (they struggle to find a way back to the boss around it tho, use summon to help them) Melee bots should be able to stand behind/to the flank of shambling/spirits * GS fixed bots not returning to their ship for A and H Bots will return back to ship after killing mage * PP gas cloud kiting improved PP gas cloud kiting improved * BPC targeting fixed Bots will mark valid prince with skull RTI now * BQL added melee spread in air pahse BQL added melee spread * VDW healing rotation improved Healers will now use strong heals and hots * Fixed Necrotic Plague Fixed issue with Necrotic where it would get dispelled too soon, or would not get dispelled at all * LK Update Refined defile logic Added 3 points for ranged and melee in winter phase (east, west, south when facing throne) fixed frost spheres targeting (hunter will focus them) Atm bots will reset z axis if they fall underground or if they get teleported by lk Better positioning in 1st phase * 10HC update until PP LK defile improved for 10nm (bots sometimes stood 2 close to defile until it grew few times) Improved rotface for HC PP remade for 10HC. Gas cloud is now properly kited Fixed a rare case of server crash when there were ooze and gas cloud alive at same time. Bots will move around puddles according to its size now. Bots that get unboud plague will simply move away from raid and die thus loosing it from raid. Volatile ooze improved stacking. Fixed ranged sometimes glitching thru walls when spreading out from other members. 10HC PP is now doable but its hard without summoning (summoning break gascloud and ooze targets so its easier to do). You need to watch boss so you dont phase 2 soon otherwise you will get 2x ooze and cloud which is almoust always a wipe. If abo is not played near perfection bots will struggle with oozes and gas clouds if they are not slowed on time. Always save energy to slow gas cloud since it will wipe the group if it reach its target. Bots will sometimes stand in puddle, just command them to move and they will figure out what to do. todo (proper malleable handling) * Up until Sindy 10HC BPC added shadow prison handling, bots stop moving if more than 12 stack, tanks more than 18 Improved spreading logic VDW fixed issue where bots in portal wold move at half speed compared to real player * fixed accidental change * LK 10HC update Added Shadow trap logic (if they stand in it, not a big deal since bots wont get yeeted only players will) When harvest soul, only player will be in another dimension (you must survive) **Sindy and LK can be done, but I must dissapoint purist, at my skill level I could not achieve to do HC without using summon or other "cheat" bot functions. Other bosses are all doable now in 10hc * ICC fixes GS, PP; BQL, SINDY Minor fixes, bite action improved * ICC improve Sindy Bots will now choose non beacon position based on difficulty, 10/25 * ICC fixed missing A/H buff Fixed missing ICC buff for A and H Buff will only be present when logged on and in ICC, once any bot or player leave ICC the buff is gone to prevent abuse. This will make ICC easier now and with recent DPS update and movement improvement bots will now actully do decent dps and even greater healing. Ally buff https://www.wowhead.com/wotlk/spell=73828/strength-of-wrynn Horde buff https://www.wowhead.com/wotlk/spell=73822/hellscreams-warsong * revert last change revert buff * ICC improve Rotface Bots will now mark Rotface with skull icon, which will make them focus boss instead of oozes automatically * ICC Festergut 10 Man fix There was a rare case in 10 Man when 2 tanks would get spores which made them both stack at melee spot. Now the code will check if any of the spored player is main tank, if it is, it will stay at melee and other spores will go at ranged spot since off tank doesn't really need to stand near main tank all the time. * ICC BPC major update, fix and improve Fixed main tank sometimes not tanking both bosses (vala and talda) Improved marking of current prince Empowered vortex: bots will now spread out when it is being cast, instead of always spreading(ranged). This will make melee also spread better now since bots will calculate and move to optimal positions. Added Kinetic bomb handling. Hunters will take care of bombs, if no hunter is present then any ranged dps will take care of kinetic bombs. * ICC BQL/VDW major update + minor fixes/improvements LDW improved spreading for ranged, tanks will move boss in the middle of the room now when shield is depleted which will make bots bug less around pillars GS Assist tank will not teleport to enemy ship and will keep tanking adds on our ship now DBS ranged spread improved (they will calcualte spot for each bot and stick with it reducing movment to minimum), fixed bug where in 25 man ranged bots would go behind walls, making them unable to dps boss, improved rune of blood tanking Festergut ranged spread improved (they will calcualte spot for each bot and stick with it reducing movment to minimum) BQL Melee spread improved, bite logic improved, added swarming shadows logic (not perfect but at least it wont be all over the room anymore), Tanks will properly handle blood mirror now VDW boss and raid healers will be automatically assinged depening by number of healers(if more than 3 healers in group, 2 will focus on raid and others will heal boss, otherwise one healer will heal raid). Druid will be assigned to raid healing if no druid present then some other random heal class. Added rotations for druid healers if they end up healing the boss. Raid healers will not use portals anymore. Healers will come to the ground now after using portals (they were stuck in air) * ICC LK minor update PP Removed pre stacking for ranged when volatile ooze spawn (they will kill it much faster now and only stack if someone actually gets targeted by ooze) LK Hunters will use trnaq shot to remove enrage from shamblings Improved valkyr cc Minimized ping-ponging during winter phase * ICC minor Sindy improve Reduced position tolerances and forced movement for beacon and non beacon positions which will make bots move to spot that they actually need to be at instead of randomly running to sindragosa or beaconed players. * ICC minor update GS Bots will mark mage with skull rti Rotface Fixed bots glitching thru walls and floors (added check if position is valid before moving) PP Bots will mark volatile ooze with skull rti now which will help them focus it and kill asap (usefull for heroic when both volatile ooze and gas cloud are present at the same time) VDW Added default group position in the middle if the room so that bots don't spread out too much which will force them to focus supressers more Fixed Boss healers not keeping themself alive when low on HP * ICC LK minor update Commented out z axis bypass since it was fixed with recent core updates. Bots no longer fall thru buggy platforms so its no longer needed which in return makes valkyrs works as they should. * ICC LM & LDW Improved LM Removed Attack Action since it was buggy and replaced it with RTI. (Improved DPS) Simplified trigger for spike action, since attack logic is handled by skull RTI now. Bots (tanks) will mark spikes with skull RTI, which will make bots instantly switch to Spike targets. If no spike is present, the boss will be marked. Added logic that will make non-tank bots move away from LM to a fixed position behind LM if they happened to be in front of LM (No more insta kills with cleave). If LM is casting Bone Storm, bots will ignore the above logic and do max dps. LDW Removed Attack Action since it was buggy and replaced it with RTI. (Improved DPS) Bots (tanks) will mark adds with skull RTI, which will make bots instantly switch to adds targets. If no spike is present, the boss will be marked, which will help with keeping allies alive when they get mind controlled by LDW. Moved 2nd phase position deeper into the room and reduced boss hp trigger to 95%, which will keep tanks where they should be during 1st phase (sometimes the boss dropped below 98% and tanks would ping pong around the room). Ranged bots will now spread closer to each other now and will ignore spreading if they are 2 far or 2 close to the boss so they can properly reposition. These changes should also fix recent bugs with bots not casting/standing still on LM and LDW. * ICC DBS Improve Replaced attack action with RTI. (Improved DPS) Ranged bots will move away from blood beast if targeted by it now.
This commit is contained in:
@@ -37,7 +37,6 @@ bool IccLmTankPositionAction::Execute(Event event)
|
||||
if (!boss)
|
||||
return false;
|
||||
|
||||
bot->SetTarget(boss->GetGUID());
|
||||
if (botAI->IsTank(bot) || botAI->IsMainTank(bot) || botAI->IsAssistTank(bot))
|
||||
{
|
||||
if (bot->GetExactDist2d(ICC_LM_TANK_POSITION) > 15.0f)
|
||||
@@ -45,9 +44,10 @@ bool IccLmTankPositionAction::Execute(Event event)
|
||||
ICC_LM_TANK_POSITION.GetPositionY(), ICC_LM_TANK_POSITION.GetPositionZ(),
|
||||
false, false, false, false, MovementPriority::MOVEMENT_COMBAT);
|
||||
else
|
||||
return Attack(boss);
|
||||
return false;
|
||||
}
|
||||
return Attack(boss);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IccSpikeAction::Execute(Event event)
|
||||
@@ -60,48 +60,78 @@ bool IccSpikeAction::Execute(Event event)
|
||||
|
||||
// Find the boss
|
||||
Unit* boss = AI_VALUE2(Unit*, "find target", "lord marrowgar");
|
||||
if (!boss) { return false; }
|
||||
if (!boss)
|
||||
return false;
|
||||
|
||||
Unit* currentTarget = AI_VALUE(Unit*, "current target");
|
||||
|
||||
GuidVector targets = AI_VALUE(GuidVector, "possible targets");
|
||||
Aura* bossaura = botAI->GetAura("Bone Storm", boss);
|
||||
|
||||
Unit* spikeTarget = nullptr;
|
||||
for (auto i = targets.begin(); i != targets.end(); ++i)
|
||||
if (boss->isInFront(bot) && !botAI->IsTank(bot) && !bossaura)
|
||||
return MoveTo(bot->GetMapId(), -390.6757f, 2230.5283f, 41.99232f, false, false, false, true,
|
||||
MovementPriority::MOVEMENT_FORCED);
|
||||
|
||||
if (!botAI->IsTank(bot))
|
||||
return false;
|
||||
|
||||
GuidVector spikes = AI_VALUE(GuidVector, "possible targets no los");
|
||||
const uint32 spikeEntries[] = {36619, 38711, 38712}; // spikes id's
|
||||
|
||||
Unit* priorityTarget = nullptr;
|
||||
bool anySpikesExist = false;
|
||||
|
||||
// First check for alive spikes
|
||||
for (uint32 entry : spikeEntries)
|
||||
{
|
||||
Unit* unit = botAI->GetUnit(*i);
|
||||
if (unit && (unit->GetEntry() == 36619 ||
|
||||
unit->GetEntry() == 38711 ||
|
||||
unit->GetEntry() == 38712))
|
||||
for (const ObjectGuid& guid : spikes)
|
||||
{
|
||||
spikeTarget = unit;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Prioritize attacking a bone spike if found
|
||||
if (spikeTarget)
|
||||
{
|
||||
if (currentTarget != spikeTarget)
|
||||
{
|
||||
if (Attack(spikeTarget))
|
||||
Unit* unit = botAI->GetUnit(guid);
|
||||
if (unit && unit->GetEntry() == entry) // Check if spike exists
|
||||
{
|
||||
return Attack(spikeTarget);
|
||||
anySpikesExist = true; // At least one spike exists
|
||||
|
||||
if (unit->IsAlive()) // Only consider alive ones for targeting
|
||||
{
|
||||
priorityTarget = unit;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return Attack(spikeTarget); // Already attacking a spike
|
||||
if (priorityTarget)
|
||||
break;
|
||||
}
|
||||
|
||||
// No bone spikes found, attack boss if not already targeting
|
||||
if (currentTarget != boss)
|
||||
// Only fallback to boss if NO spikes exist at all (alive or dead)
|
||||
if (!anySpikesExist && boss->IsAlive())
|
||||
{
|
||||
if (Attack(boss))
|
||||
priorityTarget = boss;
|
||||
}
|
||||
|
||||
// Update skull icon if needed
|
||||
if (priorityTarget)
|
||||
{
|
||||
if (Group* group = bot->GetGroup())
|
||||
{
|
||||
return Attack(boss);
|
||||
ObjectGuid currentSkull = group->GetTargetIcon(7);
|
||||
Unit* currentSkullUnit = botAI->GetUnit(currentSkull);
|
||||
|
||||
bool needsUpdate = false;
|
||||
if (!currentSkullUnit || !currentSkullUnit->IsAlive())
|
||||
{
|
||||
needsUpdate = true;
|
||||
}
|
||||
else if (currentSkullUnit != priorityTarget)
|
||||
{
|
||||
needsUpdate = true;
|
||||
}
|
||||
|
||||
if (needsUpdate)
|
||||
{
|
||||
group->SetTargetIcon(7, bot->GetGUID(), priorityTarget->GetGUID());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
//Lady
|
||||
@@ -118,10 +148,19 @@ bool IccDarkReckoningAction::Execute(Event event)
|
||||
|
||||
bool IccRangedPositionLadyDeathwhisperAction::Execute(Event event)
|
||||
{
|
||||
Unit* boss = AI_VALUE2(Unit*, "find target", "lady deathwhisper");
|
||||
if (!boss)
|
||||
return false;
|
||||
|
||||
float currentDistance = bot->GetDistance2d(boss);
|
||||
|
||||
if (currentDistance < 7.0f || currentDistance > 30.0f)
|
||||
return false;
|
||||
|
||||
if (botAI->IsRanged(bot) || botAI->IsHeal(bot))
|
||||
{
|
||||
float radius = 5.0f;
|
||||
float moveIncrement = 3.0f;
|
||||
float radius = 3.0f;
|
||||
float moveIncrement = 2.0f;
|
||||
bool isRanged = botAI->IsRanged(bot);
|
||||
|
||||
GuidVector members = AI_VALUE(GuidVector, "group members");
|
||||
@@ -155,7 +194,7 @@ bool IccAddsLadyDeathwhisperAction::Execute(Event event)
|
||||
if (!boss)
|
||||
return false;
|
||||
|
||||
if (botAI->IsTank(bot) && boss->GetHealthPct() < 98.0f)
|
||||
if (botAI->IsTank(bot) && boss->GetHealthPct() < 95.0f)
|
||||
{
|
||||
if (bot->GetExactDist2d(ICC_LDW_TANK_POSTION) > 20.0f)
|
||||
return MoveTo(bot->GetMapId(), ICC_LDW_TANK_POSTION.GetPositionX(),
|
||||
@@ -163,69 +202,68 @@ bool IccAddsLadyDeathwhisperAction::Execute(Event event)
|
||||
false, false, false, MovementPriority::MOVEMENT_COMBAT);
|
||||
}
|
||||
|
||||
if (botAI->IsMainTank(bot) || botAI->IsHeal(bot))
|
||||
if (!botAI->IsTank(bot))
|
||||
return false;
|
||||
|
||||
Unit* currentTarget = AI_VALUE(Unit*, "current target");
|
||||
|
||||
GuidVector targets = AI_VALUE(GuidVector, "possible targets");
|
||||
GuidVector targets = AI_VALUE(GuidVector, "possible targets no los");
|
||||
|
||||
Unit* add = nullptr;
|
||||
for (auto i = targets.begin(); i != targets.end(); ++i)
|
||||
{
|
||||
Unit* unit = botAI->GetUnit(*i);
|
||||
if (unit && (unit->GetEntry() == 37949 || //cult adherent
|
||||
unit->GetEntry() == 38394 ||
|
||||
unit->GetEntry() == 38625 ||
|
||||
unit->GetEntry() == 38626 ||
|
||||
unit->GetEntry() == 38010 ||
|
||||
unit->GetEntry() == 38397 ||
|
||||
unit->GetEntry() == 39000 ||
|
||||
unit->GetEntry() == 39001 ||
|
||||
unit->GetEntry() == 38136 ||
|
||||
unit->GetEntry() == 38396 ||
|
||||
unit->GetEntry() == 38632 ||
|
||||
unit->GetEntry() == 38633 ||
|
||||
unit->GetEntry() == 37890 || //cult fanatic
|
||||
unit->GetEntry() == 38393 ||
|
||||
unit->GetEntry() == 38628 ||
|
||||
unit->GetEntry() == 38629 ||
|
||||
unit->GetEntry() == 38135 ||
|
||||
unit->GetEntry() == 38395 ||
|
||||
unit->GetEntry() == 38634 ||
|
||||
unit->GetEntry() == 38009 ||
|
||||
unit->GetEntry() == 38398 ||
|
||||
unit->GetEntry() == 38630 ||
|
||||
unit->GetEntry() == 38631))
|
||||
{
|
||||
add = unit;
|
||||
break;
|
||||
}
|
||||
}
|
||||
const uint32 targetsEntries[] = {37949, 38394, 38625, 38626, 38010, 38397, 39000, 39001, 38136, 38396, 38632, 38633, 37890, 38393, 38628, 38629, 38135, 38395, 38634, 38009, 38398, 38630, 38631}; //fanatics and adherents
|
||||
|
||||
// Prioritize attacking an add if found
|
||||
if (add)
|
||||
Unit* priorityTarget = nullptr;
|
||||
bool hasValidAdds = false;
|
||||
|
||||
// First check for alive adds
|
||||
for (uint32 entry : targetsEntries)
|
||||
{
|
||||
if (currentTarget != add)
|
||||
for (const ObjectGuid& guid : targets)
|
||||
{
|
||||
if (Attack(add))
|
||||
Unit* unit = botAI->GetUnit(guid);
|
||||
if (unit && unit->IsAlive() && unit->GetEntry() == entry)
|
||||
{
|
||||
return Attack(add);
|
||||
priorityTarget = unit;
|
||||
hasValidAdds = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return Attack(add); // Already attacking an add
|
||||
if (priorityTarget)
|
||||
break;
|
||||
}
|
||||
|
||||
// No adds found, attack boss if not already targeting
|
||||
if (currentTarget != boss)
|
||||
// Only fallback to boss if NO adds exist
|
||||
if (!hasValidAdds && boss->IsAlive())
|
||||
{
|
||||
if (Attack(boss))
|
||||
priorityTarget = boss;
|
||||
}
|
||||
|
||||
// Update skull icon if needed
|
||||
if (priorityTarget)
|
||||
{
|
||||
if (Group* group = bot->GetGroup())
|
||||
{
|
||||
return Attack(boss);
|
||||
ObjectGuid currentSkull = group->GetTargetIcon(7);
|
||||
Unit* currentSkullUnit = botAI->GetUnit(currentSkull);
|
||||
|
||||
bool needsUpdate = false;
|
||||
if (!currentSkullUnit || !currentSkullUnit->IsAlive())
|
||||
{
|
||||
needsUpdate = true; // No valid skull target
|
||||
}
|
||||
else if (currentSkullUnit != priorityTarget)
|
||||
{
|
||||
needsUpdate = true; // Different target than desired
|
||||
}
|
||||
|
||||
if (needsUpdate)
|
||||
{
|
||||
group->SetTargetIcon(7, bot->GetGUID(), priorityTarget->GetGUID());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
bool IccShadeLadyDeathwhisperAction::Execute(Event event)
|
||||
@@ -479,128 +517,171 @@ bool IccDbsTankPositionAction::Execute(Event event)
|
||||
if (botAI->IsTank(bot) || botAI->IsMainTank(bot) || botAI->IsAssistTank(bot))
|
||||
{
|
||||
if (bot->GetExactDist2d(ICC_DBS_TANK_POSITION) > 5.0f)
|
||||
return MoveTo(bot->GetMapId(), ICC_DBS_TANK_POSITION.GetPositionX(),
|
||||
ICC_DBS_TANK_POSITION.GetPositionY(), ICC_DBS_TANK_POSITION.GetPositionZ(), false,
|
||||
false, false, true, MovementPriority::MOVEMENT_NORMAL);
|
||||
return MoveTo(bot->GetMapId(), ICC_DBS_TANK_POSITION.GetPositionX(), ICC_DBS_TANK_POSITION.GetPositionY(),
|
||||
ICC_DBS_TANK_POSITION.GetPositionZ(), false, false, false, true,
|
||||
MovementPriority::MOVEMENT_NORMAL);
|
||||
}
|
||||
|
||||
if (botAI->GetAura("Rune of Blood", bot))
|
||||
if (botAI->GetAura("Rune of Blood", bot) && botAI->IsTank(bot))
|
||||
return true;
|
||||
|
||||
if (botAI->IsRanged(bot) || botAI->IsHeal(bot))
|
||||
{
|
||||
// Get group and position in group
|
||||
Group* group = bot->GetGroup();
|
||||
if (!group)
|
||||
return false;
|
||||
const float evasion = 12.0f;
|
||||
|
||||
// Find this bot's position among ranged/healers in the group
|
||||
int rangedIndex = -1;
|
||||
int currentIndex = 0;
|
||||
|
||||
for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
|
||||
// Get the nearest hostile NPCs
|
||||
GuidVector npcs = AI_VALUE(GuidVector, "nearest hostile npcs");
|
||||
for (auto& npc : npcs)
|
||||
{
|
||||
Player* member = itr->GetSource();
|
||||
if (!member || !member->IsAlive())
|
||||
continue;
|
||||
|
||||
if ((botAI->IsRanged(member) || botAI->IsHeal(member)) && !botAI->IsTank(member))
|
||||
Unit* unit = botAI->GetUnit(npc);
|
||||
if (unit && (unit->GetEntry() == 38508 || unit->GetEntry() == 38596 || unit->GetEntry() == 38597 ||
|
||||
unit->GetEntry() == 38598)) // blood beast
|
||||
{
|
||||
if (member == bot)
|
||||
// Only run away if the blood beast is targeting us
|
||||
if (unit->GetVictim() == bot)
|
||||
{
|
||||
rangedIndex = currentIndex;
|
||||
break;
|
||||
float currentDistance = bot->GetDistance2d(unit);
|
||||
|
||||
// Move away from the blood beast if the bot is too close
|
||||
if (currentDistance < evasion)
|
||||
{
|
||||
return MoveAway(unit, evasion - currentDistance);
|
||||
}
|
||||
}
|
||||
currentIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
if (rangedIndex == -1)
|
||||
// Get group and position in group
|
||||
Group* group = bot->GetGroup();
|
||||
if (!group)
|
||||
return false;
|
||||
|
||||
// Find this bot's position among ranged/healers in the group
|
||||
int rangedIndex = -1;
|
||||
int currentIndex = 0;
|
||||
|
||||
for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
|
||||
{
|
||||
Player* member = itr->GetSource();
|
||||
if (!member || !member->IsAlive())
|
||||
continue;
|
||||
|
||||
if ((botAI->IsRanged(member) || botAI->IsHeal(member)) && !botAI->IsTank(member))
|
||||
{
|
||||
if (member == bot)
|
||||
{
|
||||
rangedIndex = currentIndex;
|
||||
break;
|
||||
}
|
||||
currentIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
if (rangedIndex == -1)
|
||||
return false;
|
||||
|
||||
// Fixed positions calculation
|
||||
float tankToBossAngle = 3.14f;
|
||||
const float minBossDistance = 11.0f;
|
||||
const float spreadDistance = 10.0f;
|
||||
|
||||
// Calculate position in a fixed grid (3 rows x 5 columns)
|
||||
int row = rangedIndex / 5;
|
||||
int col = rangedIndex % 5;
|
||||
|
||||
// Calculate base position
|
||||
float xOffset = (col - 2) * spreadDistance; // Center around tank position
|
||||
float yOffset = minBossDistance + (row * spreadDistance); // Each row further back
|
||||
|
||||
// Add zigzag offset for odd rows
|
||||
if (row % 2 == 1)
|
||||
xOffset += spreadDistance / 2;
|
||||
|
||||
// Rotate position based on tank-to-boss angle
|
||||
float finalX = ICC_DBS_TANK_POSITION.GetPositionX() +
|
||||
(cos(tankToBossAngle) * yOffset - sin(tankToBossAngle) * xOffset);
|
||||
float finalY = ICC_DBS_TANK_POSITION.GetPositionY() +
|
||||
(sin(tankToBossAngle) * yOffset + cos(tankToBossAngle) * xOffset);
|
||||
float finalZ = ICC_DBS_TANK_POSITION.GetPositionZ();
|
||||
|
||||
// Update Z coordinate
|
||||
bot->UpdateAllowedPositionZ(finalX, finalY, finalZ);
|
||||
|
||||
// Move if not in position
|
||||
if (bot->GetExactDist2d(finalX, finalY) > 3.0f)
|
||||
return MoveTo(bot->GetMapId(), finalX, finalY, finalZ, false, false, false, true,
|
||||
MovementPriority::MOVEMENT_COMBAT);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Fixed positions calculation
|
||||
float tankToBossAngle = 3.14f;
|
||||
const float minBossDistance = 15.0f;
|
||||
const float spreadDistance = 10.0f;
|
||||
|
||||
// Calculate position in a fixed grid (3 rows x 5 columns)
|
||||
int row = rangedIndex / 5;
|
||||
int col = rangedIndex % 5;
|
||||
|
||||
// Calculate base position
|
||||
float xOffset = (col - 2) * spreadDistance; // Center around tank position
|
||||
float yOffset = minBossDistance + (row * spreadDistance); // Each row further back
|
||||
|
||||
// Add zigzag offset for odd rows
|
||||
if (row % 2 == 1)
|
||||
xOffset += spreadDistance / 2;
|
||||
|
||||
// Rotate position based on tank-to-boss angle
|
||||
float finalX = ICC_DBS_TANK_POSITION.GetPositionX() + (cos(tankToBossAngle) * yOffset - sin(tankToBossAngle) * xOffset);
|
||||
float finalY = ICC_DBS_TANK_POSITION.GetPositionY() + (sin(tankToBossAngle) * yOffset + cos(tankToBossAngle) * xOffset);
|
||||
float finalZ = ICC_DBS_TANK_POSITION.GetPositionZ();
|
||||
|
||||
// Update Z coordinate
|
||||
bot->UpdateAllowedPositionZ(finalX, finalY, finalZ);
|
||||
|
||||
// Move if not in position
|
||||
if (bot->GetExactDist2d(finalX, finalY) > 3.0f)
|
||||
return MoveTo(bot->GetMapId(), finalX, finalY, finalZ,
|
||||
false, false, false, true, MovementPriority::MOVEMENT_COMBAT);
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IccAddsDbsAction::Execute(Event event)
|
||||
{
|
||||
if (botAI->IsHeal(bot))
|
||||
return false;
|
||||
|
||||
Unit* boss = AI_VALUE2(Unit*, "find target", "deathbringer saurfang");
|
||||
if (!boss)
|
||||
return false;
|
||||
|
||||
if (!botAI->GetAura("Rune of Blood", bot) && botAI->IsMainTank(bot))
|
||||
if (!botAI->IsMelee(bot))
|
||||
return false;
|
||||
|
||||
Unit* currentTarget = AI_VALUE(Unit*, "current target");
|
||||
|
||||
GuidVector targets = AI_VALUE(GuidVector, "possible targets");
|
||||
|
||||
Unit* add = nullptr;
|
||||
for (auto i = targets.begin(); i != targets.end(); ++i)
|
||||
{
|
||||
Unit* unit = botAI->GetUnit(*i);
|
||||
if (unit && (unit->GetEntry() == 38508 || //blood beast
|
||||
unit->GetEntry() == 38596 ||
|
||||
unit->GetEntry() == 38597 ||
|
||||
unit->GetEntry() == 38598))
|
||||
{
|
||||
add = unit;
|
||||
break;
|
||||
}
|
||||
}
|
||||
GuidVector targets = AI_VALUE(GuidVector, "possible targets no los");
|
||||
|
||||
// Prioritize attacking an add if found
|
||||
if (add && !botAI->IsHeal(bot))
|
||||
const uint32 targetsEntries[] = {38508, 38596, 38597, 38598}; // adds
|
||||
|
||||
Unit* priorityTarget = nullptr;
|
||||
bool hasValidAdds = false;
|
||||
|
||||
// First check for alive adds
|
||||
for (uint32 entry : targetsEntries)
|
||||
{
|
||||
if (currentTarget != add)
|
||||
for (const ObjectGuid& guid : targets)
|
||||
{
|
||||
if (Attack(add))
|
||||
Unit* unit = botAI->GetUnit(guid);
|
||||
if (unit && unit->IsAlive() && unit->GetEntry() == entry)
|
||||
{
|
||||
return Attack(add);
|
||||
priorityTarget = unit;
|
||||
hasValidAdds = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return Attack(add); // Already attacking an add
|
||||
if (priorityTarget)
|
||||
break;
|
||||
}
|
||||
|
||||
// No adds found, attack boss if not already targeting
|
||||
if (currentTarget != boss)
|
||||
// Only fallback to boss if NO adds exist
|
||||
if (!hasValidAdds && boss->IsAlive())
|
||||
{
|
||||
if (Attack(boss))
|
||||
priorityTarget = boss;
|
||||
}
|
||||
|
||||
// Update skull icon if needed
|
||||
if (priorityTarget)
|
||||
{
|
||||
if (Group* group = bot->GetGroup())
|
||||
{
|
||||
return Attack(boss);
|
||||
ObjectGuid currentSkull = group->GetTargetIcon(7);
|
||||
Unit* currentSkullUnit = botAI->GetUnit(currentSkull);
|
||||
|
||||
bool needsUpdate = false;
|
||||
if (!currentSkullUnit || !currentSkullUnit->IsAlive())
|
||||
{
|
||||
needsUpdate = true; // No valid skull target
|
||||
}
|
||||
else if (currentSkullUnit != priorityTarget)
|
||||
{
|
||||
needsUpdate = true; // Different target than desired
|
||||
}
|
||||
|
||||
if (needsUpdate)
|
||||
{
|
||||
group->SetTargetIcon(7, bot->GetGUID(), priorityTarget->GetGUID());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
const Position ICC_LM_TANK_POSITION = Position(-391.0f, 2259.0f, 42.0f);
|
||||
const Position ICC_DARK_RECKONING_SAFE_POSITION = Position(-523.33386f, 2211.2031f, 62.823116f);
|
||||
const Position ICC_LDW_TANK_POSTION = Position(-589.9879f, 2211.2456f, 49.476616f);
|
||||
const Position ICC_LDW_TANK_POSTION = Position(-570.1f, 2211.2456f, 49.476616f); //-590.0f
|
||||
const Position ICC_ROTTING_FROST_GIANT_TANK_POSITION = Position(-265.90125f, 2209.0605f, 199.97006f);
|
||||
const Position ICC_GUNSHIP_TELEPORT_ALLY = Position (-370.04645f, 1993.3536f, 466.65656f);
|
||||
const Position ICC_GUNSHIP_TELEPORT_ALLY2 = Position (-392.66208f, 2064.893f, 466.5672f, 5.058196f);
|
||||
|
||||
@@ -74,33 +74,6 @@ float IccAddsDbsMultiplier::GetValue(Action* action)
|
||||
}
|
||||
}
|
||||
|
||||
if (botAI->IsDps(bot))
|
||||
{
|
||||
GuidVector targets = AI_VALUE(GuidVector, "possible targets");
|
||||
bool hasAdds = false;
|
||||
for (auto& guid : targets)
|
||||
{
|
||||
Unit* unit = botAI->GetUnit(guid);
|
||||
if (unit && unit->IsAlive() && (
|
||||
unit->GetEntry() == 38508 || //blood beast
|
||||
unit->GetEntry() == 38596 ||
|
||||
unit->GetEntry() == 38597 ||
|
||||
unit->GetEntry() == 38598))
|
||||
{
|
||||
hasAdds = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasAdds && !botAI->IsMainTank(bot))
|
||||
{
|
||||
if (dynamic_cast<IccAddsDbsAction*>(action))
|
||||
return 2.0f;
|
||||
else if (dynamic_cast<DpsAssistAction*>(action) || dynamic_cast<TankAssistAction*>(action) ||
|
||||
dynamic_cast<CombatFormationMoveAction*>(action) || dynamic_cast<FollowAction*>(action))
|
||||
return 0.0f;
|
||||
}
|
||||
}
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,25 +25,7 @@ bool IccSpikeNearTrigger::IsActive()
|
||||
if (!boss)
|
||||
return false;
|
||||
|
||||
GuidVector npcs = AI_VALUE(GuidVector, "nearest hostile npcs");
|
||||
for (auto& npc : npcs)
|
||||
{
|
||||
Unit* unit = botAI->GetUnit(npc);
|
||||
if (unit)
|
||||
{
|
||||
if (unit->GetEntry() == 36619 || unit->GetEntry() == 38711 || unit->GetEntry() == 38712 ) //spike ID
|
||||
{
|
||||
if (unit->GetDistance(bot) <= 20.0f)
|
||||
{
|
||||
return botAI->IsDps(bot);
|
||||
}
|
||||
|
||||
return botAI->IsRangedDps(bot);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
//Lady Deathwhisper
|
||||
@@ -144,7 +126,8 @@ bool IccGunshipTeleportAllyTrigger::IsActive()
|
||||
bool IccGunshipTeleportHordeTrigger::IsActive()
|
||||
{
|
||||
Unit* boss = AI_VALUE2(Unit*, "find target", "skybreaker sorcerer");
|
||||
if (!boss) { return false; }
|
||||
if (!boss)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -153,7 +136,8 @@ bool IccGunshipTeleportHordeTrigger::IsActive()
|
||||
bool IccDbsTankPositionTrigger::IsActive()
|
||||
{
|
||||
Unit* boss = AI_VALUE2(Unit*, "find target", "deathbringer saurfang");
|
||||
if (!boss) { return false; }
|
||||
if (!boss)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -182,9 +166,10 @@ bool IccDbsMainTankRuneOfBloodTrigger::IsActive()
|
||||
bool IccAddsDbsTrigger::IsActive()
|
||||
{
|
||||
Unit* boss = AI_VALUE2(Unit*, "find target", "deathbringer saurfang");
|
||||
if (!boss) { return false; }
|
||||
if (!boss)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
//DOGS
|
||||
@@ -1012,4 +997,4 @@ bool IccLichKingAddsTrigger::IsActive()
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user