void UpdateAI(const uint32 diff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; if (Vengeance_Timer < diff) { DoCast(m_creature, SPELL_VENGEANCE); Vengeance_Timer = 12000; } else Vengeance_Timer -= diff; if (Radiance_Timer < diff) { DoCast(m_creature, DIFFICULTY(SPELL_RADIANCE)); Radiance_Timer = 20000; } else Radiance_Timer -= diff; if (Hammer_Timer < diff) { if (Player *target = SelectRandomPlayer()) { DoCast(target, SPELL_HAMMER_OF_JUSTICE); HammerTarget = target->GetGUID(); } Hammer_Timer = 50000; } else Hammer_Timer -= diff; if (Hammer_Dmg_Timer < diff) { if (Unit *pHammerTarget = Unit::GetUnit(*m_creature, HammerTarget)) DoCast(pHammerTarget, SPELL_HAMMER); Hammer_Dmg_Timer = 50000; } else Hammer_Dmg_Timer -= diff; DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { if(isCharging) { if(!ChargeTargetGUID) { m_creature->SetSpeed(MOVE_RUN, 1.2f); m_creature->GetMotionMaster()->Clear(); if(m_creature->getVictim()) { m_creature->Attack(m_creature->getVictim(), true); m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); } isCharging = false; } return; } if(!m_creature->SelectHostilTarget() && !m_creature->getVictim()) return; if(Berserk_Timer < diff) { DoScriptText(SAY_BERSERK, m_creature); DoCast(m_creature, SPELL_BERSERK, true); Berserk_Timer = 600000; }else Berserk_Timer -= diff; if(ShapeShift_Timer < diff) { if(inBearForm) { DoScriptText(SAY_TOTROLL, m_creature); m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY + 1, 5122); m_creature->RemoveAurasDueToSpell(SPELL_BEARFORM); Surge_Timer = 15000 + rand()%5000; BrutalSwipe_Timer = 7000 + rand()%5000; Mangle_Timer = 10000 + rand()%5000; ShapeShift_Timer = 45000 + rand()%5000; inBearForm = false; } else { DoScriptText(SAY_TOBEAR, m_creature); m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY + 1, 0); DoCast(m_creature, SPELL_BEARFORM, true); LaceratingSlash_Timer = 2000; // dur 18s RendFlesh_Timer = 3000; // dur 5s DeafeningRoar_Timer = 5000 + rand()%5000; // dur 2s ShapeShift_Timer = 20000 + rand()%5000; // dur 30s inBearForm = true; } }else ShapeShift_Timer -= diff; if(!inBearForm) { if(BrutalSwipe_Timer < diff) { DoCast(m_creature->getVictim(), SPELL_BRUTALSWIPE); BrutalSwipe_Timer = 7000 + rand()%5000; }else BrutalSwipe_Timer -= diff; if(Mangle_Timer < diff) { if(!m_creature->getVictim()->HasAura(SPELL_MANGLEEFFECT, 0)) { DoCast(m_creature->getVictim(), SPELL_MANGLE); Mangle_Timer = 1000; } else Mangle_Timer = 10000 + rand()%5000; }else Mangle_Timer -= diff; if(Surge_Timer < diff) { DoScriptText(SAY_SURGE, m_creature); Unit *target = SelectRandomPlayer(45); if(!target) target = m_creature->getVictim(); isCharging = true; ChargeTargetGUID = target->GetGUID(); float x, y, z; target->GetContactPoint(m_creature, x, y, z); m_creature->SetSpeed(MOVE_RUN, 5.0f); m_creature->GetMotionMaster()->Clear(); m_creature->GetMotionMaster()->MovePoint(0, x, y, z); Surge_Timer = 15000 + rand()%5000; return; }else Surge_Timer -= diff; } else { if(LaceratingSlash_Timer < diff) { if(!m_creature->getVictim()->HasAura(SPELL_MANGLEEFFECT, 0)) DoCast(m_creature->getVictim(), SPELL_LACERATINGSLASH); else { int32 bp0 = 3470; m_creature->CastCustomSpell(m_creature->getVictim(), SPELL_LACERATINGSLASH, &bp0, NULL, NULL, false); } LaceratingSlash_Timer = 18000 + rand()%5000; }else LaceratingSlash_Timer -= diff; if(RendFlesh_Timer < diff) { if(!m_creature->getVictim()->HasAura(SPELL_MANGLEEFFECT, 0)) DoCast(m_creature->getVictim(), SPELL_RENDFLESH); else { int32 bp1 = 4670; m_creature->CastCustomSpell(m_creature->getVictim(), SPELL_RENDFLESH, NULL, &bp1, NULL, false); } RendFlesh_Timer = 5000 + rand()%5000; }else RendFlesh_Timer -= diff; if(DeafeningRoar_Timer < diff) { DoCast(m_creature->getVictim(), SPELL_DEAFENINGROAR); DeafeningRoar_Timer = 15000 + rand()%5000; }else DeafeningRoar_Timer -= diff; } DoMeleeAttackIfReady(); }
CanCastResult BossSpellWorker::_BSWSpellSelector(uint8 m_uiSpellIdx, Unit* pTarget) { SpellEntry const *spell; SpellTable* pSpell = &m_BossSpell[m_uiSpellIdx]; Unit* pSummon = NULL; debug_log("BSW: Casting spell number %u type %u",pSpell->m_uiSpellEntry[currentDifficulty], pSpell->m_CastTarget); switch (pSpell->m_CastTarget) { case DO_NOTHING: return CAST_OK; case CAST_ON_SELF: if (!pSpell->m_IsBugged) return _DoCastSpellIfCan(boss, pSpell->m_uiSpellEntry[currentDifficulty]); else return _BSWDoCast(m_uiSpellIdx, boss); break; case CAST_ON_SUMMONS: if (!pTarget) return CAST_FAIL_OTHER; else return _DoCastSpellIfCan(pTarget, pSpell->m_uiSpellEntry[currentDifficulty]); break; case CAST_ON_VICTIM: pTarget = boss->getVictim(); return _BSWCastOnTarget(pTarget, m_uiSpellIdx); break; case CAST_ON_RANDOM: pTarget = boss->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0); return _BSWCastOnTarget(pTarget, m_uiSpellIdx); break; case CAST_ON_BOTTOMAGGRO: pTarget = boss->SelectAttackingTarget(ATTACKING_TARGET_BOTTOMAGGRO,0); return _BSWCastOnTarget(pTarget, m_uiSpellIdx); break; case CAST_ON_TARGET: return _BSWCastOnTarget(pTarget, m_uiSpellIdx); break; case APPLY_AURA_SELF: spell = (SpellEntry *)GetSpellStore()->LookupEntry(pSpell->m_uiSpellEntry[currentDifficulty]); if (spell) if (boss->AddAura(new BossAura(spell, EFFECT_INDEX_0, &pSpell->varData, boss, boss))) return CAST_OK; return CAST_FAIL_OTHER; break; case APPLY_AURA_TARGET: if (!pTarget || !pTarget->IsInMap(boss)) return CAST_FAIL_OTHER; _doAura(m_uiSpellIdx, pTarget, EFFECT_INDEX_0); return CAST_OK; break; case SUMMON_NORMAL: pSummon = _doSummon(m_uiSpellIdx, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 5000); if(pSummon) return CAST_OK; else return CAST_FAIL_OTHER; break; case SUMMON_TEMP: pSummon = _doSummon(m_uiSpellIdx, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, urand(pSpell->m_uiSpellTimerMin[currentDifficulty],pSpell->m_uiSpellTimerMax[currentDifficulty])); if(pSummon) return CAST_OK; else return CAST_FAIL_OTHER; break; case SUMMON_INSTANT: pSummon = _doSummon(m_uiSpellIdx, TEMPSUMMON_MANUAL_DESPAWN,0); if(pSummon) return CAST_OK; else return CAST_FAIL_OTHER; break; case CAST_ON_ALLPLAYERS: { CanCastResult res1 = CAST_FAIL_OTHER; Map::PlayerList const& pPlayers = pMap->GetPlayers(); for (Map::PlayerList::const_iterator itr = pPlayers.begin(); itr != pPlayers.end(); ++itr) { pTarget = itr->getSource(); if (pTarget && pTarget->isAlive() && pTarget->IsWithinDistInMap(boss, pSpell->LocData.x)) { if (!pSpell->m_IsBugged) { res1 = _DoCastSpellIfCan(pTarget, pSpell->m_uiSpellEntry[currentDifficulty]); } else { _BSWDoCast(m_uiSpellIdx, pTarget); res1 = CAST_OK; }; }; return res1; } break; } case CAST_ON_FRENDLY: pTarget = SelectLowHPFriendly(pSpell->LocData.x); return _BSWCastOnTarget(pTarget, m_uiSpellIdx); break; case CAST_ON_FRENDLY_LOWHP: pTarget = SelectLowHPFriendly(pSpell->LocData.x); return _BSWCastOnTarget(pTarget, m_uiSpellIdx); break; case CAST_ON_RANDOM_POINT: if (!pTarget) pTarget = boss; if (pSpell->LocData.z <= 1.0f) { float fPosX, fPosY, fPosZ; if (!pTarget->IsPositionValid() || !pTarget->IsInMap(boss)) { if (pTarget->GetTypeId() == TYPEID_PLAYER) error_log("BSW: CAST_ON_RANDOM_POINT FAILED: player has invalid position. SpellID is %u",pSpell->m_uiSpellEntry[currentDifficulty]); else error_log("BSW: CAST_ON_RANDOM_POINT FAILED: creature has invalid position. SpellID is %u",pSpell->m_uiSpellEntry[currentDifficulty]); return CAST_FAIL_OTHER; } pTarget->GetPosition(fPosX, fPosY, fPosZ); pTarget->GetRandomPoint(fPosX, fPosY, fPosZ, urand((uint32)pSpell->LocData.x, (uint32)pSpell->LocData.y), fPosX, fPosY, fPosZ); if ((int)fPosZ == 0) { error_log("BSW: CAST_ON_RANDOM_POINT FAILED: Positon Z is NULL. Strange bug"); return CAST_FAIL_OTHER; } if (SpellEntry const *spell = (SpellEntry *)GetSpellStore()->LookupEntry(pSpell->m_uiSpellEntry[currentDifficulty])) if (SpellRangeEntry const *pSpellRange = GetSpellRangeStore()->LookupEntry(spell->rangeIndex)) if (boss->GetDistance(fPosX, fPosY, fPosZ) <= pSpellRange->maxRange) { boss->CastSpell(fPosX, fPosY, fPosZ, pSpell->m_uiSpellEntry[currentDifficulty], false); return CAST_OK; }; return CAST_FAIL_TOO_FAR; } else return CAST_FAIL_OTHER; break; case CAST_ON_RANDOM_PLAYER: if ( pSpell->LocData.x < 1 ) pTarget = SelectRandomPlayer(); else pTarget = SelectRandomPlayerAtRange((float)pSpell->LocData.x); if (pTarget && pTarget->IsInMap(boss)) return _BSWCastOnTarget(pTarget, m_uiSpellIdx); else return CAST_FAIL_OTHER; break; case APPLY_AURA_ALLPLAYERS: { Map::PlayerList const& pPlayers = pMap->GetPlayers(); for (Map::PlayerList::const_iterator itr = pPlayers.begin(); itr != pPlayers.end(); ++itr) { pTarget = itr->getSource(); if (pTarget && pTarget->isAlive() && pTarget->IsWithinDistInMap(boss, pSpell->LocData.x)) _doAura(m_uiSpellIdx, pTarget, EFFECT_INDEX_0); } return CAST_OK; } break; case SPELLTABLEPARM_NUMBER: default: return CAST_FAIL_OTHER; break; }; error_log("BSW: FAILED casting spell number %u type %u - type not exists",pSpell->m_uiSpellEntry[currentDifficulty], pSpell->m_CastTarget); return CAST_FAIL_OTHER; };
void UpdateAI(const uint32 diff) { if (!m_creature->SelectHostilTarget() && !m_creature->getVictim()) return; if(StormCount) { Unit* target = Unit::GetUnit(*m_creature, CloudGUID); if(!target || !target->isAlive()) { EnterEvadeMode(); return; } else if(Unit* Cyclone = Unit::GetUnit(*m_creature, CycloneGUID)) Cyclone->CastSpell(target, 25160, true); // keep casting or... if(StormSequenceTimer < diff) { HandleStormSequence(target); }else StormSequenceTimer -= diff; return; } if (Enrage_Timer < diff) { DoYell(SAY_ONENRAGE, LANG_UNIVERSAL, NULL); DoPlaySoundToSet(m_creature, SOUND_ONENRAGE); m_creature->CastSpell(m_creature, SPELL_BERSERK, true); Enrage_Timer = 600000; }else Enrage_Timer -= diff; if (StaticDisruption_Timer < diff) { Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 1); if(!target) target = m_creature->getVictim(); TargetGUID = target->GetGUID(); m_creature->CastSpell(target, SPELL_STATIC_DISRUPTION, false); m_creature->SetInFront(m_creature->getVictim()); StaticDisruption_Timer = (10+rand()%8)*1000; // < 20s float dist = m_creature->GetDistance(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ()); if (dist < 5.0f) dist = 5.0f; SDisruptAOEVisual_Timer = 1000 + floor(dist / 30 * 1000.0f); }else StaticDisruption_Timer -= diff; if (SDisruptAOEVisual_Timer < diff) { Unit* SDVictim = Unit::GetUnit((*m_creature), TargetGUID); if(SDVictim && SDVictim->isAlive()) SDVictim->CastSpell(SDVictim, SPELL_STATIC_VISUAL, true); SDisruptAOEVisual_Timer = 99999; TargetGUID = 0; }else SDisruptAOEVisual_Timer -= diff; if (GustOfWind_Timer < diff) { Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 1); if(!target) target = m_creature->getVictim(); DoCast(target, SPELL_GUST_OF_WIND); GustOfWind_Timer = (20+rand()%10)*1000; //20 to 30 seconds(bosskillers) } else GustOfWind_Timer -= diff; if (CallLighting_Timer < diff) { DoCast(m_creature->getVictim(), SPELL_CALL_LIGHTNING); CallLighting_Timer = (12 + rand()%5)*1000; //totaly random timer. can't find any info on this } else CallLighting_Timer -= diff; if (!isRaining && ElectricalStorm_Timer < 8000 + rand()%5000) { SetWeather(WEATHER_STATE_HEAVY_RAIN, 0.9999f); isRaining = true; } if (ElectricalStorm_Timer < diff) { Unit* target = SelectRandomPlayer(50); if(!target) target = m_creature->getVictim(); float x, y, z; target->GetPosition(x, y, z); Creature *Cloud = m_creature->SummonCreature(MOB_TEMP_TRIGGER, x, y, m_creature->GetPositionZ() + 10, 0, TEMPSUMMON_TIMED_DESPAWN, 15000); if(Cloud) { CloudGUID = Cloud->GetGUID(); Cloud->AddMonsterMoveFlag(MONSTER_MOVE_LEVITATING); Cloud->StopMoving(); Cloud->SetFloatValue(OBJECT_FIELD_SCALE_X, 3.0f); Cloud->setFaction(35); Cloud->SetMaxHealth(9999999); Cloud->SetHealth(9999999); Cloud->CastSpell(Cloud, 45213, true); // cloud visual m_creature->StopMoving(); Cloud->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); m_creature->CastSpell(Cloud, 43501, false); // siphon soul } Unit *Cyclone = m_creature->SummonCreature(MOB_TEMP_TRIGGER, x, y, z, 0, TEMPSUMMON_TIMED_DESPAWN, 15000); if(Cyclone) { Cyclone->CastSpell(Cyclone, 25160, true); // wind visual CycloneGUID = Cyclone->GetGUID(); } ElectricalStorm_Timer = 60000; //60 seconds(bosskillers) StormCount = 1; StormSequenceTimer = 0; } else ElectricalStorm_Timer -= diff; if (SummonEagles_Timer < diff) { DoYell(SAY_ONSUMMON, LANG_UNIVERSAL, NULL); DoPlaySoundToSet(m_creature, SOUND_ONSUMMON); float x, y, z; m_creature->GetPosition(x, y, z); for (uint8 i = 0; i < 6 + rand()%3; i++) { if(Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0)) { x = target->GetPositionX() + 10 - rand()%20; y = target->GetPositionY() + 10 - rand()%20; z = target->GetPositionZ() + 6 + rand()%5 + 10; if(z > 95) z = 95 - rand()%5; } Creature *pCreature = m_creature->SummonCreature(MOB_SOARING_EAGLE, x, y, z, 0, TEMPSUMMON_CORPSE_DESPAWN, 0); if (pCreature) { pCreature->AddThreat(m_creature->getVictim(), 1.0f); pCreature->AI()->AttackStart(m_creature->getVictim()); } } SummonEagles_Timer = 999999; } else SummonEagles_Timer -= diff; DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { if (withhead) { switch (Phase) { case 0: { if (!IsFlying) { if (say_timer <= diff) { say_timer = 3000; Player* player = SelectRandomPlayer(100.0f, false); if (count < 3) { if (player) player->Say(Text[count], 0); } else { DoCast(me, SPELL_RHYME_BIG); if (player) { player->Say(Text[count], 0); player->HandleEmoteCommand(ANIM_EMOTE_SHOUT); } wp_reached = true; IsFlying = true; count = 0; break; } ++count; } else say_timer -= diff; } else { if (wp_reached) { wp_reached = false; me->GetMotionMaster()->Clear(false); me->GetMotionMaster()->MovePoint(id, FlightPoint[id].x, FlightPoint[id].y, FlightPoint[id].z); } } } break; case 1: if (burned) break; if (burn <= diff) { if (Creature* flame = me->SummonCreature(HELPER, Spawn[0].x, Spawn[0].y, Spawn[0].z, 0, TEMPSUMMON_TIMED_DESPAWN, 17000)) CAST_AI(mob_wisp_invis::mob_wisp_invisAI, flame->AI())->SetType(2); burned = true; } else burn -= diff; break; case 2: if (conflagrate <= diff) { if (Unit* player = SelectRandomPlayer(30.0f)) DoCast(player, SPELL_CONFLAGRATION, false); conflagrate = urand(10000, 16000); } else conflagrate -= diff; break; case 3: if (summonadds <= diff) { me->InterruptNonMeleeSpells(false); DoCast(me, SPELL_SUMMON_PUMPKIN); SaySound(SAY_SPROUTING_PUMPKINS); summonadds = urand(25000, 35000); } else summonadds -= diff; break; } if (laugh <= diff) { laugh = urand(11000, 22000); me->MonsterTextEmote(EMOTE_LAUGHS, 0); DoPlaySoundToSet(me, RandomLaugh[rand()%3]); } else laugh -= diff; if (UpdateVictim()) { DoMeleeAttackIfReady(); if (cleave <= diff) { DoCast(me->getVictim(), SPELL_CLEAVE); cleave = urand(2000, 6000); //1 cleave per 2.0f-6.0fsec } else cleave -= diff; } } else { if (regen <= diff) { regen = 1000; //"body calls head" if (me->IsFullHealth() && !returned) { if (Phase > 1) --Phase; else Phase = 1; Creature* Head = Unit::GetCreature((*me), headGUID); if (Head && Head->isAlive()) { CAST_AI(mob_head::mob_headAI, Head->AI())->Phase = Phase; CAST_AI(mob_head::mob_headAI, Head->AI())->Disappear(); } return; } } else regen -= diff; if (whirlwind <= diff) { whirlwind = urand(4000, 8000); if (urand(0, 1)) { me->RemoveAurasDueToSpell(SPELL_CONFUSE); DoCast(me, SPELL_WHIRLWIND, true); DoCast(me, SPELL_CONFUSE); } else me->RemoveAurasDueToSpell(SPELL_WHIRLWIND); } else whirlwind -= diff; } }