ICC Strategy (doable 10/25NM) (#789)

* 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
This commit is contained in:
Noscopezz
2025-01-03 19:15:16 +01:00
committed by GitHub
parent fa02cdb369
commit 16d06c4832
11 changed files with 5187 additions and 11 deletions

View File

@@ -10,13 +10,100 @@ class RaidIccActionContext : public NamedObjectContext<Action>
public:
RaidIccActionContext()
{
creators["icc lm tank position"] = &RaidIccActionContext::icc_lm_tank_position;
creators["icc spike"] = &RaidIccActionContext::icc_spike;
creators["icc dark reckoning"] = &RaidIccActionContext::icc_dark_reckoning;
creators["icc ranged position lady deathwhisper"] = &RaidIccActionContext::icc_ranged_position_lady_deathwhisper;
creators["icc adds lady deathwhisper"] = &RaidIccActionContext::icc_adds_lady_deathwhisper;
creators["icc shade lady deathwhisper"] = &RaidIccActionContext::icc_shade_lady_deathwhisper;
creators["icc rotting frost giant tank position"] = &RaidIccActionContext::icc_rotting_frost_giant_tank_position;
creators["icc cannon fire"] = &RaidIccActionContext::icc_cannon_fire;
creators["icc gunship enter cannon"] = &RaidIccActionContext::icc_gunship_enter_cannon;
creators["icc gunship teleport ally"] = &RaidIccActionContext::icc_gunship_teleport_ally;
creators["icc gunship teleport horde"] = &RaidIccActionContext::icc_gunship_teleport_horde;
creators["icc dbs tank position"] = &RaidIccActionContext::icc_dbs_tank_position;
creators["icc adds dbs"] = &RaidIccActionContext::icc_adds_dbs;
creators["icc festergut tank position"] = &RaidIccActionContext::icc_festergut_tank_position;
creators["icc festergut spore"] = &RaidIccActionContext::icc_festergut_spore;
creators["icc rotface tank position"] = &RaidIccActionContext::icc_rotface_tank_position;
creators["icc rotface group position"] = &RaidIccActionContext::icc_rotface_group_position;
creators["icc rotface move away from explosion"] = &RaidIccActionContext::icc_rotface_move_away_from_explosion;
creators["icc putricide volatile ooze"] = &RaidIccActionContext::icc_putricide_volatile_ooze;
creators["icc putricide gas cloud"] = &RaidIccActionContext::icc_putricide_gas_cloud;
creators["icc putricide growing ooze puddle"] = &RaidIccActionContext::icc_putricide_growing_ooze_puddle;
creators["avoid malleable goo"] = &RaidIccActionContext::avoid_malleable_goo;
creators["icc bpc keleseth tank"] = &RaidIccActionContext::icc_bpc_keleseth_tank;
creators["icc bpc nucleus"] = &RaidIccActionContext::icc_bpc_nucleus;
creators["icc bpc main tank"] = &RaidIccActionContext::icc_bpc_main_tank;
creators["icc bpc empowered vortex"] = &RaidIccActionContext::icc_bpc_empowered_vortex;
creators["icc bql tank position"] = &RaidIccActionContext::icc_bql_tank_position;
creators["icc bql pact of darkfallen"] = &RaidIccActionContext::icc_bql_pact_of_darkfallen;
creators["icc bql vampiric bite"] = &RaidIccActionContext::icc_bql_vampiric_bite;
creators["icc valkyre spear"] = &RaidIccActionContext::icc_valkyre_spear;
creators["icc sister svalna"] = &RaidIccActionContext::icc_sister_svalna;
creators["icc valithria portal"] = &RaidIccActionContext::icc_valithria_portal;
creators["icc valithria heal"] = &RaidIccActionContext::icc_valithria_heal;
creators["icc valithria dream cloud"] = &RaidIccActionContext::icc_valithria_dream_cloud;
creators["icc sindragosa tank position"] = &RaidIccActionContext::icc_sindragosa_tank_position;
creators["icc sindragosa frost beacon"] = &RaidIccActionContext::icc_sindragosa_frost_beacon;
creators["icc sindragosa blistering cold"] = &RaidIccActionContext::icc_sindragosa_blistering_cold;
creators["icc sindragosa unchained magic"] = &RaidIccActionContext::icc_sindragosa_unchained_magic;
creators["icc sindragosa chilled to the bone"] = &RaidIccActionContext::icc_sindragosa_chilled_to_the_bone;
creators["icc sindragosa mystic buffet"] = &RaidIccActionContext::icc_sindragosa_mystic_buffet;
creators["icc sindragosa frost bomb"] = &RaidIccActionContext::icc_sindragosa_frost_bomb;
creators["icc sindragosa tank swap position"] = &RaidIccActionContext::icc_sindragosa_tank_swap_position;
creators["icc lich king necrotic plague"] = &RaidIccActionContext::icc_lich_king_necrotic_plague;
creators["icc lich king winter"] = &RaidIccActionContext::icc_lich_king_winter;
creators["icc lich king adds"] = &RaidIccActionContext::icc_lich_king_adds;
}
private:
static Action* icc_lm_tank_position(PlayerbotAI* ai) { return new IccLmTankPositionAction(ai); }
static Action* icc_spike(PlayerbotAI* ai) { return new IccSpikeAction(ai); }
static Action* icc_dark_reckoning(PlayerbotAI* ai) { return new IccDarkReckoningAction(ai); }
static Action* icc_ranged_position_lady_deathwhisper(PlayerbotAI* ai) { return new IccRangedPositionLadyDeathwhisperAction(ai); }
static Action* icc_adds_lady_deathwhisper(PlayerbotAI* ai) { return new IccAddsLadyDeathwhisperAction(ai); }
static Action* icc_shade_lady_deathwhisper(PlayerbotAI* ai) { return new IccShadeLadyDeathwhisperAction(ai); }
static Action* icc_rotting_frost_giant_tank_position(PlayerbotAI* ai) { return new IccRottingFrostGiantTankPositionAction(ai); }
static Action* icc_cannon_fire(PlayerbotAI* ai) { return new IccCannonFireAction(ai); }
static Action* icc_gunship_enter_cannon(PlayerbotAI* ai) { return new IccGunshipEnterCannonAction(ai); }
static Action* icc_gunship_teleport_ally(PlayerbotAI* ai) { return new IccGunshipTeleportAllyAction(ai); }
static Action* icc_gunship_teleport_horde(PlayerbotAI* ai) { return new IccGunshipTeleportHordeAction(ai); }
static Action* icc_dbs_tank_position(PlayerbotAI* ai) { return new IccDbsTankPositionAction(ai); }
static Action* icc_adds_dbs(PlayerbotAI* ai) { return new IccAddsDbsAction(ai); }
static Action* icc_festergut_tank_position(PlayerbotAI* ai) { return new IccFestergutTankPositionAction(ai); }
static Action* icc_festergut_spore(PlayerbotAI* ai) { return new IccFestergutSporeAction(ai); }
static Action* icc_rotface_tank_position(PlayerbotAI* ai) { return new IccRotfaceTankPositionAction(ai); }
static Action* icc_rotface_group_position(PlayerbotAI* ai) { return new IccRotfaceGroupPositionAction(ai); }
static Action* icc_rotface_move_away_from_explosion(PlayerbotAI* ai) { return new IccRotfaceMoveAwayFromExplosionAction(ai); }
static Action* icc_putricide_volatile_ooze(PlayerbotAI* ai) { return new IccPutricideVolatileOozeAction(ai); }
static Action* icc_putricide_gas_cloud(PlayerbotAI* ai) { return new IccPutricideGasCloudAction(ai); }
static Action* icc_putricide_growing_ooze_puddle(PlayerbotAI* ai) { return new IccPutricideGrowingOozePuddleAction(ai); }
static Action* avoid_malleable_goo(PlayerbotAI* ai) { return new AvoidMalleableGooAction(ai); }
static Action* icc_bpc_keleseth_tank(PlayerbotAI* ai) { return new IccBpcKelesethTankAction(ai); }
static Action* icc_bpc_nucleus(PlayerbotAI* ai) { return new IccBpcNucleusAction(ai); }
static Action* icc_bpc_main_tank(PlayerbotAI* ai) { return new IccBpcMainTankAction(ai); }
static Action* icc_bpc_empowered_vortex(PlayerbotAI* ai) { return new IccBpcEmpoweredVortexAction(ai); }
static Action* icc_bql_tank_position(PlayerbotAI* ai) { return new IccBqlTankPositionAction(ai); }
static Action* icc_bql_pact_of_darkfallen(PlayerbotAI* ai) { return new IccBqlPactOfDarkfallenAction(ai); }
static Action* icc_bql_vampiric_bite(PlayerbotAI* ai) { return new IccBqlVampiricBiteAction(ai); }
static Action* icc_valkyre_spear(PlayerbotAI* ai) { return new IccValkyreSpearAction(ai); }
static Action* icc_sister_svalna(PlayerbotAI* ai) { return new IccSisterSvalnaAction(ai); }
static Action* icc_valithria_portal(PlayerbotAI* ai) { return new IccValithriaPortalAction(ai); }
static Action* icc_valithria_heal(PlayerbotAI* ai) { return new IccValithriaHealAction(ai); }
static Action* icc_valithria_dream_cloud(PlayerbotAI* ai) { return new IccValithriaDreamCloudAction(ai); }
static Action* icc_sindragosa_tank_position(PlayerbotAI* ai) { return new IccSindragosaTankPositionAction(ai); }
static Action* icc_sindragosa_frost_beacon(PlayerbotAI* ai) { return new IccSindragosaFrostBeaconAction(ai); }
static Action* icc_sindragosa_blistering_cold(PlayerbotAI* ai) { return new IccSindragosaBlisteringColdAction(ai); }
static Action* icc_sindragosa_unchained_magic(PlayerbotAI* ai) { return new IccSindragosaUnchainedMagicAction(ai); }
static Action* icc_sindragosa_chilled_to_the_bone(PlayerbotAI* ai) { return new IccSindragosaChilledToTheBoneAction(ai); }
static Action* icc_sindragosa_mystic_buffet(PlayerbotAI* ai) { return new IccSindragosaMysticBuffetAction(ai); }
static Action* icc_sindragosa_frost_bomb(PlayerbotAI* ai) { return new IccSindragosaFrostBombAction(ai); }
static Action* icc_sindragosa_tank_swap_position(PlayerbotAI* ai) { return new IccSindragosaTankSwapPositionAction(ai); }
static Action* icc_lich_king_necrotic_plague(PlayerbotAI* ai) { return new IccLichKingNecroticPlagueAction(ai); }
static Action* icc_lich_king_winter(PlayerbotAI* ai) { return new IccLichKingWinterAction(ai); }
static Action* icc_lich_king_adds(PlayerbotAI* ai) { return new IccLichKingAddsAction(ai); }
};
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,9 +1,114 @@
#ifndef _PLAYERBOT_RAIDICCACTIONS_H
#define _PLAYERBOT_RAIDICCACTIONS_H
#include "Action.h"
#include "MovementActions.h"
#include "PlayerbotAI.h"
#include "Playerbots.h"
#include "AttackAction.h"
#include "LastMovementValue.h"
#include "ObjectGuid.h"
#include "PlayerbotAIConfig.h"
#include "RaidIccStrategy.h"
#include "ScriptedCreature.h"
#include "SharedDefines.h"
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_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_HORDE = Position (-449.5343f, 2477.2024f, 470.17648f);
const Position ICC_DBS_TANK_POSITION = Position(-494.26517f, 2211.549f, 541.11414f);
const Position ICC_FESTERGUT_TANK_POSITION = Position(4269.1772f, 3144.7673f, 360.38577f);
const Position ICC_FESTERGUT_RANGED_SPORE = Position(4261.143f, 3109.4146f, 360.38605f);
const Position ICC_FESTERGUT_MELEE_SPORE = Position(4269.1772f, 3144.7673f, 360.38577f);
const Position ICC_ROTFACE_TANK_POSITION = Position(4447.061f, 3150.9758f, 360.38568f);
const Position ICC_ROTFACE_BIG_OOZE_POSITION = Position(4432.687f, 3142.3035f, 360.38623f);
const Position ICC_ROTFACE_SAFE_POSITION = Position(4446.557f, 3065.6594f, 360.51843f);
const Position ICC_PUTRICIDE_TANK_OOZE_POSITION = Position(4362.709f, 3229.1448f, 389.4083f);
const Position ICC_PUTRICIDE_TANK_GAS_CLOUD_POSITION = Position(4397.0386f, 3221.385f, 389.3999f);
const Position ICC_PUTRICIDE_GAS1_POSITION = Position(4350.772f, 3249.9773f, 389.39508f);
const Position ICC_PUTRICIDE_GAS2_POSITION = Position(4390.002f, 3204.8855f, 389.39938f);
const Position ICC_PUTRICIDE_GAS3_POSITION = Position(4367.753f, 3177.5894f, 389.39575f);
const Position ICC_PUTRICIDE_GAS4_POSITION = Position(4321.8486f, 3206.464f, 389.3982f);
const Position ICC_BPC_OT_POSITION = Position(4649.2236f, 2796.0972f, 361.1815f);
const Position ICC_BPC_MT_POSITION = Position(4648.5674f, 2744.847f, 361.18222f);
const Position ICC_BQL_CENTER_POSITION = Position(4595.0f, 2769.0f, 400.0f);
const Position ICC_BQL_TANK_POSITION = Position(4616.102f, 2768.9167f, 400.13797f);
const Position ICC_SINDRAGOSA_TANK_POSITION = Position(4408.016f, 2508.0647f, 203.37955f);
const Position ICC_SINDRAGOSA_RANGED_POSITION = Position(4373.7686f, 2498.0042f, 203.38176f);
const Position ICC_SINDRAGOSA_MELEE_POSITION = Position(4389.22f, 2499.5237f, 203.38033f);
const Position ICC_SINDRAGOSA_BLISTERING_COLD_POSITION = Position(4357.036f, 2484.5574f, 203.4777f);
const Position ICC_SINDRAGOSA_THOMB1_POSITION = Position(4381.819f, 2471.1448f, 203.37704f); // Westmost position
const Position ICC_SINDRAGOSA_THOMB2_POSITION = Position(4381.819f, 2483.1448f, 203.37704f); // 12y east from pos1
const Position ICC_SINDRAGOSA_THOMB3_POSITION = Position(4381.819f, 2471.1448f, 203.37704f); // Same as pos1
const Position ICC_SINDRAGOSA_THOMB4_POSITION = Position(4381.819f, 2483.1448f, 203.37704f); // Same as pos2
const Position ICC_SINDRAGOSA_THOMB5_POSITION = Position(4381.819f, 2495.1448f, 203.37704f); // 12y east from pos2/4
const Position ICC_SINDRAGOSA_CENTER_POSITION = Position(4408.0464f, 2484.478f, 203.37529f);
const Position ICC_SINDRAGOSA_THOMBMB2_POSITION = Position(4382.6113f, 2505.4922f, 203.38197f);
const Position ICC_SINDRAGOSA_FBOMB_POSITION = Position(4400.031f, 2507.0295f, 203.37929f);
const Position ICC_SINDRAGOSA_LOS2_POSITION = Position(4376.0938f, 2511.103f, 203.38303f);
const Position ICC_LICH_KING_ADDS_POSITION = Position(486.63647f, -2095.7915f, 840.857f);
//Lord Marrogwar
class IccLmTankPositionAction : public AttackAction
{
public:
IccLmTankPositionAction(PlayerbotAI* botAI, std::string const name = "icc lm tank position")
: AttackAction(botAI, name) {}
bool Execute(Event event) override;
};
class IccSpikeAction : public AttackAction
{
public:
IccSpikeAction(PlayerbotAI* botAI) : AttackAction(botAI, "icc spike") {}
bool Execute(Event event) override;
};
//Lady Deathwhisper
class IccDarkReckoningAction : public MovementAction
{
public:
IccDarkReckoningAction(PlayerbotAI* botAI, std::string const name = "icc dark reckoning")
: MovementAction(botAI, name) {}
bool Execute(Event event) override;
};
class IccRangedPositionLadyDeathwhisperAction : public AttackAction
{
public:
IccRangedPositionLadyDeathwhisperAction(PlayerbotAI* botAI, std::string const name = "icc ranged position lady deathwhisper")
: AttackAction(botAI, name) {}
bool Execute(Event event) override;
};
class IccAddsLadyDeathwhisperAction : public AttackAction
{
public:
IccAddsLadyDeathwhisperAction(PlayerbotAI* botAI, std::string const name = "icc adds lady deathwhisper")
: AttackAction(botAI, name) {}
bool Execute(Event event) override;
};
class IccShadeLadyDeathwhisperAction : public MovementAction
{
public:
IccShadeLadyDeathwhisperAction(PlayerbotAI* botAI, std::string const name = "icc shade lady deathwhisper")
: MovementAction(botAI, name) {}
bool Execute(Event event) override;
};
//Gunship Battle
class IccRottingFrostGiantTankPositionAction : public AttackAction
{
public:
IccRottingFrostGiantTankPositionAction(PlayerbotAI* botAI, std::string const name = "icc rotting frost giant tank position")
: AttackAction(botAI, name) {}
bool Execute(Event event) override;
};
class IccCannonFireAction : public Action
{
@@ -22,4 +127,308 @@ public:
bool EnterVehicle(Unit* vehicleBase, bool moveIfFar);
};
class IccGunshipTeleportAllyAction : public AttackAction
{
public:
IccGunshipTeleportAllyAction(PlayerbotAI* botAI, std::string const name = "icc gunship teleport ally")
: AttackAction(botAI, name) {}
bool Execute(Event event) override;
};
class IccGunshipTeleportHordeAction : public AttackAction
{
public:
IccGunshipTeleportHordeAction(PlayerbotAI* botAI, std::string const name = "icc gunship teleport horde")
: AttackAction(botAI, name) {}
bool Execute(Event event) override;
};
//DBS
class IccDbsTankPositionAction : public AttackAction
{
public:
IccDbsTankPositionAction(PlayerbotAI* botAI, std::string const name = "icc dbs tank position")
: AttackAction(botAI, name) {}
bool Execute(Event event) override;
};
class IccAddsDbsAction : public AttackAction
{
public:
IccAddsDbsAction(PlayerbotAI* botAI, std::string const name = "icc adds dbs")
: AttackAction(botAI, name) {}
bool Execute(Event event) override;
};
//FESTERGUT
class IccFestergutTankPositionAction : public AttackAction
{
public:
IccFestergutTankPositionAction(PlayerbotAI* botAI, std::string const name = "icc festergut tank position")
: AttackAction(botAI, name) {}
bool Execute(Event event) override;
};
class IccFestergutSporeAction : public AttackAction
{
public:
IccFestergutSporeAction(PlayerbotAI* botAI, std::string const name = "icc festergut spore")
: AttackAction(botAI, name) {}
bool Execute(Event event) override;
};
//Rotface
class IccRotfaceTankPositionAction : public AttackAction
{
public:
IccRotfaceTankPositionAction(PlayerbotAI* botAI, std::string const name = "icc rotface tank position")
: AttackAction(botAI, name) {}
bool Execute(Event event) override;
};
class IccRotfaceGroupPositionAction : public AttackAction
{
public:
IccRotfaceGroupPositionAction(PlayerbotAI* botAI, std::string const name = "icc rotface group position")
: AttackAction(botAI, name) {}
bool Execute(Event event) override;
};
class IccRotfaceMoveAwayFromExplosionAction : public MovementAction
{
public:
IccRotfaceMoveAwayFromExplosionAction(PlayerbotAI* botAI, std::string const name = "icc rotface move away from explosion")
: MovementAction(botAI, name) {}
bool Execute(Event event) override;
};
//PP
class IccPutricideGrowingOozePuddleAction : public AttackAction
{
public:
IccPutricideGrowingOozePuddleAction(PlayerbotAI* botAI, std::string const name = "icc putricide growing ooze puddle")
: AttackAction(botAI, name) {}
bool Execute(Event event) override;
};
class IccPutricideVolatileOozeAction : public AttackAction
{
public:
IccPutricideVolatileOozeAction(PlayerbotAI* botAI, std::string const name = "icc putricide volatile ooze")
: AttackAction(botAI, name) {}
bool Execute(Event event) override;
};
class IccPutricideGasCloudAction : public AttackAction
{
public:
IccPutricideGasCloudAction(PlayerbotAI* botAI, std::string const name = "icc putricide gas cloud")
: AttackAction(botAI, name) {}
bool Execute(Event event) override;
private:
static uint8_t lastKnownPosition; // 0 = none, 1-4 = positions 1-4
};
class AvoidMalleableGooAction : public MovementAction
{
public:
AvoidMalleableGooAction(PlayerbotAI* ai) : MovementAction(ai, "avoid malleable goo") {}
bool Execute(Event event) override;
};
//BPC
class IccBpcKelesethTankAction : public AttackAction
{
public:
IccBpcKelesethTankAction(PlayerbotAI* botAI)
: AttackAction(botAI, "icc bpc keleseth tank") {}
bool Execute(Event event) override;
};
class IccBpcNucleusAction : public AttackAction
{
public:
IccBpcNucleusAction(PlayerbotAI* botAI)
: AttackAction(botAI, "icc bpc nucleus") {}
bool Execute(Event event) override;
};
class IccBpcMainTankAction : public AttackAction
{
public:
IccBpcMainTankAction(PlayerbotAI* botAI)
: AttackAction(botAI, "icc bpc main tank") {}
bool Execute(Event event) override;
};
//BPC Vortex
class IccBpcEmpoweredVortexAction : public MovementAction
{
public:
IccBpcEmpoweredVortexAction(PlayerbotAI* botAI)
: MovementAction(botAI, "icc bpc empowered vortex") {}
bool Execute(Event event) override;
};
//Blood Queen Lana'thel
class IccBqlTankPositionAction : public AttackAction
{
public:
IccBqlTankPositionAction(PlayerbotAI* botAI)
: AttackAction(botAI, "icc bql tank position") {}
bool Execute(Event event) override;
};
class IccBqlPactOfDarkfallenAction : public MovementAction
{
public:
IccBqlPactOfDarkfallenAction(PlayerbotAI* botAI)
: MovementAction(botAI, "icc bql pact of darkfallen") {}
bool Execute(Event event) override;
};
class IccBqlVampiricBiteAction : public AttackAction
{
public:
IccBqlVampiricBiteAction(PlayerbotAI* botAI)
: AttackAction(botAI, "icc bql vampiric bite") {}
bool Execute(Event event) override;
};
//VDW
class IccValkyreSpearAction : public AttackAction
{
public:
IccValkyreSpearAction(PlayerbotAI* botAI)
: AttackAction(botAI, "icc valkyre spear") {}
bool Execute(Event event) override;
};
class IccSisterSvalnaAction : public AttackAction
{
public:
IccSisterSvalnaAction(PlayerbotAI* botAI)
: AttackAction(botAI, "icc sister svalna") {}
bool Execute(Event event) override;
};
class IccValithriaPortalAction : public MovementAction
{
public:
IccValithriaPortalAction(PlayerbotAI* botAI)
: MovementAction(botAI, "icc valithria portal") {}
bool Execute(Event event) override;
};
class IccValithriaHealAction : public AttackAction
{
public:
IccValithriaHealAction(PlayerbotAI* botAI)
: AttackAction(botAI, "icc valithria heal") {}
bool Execute(Event event) override;
};
class IccValithriaDreamCloudAction : public MovementAction
{
public:
IccValithriaDreamCloudAction(PlayerbotAI* botAI)
: MovementAction(botAI, "icc valithria dream cloud") {}
bool Execute(Event event) override;
};
//Sindragosa
class IccSindragosaTankPositionAction : public AttackAction
{
public:
IccSindragosaTankPositionAction(PlayerbotAI* botAI)
: AttackAction(botAI, "icc sindragosa tank position") {}
bool Execute(Event event) override;
};
class IccSindragosaFrostBeaconAction : public AttackAction
{
public:
IccSindragosaFrostBeaconAction(PlayerbotAI* botAI)
: AttackAction(botAI, "icc sindragosa frost beacon") {}
bool Execute(Event event) override;
};
class IccSindragosaBlisteringColdAction : public AttackAction
{
public:
IccSindragosaBlisteringColdAction(PlayerbotAI* botAI)
: AttackAction(botAI, "icc sindragosa blistering cold") {}
bool Execute(Event event) override;
};
class IccSindragosaUnchainedMagicAction : public AttackAction
{
public:
IccSindragosaUnchainedMagicAction(PlayerbotAI* botAI)
: AttackAction(botAI, "icc sindragosa unchained magic") {}
bool Execute(Event event) override;
};
class IccSindragosaChilledToTheBoneAction : public AttackAction
{
public:
IccSindragosaChilledToTheBoneAction(PlayerbotAI* botAI)
: AttackAction(botAI, "icc sindragosa chilled to the bone") {}
bool Execute(Event event) override;
};
class IccSindragosaMysticBuffetAction : public AttackAction
{
public:
IccSindragosaMysticBuffetAction(PlayerbotAI* botAI)
: AttackAction(botAI, "icc sindragosa mystic buffet") {}
bool Execute(Event event) override;
};
class IccSindragosaFrostBombAction : public AttackAction
{
public:
IccSindragosaFrostBombAction(PlayerbotAI* botAI)
: AttackAction(botAI, "icc sindragosa frost bomb") {}
bool Execute(Event event) override;
};
class IccSindragosaTankSwapPositionAction : public AttackAction
{
public:
IccSindragosaTankSwapPositionAction(PlayerbotAI* botAI)
: AttackAction(botAI, "sindragosa tank swap position") {}
bool Execute(Event event) override;
};
//LK
class IccLichKingNecroticPlagueAction : public MovementAction
{
public:
IccLichKingNecroticPlagueAction(PlayerbotAI* botAI)
: MovementAction(botAI, "icc lich king necrotic plague") {}
bool Execute(Event event) override;
};
class IccLichKingWinterAction : public AttackAction
{
public:
IccLichKingWinterAction(PlayerbotAI* botAI)
: AttackAction(botAI, "icc lich king winter") {}
bool Execute(Event event) override;
};
class IccLichKingAddsAction : public AttackAction
{
public:
IccLichKingAddsAction(PlayerbotAI* botAI)
: AttackAction(botAI, "icc lich king adds") {}
bool Execute(Event event) override;
};
#endif

View File

@@ -0,0 +1,632 @@
#include "RaidIccMultipliers.h"
#include "ChooseTargetActions.h"
#include "DKActions.h"
#include "DruidActions.h"
#include "DruidBearActions.h"
#include "FollowActions.h"
#include "GenericActions.h"
#include "GenericSpellActions.h"
#include "HunterActions.h"
#include "MageActions.h"
#include "MovementActions.h"
#include "PaladinActions.h"
#include "PriestActions.h"
#include "RaidIccActions.h"
#include "ReachTargetActions.h"
#include "RogueActions.h"
#include "ScriptedCreature.h"
#include "ShamanActions.h"
#include "UseMeetingStoneAction.h"
#include "WarriorActions.h"
#include "PlayerbotAI.h"
float IccLadyDeathwhisperMultiplier::GetValue(Action* action)
{
Unit* boss = AI_VALUE2(Unit*, "find target", "lady deathwhisper");
if (!boss)
{
return 1.0f;
}
if (dynamic_cast<CombatFormationMoveAction*>(action) || dynamic_cast<FollowAction*>(action))
{
return 0.0f;
}
return 1.0f;
}
float IccAddsDbsMultiplier::GetValue(Action* action)
{
Unit* boss = AI_VALUE2(Unit*, "find target", "deathbringer saurfang");
if (!boss)
{
return 1.0f;
}
if (dynamic_cast<CombatFormationMoveAction*>(action) || dynamic_cast<FollowAction*>(action))
{
return 0.0f;
}
if (botAI->IsMainTank(bot))
{
Aura* aura = botAI->GetAura("rune of blood", bot);
if (aura)
{
if (dynamic_cast<CastTauntAction*>(action) || dynamic_cast<CastDarkCommandAction*>(action) ||
dynamic_cast<CastHandOfReckoningAction*>(action) || dynamic_cast<CastGrowlAction*>(action))
{
return 0.0f;
}
}
}
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;
}
float IccDogsMultiplier::GetValue(Action* action)
{
bool bossPresent = false;
if (AI_VALUE2(Unit*, "find target", "stinky") || AI_VALUE2(Unit*, "find target", "precious"))
bossPresent = true;
if (!bossPresent)
return 1.0f;
if (botAI->IsMainTank(bot))
{
Aura* aura = botAI->GetAura("mortal wound", bot, false, true);
if (aura && aura->GetStackAmount() >= 8)
{
if (dynamic_cast<CastTauntAction*>(action) || dynamic_cast<CastDarkCommandAction*>(action) ||
dynamic_cast<CastHandOfReckoningAction*>(action) || dynamic_cast<CastGrowlAction*>(action))
{
return 0.0f;
}
}
}
return 1.0f;
}
float IccFestergutMultiplier::GetValue(Action* action)
{
Unit* boss = AI_VALUE2(Unit*, "find target", "festergut");
if (!boss)
{
return 1.0f;
}
if (dynamic_cast<CombatFormationMoveAction*>(action) || dynamic_cast<FollowAction*>(action))
{
return 0.0f;
}
if (botAI->IsMainTank(bot))
{
Aura* aura = botAI->GetAura("gastric bloat", bot, false, true);
if (aura && aura->GetStackAmount() >= 6)
{
if (dynamic_cast<CastTauntAction*>(action) || dynamic_cast<CastDarkCommandAction*>(action) ||
dynamic_cast<CastHandOfReckoningAction*>(action) || dynamic_cast<CastGrowlAction*>(action))
{
return 0.0f;
}
}
}
if (bot->HasAura(69279) && (bot->getClass() == CLASS_HUNTER))
{
if (dynamic_cast<DpsAssistAction*>(action) || dynamic_cast<TankAssistAction*>(action) ||
dynamic_cast<CastDebuffSpellOnAttackerAction*>(action) || dynamic_cast<CombatFormationMoveAction*>(action) ||
dynamic_cast<FleeAction*>(action))
{
return 0.0f;
}
}
return 1.0f;
}
float IccRotfaceMultiplier::GetValue(Action* action)
{
// If we're already executing the escape movement, don't interrupt it
if (dynamic_cast<IccRotfaceMoveAwayFromExplosionAction*>(action))
return 1.0f;
Unit* boss = AI_VALUE2(Unit*, "find target", "big ooze");
if (!boss) { return 1.0f; }
if (dynamic_cast<CombatFormationMoveAction*>(action) || dynamic_cast<FollowAction*>(action))
{
return 0.0f;
}
if (dynamic_cast<FleeAction*>(action))
{
return 0.0f;
}
static std::map<ObjectGuid, uint32> lastExplosionTimes;
static std::map<ObjectGuid, bool> hasMoved;
ObjectGuid botGuid = bot->GetGUID();
// When cast starts, record the time
if (boss->HasUnitState(UNIT_STATE_CASTING) && boss->FindCurrentSpellBySpellId(69839))
{
if (lastExplosionTimes[botGuid] == 0) // Only set if not already set
{
lastExplosionTimes[botGuid] = time(nullptr);
hasMoved[botGuid] = false;
}
}
// If explosion cast is no longer active, reset the timers
if (!boss->HasUnitState(UNIT_STATE_CASTING) || !boss->FindCurrentSpellBySpellId(69839))
{
if (lastExplosionTimes[botGuid] > 0 && time(nullptr) - lastExplosionTimes[botGuid] >= 16)
{
lastExplosionTimes[botGuid] = 0;
hasMoved[botGuid] = false;
return 1.0f; // Allow normal actions to resume
}
}
// If 9 seconds have passed since cast start and we haven't moved yet
if (lastExplosionTimes[botGuid] > 0 && !hasMoved[botGuid] && time(nullptr) - lastExplosionTimes[botGuid] >= 9)
{
if (dynamic_cast<MovementAction*>(action)
&& !dynamic_cast<IccRotfaceMoveAwayFromExplosionAction*>(action))
{
return 0.0f; // Block other movement actions
}
hasMoved[botGuid] = true; // Mark that we've initiated movement
}
// Continue blocking other movements for 7 seconds after moving
if (hasMoved[botGuid] && time(nullptr) - lastExplosionTimes[botGuid] < 16 // 9 seconds wait + 7 seconds stay
&& dynamic_cast<MovementAction*>(action)
&& !dynamic_cast<IccRotfaceMoveAwayFromExplosionAction*>(action))
{
return 0.0f;
}
return 1.0f;
}
/*float IccRotfaceGroupPositionMultiplier::GetValue(Action* action)
{
if (dynamic_cast<IccRotfaceGroupPositionAction*>(action))
return 1.0f;
if (dynamic_cast<CombatFormationMoveAction*>(action))
return 0.0f;
return 1.0f;
}*/
float IccAddsPutricideMultiplier::GetValue(Action* action)
{
Unit* boss = AI_VALUE2(Unit*, "find target", "professor putricide");
if (!boss)
{
return 1.0f;
}
if (botAI->IsMainTank(bot))
{
Aura* aura = botAI->GetAura("mutated plague", bot, false, true);
if (aura && aura->GetStackAmount() >= 4)
{
if (dynamic_cast<CastTauntAction*>(action) || dynamic_cast<CastDarkCommandAction*>(action) ||
dynamic_cast<CastHandOfReckoningAction*>(action) || dynamic_cast<CastGrowlAction*>(action))
{
return 0.0f;
}
}
}
if (dynamic_cast<IccPutricideVolatileOozeAction*>(action) || dynamic_cast<IccPutricideGasCloudAction*>(action))
{
if (dynamic_cast<AvoidMalleableGooAction*>(action))
return 0.0f;
}
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->GetEntry() == 37697 || unit->GetEntry() == 38604 || unit->GetEntry() == 38758 || unit->GetEntry() == 38759 ||//volatile ooze
unit->GetEntry() == 37562 || unit->GetEntry() == 38602 || unit->GetEntry() == 38760 || unit->GetEntry() == 38761)) //gas cloud
{
hasAdds = true;
break;
}
}
if (hasAdds)
{
if (dynamic_cast<IccPutricideVolatileOozeAction*>(action) || dynamic_cast<IccPutricideGasCloudAction*>(action))
return 2.0f;
else if (dynamic_cast<DpsAssistAction*>(action) || dynamic_cast<TankAssistAction*>(action))
return 0.0f;
}
}
return 1.0f;
}
//bpc
float IccBpcAssistMultiplier::GetValue(Action* action)
{
if (!action)
return 1.0f;
Unit* keleseth = AI_VALUE2(Unit*, "find target", "prince keleseth");
if (!keleseth || !keleseth->IsAlive())
return 1.0f;
// For assist tank during BPC fight
if (botAI->IsAssistTank(bot))
{
// Allow BPC-specific actions
if (dynamic_cast<IccBpcKelesethTankAction*>(action) ||
dynamic_cast<IccBpcNucleusAction*>(action))
return 1.0f;
// Disable normal assist behavior
if (dynamic_cast<TankAssistAction*>(action))
return 0.0f;
// Disable following
if (dynamic_cast<FollowAction*>(action))
return 0.0f;
}
return 1.0f;
}
//BQL
float IccBqlPactOfDarkfallenMultiplier::GetValue(Action* action)
{
if (!action)
return 1.0f;
if (action->getName() == "icc bql pact of darkfallen")
return 1.0f;
// If bot has Pact of Darkfallen aura, return 0 for all other actions
if (bot->HasAura(71340))
return 0.0f;
return 1.0f;
}
float IccBqlVampiricBiteMultiplier::GetValue(Action* action)
{
Unit* boss = AI_VALUE2(Unit*, "find target", "blood-queen lana'thel");
if (!boss)
return 1.0f;
if (bot->HasAura(70877) || bot->HasAura(71474)) // If bot has frenzied bloodthirst
{
if (dynamic_cast<IccBqlVampiricBiteAction*>(action))
return 5.0f; // Highest priority for bite action
else if (dynamic_cast<DpsAssistAction*>(action) ||
dynamic_cast<TankAssistAction*>(action) ||
dynamic_cast<CastDebuffSpellOnAttackerAction*>(action) ||
dynamic_cast<CombatFormationMoveAction*>(action))
return 0.0f; // Disable all formation/movement actions
else
return 0.0f; // Disable all other actions
}
return 1.0f;
}
//VDW
float IccValithriaDreamCloudMultiplier::GetValue(Action* action)
{
if (!bot->HasAura(70766))
return 1.0f;
// If bot is in dream state, prioritize cloud collection over other actions
if (bot->HasAura(70766) && dynamic_cast<IccValithriaDreamCloudAction*>(action))
return 2.0f;
else if (dynamic_cast<FollowAction*>(action))
return 0.0f;
return 1.0f;
}
//SINDRAGOSA
float IccSindragosaTankPositionMultiplier::GetValue(Action* action)
{
Unit* boss = AI_VALUE2(Unit*, "find target", "sindragosa");
if (!boss)
return 1.0f;
if (dynamic_cast<IccSindragosaTankPositionAction*>(action))
return 1.0f;
else if (dynamic_cast<CombatFormationMoveAction*>(action))
return 0.0f;
return 1.0f;
}
float IccSindragosaFrostBeaconMultiplier::GetValue(Action* action)
{
Unit* boss = AI_VALUE2(Unit*, "find target", "sindragosa");
if (!boss)
return 1.0f;
if (!dynamic_cast<IccSindragosaFrostBeaconAction*>(action))
return 1.0f;
// Highest priority if we have beacon
if (bot->HasAura(70126))
return 2.0f;
// Lower priority for non-beaconed players
float const MIN_SAFE_DISTANCE = 11.0f;
GuidVector members = AI_VALUE(GuidVector, "group members");
for (auto& member : members)
{
Unit* player = botAI->GetUnit(member);
if (!player || player->GetGUID() == bot->GetGUID())
continue;
if (player->HasAura(70126)) // Frost Beacon
{
float dist = bot->GetExactDist2d(player);
if (dist < MIN_SAFE_DISTANCE)
return 1.5f; // Medium priority if too close to beaconed player
}
}
return 1.0f;
}
float IccSindragosaBlisteringColdPriorityMultiplier::GetValue(Action* action)
{
Unit* boss = AI_VALUE2(Unit*, "find target", "sindragosa");
if (!boss)
return 1.0f;
// Check if boss is casting blistering cold (using both normal and heroic spell IDs)
if (boss->HasUnitState(UNIT_STATE_CASTING) &&
(boss->FindCurrentSpellBySpellId(70123) || boss->FindCurrentSpellBySpellId(71047) ||
boss->FindCurrentSpellBySpellId(71048) || boss->FindCurrentSpellBySpellId(71049)))
{
// If this is the blistering cold action, give it highest priority
if (dynamic_cast<IccSindragosaBlisteringColdAction*>(action) ||
dynamic_cast<IccSindragosaTankSwapPositionAction*>(action))
return 5.0f;
// Disable all other actions while blistering cold is casting
return 0.0f;
}
return 1.0f;
}
float IccSindragosaMysticBuffetMultiplier::GetValue(Action* action)
{
Unit* boss = AI_VALUE2(Unit*, "find target", "sindragosa");
if (!boss)
return 1.0f;
if (botAI->IsMainTank(bot))
{
Aura* aura = botAI->GetAura("mystic buffet", bot, false, true);
if (aura && aura->GetStackAmount() >= 8)
{
if (dynamic_cast<CastTauntAction*>(action) || dynamic_cast<CastDarkCommandAction*>(action) ||
dynamic_cast<CastHandOfReckoningAction*>(action) || dynamic_cast<CastGrowlAction*>(action))
{
return 0.0f;
}
}
}
if (boss->GetVictim() == bot)
return 1.0f;
// Only modify actions if we have buffet stacks
Aura* aura = bot->GetAura(70127);
Aura* aura2 = bot->GetAura(72528);
// Return normal priority if no auras or not enough stacks
if (!aura && !aura2)
return 1.0f;
bool hasEnoughStacks = (aura && aura->GetStackAmount() >= 3) || (aura2 && aura2->GetStackAmount() >= 3);
if (!hasEnoughStacks)
return 1.0f;
if (dynamic_cast<IccSindragosaMysticBuffetAction*>(action) ||
dynamic_cast<IccSindragosaTankSwapPositionAction*>(action))
return 5.0f;
else if (dynamic_cast<CombatFormationMoveAction*>(action) ||
dynamic_cast<IccSindragosaTankPositionAction*>(action)
|| dynamic_cast<FollowAction*>(action) || dynamic_cast<TankAssistAction*>(action))
return 0.0f;
return 1.0f;
}
float IccSindragosaFrostBombMultiplier::GetValue(Action* action)
{
if (!action || !bot || !bot->IsAlive())
return 1.0f;
Unit* boss = AI_VALUE2(Unit*, "find target", "sindragosa");
if (!boss)
return 1.0f;
float const MAX_REACTION_RANGE = 200.0f;
// Check if there's an active frost bomb marker within range
bool hasMarkerInRange = false;
float closestDist = std::numeric_limits<float>::max();
GuidVector npcs = AI_VALUE(GuidVector, "nearest hostile npcs");
for (auto& npc : npcs)
{
Unit* unit = botAI->GetUnit(npc);
if (!unit || !unit->IsAlive())
continue;
if (unit->HasAura(70022)) // Frost bomb visual
{
float dist = bot->GetDistance(unit);
if (dist <= MAX_REACTION_RANGE && dist < closestDist)
{
hasMarkerInRange = true;
closestDist = dist;
}
}
}
if (!hasMarkerInRange)
return 1.0f;
if (dynamic_cast<IccSindragosaFrostBombAction*>(action))
return 5.0f;
else if (dynamic_cast<CombatFormationMoveAction*>(action) ||
dynamic_cast<IccSindragosaTankPositionAction*>(action)
|| dynamic_cast<IccSindragosaBlisteringColdAction*>(action)
|| dynamic_cast<FollowAction*>(action))
return 0.0f;
return 1.0f;
}
float IccLichKingNecroticPlagueMultiplier::GetValue(Action* action)
{
// Allow plague movement action to proceed
if (dynamic_cast<IccLichKingNecroticPlagueAction*>(action))
return 1.0f;
// Block combat formation and cure actions by default
else if (dynamic_cast<CombatFormationMoveAction*>(action))
return 0.0f;
// Handle cure actions
if (dynamic_cast<CurePartyMemberAction*>(action))
{
static std::map<ObjectGuid, uint32> plagueTimes;
static std::map<ObjectGuid, bool> allowCure;
Unit* target = action->GetTarget();
if (!target || !target->IsPlayer())
return 0.0f;
ObjectGuid targetGuid = target->GetGUID();
uint32 currentTime = getMSTime();
// Check if target has plague
bool hasPlague = target->HasAura(70338) || target->HasAura(73785) ||
target->HasAura(73786) || target->HasAura(73787) ||
target->HasAura(70337) || target->HasAura(73912) ||
target->HasAura(73913) || target->HasAura(73914);
// If no plague, reset timers and block cure
if (!hasPlague)
{
plagueTimes.erase(targetGuid);
allowCure.erase(targetGuid);
return 0.0f;
}
// If we haven't seen this plague yet, start the timer
if (plagueTimes.find(targetGuid) == plagueTimes.end())
{
plagueTimes[targetGuid] = currentTime;
allowCure[targetGuid] = false;
return 0.0f;
}
// If we've already allowed cure for this plague instance, keep allowing it
if (allowCure[targetGuid])
{
return 1.0f;
}
// Check if enough time has passed
uint32 timeSincePlague = currentTime - plagueTimes[targetGuid];
if (timeSincePlague >= 3000)
{
allowCure[targetGuid] = true;
return 1.0f;
}
else
{
return 0.0f;
}
}
return 1.0f;
}
float IccLichKingAddsMultiplier::GetValue(Action* action)
{
Unit* boss = AI_VALUE2(Unit*, "find target", "the lich king");
if (!boss)
return 1.0f;
if (botAI->IsMainTank(bot) && dynamic_cast<IccLichKingWinterAction*>(action))
{
if (dynamic_cast<TankAssistAction*>(action))
return 0.0f;
}
if (botAI->IsAssistTank(bot))
{
// Allow BPC-specific actions
if (dynamic_cast<IccLichKingAddsAction*>(action))
return 1.0f;
// Disable normal assist behavior
if (dynamic_cast<TankAssistAction*>(action))
return 0.0f;
if (dynamic_cast<CurePartyMemberAction*>(action))
return 0.0f;
// Disable following
if (dynamic_cast<FollowAction*>(action))
return 0.0f;
}
return 1.0f;
}
//raging spirit, Ice sphere, valkyere shadowguard, sphere 36633 39305 39306 39307

View File

@@ -0,0 +1,152 @@
#ifndef _PLAYERBOT_RAIDICCMULTIPLIERS_H
#define _PLAYERBOT_RAIDICCMULTIPLIERS_H
#include "Multiplier.h"
//Lady Deathwhisper
class IccLadyDeathwhisperMultiplier : public Multiplier
{
public:
IccLadyDeathwhisperMultiplier(PlayerbotAI* ai) : Multiplier(ai, "icc lady deathwhisper") {}
virtual float GetValue(Action* action);
};
//DBS
class IccAddsDbsMultiplier : public Multiplier
{
public:
IccAddsDbsMultiplier(PlayerbotAI* ai) : Multiplier(ai, "icc adds dbs") {}
virtual float GetValue(Action* action);
};
//DOGS
class IccDogsMultiplier : public Multiplier
{
public:
IccDogsMultiplier(PlayerbotAI* ai) : Multiplier(ai, "icc dogs") {}
virtual float GetValue(Action* action);
};
//FESTERGUT
class IccFestergutMultiplier : public Multiplier
{
public:
IccFestergutMultiplier(PlayerbotAI* ai) : Multiplier(ai, "icc festergut") {}
virtual float GetValue(Action* action);
};
//ROTFACE
class IccRotfaceMultiplier : public Multiplier
{
public:
IccRotfaceMultiplier(PlayerbotAI* ai) : Multiplier(ai, "icc rotface") {}
virtual float GetValue(Action* action);
};
/*class IccRotfaceGroupPositionMultiplier : public Multiplier
{
public:
IccRotfaceGroupPositionMultiplier(PlayerbotAI* ai) : Multiplier(ai, "icc rotface group position") {}
virtual float GetValue(Action* action);
};*/
//PP
class IccAddsPutricideMultiplier : public Multiplier
{
public:
IccAddsPutricideMultiplier(PlayerbotAI* ai) : Multiplier(ai, "icc adds putricide") {}
virtual float GetValue(Action* action);
};
//BPC
class IccBpcAssistMultiplier : public Multiplier
{
public:
IccBpcAssistMultiplier(PlayerbotAI* botAI) : Multiplier(botAI, "icc bpc assist") {}
virtual float GetValue(Action* action);
};
//BQL
class IccBqlPactOfDarkfallenMultiplier : public Multiplier
{
public:
IccBqlPactOfDarkfallenMultiplier(PlayerbotAI* botAI) : Multiplier(botAI, "icc bql pact of darkfallen multiplier") {}
virtual float GetValue(Action* action) override;
};
class IccBqlVampiricBiteMultiplier : public Multiplier
{
public:
IccBqlVampiricBiteMultiplier(PlayerbotAI* ai) : Multiplier(ai, "icc bql vampiric bite") {}
virtual float GetValue(Action* action);
};
//VDW
class IccValithriaDreamCloudMultiplier : public Multiplier
{
public:
IccValithriaDreamCloudMultiplier(PlayerbotAI* ai) : Multiplier(ai, "icc valithria dream cloud") {}
virtual float GetValue(Action* action);
};
//SINDRAGOSA
class IccSindragosaTankPositionMultiplier : public Multiplier
{
public:
IccSindragosaTankPositionMultiplier(PlayerbotAI* ai) : Multiplier(ai, "icc sindragosa tank position") {}
virtual float GetValue(Action* action);
};
class IccSindragosaFrostBeaconMultiplier : public Multiplier
{
public:
IccSindragosaFrostBeaconMultiplier(PlayerbotAI* ai) : Multiplier(ai, "icc sindragosa frost beacon") {}
virtual float GetValue(Action* action);
};
/*class IccSindragosaFlyingMultiplier : public Multiplier
{
public:
IccSindragosaFlyingMultiplier(PlayerbotAI* ai) : Multiplier(ai, "icc sindragosa flying") {}
virtual float GetValue(Action* action);
};*/
class IccSindragosaMysticBuffetMultiplier : public Multiplier
{
public:
IccSindragosaMysticBuffetMultiplier(PlayerbotAI* ai) : Multiplier(ai, "icc sindragosa mystic buffet") {}
virtual float GetValue(Action* action);
};
class IccSindragosaBlisteringColdPriorityMultiplier : public Multiplier
{
public:
IccSindragosaBlisteringColdPriorityMultiplier(PlayerbotAI* ai) : Multiplier(ai, "sindragosa blistering cold priority") {}
virtual float GetValue(Action* action) override;
};
class IccSindragosaFrostBombMultiplier : public Multiplier
{
public:
IccSindragosaFrostBombMultiplier(PlayerbotAI* ai) : Multiplier(ai, "icc sindragosa frost bomb") {}
virtual float GetValue(Action* action);
};
class IccLichKingNecroticPlagueMultiplier : public Multiplier
{
public:
IccLichKingNecroticPlagueMultiplier(PlayerbotAI* ai) : Multiplier(ai, "icc lich king necrotic plague") {}
virtual float GetValue(Action* action);
};
class IccLichKingAddsMultiplier : public Multiplier
{
public:
IccLichKingAddsMultiplier(PlayerbotAI* ai) : Multiplier(ai, "icc lich king adds") {}
virtual float GetValue(Action* action);
};
#endif

View File

@@ -1,14 +1,192 @@
#include "RaidIccStrategy.h"
#include "Strategy.h"
#include "RaidIccMultipliers.h"
void RaidIccStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
{
triggers.push_back(new TriggerNode(
"icc gunship cannon near",
//Lord Marrogwar
triggers.push_back(new TriggerNode("icc lm tank position",
NextAction::array(0, new NextAction("icc lm tank position", ACTION_RAID + 5), nullptr)));
triggers.push_back(new TriggerNode("icc spike near",
NextAction::array(0, new NextAction("icc spike", ACTION_RAID + 5), nullptr)));
//Lady Deathwhisper
triggers.push_back(new TriggerNode("icc dark reckoning",
NextAction::array(0, new NextAction("icc dark reckoning", ACTION_MOVE + 5), nullptr)));
triggers.push_back(new TriggerNode("icc ranged position lady deathwhisper",
NextAction::array(0, new NextAction("icc ranged position lady deathwhisper", ACTION_MOVE + 2), nullptr)));
triggers.push_back(new TriggerNode("icc adds lady deathwhisper",
NextAction::array(0, new NextAction("icc adds lady deathwhisper", ACTION_RAID + 3), nullptr)));
triggers.push_back(new TriggerNode("icc shade lady deathwhisper",
NextAction::array(0, new NextAction("icc shade lady deathwhisper", ACTION_MOVE + 5), nullptr)));
//Gunship Battle
triggers.push_back(new TriggerNode("icc rotting frost giant tank position",
NextAction::array(0, new NextAction("icc rotting frost giant tank position", ACTION_RAID + 5), nullptr)));
triggers.push_back(new TriggerNode("icc gunship cannon near",
NextAction::array(0, new NextAction("icc gunship enter cannon", ACTION_RAID + 2), nullptr)));
triggers.push_back(
new TriggerNode("icc in cannon",
NextAction::array(0, new NextAction("icc cannon fire", ACTION_RAID), nullptr)));
}
triggers.push_back( new TriggerNode("icc in cannon",
NextAction::array(0, new NextAction("icc cannon fire", ACTION_RAID), nullptr)));
triggers.push_back(new TriggerNode("icc gunship teleport ally",
NextAction::array(0, new NextAction("icc gunship teleport ally", ACTION_RAID + 4), nullptr)));
triggers.push_back(new TriggerNode("icc gunship teleport horde",
NextAction::array(0, new NextAction("icc gunship teleport horde", ACTION_RAID + 4), nullptr)));
//DBS
triggers.push_back(new TriggerNode("icc dbs tank position",
NextAction::array(0, new NextAction("icc dbs tank position", ACTION_RAID + 3), nullptr)));
triggers.push_back(new TriggerNode("icc dbs main tank rune of blood",
NextAction::array(0, new NextAction("taunt spell", ACTION_EMERGENCY + 4), nullptr)));
triggers.push_back(new TriggerNode("icc adds dbs",
NextAction::array(0, new NextAction("icc adds dbs", ACTION_RAID + 5), nullptr)));
//DOGS
triggers.push_back(new TriggerNode("icc stinky precious main tank mortal wound",
NextAction::array(0, new NextAction("taunt spell", ACTION_EMERGENCY + 4), nullptr)));
//FESTERGUT
triggers.push_back(new TriggerNode("icc festergut tank position",
NextAction::array(0, new NextAction("icc festergut tank position", ACTION_MOVE + 4), nullptr)));
triggers.push_back(new TriggerNode("icc festergut main tank gastric bloat",
NextAction::array(0, new NextAction("taunt spell", ACTION_EMERGENCY + 6), nullptr)));
triggers.push_back(new TriggerNode("icc festergut spore",
NextAction::array(0, new NextAction("icc festergut spore", ACTION_MOVE + 5), nullptr)));
//ROTFACE
triggers.push_back(new TriggerNode("icc rotface tank position",
NextAction::array(0, new NextAction("icc rotface tank position", ACTION_RAID + 5), nullptr)));
triggers.push_back(new TriggerNode("icc rotface group position",
NextAction::array(0, new NextAction("icc rotface group position", ACTION_RAID + 6), nullptr)));
triggers.push_back(new TriggerNode("icc rotface move away from explosion",
NextAction::array(0, new NextAction("icc rotface move away from explosion", ACTION_RAID +7), nullptr)));
//PP
triggers.push_back(new TriggerNode("icc putricide volatile ooze",
NextAction::array(0, new NextAction("icc putricide volatile ooze", ACTION_EMERGENCY + 4), nullptr)));
triggers.push_back(new TriggerNode("icc putricide gas cloud",
NextAction::array(0, new NextAction("icc putricide gas cloud", ACTION_EMERGENCY + 5), nullptr)));
triggers.push_back(new TriggerNode("icc putricide growing ooze puddle",
NextAction::array(0, new NextAction("icc putricide growing ooze puddle", ACTION_EMERGENCY + 3), nullptr)));
triggers.push_back(new TriggerNode("icc putricide main tank mutated plague",
NextAction::array(0, new NextAction("taunt spell", ACTION_EMERGENCY + 6), nullptr)));
triggers.push_back(new TriggerNode("icc putricide malleable goo",
NextAction::array(0, new NextAction("avoid malleable goo", ACTION_EMERGENCY + 2), nullptr)));
//BPC
triggers.push_back(new TriggerNode("icc bpc keleseth tank",
NextAction::array(0, new NextAction("icc bpc keleseth tank", ACTION_EMERGENCY + 1), nullptr)));
triggers.push_back(new TriggerNode("icc bpc nucleus",
NextAction::array(0, new NextAction("icc bpc nucleus", ACTION_EMERGENCY + 3), nullptr)));
triggers.push_back(new TriggerNode("icc bpc main tank",
NextAction::array(0, new NextAction("icc bpc main tank", ACTION_EMERGENCY + 2), nullptr)));
triggers.push_back(new TriggerNode("icc bpc empowered vortex",
NextAction::array(0, new NextAction("icc bpc empowered vortex", ACTION_INTERRUPT), nullptr)));
//BQL
triggers.push_back(new TriggerNode("icc bql tank position",
NextAction::array(0, new NextAction("icc bql tank position", ACTION_RAID), nullptr)));
triggers.push_back(new TriggerNode("icc bql pact of darkfallen",
NextAction::array(0, new NextAction("icc bql pact of darkfallen", ACTION_EMERGENCY +1), nullptr)));
triggers.push_back(new TriggerNode("icc bql vampiric bite",
NextAction::array(0, new NextAction("icc bql vampiric bite", ACTION_EMERGENCY + 5), nullptr)));
//VDW
triggers.push_back(new TriggerNode("icc valkyre spear",
NextAction::array(0, new NextAction("icc valkyre spear", ACTION_EMERGENCY + 5), nullptr)));
triggers.push_back(new TriggerNode("icc sister svalna",
NextAction::array(0, new NextAction("icc sister svalna", ACTION_RAID + 5), nullptr)));
triggers.push_back(new TriggerNode("icc valithria portal",
NextAction::array(0, new NextAction("icc valithria portal", ACTION_RAID + 5), nullptr)));
triggers.push_back(new TriggerNode("icc valithria heal",
NextAction::array(0, new NextAction("icc valithria heal", ACTION_RAID+1), nullptr)));
triggers.push_back(new TriggerNode("icc valithria dream cloud",
NextAction::array(0, new NextAction("icc valithria dream cloud", ACTION_RAID + 4), nullptr)));
//SINDRAGOSA
triggers.push_back(new TriggerNode("icc sindragosa tank position",
NextAction::array(0, new NextAction("icc sindragosa tank position", ACTION_RAID + 1), nullptr)));
triggers.push_back(new TriggerNode("icc sindragosa frost beacon",
NextAction::array(0, new NextAction("icc sindragosa frost beacon", ACTION_RAID + 5), nullptr)));
triggers.push_back(new TriggerNode("icc sindragosa blistering cold",
NextAction::array(0, new NextAction("icc sindragosa blistering cold", ACTION_EMERGENCY + 4), nullptr)));
triggers.push_back(new TriggerNode("icc sindragosa unchained magic",
NextAction::array(0, new NextAction("icc sindragosa unchained magic", ACTION_RAID + 2), nullptr)));
triggers.push_back(new TriggerNode("icc sindragosa chilled to the bone",
NextAction::array(0, new NextAction("icc sindragosa chilled to the bone", ACTION_RAID + 2), nullptr)));
triggers.push_back(new TriggerNode("icc sindragosa mystic buffet",
NextAction::array(0, new NextAction("icc sindragosa mystic buffet", ACTION_RAID + 3), nullptr)));
triggers.push_back(new TriggerNode("icc sindragosa main tank mystic buffet",
NextAction::array(0, new NextAction("taunt spell", ACTION_EMERGENCY + 3), nullptr)));
triggers.push_back(new TriggerNode("icc sindragosa frost bomb",
NextAction::array(0, new NextAction("icc sindragosa frost bomb", ACTION_RAID + 7), nullptr)));
triggers.push_back(new TriggerNode("icc sindragosa tank swap position",
NextAction::array(0, new NextAction("icc sindragosa tank swap position", ACTION_EMERGENCY + 2), nullptr)));
//LICH KING
triggers.push_back(new TriggerNode("icc lich king necrotic plague",
NextAction::array(0, new NextAction("icc lich king necrotic plague", ACTION_EMERGENCY + 3), nullptr)));
triggers.push_back(new TriggerNode("icc lich king winter",
NextAction::array(0, new NextAction("icc lich king winter", ACTION_RAID +1), nullptr)));
triggers.push_back(new TriggerNode("icc lich king adds",
NextAction::array(0, new NextAction("icc lich king adds", ACTION_RAID +2), nullptr)));
}
void RaidIccStrategy::InitMultipliers(std::vector<Multiplier*>& multipliers)
{
multipliers.push_back(new IccLadyDeathwhisperMultiplier(botAI));
multipliers.push_back(new IccAddsDbsMultiplier(botAI));
multipliers.push_back(new IccDogsMultiplier(botAI));
multipliers.push_back(new IccFestergutMultiplier(botAI));
multipliers.push_back(new IccRotfaceMultiplier(botAI));
//multipliers.push_back(new IccRotfaceGroupPositionMultiplier(botAI));
multipliers.push_back(new IccAddsPutricideMultiplier(botAI));
multipliers.push_back(new IccBpcAssistMultiplier(botAI));
multipliers.push_back(new IccBqlPactOfDarkfallenMultiplier(botAI));
multipliers.push_back(new IccBqlVampiricBiteMultiplier(botAI));
multipliers.push_back(new IccValithriaDreamCloudMultiplier(botAI));
multipliers.push_back(new IccSindragosaTankPositionMultiplier(botAI));
multipliers.push_back(new IccSindragosaFrostBeaconMultiplier(botAI));
//multipliers.push_back(new IccSindragosaFlyingMultiplier(botAI));
multipliers.push_back(new IccSindragosaMysticBuffetMultiplier(botAI));
multipliers.push_back(new IccSindragosaBlisteringColdPriorityMultiplier(botAI));
multipliers.push_back(new IccSindragosaFrostBombMultiplier(botAI));
multipliers.push_back(new IccLichKingNecroticPlagueMultiplier(botAI));
multipliers.push_back(new IccLichKingAddsMultiplier(botAI));
}

View File

@@ -4,6 +4,7 @@
#include "AiObjectContext.h"
#include "Multiplier.h"
#include "Strategy.h"
#include "RaidIccMultipliers.h"
class RaidIccStrategy : public Strategy
{
@@ -11,7 +12,7 @@ public:
RaidIccStrategy(PlayerbotAI* ai) : Strategy(ai) {}
virtual std::string const getName() override { return "icc"; }
virtual void InitTriggers(std::vector<TriggerNode*>& triggers) override;
// virtual void InitMultipliers(std::vector<Multiplier*> &multipliers) override;
virtual void InitMultipliers(std::vector<Multiplier*> &multipliers) override;
};
#endif

View File

@@ -10,13 +10,110 @@ class RaidIccTriggerContext : public NamedObjectContext<Trigger>
public:
RaidIccTriggerContext()
{
creators["icc lm tank position"] = &RaidIccTriggerContext::icc_lm_tank_position;
creators["icc spike near"] = &RaidIccTriggerContext::icc_spike_near;
creators["icc dark reckoning"] = &RaidIccTriggerContext::icc_dark_reckoning;
creators["icc ranged position lady deathwhisper"] = &RaidIccTriggerContext::icc_ranged_position_lady_deathwhisper;
creators["icc adds lady deathwhisper"] = &RaidIccTriggerContext::icc_adds_lady_deathwhisper;
creators["icc shade lady deathwhisper"] = &RaidIccTriggerContext::icc_shade_lady_deathwhisper;
creators["icc rotting frost giant tank position"] = &RaidIccTriggerContext::icc_rotting_frost_giant_tank_position;
creators["icc in cannon"] = &RaidIccTriggerContext::icc_in_cannon;
creators["icc gunship cannon near"] = &RaidIccTriggerContext::icc_gunship_cannon_near;
creators["icc gunship teleport ally"] = &RaidIccTriggerContext::icc_gunship_teleport_ally;
creators["icc gunship teleport horde"] = &RaidIccTriggerContext::icc_gunship_teleport_horde;
creators["icc dbs tank position"] = &RaidIccTriggerContext::icc_dbs_tank_position;
creators["icc dbs main tank rune of blood"] = &RaidIccTriggerContext::icc_dbs_main_tank_rune_of_blood;
creators["icc adds dbs"] = &RaidIccTriggerContext::icc_adds_dbs;
creators["icc stinky precious main tank mortal wound"] = &RaidIccTriggerContext::icc_stinky_precious_main_tank_mortal_wound;
creators["icc festergut tank position"] = &RaidIccTriggerContext::icc_festergut_tank_position;
creators["icc festergut main tank gastric bloat"] = &RaidIccTriggerContext::icc_festergut_main_tank_gastric_bloat;
creators["icc festergut spore"] = &RaidIccTriggerContext::icc_festergut_spore;
creators["icc rotface tank position"] = &RaidIccTriggerContext::icc_rotface_tank_position;
creators["icc rotface group position"] = &RaidIccTriggerContext::icc_rotface_group_position;
creators["icc rotface move away from explosion"] = &RaidIccTriggerContext::icc_rotface_move_away_from_explosion;
creators["icc putricide volatile ooze"] = &RaidIccTriggerContext::icc_putricide_volatile_ooze;
creators["icc putricide gas cloud"] = &RaidIccTriggerContext::icc_putricide_gas_cloud;
creators["icc putricide growing ooze puddle"] = &RaidIccTriggerContext::icc_putricide_growing_ooze_puddle;
creators["icc putricide main tank mutated plague"] = &RaidIccTriggerContext::icc_putricide_main_tank_mutated_plague;
creators["icc putricide malleable goo"] = &RaidIccTriggerContext::icc_putricide_malleable_goo;
creators["icc bpc keleseth tank"] = &RaidIccTriggerContext::icc_bpc_keleseth_tank;
creators["icc bpc nucleus"] = &RaidIccTriggerContext::icc_bpc_nucleus;
creators["icc bpc main tank"] = &RaidIccTriggerContext::icc_bpc_main_tank;
creators["icc bpc empowered vortex"] = &RaidIccTriggerContext::icc_bpc_empowered_vortex;
creators["icc bql tank position"] = &RaidIccTriggerContext::icc_bql_tank_position;
creators["icc bql pact of darkfallen"] = &RaidIccTriggerContext::icc_bql_pact_of_darkfallen;
creators["icc bql vampiric bite"] = &RaidIccTriggerContext::icc_bql_vampiric_bite;
creators["icc valkyre spear"] = &RaidIccTriggerContext::icc_valkyre_spear;
creators["icc sister svalna"] = &RaidIccTriggerContext::icc_sister_svalna;
creators["icc valithria portal"] = &RaidIccTriggerContext::icc_valithria_portal;
creators["icc valithria heal"] = &RaidIccTriggerContext::icc_valithria_heal;
creators["icc valithria dream cloud"] = &RaidIccTriggerContext::icc_valithria_dream_cloud;
creators["icc sindragosa tank position"] = &RaidIccTriggerContext::icc_sindragosa_tank_position;
creators["icc sindragosa frost beacon"] = &RaidIccTriggerContext::icc_sindragosa_frost_beacon;
creators["icc sindragosa blistering cold"] = &RaidIccTriggerContext::icc_sindragosa_blistering_cold;
creators["icc sindragosa unchained magic"] = &RaidIccTriggerContext::icc_sindragosa_unchained_magic;
creators["icc sindragosa chilled to the bone"] = &RaidIccTriggerContext::icc_sindragosa_chilled_to_the_bone;
creators["icc sindragosa mystic buffet"] = &RaidIccTriggerContext::icc_sindragosa_mystic_buffet;
creators["icc sindragosa main tank mystic buffet"] = &RaidIccTriggerContext::icc_sindragosa_main_tank_mystic_buffet;
creators["icc sindragosa frost bomb"] = &RaidIccTriggerContext::icc_sindragosa_frost_bomb;
creators["icc sindragosa tank swap position"] = &RaidIccTriggerContext::icc_sindragosa_tank_swap_position;
creators["icc lich king necrotic plague"] = &RaidIccTriggerContext::icc_lich_king_necrotic_plague;
creators["icc lich king winter"] = &RaidIccTriggerContext::icc_lich_king_winter;
creators["icc lich king adds"] = &RaidIccTriggerContext::icc_lich_king_adds;
}
private:
static Trigger* icc_lm_tank_position(PlayerbotAI* ai) { return new IccLmTankPositionTrigger(ai); }
static Trigger* icc_spike_near(PlayerbotAI* ai) { return new IccSpikeNearTrigger(ai); }
static Trigger* icc_dark_reckoning(PlayerbotAI* ai) { return new IccDarkReckoningTrigger(ai); }
static Trigger* icc_ranged_position_lady_deathwhisper(PlayerbotAI* ai) { return new IccRangedPositionLadyDeathwhisperTrigger(ai); }
static Trigger* icc_adds_lady_deathwhisper(PlayerbotAI* ai) { return new IccAddsLadyDeathwhisperTrigger(ai); }
static Trigger* icc_shade_lady_deathwhisper(PlayerbotAI* ai) { return new IccShadeLadyDeathwhisperTrigger(ai); }
static Trigger* icc_rotting_frost_giant_tank_position(PlayerbotAI* ai) { return new IccRottingFrostGiantTankPositionTrigger(ai); }
static Trigger* icc_in_cannon(PlayerbotAI* ai) { return new IccInCannonTrigger(ai); }
static Trigger* icc_gunship_cannon_near(PlayerbotAI* ai) { return new IccGunshipCannonNearTrigger(ai); }
static Trigger* icc_gunship_teleport_ally(PlayerbotAI* ai) { return new IccGunshipTeleportAllyTrigger(ai); }
static Trigger* icc_gunship_teleport_horde(PlayerbotAI* ai) { return new IccGunshipTeleportHordeTrigger(ai); }
static Trigger* icc_dbs_tank_position(PlayerbotAI* ai) { return new IccDbsTankPositionTrigger(ai); }
static Trigger* icc_dbs_main_tank_rune_of_blood(PlayerbotAI* ai) { return new IccDbsMainTankRuneOfBloodTrigger(ai); }
static Trigger* icc_adds_dbs(PlayerbotAI* ai) { return new IccAddsDbsTrigger(ai); }
static Trigger* icc_stinky_precious_main_tank_mortal_wound(PlayerbotAI* ai) { return new IccStinkyPreciousMainTankMortalWoundTrigger(ai); }
static Trigger* icc_festergut_tank_position(PlayerbotAI* ai) { return new IccFestergutTankPositionTrigger(ai); }
static Trigger* icc_festergut_main_tank_gastric_bloat(PlayerbotAI* ai) { return new IccFestergutMainTankGastricBloatTrigger(ai); }
static Trigger* icc_festergut_spore(PlayerbotAI* ai) { return new IccFestergutSporeTrigger(ai); }
static Trigger* icc_rotface_tank_position(PlayerbotAI* ai) { return new IccRotfaceTankPositionTrigger(ai); }
static Trigger* icc_rotface_group_position(PlayerbotAI* ai) { return new IccRotfaceGroupPositionTrigger(ai); }
static Trigger* icc_rotface_move_away_from_explosion(PlayerbotAI* ai) { return new IccRotfaceMoveAwayFromExplosionTrigger(ai); }
static Trigger* icc_putricide_volatile_ooze(PlayerbotAI* ai) { return new IccPutricideVolatileOozeTrigger(ai); }
static Trigger* icc_putricide_gas_cloud(PlayerbotAI* ai) { return new IccPutricideGasCloudTrigger(ai); }
static Trigger* icc_putricide_growing_ooze_puddle(PlayerbotAI* ai) { return new IccPutricideGrowingOozePuddleTrigger(ai); }
static Trigger* icc_putricide_main_tank_mutated_plague(PlayerbotAI* ai) { return new IccPutricideMainTankMutatedPlagueTrigger(ai); }
static Trigger* icc_putricide_malleable_goo(PlayerbotAI* ai) { return new IccPutricideMalleableGooTrigger(ai); }
static Trigger* icc_bpc_keleseth_tank(PlayerbotAI* ai) { return new IccBpcKelesethTankTrigger(ai); }
static Trigger* icc_bpc_nucleus(PlayerbotAI* ai) { return new IccBpcNucleusTrigger(ai); }
static Trigger* icc_bpc_main_tank(PlayerbotAI* ai) { return new IccBpcMainTankTrigger(ai); }
static Trigger* icc_bpc_empowered_vortex(PlayerbotAI* ai) { return new IccBpcEmpoweredVortexTrigger(ai); }
static Trigger* icc_bql_tank_position(PlayerbotAI* ai) { return new IccBqlTankPositionTrigger(ai); }
static Trigger* icc_bql_pact_of_darkfallen(PlayerbotAI* ai) { return new IccBqlPactOfDarkfallenTrigger(ai); }
static Trigger* icc_bql_vampiric_bite(PlayerbotAI* ai) { return new IccBqlVampiricBiteTrigger(ai); }
static Trigger* icc_valkyre_spear(PlayerbotAI* ai) { return new IccValkyreSpearTrigger(ai); }
static Trigger* icc_sister_svalna(PlayerbotAI* ai) { return new IccSisterSvalnaTrigger(ai); }
static Trigger* icc_valithria_portal(PlayerbotAI* ai) { return new IccValithriaPortalTrigger(ai); }
static Trigger* icc_valithria_heal(PlayerbotAI* ai) { return new IccValithriaHealTrigger(ai); }
static Trigger* icc_valithria_dream_cloud(PlayerbotAI* ai) { return new IccValithriaDreamCloudTrigger(ai); }
static Trigger* icc_sindragosa_tank_position(PlayerbotAI* ai) { return new IccSindragosaTankPositionTrigger(ai); }
static Trigger* icc_sindragosa_frost_beacon(PlayerbotAI* ai) { return new IccSindragosaFrostBeaconTrigger(ai); }
static Trigger* icc_sindragosa_blistering_cold(PlayerbotAI* ai) { return new IccSindragosaBlisteringColdTrigger(ai); }
static Trigger* icc_sindragosa_unchained_magic(PlayerbotAI* ai) { return new IccSindragosaUnchainedMagicTrigger(ai); }
static Trigger* icc_sindragosa_chilled_to_the_bone(PlayerbotAI* ai) { return new IccSindragosaChilledToTheBoneTrigger(ai); }
static Trigger* icc_sindragosa_mystic_buffet(PlayerbotAI* ai) { return new IccSindragosaMysticBuffetTrigger(ai); }
static Trigger* icc_sindragosa_main_tank_mystic_buffet(PlayerbotAI* ai) { return new IccSindragosaMainTankMysticBuffetTrigger(ai); }
static Trigger* icc_sindragosa_frost_bomb(PlayerbotAI* ai) { return new IccSindragosaFrostBombTrigger(ai); }
static Trigger* icc_sindragosa_tank_swap_position(PlayerbotAI* ai) { return new IccSindragosaTankSwapPositionTrigger(ai); }
static Trigger* icc_lich_king_necrotic_plague(PlayerbotAI* ai) { return new IccLichKingNecroticPlagueTrigger(ai); }
static Trigger* icc_lich_king_winter(PlayerbotAI* ai) { return new IccLichKingWinterTrigger(ai); }
static Trigger* icc_lich_king_adds(PlayerbotAI* ai) { return new IccLichKingAddsTrigger(ai); }
};
#endif

View File

@@ -1,4 +1,107 @@
#include "RaidIccTriggers.h"
#include "RaidIccActions.h"
#include "PlayerbotAIConfig.h"
#include "GenericTriggers.h"
#include "DungeonStrategyUtils.h"
#include "EventMap.h"
#include "Playerbots.h"
#include "ScriptedCreature.h"
#include "Trigger.h"
//Lord Marrogwar
bool IccLmTankPositionTrigger::IsActive()
{
Unit* boss = AI_VALUE2(Unit*, "find target", "lord marrowgar");
if (!boss) { return false; }
return botAI->IsTank(bot);
}
bool IccSpikeNearTrigger::IsActive()
{
Unit* boss = AI_VALUE2(Unit*, "find target", "lord marrowgar");
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;
}
//Lady Deathwhisper
bool IccDarkReckoningTrigger::IsActive()
{
Unit* add = AI_VALUE2(Unit*, "find target", "deathspeaker high priest");
if (add || bot->HasAura(69483))
return true;
return false;
}
bool IccRangedPositionLadyDeathwhisperTrigger::IsActive()
{
Unit* boss = AI_VALUE2(Unit*, "find target", "lady deathwhisper");
if (!boss)
return false;
return (botAI->IsRangedDps(bot) || botAI->IsHeal(bot));
}
bool IccAddsLadyDeathwhisperTrigger::IsActive()
{
Unit* boss = AI_VALUE2(Unit*, "find target", "lady deathwhisper");
if (!boss) { return false; }
return true;
}
bool IccShadeLadyDeathwhisperTrigger::IsActive()
{
Unit* boss = AI_VALUE2(Unit*, "find target", "lady deathwhisper");
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() == 38222 ) //vengeful sahde ID
{
return true;
}
}
}
return false;
}
//Gunship Battle
bool IccRottingFrostGiantTankPositionTrigger::IsActive()
{
Unit* boss = AI_VALUE2(Unit*, "find target", "rotting frost giant");
if (!boss) { return false; }
return true;
}
bool IccInCannonTrigger::IsActive()
{
@@ -27,3 +130,620 @@ bool IccGunshipCannonNearTrigger::IsActive()
return true;
}
bool IccGunshipTeleportAllyTrigger::IsActive()
{
Unit* boss = AI_VALUE2(Unit*, "find target", "kor'kron battle-mage");
if (!boss) { return false; }
return true;
}
bool IccGunshipTeleportHordeTrigger::IsActive()
{
Unit* boss = AI_VALUE2(Unit*, "find target", "skybreaker sorcerer");
if (!boss) { return false; }
return true;
}
//DBS
bool IccDbsTankPositionTrigger::IsActive()
{
Unit* boss = AI_VALUE2(Unit*, "find target", "deathbringer saurfang");
if (!boss) { return false; }
return true;
}
bool IccDbsMainTankRuneOfBloodTrigger::IsActive()
{
Unit* boss = AI_VALUE2(Unit*, "find target", "deathbringer saurfang");
if (!boss)
return false;
if (!botAI->IsAssistTankOfIndex(bot, 0))
return false;
Unit* mt = AI_VALUE(Unit*, "main tank");
if (!mt)
return false;
Aura* aura = botAI->GetAura("rune of blood", mt);
if (!aura)
return false;
return true;
}
bool IccAddsDbsTrigger::IsActive()
{
Unit* boss = AI_VALUE2(Unit*, "find target", "deathbringer saurfang");
if (!boss) { return false; }
return true;
}
//DOGS
bool IccStinkyPreciousMainTankMortalWoundTrigger::IsActive()
{
bool bossPresent = false;
if (AI_VALUE2(Unit*, "find target", "stinky") || AI_VALUE2(Unit*, "find target", "precious"))
bossPresent = true;
if (!bossPresent)
return false;
if (!botAI->IsAssistTankOfIndex(bot, 0))
{
return false;
}
Unit* mt = AI_VALUE(Unit*, "main tank");
if (!mt)
{
return false;
}
Aura* aura = botAI->GetAura("mortal wound", mt, false, true);
if (!aura || aura->GetStackAmount() < 8)
{
return false;
}
return true;
}
//FESTERGUT
bool IccFestergutTankPositionTrigger::IsActive()
{
Unit* boss = AI_VALUE2(Unit*, "find target", "festergut");
if (!boss || !(botAI->IsTank(bot) || botAI->IsRanged(bot) || botAI->IsHeal(bot)))
return false;
return true;
}
bool IccFestergutMainTankGastricBloatTrigger::IsActive()
{
Unit* boss = AI_VALUE2(Unit*, "find target", "festergut");
if (!boss)
{
return false;
}
if (!botAI->IsAssistTankOfIndex(bot, 0))
{
return false;
}
Unit* mt = AI_VALUE(Unit*, "main tank");
if (!mt)
{
return false;
}
Aura* aura = botAI->GetAura("Gastric Bloat", mt, false, true);
if (!aura || aura->GetStackAmount() < 6)
{
return false;
}
return true;
}
bool IccFestergutSporeTrigger::IsActive()
{
Unit* boss = AI_VALUE2(Unit*, "find target", "festergut");
if (!boss || botAI->IsTank(bot))
return false;
// Check for spore aura (ID: 69279) on any bot in the group
Group* group = bot->GetGroup();
if (!group)
return false;
for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
{
Player* member = itr->GetSource();
if (!member)
continue;
if (member->HasAura(69279)) // Spore aura ID
return true;
}
return false;
}
//ROTFACE
bool IccRotfaceTankPositionTrigger::IsActive()
{
Unit* boss = AI_VALUE2(Unit*, "find target", "rotface");
if (!boss || !(botAI->IsTank(bot) || botAI->IsMainTank(bot) || botAI->IsAssistTank(bot))) { return false; }
return true;
}
bool IccRotfaceGroupPositionTrigger::IsActive()
{
Unit* boss = AI_VALUE2(Unit*, "find target", "rotface");
if (!boss) { return false; }
return true;
}
bool IccRotfaceMoveAwayFromExplosionTrigger::IsActive()
{
Unit* boss = AI_VALUE2(Unit*, "find target", "big ooze");
if (!boss) { return false; }
return boss->HasUnitState(UNIT_STATE_CASTING) && boss->FindCurrentSpellBySpellId(69839);
}
//PP
bool IccPutricideGrowingOozePuddleTrigger::IsActive()
{
Unit* boss = AI_VALUE2(Unit*, "find target", "professor putricide");
bool botHasAura = botAI->HasAura("Gaseous Bloat", bot);
if (!boss || botHasAura)
return false;
return true;
}
bool IccPutricideVolatileOozeTrigger::IsActive()
{
Unit* boss = AI_VALUE2(Unit*, "find target", "volatile ooze");
if (!boss) { return false; }
return true;
}
bool IccPutricideGasCloudTrigger::IsActive()
{
Unit* boss = AI_VALUE2(Unit*, "find target", "gas cloud");
if (!boss) { return false; }
return true;
}
bool IccPutricideMainTankMutatedPlagueTrigger::IsActive()
{
bool bossPresent = false;
if (AI_VALUE2(Unit*, "find target", "professor putricide"))
bossPresent = true;
if (!bossPresent)
return false;
if (!botAI->IsAssistTankOfIndex(bot, 0))
{
return false;
}
Unit* mt = AI_VALUE(Unit*, "main tank");
if (!mt)
{
return false;
}
Aura* aura = botAI->GetAura("Mutated Plague", mt, false, true);
if (!aura || aura->GetStackAmount() < 4)
{
return false;
}
return true;
}
bool IccPutricideMalleableGooTrigger::IsActive()
{
Unit* boss = AI_VALUE2(Unit*, "find target", "professor putricide");
if (!boss)
return false;
Unit* boss1 = AI_VALUE2(Unit*, "find target", "volatile ooze");
if (boss1)
return false;
Unit* boss2 = AI_VALUE2(Unit*, "find target", "gas cloud");
if (boss2)
return false;
return true;
}
//BPC
bool IccBpcKelesethTankTrigger::IsActive()
{
if (!botAI->IsAssistTank(bot))
return false;
// First priority is to check for nucleuses that need to be picked up
GuidVector targets = AI_VALUE(GuidVector, "possible targets");
for (auto i = targets.begin(); i != targets.end(); ++i)
{
Unit* unit = botAI->GetUnit(*i);
if (unit && unit->IsAlive() && unit->GetEntry() == 38369) // Dark Nucleus entry
{
if (!unit->GetVictim() || unit->GetVictim() != bot)
return false; // Don't tank Keleseth if there's a nucleus to grab
}
}
Unit* boss = AI_VALUE2(Unit*, "find target", "prince keleseth");
if (!boss || boss->GetEntry() != 37972) // Verify it's actually Keleseth
return false;
return true;
}
bool IccBpcNucleusTrigger::IsActive()
{
if (!botAI->IsAssistTank(bot))
return false;
// Actively look for any nucleus that isn't targeting us
GuidVector targets = AI_VALUE(GuidVector, "possible targets");
for (auto i = targets.begin(); i != targets.end(); ++i)
{
Unit* unit = botAI->GetUnit(*i);
if (unit && unit->IsAlive() && unit->GetEntry() == 38369) // Dark Nucleus entry
{
if (!unit->GetVictim() || unit->GetVictim() != bot)
return true; // Found a nucleus that needs to be picked up
}
}
return false;
}
bool IccBpcMainTankTrigger::IsActive()
{
if (!botAI->IsMainTank(bot))
return false;
Unit* valanar = AI_VALUE2(Unit*, "find target", "prince valanar");
Unit* taldaram = AI_VALUE2(Unit*, "find target", "prince taldaram");
return valanar != nullptr || taldaram != nullptr;
}
bool IccBpcEmpoweredVortexTrigger::IsActive()
{
// Tanks should ignore this mechanic
if (botAI->IsMainTank(bot) || botAI->IsAssistTank(bot))
return false;
Unit* valanar = AI_VALUE2(Unit*, "find target", "prince valanar");
if (!valanar || !valanar->IsAlive())
return false;
// For ranged, spread whenever Valanar is empowered
if (botAI->IsRanged(bot))
return valanar->HasAura(70952); // Invocation of Blood
// For melee, only spread during vortex cast
if (valanar->HasAura(70952) && // Invocation of Blood
valanar->GetCurrentSpell(CURRENT_GENERIC_SPELL) &&
valanar->GetCurrentSpell(CURRENT_GENERIC_SPELL)->m_spellInfo->Id == 72039)
{
return true;
}
return false;
}
//BQL
bool IccBqlTankPositionTrigger::IsActive()
{
Unit* boss = AI_VALUE2(Unit*, "find target", "blood-queen lana'thel");
if (!boss || !(botAI->IsTank(bot) || botAI->IsMainTank(bot) || botAI->IsAssistTank(bot) || botAI->IsRanged(bot)))
return false;
return true;
}
bool IccBqlPactOfDarkfallenTrigger::IsActive()
{
Unit* boss = AI_VALUE2(Unit*, "find target", "blood-queen lana'thel");
if (!boss || !bot->HasAura(71340))
return false;
return true;
}
bool IccBqlVampiricBiteTrigger::IsActive()
{
Unit* boss = AI_VALUE2(Unit*, "find target", "blood-queen lana'thel");
if (!boss)
return false;
// Only trigger when bot has Frenzied Bloodthirst
if (!(bot->HasAura(70877) || bot->HasAura(71474)))
return false;
return true;
}
//VDW
bool IccValkyreSpearTrigger::IsActive()
{
// Check if there's a spear nearby
if (Creature* spear = bot->FindNearestCreature(38248, 100.0f))
return true;
return false;
}
bool IccSisterSvalnaTrigger::IsActive()
{
Unit* boss = AI_VALUE2(Unit*, "find target", "sister svalna");
if (!boss)
{
return false;
}
return true;
}
bool IccValithriaPortalTrigger::IsActive()
{
// Only healers should use portals
if (!botAI->IsHeal(bot) || bot->HasAura(70766))
return false;
// Find the nearest portal creature
Creature* portal = bot->FindNearestCreature(37945, 100.0f); // Only check within 10 yards
Creature* portal2 = bot->FindNearestCreature(38430, 100.0f); // Only check within 10 yards
return portal || portal2;
}
bool IccValithriaHealTrigger::IsActive()
{
// Only healers should use healing
if (!botAI->IsHeal(bot) || bot->HasAura(70766))
return false;
// If no portal is found within 100 yards, we should heal
if (!bot->FindNearestCreature(37945, 100.0f) && !bot->FindNearestCreature(38430, 100.0f))
return true;
// If portal is nearby (10 yards), don't heal
if (bot->FindNearestCreature(37945, 20.0f) || bot->FindNearestCreature(38430, 10.0f))
return false;
// If portal is far but within 100 yards, heal while moving to it
return true;
}
bool IccValithriaDreamCloudTrigger::IsActive()
{
// Only active if we're in dream state
if (!bot->HasAura(70766))
return false;
// Find nearest cloud of either type
Creature* dreamCloud = bot->FindNearestCreature(37985, 100.0f);
Creature* nightmareCloud = bot->FindNearestCreature(38421, 100.0f);
return (dreamCloud || nightmareCloud);
}
//SINDRAGOSA
bool IccSindragosaTankPositionTrigger::IsActive()
{
Unit* boss = AI_VALUE2(Unit*, "find target", "sindragosa");
if (!boss || bot->HasAura(70126) /*|| bot->HasAura(69762)*/ || boss->HasUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY))
return false;
return true;
}
bool IccSindragosaFrostBeaconTrigger::IsActive()
{
Unit* boss = AI_VALUE2(Unit*, "find target", "sindragosa");
if (!boss)
return false;
Group* group = bot->GetGroup();
if (!group)
return false;
Group::MemberSlotList const& groupSlot = group->GetMemberSlots();
for (Group::member_citerator itr = groupSlot.begin(); itr != groupSlot.end(); ++itr)
{
Player* member = ObjectAccessor::FindPlayer(itr->guid);
if (!member || !member->IsAlive())
continue;
if (member->HasAura(70126)) // If any player has Frost Beacon, keep trigger active
return true;
}
return false;
}
bool IccSindragosaBlisteringColdTrigger::IsActive()
{
Unit* boss = AI_VALUE2(Unit*, "find target", "sindragosa");
if (!boss)
return false;
if (botAI->IsMainTank(bot) || botAI->IsAssistTank(bot) || botAI->IsTank(bot))
return false;
// Don't move if any bot in group has ice tomb
Group* group = bot->GetGroup();
if (!group)
return false;
bool isCasting = boss->HasUnitState(UNIT_STATE_CASTING);
bool isBlisteringCold = boss->FindCurrentSpellBySpellId(70123) || boss->FindCurrentSpellBySpellId(71047) ||
boss->FindCurrentSpellBySpellId(71048) || boss->FindCurrentSpellBySpellId(71049);
return isCasting && isBlisteringCold;
}
bool IccSindragosaUnchainedMagicTrigger::IsActive()
{
Unit* boss = AI_VALUE2(Unit*, "find target", "sindragosa");
if (!boss || (boss->HasUnitState(UNIT_STATE_CASTING) && boss->FindCurrentSpellBySpellId(70123)))
return false;
return bot->HasAura(69762);
}
bool IccSindragosaChilledToTheBoneTrigger::IsActive()
{
Unit* boss = AI_VALUE2(Unit*, "find target", "sindragosa");
if (!boss || (boss->HasUnitState(UNIT_STATE_CASTING) && boss->FindCurrentSpellBySpellId(70123)))
return false;
return bot->HasAura(70106);
}
bool IccSindragosaMysticBuffetTrigger::IsActive()
{
Unit* boss = AI_VALUE2(Unit*, "find target", "sindragosa");
if (!boss)
return false;
Aura* aura = bot->GetAura(70127);
Aura* aura2 = bot->GetAura(72528);
if (!aura && !aura2)
return false;
if (bot->HasAura(70126)) // Ice Block
return false;
if ((aura && aura->GetStackAmount() >= 3) || (aura2 && aura2->GetStackAmount() >= 3))
return true;
return false;
}
bool IccSindragosaMainTankMysticBuffetTrigger::IsActive()
{
Unit* boss = AI_VALUE2(Unit*, "find target", "sindragosa");
if (!boss)
return false;
if (!botAI->IsAssistTankOfIndex(bot, 0))
{
return false;
}
Unit* mt = AI_VALUE(Unit*, "main tank");
if (!mt)
{
return false;
}
Aura* aura = botAI->GetAura("mystic buffet", mt, false, true);
if (!aura || aura->GetStackAmount() < 8)
{
return false;
}
// Only taunt if we're in position
float distToTankPos = bot->GetExactDist2d(ICC_SINDRAGOSA_TANK_POSITION);
if (distToTankPos > 3.0f)
{
return false;
}
return true;
}
bool IccSindragosaTankSwapPositionTrigger::IsActive()
{
Unit* boss = AI_VALUE2(Unit*, "find target", "sindragosa");
if (!boss) return false;
if (!botAI->IsAssistTankOfIndex(bot, 0)) return false;
// Don't tank swap if we have frost beacon
if (bot->HasAura(70126)) return false; // Frost Beacon
// First check our own stacks - don't try to tank if we have too many
Aura* selfAura = botAI->GetAura("mystic buffet", bot, false, true);
if (selfAura && selfAura->GetStackAmount() >= 8) return false;
// Check if main tank has high stacks
Unit* mt = AI_VALUE(Unit*, "main tank");
if (!mt) return false;
Aura* aura = botAI->GetAura("mystic buffet", mt, false, true);
if (!aura) return false;
uint32 stacks = aura->GetStackAmount();
return (stacks >= 7); // Start moving at 7 stacks
}
bool IccSindragosaFrostBombTrigger::IsActive()
{
if (!bot->IsAlive() || bot->HasAura(70157)) // Skip if dead or in Ice Tomb
return false;
// Simply check if frost bomb marker exists
GuidVector npcs = AI_VALUE(GuidVector, "nearest hostile npcs");
for (auto& npc : npcs)
{
Unit* unit = botAI->GetUnit(npc);
if (!unit || !unit->IsAlive())
continue;
if (unit->HasAura(70022)) // Frost bomb visual
return true;
}
return false;
}
bool IccLichKingNecroticPlagueTrigger::IsActive()
{
if (!bot || !bot->IsAlive())
return false;
// Check for plague by name instead of ID
bool hasPlague = botAI->HasAura("Necrotic Plague", bot);
return hasPlague;
}
bool IccLichKingWinterTrigger::IsActive()
{
Unit* boss = AI_VALUE2(Unit*, "find target", "the lich king");
if (!boss)
return false;
// Check for either Remorseless Winter
bool hasWinterAura = boss->HasAura(72259) || boss->HasAura(74273) || boss->HasAura(74274) || boss->HasAura(74275);
bool hasWinter2Aura = boss->HasAura(68981) || boss->HasAura(74270) || boss->HasAura(74271) || boss->HasAura(74272);
if (!hasWinterAura && !hasWinter2Aura)
return false;
return true;
}
bool IccLichKingAddsTrigger::IsActive()
{
Unit* boss = AI_VALUE2(Unit*, "find target", "the lich king");
if (!boss)
return false;
return true;
}

View File

@@ -5,6 +5,57 @@
#include "Playerbots.h"
#include "Trigger.h"
//Lord Marrowgar
class IccLmTankPositionTrigger : public Trigger
{
public:
IccLmTankPositionTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc lm tank position") {}
bool IsActive() override;
};
class IccSpikeNearTrigger : public Trigger
{
public:
IccSpikeNearTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc spike near") {}
bool IsActive() override;
};
//Lady Deathwhisper
class IccDarkReckoningTrigger : public Trigger
{
public:
IccDarkReckoningTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc dark reckoning") {}
bool IsActive() override;
};
class IccRangedPositionLadyDeathwhisperTrigger : public Trigger
{
public:
IccRangedPositionLadyDeathwhisperTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc ranged position lady deathwhisper") {}
bool IsActive() override;
};
class IccAddsLadyDeathwhisperTrigger : public Trigger
{
public:
IccAddsLadyDeathwhisperTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc adds lady deathwhisper") {}
bool IsActive() override;
};
class IccShadeLadyDeathwhisperTrigger : public Trigger
{
public:
IccShadeLadyDeathwhisperTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc shade lady deathwhisper") {}
bool IsActive() override;
};
//Gunship Battle
class IccRottingFrostGiantTankPositionTrigger : public Trigger
{
public:
IccRottingFrostGiantTankPositionTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc rotting frost giant tank position") {}
bool IsActive() override;
};
class IccInCannonTrigger : public Trigger
{
@@ -20,4 +71,305 @@ public:
bool IsActive() override;
};
class IccGunshipTeleportAllyTrigger : public Trigger
{
public:
IccGunshipTeleportAllyTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc gunship teleport ally") {}
bool IsActive() override;
};
class IccGunshipTeleportHordeTrigger : public Trigger
{
public:
IccGunshipTeleportHordeTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc gunship teleport horde") {}
bool IsActive() override;
};
//DBS
class IccDbsTankPositionTrigger : public Trigger
{
public:
IccDbsTankPositionTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc dbs tank position") {}
bool IsActive() override;
};
class IccDbsMainTankRuneOfBloodTrigger : public Trigger
{
public:
IccDbsMainTankRuneOfBloodTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc dbs main tank rune of blood") {}
bool IsActive() override;
};
class IccAddsDbsTrigger : public Trigger
{
public:
IccAddsDbsTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc adds dbs") {}
bool IsActive() override;
};
//DOGS
class IccStinkyPreciousMainTankMortalWoundTrigger : public Trigger
{
public:
IccStinkyPreciousMainTankMortalWoundTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc stinky precious main tank mortal wound") {}
bool IsActive() override;
};
//FESTERGUT
class IccFestergutTankPositionTrigger : public Trigger
{
public:
IccFestergutTankPositionTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc festergut tank position") {}
bool IsActive() override;
};
class IccFestergutMainTankGastricBloatTrigger : public Trigger
{
public:
IccFestergutMainTankGastricBloatTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc festergut main tank gastric bloat") {}
bool IsActive() override;
};
class IccFestergutSporeTrigger : public Trigger
{
public:
IccFestergutSporeTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc festergut spore") {}
bool IsActive() override;
};
//ROTFACE
class IccRotfaceTankPositionTrigger : public Trigger
{
public:
IccRotfaceTankPositionTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc rotface tank position") {}
bool IsActive() override;
};
class IccRotfaceGroupPositionTrigger : public Trigger
{
public:
IccRotfaceGroupPositionTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc rotface group position") {}
bool IsActive() override;
};
class IccRotfaceMoveAwayFromExplosionTrigger : public Trigger
{
public:
IccRotfaceMoveAwayFromExplosionTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc rotface move away from explosion") {}
bool IsActive() override;
};
//PP
class IccPutricideVolatileOozeTrigger : public Trigger
{
public:
IccPutricideVolatileOozeTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc putricide volatile ooze") {}
bool IsActive() override;
};
class IccPutricideGasCloudTrigger : public Trigger
{
public:
IccPutricideGasCloudTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc putricide gas cloud") {}
bool IsActive() override;
};
class IccPutricideGrowingOozePuddleTrigger : public Trigger
{
public:
IccPutricideGrowingOozePuddleTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc putricide growing ooze puddle") {}
bool IsActive() override;
};
class IccPutricideMainTankMutatedPlagueTrigger : public Trigger
{
public:
IccPutricideMainTankMutatedPlagueTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc putricide main tank mutated plague") {}
bool IsActive() override;
};
class IccPutricideMalleableGooTrigger : public Trigger
{
public:
IccPutricideMalleableGooTrigger(PlayerbotAI* ai) : Trigger(ai, "icc putricide malleable goo") {}
bool IsActive() override;
};
//BPC
class IccBpcKelesethTankTrigger : public Trigger
{
public:
IccBpcKelesethTankTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc bpc keleseth tank") {}
bool IsActive() override;
};
class IccBpcNucleusTrigger : public Trigger
{
public:
IccBpcNucleusTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc bpc nucleus") {}
bool IsActive() override;
};
class IccBpcMainTankTrigger : public Trigger
{
public:
IccBpcMainTankTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc bpc main tank") {}
bool IsActive() override;
};
class IccBpcEmpoweredVortexTrigger : public Trigger
{
public:
IccBpcEmpoweredVortexTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc bpc empowered vortex") {}
bool IsActive() override;
};
//Bql
class IccBqlTankPositionTrigger : public Trigger
{
public:
IccBqlTankPositionTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc bql tank position") {}
bool IsActive() override;
};
class IccBqlPactOfDarkfallenTrigger : public Trigger
{
public:
IccBqlPactOfDarkfallenTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc bql pact of darkfallen") {}
bool IsActive() override;
};
class IccBqlVampiricBiteTrigger : public Trigger
{
public:
IccBqlVampiricBiteTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc bql vampiric bite") {}
bool IsActive() override;
};
//VDW
class IccValkyreSpearTrigger : public Trigger
{
public:
IccValkyreSpearTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc valkyre spear") {}
bool IsActive() override;
};
class IccSisterSvalnaTrigger : public Trigger
{
public:
IccSisterSvalnaTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc sister svalna") {}
bool IsActive() override;
};
class IccValithriaPortalTrigger : public Trigger
{
public:
IccValithriaPortalTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc valithria portal") {}
bool IsActive() override;
};
class IccValithriaHealTrigger : public Trigger
{
public:
IccValithriaHealTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc valithria heal") {}
bool IsActive() override;
};
class IccValithriaDreamCloudTrigger : public Trigger
{
public:
IccValithriaDreamCloudTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc valithria dream cloud") {}
bool IsActive() override;
};
//SINDRAGOSA
class IccSindragosaTankPositionTrigger : public Trigger
{
public:
IccSindragosaTankPositionTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc sindragosa tank position") {}
bool IsActive() override;
};
class IccSindragosaFrostBeaconTrigger : public Trigger
{
public:
IccSindragosaFrostBeaconTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc sindragosa frost beacon") {}
bool IsActive() override;
};
class IccSindragosaBlisteringColdTrigger : public Trigger
{
public:
IccSindragosaBlisteringColdTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc sindragosa blistering cold") {}
bool IsActive() override;
};
class IccSindragosaUnchainedMagicTrigger : public Trigger
{
public:
IccSindragosaUnchainedMagicTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc sindragosa unchained magic") {}
bool IsActive() override;
};
class IccSindragosaChilledToTheBoneTrigger : public Trigger
{
public:
IccSindragosaChilledToTheBoneTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc sindragosa chilled to the bone") {}
bool IsActive() override;
};
class IccSindragosaMysticBuffetTrigger : public Trigger
{
public:
IccSindragosaMysticBuffetTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc sindragosa mystic buffet") {}
bool IsActive() override;
};
class IccSindragosaMainTankMysticBuffetTrigger : public Trigger
{
public:
IccSindragosaMainTankMysticBuffetTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc sindragosa main tank mystic buffet") {}
bool IsActive() override;
};
class IccSindragosaTankSwapPositionTrigger : public Trigger
{
public:
IccSindragosaTankSwapPositionTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc sindragosa tank swap position") {}
bool IsActive() override;
};
class IccSindragosaFrostBombTrigger : public Trigger
{
public:
IccSindragosaFrostBombTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc sindragosa frost bomb") {}
bool IsActive() override;
};
//LICH KING
class IccLichKingNecroticPlagueTrigger : public Trigger
{
public:
IccLichKingNecroticPlagueTrigger(PlayerbotAI* ai) : Trigger(ai, "icc lich king necrotic plague") {}
bool IsActive() override;
};
class IccLichKingWinterTrigger : public Trigger
{
public:
IccLichKingWinterTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc lich king winter") {}
bool IsActive() override;
};
class IccLichKingAddsTrigger : public Trigger
{
public:
IccLichKingAddsTrigger(PlayerbotAI* botAI) : Trigger(botAI, "icc lich king adds") {}
bool IsActive() override;
};
#endif

View File

@@ -243,4 +243,4 @@ bool ExitTwilightPortalAction::Execute(Event event)
bot->GetSession()->HandleGameObjectUseOpcode(data1);
return true;
}
}