void DoAction(int32 const action) { switch (action) { case START_INTRO: { if (Creature* baxter = ObjectAccessor::GetCreature(*me, _instance? _instance->GetData64(DATA_BAXTER) : 0)) baxter->AI()->DoAction(START_INTRO); if (Creature* frye = ObjectAccessor::GetCreature(*me, _instance ? _instance->GetData64(DATA_FRYE) : 0)) frye->AI()->DoAction(START_INTRO); _phase = PHASE_INTRO; me->SetReactState(REACT_PASSIVE); me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); SetInCombat(me); break; } case START_FIGHT: { _phase = PHASE_NORMAL; me->setFaction(FACTION_HOSTIL); me->SetReactState(REACT_AGGRESSIVE); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); SetInCombat(me); _instance->SetData(TYPE_CROWN, IN_PROGRESS); break; } case APOTHECARY_DIED: { ++_deadCount; if (_deadCount > 2) // all 3 apothecarys dead, set lootable { _summons.DespawnAll(); me->SetCorpseDelay(90); // set delay me->setDeathState(JUST_DIED); // update delay _instance->SetData(TYPE_CROWN, DONE); me->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); Map* map = me->GetMap(); if (map && map->IsDungeon()) { Map::PlayerList const& players = map->GetPlayers(); if (!players.isEmpty()) for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i) if (Player* player = i->getSource()) if (player->GetDistance(me) < 120.0f) sLFGMgr->RewardDungeonDoneFor(288, player); } } else { if (me->HasFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE)) me->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); } break; } case SPAWN_CRAZED: { uint8 i = urand(0, 3); if (Creature* crazed = me->SummonCreature(NPC_CRAZED_APOTHECARY, Loc[i], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 3*IN_MILLISECONDS)) { crazed->setFaction(FACTION_HOSTIL); crazed->SetReactState(REACT_PASSIVE); crazed->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); crazed->GetMotionMaster()->MovePoint(1, Loc[i + 4]); } if (!_firstCrazed) { DoScriptText(SAY_SUMMON_ADDS, me); _firstCrazed = true; } break; } } }
uint32 NextStep(uint32 Step) { Unit* arca = Unit::GetUnit((*me),ArcanagosGUID); Map* pMap = me->GetMap(); switch(Step) { case 0: return 9999999; case 1: me->MonsterYell(SAY_DIALOG_MEDIVH_1,LANG_UNIVERSAL,NULL); return 10000; case 2: if (arca) CAST_CRE(arca)->MonsterYell(SAY_DIALOG_ARCANAGOS_2,LANG_UNIVERSAL,NULL); return 20000; case 3: me->MonsterYell(SAY_DIALOG_MEDIVH_3,LANG_UNIVERSAL,NULL); return 10000; case 4: if (arca) CAST_CRE(arca)->MonsterYell(SAY_DIALOG_ARCANAGOS_4, LANG_UNIVERSAL, NULL); return 20000; case 5: me->MonsterYell(SAY_DIALOG_MEDIVH_5, LANG_UNIVERSAL, NULL); return 20000; case 6: if (arca) CAST_CRE(arca)->MonsterYell(SAY_DIALOG_ARCANAGOS_6, LANG_UNIVERSAL, NULL); return 10000; case 7: FireArcanagosTimer = 500; return 5000; case 8: FireMedivhTimer = 500; DoCast(me, SPELL_MANA_SHIELD); return 10000; case 9: me->MonsterTextEmote(EMOTE_DIALOG_MEDIVH_7, 0, false); return 10000; case 10: if (arca) DoCast(arca, SPELL_CONFLAGRATION_BLAST, false); return 1000; case 11: if (arca) CAST_CRE(arca)->MonsterYell(SAY_DIALOG_ARCANAGOS_8, LANG_UNIVERSAL, NULL); return 5000; case 12: arca->GetMotionMaster()->MovePoint(0, -11010.82,-1761.18, 156.47); arca->setActive(true); arca->InterruptNonMeleeSpells(true); arca->SetSpeed(MOVE_FLIGHT, 2.0f); return 10000; case 13: me->MonsterYell(SAY_DIALOG_MEDIVH_9, LANG_UNIVERSAL, NULL); return 10000; case 14: me->SetVisibility(VISIBILITY_OFF); me->ClearInCombat(); if (pMap->IsDungeon()) { InstanceMap::PlayerList const &PlayerList = pMap->GetPlayers(); for (InstanceMap::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) { if (i->getSource()->isAlive()) { if (i->getSource()->GetQuestStatus(9645) == QUEST_STATUS_INCOMPLETE) i->getSource()->CompleteQuest(9645); } } } return 50000; case 15: arca->DealDamage(arca,arca->GetHealth(),NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); return 5000; default : return 9999999; } }
void UpdateAI(const uint32 diff) { if (!CanStartEvent)//boss is invisible, don't attack { if (CheckCanStart()) { if (Submerged) { me->SetVisible(true); Submerged = false; WaitTimer2 = 500; } if (!Submerged && WaitTimer2 <= diff)//wait 500ms before emerge anim { me->RemoveAllAuras(); me->RemoveFlag(UNIT_NPC_EMOTESTATE,EMOTE_STATE_SUBMERGED); DoCast(me, SPELL_EMERGE, false); WaitTimer2 = 60000;//never reached WaitTimer = 3000; } else WaitTimer2 -= diff; if (WaitTimer <= diff)//wait 3secs for emerge anim, then attack { WaitTimer = 3000; CanStartEvent=true;//fresh fished from pool me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); } else WaitTimer -= diff; } return; } if (me->getThreatManager().getThreatList().empty())//check if should evade { if (me->isInCombat()) EnterEvadeMode(); return; } if (!Submerged) { if (PhaseTimer <= diff) { me->InterruptNonMeleeSpells(false); DoCast(me, SPELL_SUBMERGE); PhaseTimer = 60000;//60secs submerged Submerged = true; } else PhaseTimer-=diff; if (SpoutTimer <= diff) { me->MonsterTextEmote(EMOTE_SPOUT,0,true); me->SetReactState(REACT_PASSIVE); me->GetMotionMaster()->MoveRotate(20000, rand()%2 ? ROTATE_DIRECTION_LEFT : ROTATE_DIRECTION_RIGHT); SpoutTimer = 45000; WhirlTimer = 20000;//whirl directly after spout RotTimer = 20000; return; } else SpoutTimer -= diff; //Whirl directly after a Spout and at random times if (WhirlTimer <= diff) { WhirlTimer = 18000; DoCast(me, SPELL_WHIRL); } else WhirlTimer -= diff; if (CheckTimer <= diff)//check if there are players in melee range { InRange = false; Map* pMap = me->GetMap(); Map::PlayerList const &PlayerList = pMap->GetPlayers(); if (!PlayerList.isEmpty()) { for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) { if (me->IsWithinMeleeRange(i->getSource())) InRange = true; } } CheckTimer = 2000; } else CheckTimer -= diff; if (RotTimer) { Map* pMap = me->GetMap(); if (pMap->IsDungeon()) { Map::PlayerList const &PlayerList = pMap->GetPlayers(); for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) { if (i->getSource() && i->getSource()->isAlive() && me->HasInArc(float(diff/20000*M_PI*2),i->getSource()) && me->IsWithinDist(i->getSource(), SPOUT_DIST) && !i->getSource()->IsInWater()) DoCast(i->getSource(), SPELL_SPOUT, true);//only knock back palyers in arc, in 100yards, not in water } } if (SpoutAnimTimer <= diff) { DoCast(me, SPELL_SPOUT_ANIM, true); SpoutAnimTimer = 1000; } else SpoutAnimTimer -= diff; if (RotTimer <= diff) { RotTimer = 0; } else RotTimer -= diff; return; } if (GeyserTimer <= diff) { Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,1); if (!pTarget && me->getVictim()) pTarget = me->getVictim(); if (pTarget) DoCast(pTarget, SPELL_GEYSER, true); GeyserTimer = rand()%5000 + 15000; } else GeyserTimer -= diff; if (!InRange)//if on players in melee range cast Waterbolt { if (WaterboltTimer <= diff) { Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,0); if (!pTarget && me->getVictim()) pTarget = me->getVictim(); if (pTarget) DoCast(pTarget, SPELL_WATERBOLT, true); WaterboltTimer = 3000; } else WaterboltTimer -= diff; } if (!UpdateCombatState()) return; DoMeleeAttackIfReady(); }else//submerged { if (PhaseTimer <= diff) { Submerged = false; me->InterruptNonMeleeSpells(false);//shouldn't be any me->RemoveAllAuras(); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE); me->RemoveFlag(UNIT_NPC_EMOTESTATE,EMOTE_STATE_SUBMERGED); DoCast(me, SPELL_EMERGE, true); Spawned = false; SpoutTimer = 3000; // directly cast Spout after emerging! PhaseTimer = 120000; return; } else PhaseTimer-=diff; if (me->getThreatManager().getThreatList().empty())//check if should evade { EnterEvadeMode(); return; } if (!me->isInCombat()) DoZoneInCombat(); if (!Spawned) { me->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE); //spawn adds for (uint8 i = 0; i < 9; ++i) { Creature* Summoned; if (i < 6) Summoned = me->SummonCreature(MOB_COILFANG_AMBUSHER,AddPos[i][0],AddPos[i][1],AddPos[i][2], 0, TEMPSUMMON_CORPSE_DESPAWN, 0); else Summoned = me->SummonCreature(MOB_COILFANG_GUARDIAN,AddPos[i][0],AddPos[i][1],AddPos[i][2], 0, TEMPSUMMON_CORPSE_DESPAWN, 0); if (Summoned) Summons.Summon(Summoned); } Spawned = true; } } }
void UpdateAI(const uint32 diff) { if (pInstance) { if (!leotherasGUID) leotherasGUID = pInstance->GetData64(DATA_LEOTHERAS); if (!me->isInCombat() && pInstance->GetData64(DATA_LEOTHERAS_EVENT_STARTER)) { Unit *victim = NULL; victim = Unit::GetUnit(*me, pInstance->GetData64(DATA_LEOTHERAS_EVENT_STARTER)); if (victim) AttackStart(victim); } } if (!UpdateVictim()) { CastChanneling(); return; } if (pInstance && !pInstance->GetData64(DATA_LEOTHERAS_EVENT_STARTER)) { EnterEvadeMode(); return; } if (Mindblast_Timer <= diff) { Unit *pTarget = NULL; pTarget = SelectUnit(SELECT_TARGET_RANDOM,0); if (pTarget)DoCast(pTarget, SPELL_MINDBLAST); Mindblast_Timer = 10000 + rand()%5000; } else Mindblast_Timer -= diff; if (Earthshock_Timer <= diff) { Map* pMap = me->GetMap(); Map::PlayerList const &PlayerList = pMap->GetPlayers(); for (Map::PlayerList::const_iterator itr = PlayerList.begin(); itr != PlayerList.end(); ++itr) { if (Player* i_pl = itr->getSource()) { bool isCasting = false; for (uint8 i = 0; i < CURRENT_MAX_SPELL; ++i) if (i_pl->GetCurrentSpell(i)) isCasting = true; if (isCasting) { DoCast(i_pl, SPELL_EARTHSHOCK); break; } } } Earthshock_Timer = 8000 + rand()%7000; } else Earthshock_Timer -= diff; DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 uiDiff) { //Return since we have no target if (!UpdateVictim()) return; if (m_bIsAura) { // workaround for PULSING_SHOCKWAVE if (m_uiPulsingShockwave_Timer <= uiDiff) { Map* pMap = me->GetMap(); if (pMap->IsDungeon()) { Map::PlayerList const &PlayerList = pMap->GetPlayers(); if (PlayerList.isEmpty()) return; for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) if (i->getSource() && i->getSource()->isAlive() && i->getSource()->isTargetableForAttack()) { int32 dmg; float m_fDist = me->GetExactDist(i->getSource()->GetPositionX(), i->getSource()->GetPositionY(), i->getSource()->GetPositionZ()); dmg = DUNGEON_MODE(100, 150); // need to correct damage if (m_fDist > 1.0f) // Further from 1 yard dmg = int32(dmg*m_fDist); me->CastCustomSpell(i->getSource(), DUNGEON_MODE(52942, 59837), &dmg, 0, 0, false); } } m_uiPulsingShockwave_Timer = 2000; } else m_uiPulsingShockwave_Timer -= uiDiff; } else { if (m_uiResumePulsingShockwave_Timer <= uiDiff) { //breaks at movement, can we assume when it's time, this spell is casted and also must stop movement? DoCast(me, SPELL_PULSING_SHOCKWAVE_AURA, true); DoCast(me, SPELL_PULSING_SHOCKWAVE_N); // need core support m_bIsAura = true; m_uiResumePulsingShockwave_Timer = 0; } else m_uiResumePulsingShockwave_Timer -= uiDiff; } if (m_uiArcLightning_Timer <= uiDiff) { if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0)) DoCast(pTarget, SPELL_ARC_LIGHTNING); m_uiArcLightning_Timer = 15000 + rand()%1000; } else m_uiArcLightning_Timer -= uiDiff; if (m_uiLightningNova_Timer <= uiDiff) { DoScriptText(RAND(SAY_NOVA_1,SAY_NOVA_2,SAY_NOVA_3), me); DoScriptText(EMOTE_NOVA, me); DoCast(me, SPELL_LIGHTNING_NOVA_N); m_bIsAura = false; m_uiResumePulsingShockwave_Timer = DUNGEON_MODE(5000, 4000); // Pause Pulsing Shockwave aura m_uiLightningNova_Timer = 20000 + rand()%1000; } else m_uiLightningNova_Timer -= uiDiff; // Health check if (HealthBelowPct(100 - 25 * m_uiHealthAmountModifier)) { switch(m_uiHealthAmountModifier) { case 1: DoScriptText(SAY_75HEALTH, me); break; case 2: DoScriptText(SAY_50HEALTH, me); break; case 3: DoScriptText(SAY_25HEALTH, me); break; } ++m_uiHealthAmountModifier; } DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { if (isFlameBreathing) { if (!me->IsNonMeleeSpellCasted(false)) isFlameBreathing = false; else return; } if (isBombing) { if (BombSequenceTimer <= diff) HandleBombSequence(); else BombSequenceTimer -= diff; return; } if (!UpdateVictim()) return; //enrage if under 25% hp before 5 min. if (!enraged && HealthBelowPct(25)) EnrageTimer = 0; if (EnrageTimer <= diff) { if (!enraged) { DoCast(me, SPELL_ENRAGE, true); enraged = true; EnrageTimer = 300000; } else { DoScriptText(SAY_BERSERK, me); DoCast(me, SPELL_BERSERK, true); EnrageTimer = 300000; } } else EnrageTimer -= diff; if (BombTimer <= diff) { DoScriptText(SAY_FIRE_BOMBS, me); me->AttackStop(); me->GetMotionMaster()->Clear(); DoTeleportTo(JanalainPos[0][0], JanalainPos[0][1], JanalainPos[0][2]); me->StopMoving(); DoCast(me, SPELL_FIRE_BOMB_CHANNEL, false); //DoTeleportPlayer(me, JanalainPos[0][0], JanalainPos[0][1], JanalainPos[0][2], 0); //DoCast(me, SPELL_TELE_TO_CENTER, true); FireWall(); SpawnBombs(); isBombing = true; BombSequenceTimer = 100; //Teleport every Player into the middle Map* map = me->GetMap(); if (!map->IsDungeon()) return; Map::PlayerList const &PlayerList = map->GetPlayers(); for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) if (Player* i_pl = i->getSource()) if (i_pl->isAlive()) DoTeleportPlayer(i_pl, JanalainPos[0][0]-5+rand()%10, JanalainPos[0][1]-5+rand()%10, JanalainPos[0][2], 0); //DoCast(Temp, SPELL_SUMMON_PLAYERS, true) // core bug, spell does not work if too far return; } else BombTimer -= diff; if (!noeggs) { if (HealthBelowPct(35)) { DoScriptText(SAY_ALL_EGGS, me); me->AttackStop(); me->GetMotionMaster()->Clear(); DoTeleportTo(JanalainPos[0][0], JanalainPos[0][1], JanalainPos[0][2]); me->StopMoving(); DoCast(me, SPELL_HATCH_ALL, false); HatchAllEggs(2); noeggs = true; } else if (HatcherTimer <= diff) { if (HatchAllEggs(0)) { DoScriptText(SAY_SUMMON_HATCHER, me); me->SummonCreature(MOB_AMANI_HATCHER, hatcherway[0][0][0], hatcherway[0][0][1], hatcherway[0][0][2], 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000); me->SummonCreature(MOB_AMANI_HATCHER, hatcherway[1][0][0], hatcherway[1][0][1], hatcherway[1][0][2], 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000); HatcherTimer = 90000; } else noeggs = true; } else HatcherTimer -= diff; } EnterEvadeIfOutOfCombatArea(diff); DoMeleeAttackIfReady(); if (FireBreathTimer <= diff) { if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) { me->AttackStop(); me->GetMotionMaster()->Clear(); DoCast(target, SPELL_FLAME_BREATH, false); me->StopMoving(); isFlameBreathing = true; } FireBreathTimer = 8000; } else FireBreathTimer -= diff; }
void UpdateAI(const uint32 diff) { if(InciteChaos) { if(InciteChaosWait_Timer < diff) { InciteChaos = false; DoZoneInCombat(); DoResetThreat(); Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0, 50, true); if(target) AttackStart(target); } else InciteChaosWait_Timer -= diff; return; } if (!UpdateVictim()) return; else TrashAggro(); if(InciteChaos_Timer < diff) { DoCast(me, SPELL_INCITE_CHAOS); Map *map = me->GetMap(); Map::PlayerList const &PlayerList = map->GetPlayers(); if(PlayerList.isEmpty()) return; for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) { Player *plr = i->getSource(); Player *target = (Player*)SelectUnit(SELECT_TARGET_RANDOM, 0, 100, true, plr->GetGUID()); if(plr && plr->IsAIEnabled && target) plr->AI()->AttackStart(target); } //DoResetThreat(); InciteChaos = true; InciteChaos_Timer = 40000; InciteChaosWait_Timer = 16000; return; } else InciteChaos_Timer -= diff; //Charge_Timer if (Charge_Timer < diff) { if (Unit *target = SelectUnit(SELECT_TARGET_RANDOM, 0, 50, true)) DoCast(target, SPELL_CHARGE); Charge_Timer = 25000; } else Charge_Timer -= diff; //Knockback_Timer if (Knockback_Timer < diff) { DoCast(me, SPELL_WAR_STOMP); Knockback_Timer = 20000; } else Knockback_Timer -= diff; DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 uiDiff) { //Return since we have no target if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; if (m_bIsAura) { // workaround for PULSING_SHOCKWAVE if (m_uiPulsingShockwave_Timer < uiDiff) { Map *map = m_creature->GetMap(); if (map->IsDungeon()) { Map::PlayerList const &PlayerList = map->GetPlayers(); if (PlayerList.isEmpty()) return; for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) if (i->getSource()->isAlive() && i->getSource()->isTargetableForAttack()) { int32 dmg; float m_fDist = m_creature->GetDistance(i->getSource()); if (m_fDist <= 1.0f) // Less than 1 yard dmg = (m_bIsRegularMode ? 800 : 850); // need to correct damage else // Further from 1 yard dmg = ((m_bIsRegularMode ? 200 : 250) * m_fDist) + (m_bIsRegularMode ? 800 : 850); // need to correct damage m_creature->CastCustomSpell(i->getSource(), (m_bIsRegularMode ? 52942 : 59837), &dmg, 0, 0, false); } } m_uiPulsingShockwave_Timer = 2000; }else m_uiPulsingShockwave_Timer -= uiDiff; } else { if (m_uiResumePulsingShockwave_Timer < uiDiff) { //breaks at movement, can we assume when it's time, this spell is casted and also must stop movement? //m_creature->CastSpell(m_creature, SPELL_PULSING_SHOCKWAVE_AURA, true); //DoCastSpellIfCan(m_creature, m_bIsRegularMode ? SPELL_PULSING_SHOCKWAVE_N : SPELL_PULSING_SHOCKWAVE_H); // need core support m_bIsAura = true; m_uiResumePulsingShockwave_Timer = 0; } else m_uiResumePulsingShockwave_Timer -= uiDiff; } if (m_uiArcLightning_Timer < uiDiff) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) DoCastSpellIfCan(pTarget, SPELL_ARC_LIGHTNING); m_uiArcLightning_Timer = urand(15000, 16000); } else m_uiArcLightning_Timer -= uiDiff; if (m_uiLightningNova_Timer < uiDiff) { switch(urand(0, 2)) { case 0: DoScriptText(SAY_NOVA_1, m_creature);break; case 1: DoScriptText(SAY_NOVA_2, m_creature);break; case 2: DoScriptText(SAY_NOVA_3, m_creature);break; } DoCastSpellIfCan(m_creature, m_bIsRegularMode ? SPELL_LIGHTNING_NOVA_N : SPELL_LIGHTNING_NOVA_H); m_bIsAura = false; m_uiResumePulsingShockwave_Timer = (m_bIsRegularMode ? 5000 : 4000); // Pause Pulsing Shockwave aura m_uiLightningNova_Timer = urand(20000, 21000); } else m_uiLightningNova_Timer -= uiDiff; // Health check if (m_creature->GetHealthPercent() < float(100 - 25*m_uiHealthAmountModifier)) { switch(m_uiHealthAmountModifier) { case 1: DoScriptText(SAY_75HEALTH, m_creature); break; case 2: DoScriptText(SAY_50HEALTH, m_creature); break; case 3: DoScriptText(SAY_25HEALTH, m_creature); break; } ++m_uiHealthAmountModifier; } DoMeleeAttackIfReady(); }
/* Tribute Event */ void instance_dire_maul::GordokTributeEvent(uint32 diff) { if(1<2)return; Creature* pChoRush = instance->GetCreature(m_uiChoRushGUID); Creature* pMizzle = instance->GetCreature(m_uiMizzleGUID); Creature* pTrigger = instance->GetCreature(m_uiTributeTriggerGUID); Map* pMap; pMap = pChoRush->GetMap(); Map::PlayerList const &PlayerList = pMap->GetPlayers(); if ((GetData(TYPE_KING_GORDOK) == DONE) && pMap->GetCreature(m_uiChoRushGUID)->isAlive() && !pChoRushHome) { pChoRush->SetFlag(UNIT_NPC_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_PASSIVE); pChoRush->setFaction(35); pChoRush->DeleteThreatList(); pChoRush->CombatStop(); pChoRush->SetCanAttackPlayer(false); pChoRush->AI()->EnterEvadeMode(); pChoRushHome = true; GossipStepGordok = 1; Text_Timer_Event = 1000; } else if ((TYPE_KING_GORDOK == DONE) && pMap->GetCreature(m_uiChoRushGUID)->isDead()) { for(Map::PlayerList::const_iterator itr = PlayerList.begin(); itr != PlayerList.end(); ++itr) { Player* pPlayer = itr->getSource(); if (pPlayer->IsWithinDistInMap(pTrigger, 30.0f)) pTrigger->CastSpell(pPlayer, SPELL_KING_OF_GORDOK, false); } } if(pChoRushHome) { if (Text_Timer_Event<diff) { switch (GossipStepGordok) { case 1: DoScriptText(ChoRush_SAY_1, pChoRush); pChoRush->HandleEmote(EMOTE_STATE_TALK); pChoRush->SummonCreature(NPC_MIZZLE_THE_CRAFTY, 817.666f, 478.371f, 37.3182f, 3.07057f, TEMPSUMMON_TIMED_DESPAWN, 9000000); Text_Timer_Event = 5000; break; case 2: pChoRush->HandleEmote(EMOTE_STATE_SIT); DoScriptText(Mizzle_SAY_1, pMizzle); pMizzle->HandleEmote(EMOTE_STATE_TALK); Text_Timer_Event = 5000; break; case 3: DoScriptText(Mizzle_SAY_2, pMizzle); pMizzle->HandleEmote(EMOTE_STATE_TALK); Text_Timer_Event = 8000; break; case 4: for(Map::PlayerList::const_iterator itr = PlayerList.begin(); itr != PlayerList.end(); ++itr) { Player* pPlayer = itr->getSource(); if (pPlayer->IsWithinDistInMap(pMizzle, 50.0f)) pMizzle->CastSpell(pPlayer, SPELL_KING_OF_GORDOK, false); } if (pMap->GetCreature(m_uiMoldarGUID)->isAlive() && pMap->GetCreature(m_uiMizzleGUID)->isAlive() && pMap->GetCreature(m_uiFengusGUID)->isAlive()) { pMizzle->SummonObject(pMap, GO_GORDOK_TRIBUTE, 809.899719f, 482.306366f, 37.318359f, 0.212846f); pMizzle->HandleEmote(EMOTE_ONESHOT_APPLAUD); } pChoRushHome = false; break; } } else Text_Timer_Event -= diff; } }
bool NetherBeam(int beamerID) { if(beamerID < 0 || beamerID > 2) return false; Map *map = m_creature->GetMap(); if(!map->IsDungeon()) return false; Unit* uBeamer = Unit::GetUnit(*m_creature, BeamerGUID[beamerID]); if(!uBeamer) return false; Unit* uBeamerHelp = Unit::GetUnit(*m_creature, BeamerhelpGUID[beamerID]); if(!uBeamerHelp) return false; CandidatesGUID[beamerID] = m_creature->GetGUID(); Unit* uCandidate = Unit::GetUnit(*m_creature, CandidatesGUID[beamerID]); if(!uCandidate) return false; int spell_exhaustion = -1; Unit* uLastCandidate = NULL; int creature_portal = -1; int spell_plr = -1; int spell_creature = -1; int spell_beam = -1; // switch beam specific settings/variables uLastCandidate = Unit::GetUnit(*m_creature, LastCandidatesGUID[beamerID]); switch(beamerID) { case 0: // blue spell_exhaustion = SPELL_EXHAUSTION_DOM; //uLastCandidate = lastDOMcandidate; creature_portal = CREATURE_BLUEPORTAL; spell_plr = SPELL_DOMINANCE_PLR; spell_creature = SPELL_DOMINANCE_NS; spell_beam = SPELL_BEAM_DOM; break; case 1: // green spell_exhaustion = SPELL_EXHAUSTION_SER; //uLastCandidate = lastSERcandidate; creature_portal = CREATURE_GREENPORTAL; spell_plr = SPELL_SERENITY_PLR; spell_creature = SPELL_SERENITY_NS; spell_beam = SPELL_BEAM_SER; break; case 2: // red spell_exhaustion = SPELL_EXHAUSTION_PER; //uLastCandidate = lastPERcandidate; creature_portal = CREATURE_REDPORTAL; spell_plr = SPELL_PERSEVERENCE_PLR; spell_creature = SPELL_PERSEVERENCE_NS; spell_beam = SPELL_BEAM_PER; break; default: return false; // oO? something got wrong... } // step throught each player in the list and check, if he is in the beam Map::PlayerList const &PlayerList = map->GetPlayers(); for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) { if(i->getSource() && i->getSource()->isAlive()) { plr = Unit::GetUnit(*m_creature, i->getSource()->GetGUID()); BossDist = m_creature->GetDistance2d(uBeamer); BossAngle = m_creature->GetAngle(uBeamer); PlrDist = plr->GetDistance2d(uBeamer); PlrAngle = plr->GetAngle(uBeamer); if((BossAngle - degrad10) < PlrAngle // is in range? && PlrAngle < (BossAngle + degrad10) // is in range? && PlrDist < BossDist // is in range? && !plr->HasAura(spell_exhaustion,0) // hasn't yet the spell? && plr->isAlive()) { // is alive? uCandidate = plr; // ok, take him as candidate if(beamerID==2) // red beam PLRonRedBeam = true; } } } if(uCandidate == m_creature) { if(uCandidate != uLastCandidate) { if(uBeamer) { uBeamer->DealDamage(uBeamerHelp, uBeamerHelp->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); if(uBeamerHelp) { BeamerhelpGUID[beamerID] = 0; uBeamerHelp = NULL; uBeamerHelp = uBeamer->SummonCreature(creature_portal,RandomedCoords[beamerID][0],RandomedCoords[beamerID][1],RandomedCoords[beamerID][2],0,TEMPSUMMON_CORPSE_DESPAWN,0); BeamerhelpGUID[beamerID] = uBeamerHelp->GetGUID(); uBeamerHelp->SetUInt32Value(UNIT_FIELD_DISPLAYID, 11686); uBeamerHelp->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); uBeamerHelp->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); } } uLastCandidate = uCandidate; } uBeamerHelp = Unit::GetUnit(*m_creature, BeamerhelpGUID[beamerID]); if(uBeamer) uBeamer->CastSpell(m_creature,spell_creature,true); if(uBeamerHelp) uBeamerHelp->CastSpell(uCandidate,spell_beam,true); } else { if(uCandidate != uLastCandidate) { if(uBeamer) { uBeamer->DealDamage(uBeamerHelp, uBeamerHelp->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); if(uBeamerHelp) { BeamerhelpGUID[beamerID] = 0; uBeamerHelp = NULL; uBeamerHelp = uBeamer->SummonCreature(creature_portal,RandomedCoords[beamerID][0],RandomedCoords[beamerID][1],RandomedCoords[beamerID][2],0,TEMPSUMMON_CORPSE_DESPAWN,0); BeamerhelpGUID[beamerID] = uBeamerHelp->GetGUID(); uBeamerHelp->SetUInt32Value(UNIT_FIELD_DISPLAYID, 11686); uBeamerHelp->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); uBeamerHelp->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); } } uLastCandidate = uCandidate; ExhaustHandler(uCandidate,beamerID); } uBeamerHelp = Unit::GetUnit(*m_creature, BeamerhelpGUID[beamerID]); if(uBeamer) uBeamer->CastSpell(uCandidate,spell_plr,true); if(uBeamerHelp) uBeamerHelp->CastSpell(uCandidate,spell_beam,true); } LastCandidatesGUID[beamerID] = uLastCandidate->GetGUID(); CandidatesGUID[beamerID] = uCandidate->GetGUID(); return true; }
CanCastResult BSWScriptedAI::_BSWSpellSelector(uint8 m_uiSpellIdx, Unit* pTarget) { BSWRecord* pSpell = &m_BSWRecords[m_uiSpellIdx]; Unit* pSummon = NULL; CanCastResult result = CAST_FAIL_OTHER; debug_log("BSW: Casting spell number %u type %u",pSpell->m_uiSpellEntry[currentDifficulty], pSpell->m_CastTarget); if (pSpell->m_uiSpellTimerMax[currentDifficulty] >= HOUR*IN_MILLISECONDS) m_creature->InterruptNonMeleeSpells(true); switch (pSpell->m_CastTarget) { case DO_NOTHING: result = CAST_OK; break; case CAST_ON_SELF: result = _BSWCastOnTarget(m_creature, m_uiSpellIdx); break; case CAST_ON_SUMMONS: result = _BSWCastOnTarget(pTarget, m_uiSpellIdx); break; case CAST_ON_VICTIM: pTarget = m_creature->getVictim(); result = _BSWCastOnTarget(pTarget, m_uiSpellIdx); break; case CAST_ON_RANDOM: pTarget = _doSelect(0, false, 60.0f); result = _BSWCastOnTarget(pTarget, m_uiSpellIdx); break; case CAST_ON_BOTTOMAGGRO: pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_BOTTOMAGGRO,0); result = _BSWCastOnTarget(pTarget, m_uiSpellIdx); break; case CAST_ON_TARGET: result = _BSWCastOnTarget(pTarget, m_uiSpellIdx); break; case APPLY_AURA_SELF: if (_doAura(m_uiSpellIdx, m_creature, EFFECT_INDEX_0)) result = CAST_OK; else result = CAST_FAIL_OTHER; break; case APPLY_AURA_TARGET: if (!pTarget || !pTarget->IsInMap(m_creature)) { result = CAST_FAIL_OTHER; break; } if (_doAura(m_uiSpellIdx, pTarget, EFFECT_INDEX_0)) result = CAST_OK; else result = CAST_FAIL_OTHER; break; case SUMMON_NORMAL: pSummon = _doSummon(m_uiSpellIdx, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 5000); if(pSummon) result = CAST_OK; else result = 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) result = CAST_OK; else result = CAST_FAIL_OTHER; break; case SUMMON_INSTANT: pSummon = _doSummon(m_uiSpellIdx, TEMPSUMMON_MANUAL_DESPAWN,0); if(pSummon) result = CAST_OK; else result = CAST_FAIL_OTHER; break; case CAST_ON_ALLPLAYERS: { Map* pMap = m_creature->GetMap(); Map::PlayerList const& pPlayers = pMap->GetPlayers(); if (!pPlayers.isEmpty()) { for (Map::PlayerList::const_iterator itr = pPlayers.begin(); itr != pPlayers.end(); ++itr) { pTarget = itr->getSource(); if (pTarget && pTarget->isAlive() && pTarget->IsWithinDistInMap(m_creature, pSpell->LocData.x)) { if (!pSpell->m_IsBugged) { m_creature->CastSpell(pTarget, pSpell->m_uiSpellEntry[currentDifficulty], false); } else { _BSWDoCast(m_uiSpellIdx, pTarget); }; result = CAST_OK; }; } } else result = CAST_FAIL_OTHER; } break; case CAST_ON_FRENDLY: pTarget = DoSelectLowestHpFriendly(pSpell->LocData.x,0); result = _BSWCastOnTarget(pTarget, m_uiSpellIdx); break; case CAST_ON_FRENDLY_LOWHP: pTarget = DoSelectLowestHpFriendly(pSpell->LocData.x,1); result = _BSWCastOnTarget(pTarget, m_uiSpellIdx); break; case CAST_ON_RANDOM_POINT: if (!pTarget) pTarget = m_creature; if (pSpell->LocData.z <= 1.0f) { float fPosX, fPosY, fPosZ; if (!pTarget->IsPositionValid() || !pTarget->IsInMap(m_creature)) { 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]); result = CAST_FAIL_OTHER; break; } 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"); result = CAST_FAIL_OTHER; break; } if (SpellEntry const *spell = (SpellEntry *)GetSpellStore()->LookupEntry(pSpell->m_uiSpellEntry[currentDifficulty])) if (SpellRangeEntry const *pSpellRange = GetSpellRangeStore()->LookupEntry(spell->rangeIndex)) if (m_creature->GetDistance(fPosX, fPosY, fPosZ) <= pSpellRange->maxRange) { m_creature->CastSpell(fPosX, fPosY, fPosZ, pSpell->m_uiSpellEntry[currentDifficulty], false); result = CAST_OK; break; }; result = CAST_FAIL_TOO_FAR; } else result = CAST_FAIL_OTHER; break; case CAST_ON_RANDOM_PLAYER: if ( pSpell->LocData.x < 1 ) pTarget = _doSelect(0, false, 60.0f); else pTarget = _doSelect(0, false, (float)pSpell->LocData.x); result = _BSWCastOnTarget(pTarget, m_uiSpellIdx); break; case APPLY_AURA_ALLPLAYERS: { Map* pMap = m_creature->GetMap(); 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(m_creature, pSpell->LocData.x)) { _doAura(m_uiSpellIdx, pTarget, EFFECT_INDEX_0); result = CAST_OK; } } } break; case FORCE_CAST: result = _BSWDoForceCast(m_uiSpellIdx, pTarget); break; case SPELLTABLEPARM_NUMBER: default: error_log("BSW: FAILED casting spell number %u type %u - type not exists",pSpell->m_uiSpellEntry[currentDifficulty], pSpell->m_CastTarget); result = CAST_FAIL_OTHER; break; }; if (pSpell->textEntry && result == CAST_OK) { if (pTarget) DoScriptText(pSpell->textEntry,m_creature,pTarget); else DoScriptText(pSpell->textEntry,m_creature); }; debug_log("BSW: Casted spell number %u, result = %u",pSpell->m_uiSpellEntry[currentDifficulty], result); return result; };
void SetData(uint32 type, uint32 data) { switch (type) { case DATA_RAGEWINTERCHILLEVENT: Encounters[0] = data; break; case DATA_ANETHERONEVENT: Encounters[1] = data; break; case DATA_KAZROGALEVENT: Encounters[2] = data; break; case DATA_AZGALOREVENT: { Encounters[3] = data; if (data == DONE) { if (ArchiYell)break; ArchiYell = true; Creature* pCreature = instance->GetCreature(Azgalor); if (pCreature) { Creature* pUnit = pCreature->SummonCreature(21987,pCreature->GetPositionX(),pCreature->GetPositionY(),pCreature->GetPositionZ(),0,TEMPSUMMON_TIMED_DESPAWN,10000); Map* pMap = pCreature->GetMap(); if (pMap->IsDungeon() && pUnit) { pUnit->SetVisibility(VISIBILITY_OFF); Map::PlayerList const &PlayerList = pMap->GetPlayers(); if (PlayerList.isEmpty()) return; for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) { if (i->getSource()) { WorldPacket data(SMSG_MESSAGECHAT, 200); pUnit->BuildMonsterChat(&data,CHAT_MSG_MONSTER_YELL,YELL_EFFORTS,0,YELL_EFFORTS_NAME,i->getSource()->GetGUID()); i->getSource()->GetSession()->SendPacket(&data); WorldPacket data2(SMSG_PLAY_SOUND, 4); data2 << 10986; i->getSource()->GetSession()->SendPacket(&data2); } } } } } } break; case DATA_ARCHIMONDEEVENT: Encounters[4] = data; break; case DATA_RESET_TRASH_COUNT: Trash = 0; break; case DATA_TRASH: if (data) Trash = data; else Trash--; UpdateWorldState(WORLD_STATE_ENEMYCOUNT, Trash); break; case DATA_ALLIANCE_RETREAT: allianceRetreat = data; OpenDoor(HordeGate,true); SaveToDB(); break; case DATA_HORDE_RETREAT: hordeRetreat = data; OpenDoor(ElfGate,true); SaveToDB(); break; case DATA_RAIDDAMAGE: RaidDamage += data; if (RaidDamage >= MINRAIDDAMAGE) RaidDamage = MINRAIDDAMAGE; break; case DATA_RESET_RAIDDAMAGE: RaidDamage = 0; break; } debug_log("BSCR: Instance Hyjal: Instance data updated for event %u (Data=%u)",type,data); if (data == DONE) SaveToDB(); }
void UpdateAI(const uint32 uiDiff) override { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; if (m_uiAchievCheck) { if (m_uiAchievCheck < uiDiff) { Map *map = m_creature->GetMap(); if (map->IsDungeon()) { Map::PlayerList const &PlayerList = map->GetPlayers(); for(Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) { if (i->getSource()->GetTotalAuraModValue(UNIT_MOD_RESISTANCE_FROST) > 100.0f) { if (m_pInstance) { m_pInstance->SetSpecialAchievementCriteria(TYPE_ACHIEV_HUNDRED_CLUB, false); m_uiAchievCheck = 0; } } } m_uiAchievCheck = 1000; } } else m_uiAchievCheck -= uiDiff; } switch (m_Phase) { case PHASE_GROUND: if (m_uiCleaveTimer < uiDiff) { if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_CLEAVE) == CAST_OK) m_uiCleaveTimer = urand(5000, 10000); } else m_uiCleaveTimer -= uiDiff; if (m_uiTailSweepTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, m_bIsRegularMode ? SPELL_TAIL_SWEEP : SPELL_TAIL_SWEEP_H) == CAST_OK) m_uiTailSweepTimer = urand(7000, 10000); } else m_uiTailSweepTimer -= uiDiff; if (m_uiLifeDrainTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, m_bIsRegularMode ? SPELL_LIFE_DRAIN : SPELL_LIFE_DRAIN_H) == CAST_OK) m_uiLifeDrainTimer = 23000; } else m_uiLifeDrainTimer -= uiDiff; if (m_uiBlizzardTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_SUMMON_BLIZZARD) == CAST_OK) m_uiBlizzardTimer = 20000; } else m_uiBlizzardTimer -= uiDiff; if (m_creature->GetHealthPercent() > 10.0f) { if (m_uiFlyTimer < uiDiff) { m_Phase = PHASE_LIFT_OFF; m_creature->InterruptNonMeleeSpells(false); SetCombatMovement(false); m_creature->GetMotionMaster()->Clear(false); m_creature->GetMotionMaster()->MovePoint(1, aLiftOffPosition[0], aLiftOffPosition[1], aLiftOffPosition[2]); // TODO This should clear the target, too return; } else m_uiFlyTimer -= uiDiff; } // Only Phase in which we have melee attack! DoMeleeAttackIfReady(); break; case PHASE_LIFT_OFF: break; case PHASE_AIR_BOLTS: // WOTLK Changed, originally was 5 if (m_uiIceboltCount == (uint32)(m_bIsRegularMode ? 2 : 3)) { if (m_uiFrostBreathTimer < uiDiff) { m_Phase = PHASE_AIR_BREATH; DoScriptText(EMOTE_BREATH, m_creature); DoCastSpellIfCan(m_creature, SPELL_FROST_BREATH_DUMMY); m_uiFrostBreathTimer = 7000; } else m_uiFrostBreathTimer -= uiDiff; } else { if (m_uiIceboltTimer < uiDiff) { DoCastSpellIfCan(m_creature, SPELL_ICEBOLT); ++m_uiIceboltCount; m_uiIceboltTimer = 4000; } else m_uiIceboltTimer -= uiDiff; } break; case PHASE_AIR_BREATH: if (m_uiFrostBreathTimer) { if (m_uiFrostBreathTimer <= uiDiff) { DoCastSpellIfCan(m_creature, SPELL_FROST_BREATH_A, CAST_TRIGGERED); DoCastSpellIfCan(m_creature, SPELL_FROST_BREATH_B, CAST_TRIGGERED); m_uiFrostBreathTimer = 0; m_uiLandTimer = 4000; } else m_uiFrostBreathTimer -= uiDiff; } if (m_uiLandTimer) { if (m_uiLandTimer <= uiDiff) { RemoveAuraAndIce(); // Begin Landing DoScriptText(EMOTE_GROUND, m_creature); m_creature->HandleEmote(EMOTE_ONESHOT_LAND); m_creature->SetLevitate(false); m_Phase = PHASE_LANDING; m_uiLandTimer = 2000; } else m_uiLandTimer -= uiDiff; } break; case PHASE_LANDING: if (m_uiLandTimer < uiDiff) { m_Phase = PHASE_GROUND; SetCombatMovement(false); m_creature->GetMotionMaster()->Clear(false); m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); m_uiFlyTimer = 67000; m_uiLandTimer = 0; } else m_uiLandTimer -= uiDiff; break; } // Enrage can happen in any phase if (m_uiBerserkTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_BESERK) == CAST_OK) { DoScriptText(EMOTE_GENERIC_ENRAGED, m_creature); m_uiBerserkTimer = 300000; } } else m_uiBerserkTimer -= uiDiff; }
void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; switch (stage) { case 0: { bsw->timedCast(SPELL_FEROCIOUS_BUTT, uiDiff); bsw->timedCast(SPELL_ARCTIC_BREATH, uiDiff); bsw->timedCast(SPELL_WHIRL, uiDiff); if (bsw->timedQuery(SPELL_MASSIVE_CRASH, uiDiff)) stage = 1; bsw->timedCast(SPELL_FROTHING_RAGE, uiDiff); DoMeleeAttackIfReady(); break; } case 1: { if (bsw->doCast(SPELL_MASSIVE_CRASH) == CAST_OK) stage = 2; break; } case 2: { if (pTarget = bsw->SelectUnit()) { TrampleCasted = false; m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); stage = 3; bsw->resetTimer(SPELL_TRAMPLE); DoScriptText(-1713506,m_creature,pTarget); SetCombatMovement(false); m_creature->GetMotionMaster()->MoveIdle(); } break; } case 3: { if (bsw->timedQuery(SPELL_TRAMPLE,uiDiff)) { pTarget->GetPosition(fPosX, fPosY, fPosZ); TrampleCasted = false; MovementStarted = true; m_creature->GetMotionMaster()->MovePoint(1, fPosX, fPosY, fPosZ); DoScriptText(-1713508,m_creature); bsw->doCast(SPELL_ADRENALINE); stage = 4; } break; } case 4: { if (MovementStarted) { Map* pMap = m_creature->GetMap(); Map::PlayerList const &lPlayers = pMap->GetPlayers(); for(Map::PlayerList::const_iterator itr = lPlayers.begin(); itr != lPlayers.end(); ++itr) { Unit* pPlayer = itr->getSource(); if (!pPlayer) continue; if (pPlayer->isAlive() && pPlayer->IsWithinDistInMap(m_creature, 5.0f)) { bsw->doCast(SPELL_TRAMPLE, pPlayer); TrampleCasted = true; MovementStarted = false; m_creature->GetMotionMaster()->MovementExpired(); m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); } } } else stage = 5; if (TrampleCasted) stage = 5; break; } case 5: { if (!TrampleCasted) { bsw->doCast(SPELL_STAGGERED_DAZE); DoScriptText(-1713507,m_creature); } MovementStarted = false; m_creature->GetMotionMaster()->MovementExpired(); m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); SetCombatMovement(true); m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); stage = 0; break; } } }
void SetData(uint32 type, uint32 data) { switch(type) { case DATA_RAGEWINTERCHILLEVENT: m_auiEncounter[0] = data; break; case DATA_ANETHERONEVENT: m_auiEncounter[1] = data; break; case DATA_KAZROGALEVENT: m_auiEncounter[2] = data; break; case DATA_AZGALOREVENT: { m_auiEncounter[3] = data; if (data == DONE) { if (ArchiYell)break; ArchiYell = true; Creature* creature = instance->GetCreature(Azgalor); if (creature) { Creature* pUnit = creature->SummonCreature(21987,creature->GetPositionX(),creature->GetPositionY(),creature->GetPositionZ(),0,TEMPSUMMON_TIMED_DESPAWN,10000); Map* pMap = creature->GetMap(); if (pMap->IsDungeon() && pUnit) { pUnit->SetVisible(false); Map::PlayerList const &PlayerList = pMap->GetPlayers(); if (PlayerList.isEmpty()) return; for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) { if (i->getSource()) { WorldPacket data(SMSG_MESSAGECHAT, 200); pUnit->BuildMonsterChat(&data,CHAT_MSG_MONSTER_YELL,YELL_EFFORTS,0,YELL_EFFORTS_NAME,i->getSource()->GetGUID()); i->getSource()->GetSession()->SendPacket(&data); WorldPacket data2(SMSG_PLAY_SOUND, 4); data2 << 10986; i->getSource()->GetSession()->SendPacket(&data2); } } } } } } break; case DATA_ARCHIMONDEEVENT: m_auiEncounter[4] = data; break; case DATA_RESET_TRASH_COUNT: Trash = 0; break; case DATA_TRASH: if (data) Trash = data; else Trash--; DoUpdateWorldState(WORLD_STATE_ENEMYCOUNT, Trash); break; case TYPE_RETREAT: if (data == SPECIAL) { if (!m_uiAncientGemGUID.empty()) { for (std::list<uint64>::const_iterator itr = m_uiAncientGemGUID.begin(); itr != m_uiAncientGemGUID.end(); ++itr) { //don't know how long it expected DoRespawnGameObject(*itr,DAY); } } } break; case DATA_ALLIANCE_RETREAT: allianceRetreat = data; HandleGameObject(HordeGate, true); SaveToDB(); break; case DATA_HORDE_RETREAT: hordeRetreat = data; HandleGameObject(ElfGate, true); SaveToDB(); break; case DATA_RAIDDAMAGE: RaidDamage += data; if (RaidDamage >= MINRAIDDAMAGE) RaidDamage = MINRAIDDAMAGE; break; case DATA_RESET_RAIDDAMAGE: RaidDamage = 0; break; } sLog->outDebug(LOG_FILTER_TSCR, "TSCR: Instance Hyjal: Instance data updated for event %u (Data=%u)",type,data); if (data == DONE) { OUT_SAVE_INST_DATA; std::ostringstream saveStream; saveStream << m_auiEncounter[0] << " " << m_auiEncounter[1] << " " << m_auiEncounter[2] << " " << m_auiEncounter[3] << " " << m_auiEncounter[4] << " " << allianceRetreat << " " << hordeRetreat << " " << RaidDamage; str_data = saveStream.str(); SaveToDB(); OUT_SAVE_INST_DATA_COMPLETE; } }
void UpdateAI(const uint32 diff) { //Return since we have no target if (!UpdateVictim() /*|| !m_creature->getVictim()*/ )//rotate resets target return; //Check if players in water and if in water cast spell Map *map = m_creature->GetMap(); if (map->IsDungeon() && pInstance->GetData(DATA_THELURKERBELOWEVENT) == IN_PROGRESS) { Map::PlayerList const &PlayerList = map->GetPlayers(); if (PlayerList.isEmpty()) return; for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) { if (i->getSource()->isAlive() && i->getSource()->IsInWater() && !i->getSource()->HasAura(SPELL_SCALDINGWATER, 0)) i->getSource()->CastSpell(i->getSource(), SPELL_SCALDINGWATER, true); else if(!i->getSource()->IsInWater()) i->getSource()->RemoveAurasDueToSpell(SPELL_SCALDINGWATER); } } Rotate(diff);//always check rotate things if(!Submerged) { if(PhaseTimer < diff) { m_creature->InterruptNonMeleeSpells(false); DoCast(m_creature,SPELL_SUBMERGE); PhaseTimer = 60000;//60secs submerged Submerged = true; } else PhaseTimer-=diff; } if(!Submerged && RotType == NOROTATE)//is not spouting and not submerged { if(SpoutTimer < diff) { if(m_creature->getVictim() && RotType == NOROTATE) StartRotate(m_creature->getVictim());//start spout and random rotate SpoutTimer= 35000; return; } else SpoutTimer -= diff; //Whirl directly after a Spout and at random times if(WhirlTimer < diff) { WhirlTimer = rand()%5000 + 15000; DoCast(m_creature,SPELL_WHIRL); WaterboltTimer += 5000;//add 5secs to waterbolt timer, to add some time to run back to boss } else WhirlTimer -= diff; if(GeyserTimer < diff) { Unit* target = NULL; target = SelectUnit(SELECT_TARGET_RANDOM,1); if(target) DoCast(target,SPELL_GEYSER,true); else target = SelectUnit(SELECT_TARGET_RANDOM,0); if(target) DoCast(target,SPELL_GEYSER,true); GeyserTimer = rand()%5000 + 15000; } else GeyserTimer -= diff; if(WaterboltTimer < diff) { Unit* target = SelectUnit(SELECT_TARGET_NEAREST,0,14,true); if(!target) { target = SelectUnit(SELECT_TARGET_RANDOM,0); if(target) DoCast(target,SPELL_WATERBOLT); } WaterboltTimer = 3000; } else WaterboltTimer -= diff; if (!UpdateVictim() ) return; DoMeleeAttackIfReady(); } else if(!Submerged) return; else if(Submerged)//phase 2, submerged { if(PhaseTimer < diff) { Submerged = false; m_creature->InterruptNonMeleeSpells(false);//shouldn't be any m_creature->RemoveAllAuras(); m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); m_creature->RemoveFlag(UNIT_NPC_EMOTESTATE,EMOTE_STATE_SUBMERGED); m_creature->RemoveFlag(UNIT_FIELD_BYTES_1,9); DoCast(m_creature,SPELL_EMERGE); Spawned = false; SpoutTimer = 4000; // directly cast Spout after emerging! WhirlTimer = 26000; PhaseTimer = 120000; return; } else PhaseTimer-=diff; if(!m_creature->isInCombat()) m_creature->SetInCombatState(false); if(!Spawned) { m_creature->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); //spawn adds for (uint8 i = 0; i < 9; ++i) { Creature* Summoned; if(i < 7) Summoned = m_creature->SummonCreature(MOB_COILFANG_AMBUSHER,AddPos[i][0],AddPos[i][1],AddPos[i][2], 0, TEMPSUMMON_CORPSE_DESPAWN, 0); else Summoned = m_creature->SummonCreature(MOB_COILFANG_GUARDIAN,AddPos[i][0],AddPos[i][1],AddPos[i][2], 0, TEMPSUMMON_CORPSE_DESPAWN, 0); if(Summoned) Summons.Summon(Summoned); Spawned = true; } } } }
void UpdateAI(const uint32 diff) { if (!UpdateVictim()) return; if (ResetTimer <= diff) { if (me->IsWithinDist3d(119.223f, 1035.45f, 29.4481f, 10)) { EnterEvadeMode(); return; } ResetTimer = 5000; } else ResetTimer -= diff; if (CheckAddState_Timer <= diff) { for (uint8 i = 0; i < 4; ++i) if (Creature *pTemp = Unit::GetCreature(*me, AddGUID[i])) if (pTemp->isAlive() && !pTemp->getVictim()) pTemp->AI()->AttackStart(me->getVictim()); CheckAddState_Timer = 5000; } else CheckAddState_Timer -= diff; if (DrainPower_Timer <= diff) { DoCast(me, SPELL_DRAIN_POWER, true); Map *map = me->GetMap(); if (!map->IsDungeon()) return; Map::PlayerList const &PlayerList = map->GetPlayers(); for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) { if (Player* i_pl = i->getSource()) if (i_pl->isAlive())me->AddAura(44132, me); //+1% Damage for each active player on boss (+ActivePlayer_Stack) } //me->AddAura(44132, me); me->MonsterYell(YELL_DRAIN_POWER, LANG_UNIVERSAL, NULL); DoPlaySoundToSet(me, SOUND_YELL_DRAIN_POWER); DrainPower_Timer = urand(40000, 55000); // must cast in 60 sec, or buff/debuff will disappear } else DrainPower_Timer -= diff; if (SpiritBolts_Timer <= diff) { if (DrainPower_Timer < 12000) // channel 10 sec SpiritBolts_Timer = 13000; // cast drain power first else { DoCast(me, SPELL_SPIRIT_BOLTS, true); me->MonsterYell(YELL_SPIRIT_BOLTS, LANG_UNIVERSAL, NULL); DoPlaySoundToSet(me, SOUND_YELL_SPIRIT_BOLTS); SpiritBolts_Timer = 40000; SiphonSoul_Timer = 10000; // ready to drain PlayerAbility_Timer = 99999; } } else SpiritBolts_Timer -= diff; if (SiphonSoul_Timer <= diff) { Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 70, true); Unit *trigger = DoSpawnCreature(MOB_TEMP_TRIGGER, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN, 30000); if (!pTarget || !trigger) { EnterEvadeMode(); return; } else { trigger->SetDisplayId(11686); trigger->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); trigger->CastSpell(pTarget, SPELL_SIPHON_SOUL, true); trigger->GetMotionMaster()->MoveChase(me); //DoCast(pTarget, SPELL_SIPHON_SOUL, true); //me->SetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT, pTarget->GetGUID()); //me->SetUInt32Value(UNIT_CHANNEL_SPELL, SPELL_SIPHON_SOUL); PlayerGUID = pTarget->GetGUID(); PlayerAbility_Timer = urand(8000, 10000); PlayerClass = pTarget->getClass() - 1; if (PlayerClass == 10) PlayerClass = 9; // druid else if (PlayerClass == 4 && pTarget->HasSpell(15473)) PlayerClass = 5; // shadow priest SiphonSoul_Timer = 99999; // buff lasts 30 sec } } else SiphonSoul_Timer -= diff; if (PlayerAbility_Timer <= diff) { //Unit *pTarget = Unit::GetUnit(*me, PlayerGUID); //if (pTarget && pTarget->isAlive()) //{ UseAbility(); PlayerAbility_Timer = urand(8000, 10000); //} } else PlayerAbility_Timer -= diff; DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; if (!m_pInstance || m_pInstance->GetData(TYPE_KELTHUZAD) != IN_PROGRESS) return; if (m_uiPhase == PHASE_INTRO) { if (m_uiIntroPackCount < 7) { if (m_uiSummonIntroTimer < uiDiff) { if (!m_uiIntroPackCount) DoScriptText(SAY_SUMMON_MINIONS, m_creature); SummonIntroCreatures(m_uiIntroPackCount); ++m_uiIntroPackCount; m_uiSummonIntroTimer = 2000; } else m_uiSummonIntroTimer -= uiDiff; } else { if (m_uiPhase1Timer < uiDiff) { m_uiPhase = PHASE_NORMAL; DespawnIntroCreatures(); m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); SetCombatMovement(true); m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); DoScriptText(EMOTE_PHASE2, m_creature); switch(urand(0, 2)) { case 0: DoScriptText(SAY_AGGRO1, m_creature); break; case 1: DoScriptText(SAY_AGGRO2, m_creature); break; case 2: DoScriptText(SAY_AGGRO3, m_creature); break; }; } else m_uiPhase1Timer -= uiDiff; if (m_uiSoldierCount < MAX_SOLDIER_COUNT) { if (m_uiSoldierTimer < uiDiff) { SummonMob(NPC_SOLDIER_FROZEN); ++m_uiSoldierCount; m_uiSoldierTimer = 3000; } else m_uiSoldierTimer -= uiDiff; } if (m_uiAbominationCount < MAX_ABOMINATION_COUNT) { if (m_uiAbominationTimer < uiDiff) { SummonMob(NPC_UNSTOPPABLE_ABOM); ++m_uiAbominationCount; m_uiAbominationTimer = 25000; } else m_uiAbominationTimer -= uiDiff; } if (m_uiBansheeCount < MAX_BANSHEE_COUNT) { if (m_uiBansheeTimer < uiDiff) { SummonMob(NPC_SOUL_WEAVER); ++m_uiBansheeCount; m_uiBansheeTimer = 25000; } else m_uiBansheeTimer -= uiDiff; } } } else // normal or guardian phase { if (m_uiFrostBoltTimer < uiDiff) { if (DoCastSpellIfCan(m_creature->getVictim(), m_bIsRegularMode ? SPELL_FROST_BOLT : SPELL_FROST_BOLT_H) == CAST_OK) m_uiFrostBoltTimer = urand(1000, 60000); } else m_uiFrostBoltTimer -= uiDiff; if (m_uiFrostBoltNovaTimer < uiDiff) { if (DoCastSpellIfCan(m_creature->getVictim(), m_bIsRegularMode ? SPELL_FROST_BOLT_NOVA : SPELL_FROST_BOLT_NOVA_H) == CAST_OK) m_uiFrostBoltNovaTimer = 15000; } else m_uiFrostBoltNovaTimer -= uiDiff; //Check for Mana Detonation if (m_uiManaDetonationTimer < uiDiff) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,1)) if (pTarget->getPowerType() == POWER_MANA) { int32 curPower = pTarget->GetPower(POWER_MANA); if (curPower < (m_bIsRegularMode ? 4000 : 5500)) return; m_creature->CastSpell(pTarget,SPELL_MANA_DETONATION, true); int32 manareduction = m_bIsRegularMode ? urand(2500,4000) : urand(3500,5500); int32 mana = curPower - manareduction; pTarget->SetPower(POWER_MANA, mana); Map *map = m_creature->GetMap(); if (map->IsDungeon()) { Map::PlayerList const &PlayerList = map->GetPlayers(); if (!PlayerList.isEmpty()) for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) { if (i->getSource()->isAlive() && pTarget->GetDistance2d(i->getSource()->GetPositionX(), i->getSource()->GetPositionY()) < 15) i->getSource()->DealDamage(i->getSource(), manareduction, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, true); } } } if (rand()%2) DoScriptText(SAY_SPECIAL1_MANA_DET, m_creature); m_uiManaDetonationTimer = 15000; }else m_uiManaDetonationTimer -= uiDiff; if (m_uiShadowFissureTimer < uiDiff) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) { m_creature->CastSpell(pTarget,SPELL_SHADOW_FISSURE,true); m_uiShadowFissureActiveTimer = 3000; if (urand(0, 1)) DoScriptText(SAY_SPECIAL3_MANA_DET, m_creature); } m_uiShadowFissureTimer = 25000; } else m_uiShadowFissureTimer -= uiDiff; if(m_uiShadowFissureActiveTimer) if(m_uiShadowFissureActiveTimer < uiDiff) { // hack for shadow fissure // TODO: find energy beam visual spell m_uiShadowFissureActiveTimer = 0; Creature* pFissure = GetClosestCreatureWithEntry(m_creature, NPC_SHADOW_FISSURE, 100.0f); if(!pFissure) return; Map::PlayerList const& pPlayers = m_creature->GetMap()->GetPlayers(); for (Map::PlayerList::const_iterator itr = pPlayers.begin(); itr != pPlayers.end(); ++itr) if(itr->getSource()->GetDistance2d(pFissure) < 2.0f) pFissure->DealDamage(itr->getSource(),itr->getSource()->GetHealth(),NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); } else m_uiShadowFissureActiveTimer -= uiDiff; if (m_uiFrostBlastTimer < uiDiff) { if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_FROST_BLAST) == CAST_OK) { if (urand(0, 1)) DoScriptText(SAY_FROST_BLAST, m_creature); m_uiFrostBlastTimer = urand(30000, 60000); } } else m_uiFrostBlastTimer -= uiDiff; // not sure if this is right //if (!m_bIsRegularMode) //{ if (m_uiChainsTimer < uiDiff) { if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_CHAINS_OF_KELTHUZAD) == CAST_OK) { DoScriptText(urand(0, 1) ? SAY_CHAIN1 : SAY_CHAIN2, m_creature); m_uiChainsTimer = urand(30000, 60000); } } else m_uiChainsTimer -= uiDiff; //} if (m_uiPhase == PHASE_NORMAL) { if (m_creature->GetHealthPercent() < 45.0f) { m_uiPhase = PHASE_GUARDIANS; DoScriptText(SAY_REQUEST_AID, m_creature); // here Lich King should respond to Kel'Thuzad but I don't know which creature to make talk // so for now just make Kel'Thuzad says it. DoScriptText(SAY_ANSWER_REQUEST, m_creature); } } else if (m_uiPhase == PHASE_GUARDIANS && m_uiGuardiansCount < m_uiGuardiansCountMax) { if (m_uiGuardiansTimer < uiDiff) { // Summon a Guardian of Icecrown in a random alcove SummonMob(NPC_GUARDIAN); m_uiGuardiansTimer = 5000; } else m_uiGuardiansTimer -= uiDiff; } DoMeleeAttackIfReady(); } }
void UpdateAI(const uint32 diff) { if(isFlameBreathing) { if(!m_creature->IsNonMeleeSpellCasted(false)) { isFlameBreathing = false; }else return; } if(isBombing) { if(BombSequenceTimer < diff) { HandleBombSequence(); }else BombSequenceTimer -= diff; return; } if(!m_creature->SelectHostilTarget() && !m_creature->getVictim()) return; //enrage if under 25% hp before 5 min. if(!enraged && m_creature->GetHealth() * 4 < m_creature->GetMaxHealth()) EnrageTimer = 0; if(EnrageTimer < diff) { if(!enraged) { m_creature->CastSpell(m_creature, SPELL_ENRAGE, true); enraged = true; EnrageTimer = 300000; } else { DoScriptText(SAY_BERSERK, m_creature); m_creature->CastSpell(m_creature, SPELL_BERSERK, true); EnrageTimer = 300000; } }else EnrageTimer -= diff; if(BombTimer < diff) { DoScriptText(SAY_FIRE_BOMBS, m_creature); m_creature->AttackStop(); m_creature->GetMotionMaster()->Clear(); m_creature->Relocate(JanalainPos[0][0],JanalainPos[0][1],JanalainPos[0][2],0); m_creature->SendMonsterMove(JanalainPos[0][0], JanalainPos[0][1],JanalainPos[0][2],0,0,0); m_creature->StopMoving(); m_creature->CastSpell(m_creature, SPELL_FIRE_BOMB_CHANNEL, false); //DoTeleportPlayer(m_creature, JanalainPos[0][0], JanalainPos[0][1],JanalainPos[0][2], 0); //m_creature->CastSpell(m_creature, SPELL_TELE_TO_CENTER, true); FireWall(); SpawnBombs(); isBombing = true; BombSequenceTimer = 100; //Teleport every Player into the middle Map *map = m_creature->GetMap(); if(!map->IsDungeon()) return; Map::PlayerList const &PlayerList = map->GetPlayers(); if (!PlayerList.isEmpty()) return; for(Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) { if(i->getSource()->isAlive()) DoTeleportPlayer(i->getSource(), JanalainPos[0][0]-5+rand()%10, JanalainPos[0][1]-5+rand()%10, JanalainPos[0][2], 0); } //m_creature->CastSpell(Temp, SPELL_SUMMON_PLAYERS, true); // core bug, spell does not work if too far return; }else BombTimer -= diff; if (!noeggs) { if(100 * m_creature->GetHealth() < 35 * m_creature->GetMaxHealth()) { m_creature->AttackStop(); m_creature->GetMotionMaster()->Clear(); m_creature->Relocate(JanalainPos[0][0],JanalainPos[0][1],JanalainPos[0][2],0); m_creature->SendMonsterMove(JanalainPos[0][0], JanalainPos[0][1],JanalainPos[0][2],0,0,0); m_creature->StopMoving(); m_creature->CastSpell(m_creature, SPELL_HATCH_ALL, false); HatchAllEggs(2); noeggs = true; } else if(HatcherTimer < diff) { if(HatchAllEggs(0)) { DoScriptText(SAY_SUMMON_HATCHER, m_creature); m_creature->SummonCreature(MOB_AMANI_HATCHER,hatcherway[0][0][0],hatcherway[0][0][1],hatcherway[0][0][2],0,TEMPSUMMON_CORPSE_TIMED_DESPAWN,10000); m_creature->SummonCreature(MOB_AMANI_HATCHER,hatcherway[1][0][0],hatcherway[1][0][1],hatcherway[1][0][2],0,TEMPSUMMON_CORPSE_TIMED_DESPAWN,10000); HatcherTimer = 90000; } else noeggs = true; }else HatcherTimer -= diff; } if(ResetTimer < diff) { float x, y, z; m_creature->GetPosition(x, y, z); if(x < -70 || x > 0 || y > 1176 || y < 1121 || z < 18) EnterEvadeMode(); ResetTimer = 5000; }else ResetTimer -= diff; DoMeleeAttackIfReady(); if(FireBreathTimer < diff) { if(Unit* target = SelectUnit(SELECT_TARGET_RANDOM,0)) { m_creature->AttackStop(); m_creature->GetMotionMaster()->Clear(); m_creature->CastSpell(target, SPELL_FLAME_BREATH, false); m_creature->StopMoving(); isFlameBreathing = true; } FireBreathTimer = 8000; }else FireBreathTimer -= diff; }
void UpdateAI(const uint32 diff) { if (WaterTimer < diff) // every 1000ms { Map *map = m_creature->GetMap(); if(!map->IsDungeon()) return; Map::PlayerList const &players = map->GetPlayers(); if(players.getSize()==0) return; for(Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) { Player* plr = itr->getSource(); if (!plr) continue; if (!(plr)->GetSession() || !(plr)->isAlive()) continue; if (!InCombat && plr->GetDistance(m_creature) < 2.25 && (plr->HasAura(33095, 2))) { if (TimeToSpawn%40 == 0) { DoYell(EMOTE_STOPFISHING, LANG_UNIVERSAL, NULL); } if (FirstVictim == 0) FirstVictim = plr; // Remember the first player who started fishing // the player is trying to catch fish TimeToSpawn--; // Time to spawn reduced for every fishing player by 1 per second } // --> more fishermen(and-women): faster spawn if (!InCombat && (TimeToSpawn<=1)) // effective up to TimeToSpawn seconds of fishing { if (pInstance) pInstance->SetData(DATA_THELURKERBELOWEVENT, IN_PROGRESS); m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); m_creature->RemoveFlag(UNIT_NPC_EMOTESTATE, EMOTE_STATE_SUBMERGED); DoCast(m_creature, SPELL_EMERGE); m_creature->setFaction(14); InCombat = true; if (FirstVictim) { if (FirstVictim->GetSession() && FirstVictim->isAlive()) m_creature->AddThreat(FirstVictim, 1.0f); // guarantee, that first fisher is first in ThreatList } Aggro(NULL); // Put anybody else into the fight (with 0.0 aggro) } if(plr && plr->GetDistance(m_creature ) > 5625) { if (plr->HasAura(SCALDING_WATER,0)) plr->RemoveAurasDueToSpell(SCALDING_WATER); if (plr->IsInWater() && !plr->isGameMaster() && !InCombat) { Fishy = plr->SummonCreature(MOB_COILFANG_FRENZY,plr->GetPositionX(),plr->GetPositionY(),plr->GetPositionZ(),plr->GetOrientation(),TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,15000); if (Fishy) Fishy->AI()->AttackStart(plr); } }else{ if (plr->IsInWater()) { if (!plr->HasAura(SCALDING_WATER,0)) plr->CastSpell(plr,SCALDING_WATER,true); }else{ if (plr->HasAura(SCALDING_WATER,0)) plr->RemoveAurasDueToSpell(SCALDING_WATER); } } } WaterTimer = 1000; }else WaterTimer -= diff; //Return since we have no target if (!m_creature->SelectHostilTarget() || !m_creature->getVictim() ) return; if(!Submerged) { if(SpoutTimer < diff) { //Turning while spouting ;) bit fuzzy but working if (OrientationUpdated == -1) { OrientationUpdated = 0; Unit* target = NULL; target = SelectUnit(SELECT_TARGET_TOPAGGRO,0); m_creature->SetUInt64Value(UNIT_FIELD_TARGET, 0); //DoTextEmote(EMOTE_SPOUT,NULL); SpoutTimer = 5000; switch(rand()%2) { case 0: Clockwise = true; break; case 1: Clockwise = false; break; } guids.clear(); //clear targets return; } else { if(Clockwise) SpoutAngle += PI/100; else SpoutAngle -= PI/100; if(SpoutAngle > 2*PI) SpoutAngle -= 2*PI; if(SpoutAngle < 0) SpoutAngle += 2*PI; //So spin around ya evil fish m_creature->SetUInt64Value(UNIT_FIELD_TARGET, 0); m_creature->SetOrientation(SpoutAngle); m_creature->StopMoving(); //Spout part if(SVTimer < diff) { DoCast(m_creature, SPELL_SPOUT); SVTimer = 850; } SVTimer -= diff; OrientationUpdated++; SpoutTimer = 100; if (OrientationUpdated == 200) { SpoutTimer = 45000; OrientationUpdated = -1; WhirlTimer = 5000; Unit *victim = m_creature->getVictim(); if(victim) { m_creature->SetUInt64Value(UNIT_FIELD_TARGET, victim->GetGUID()); } } } }else SpoutTimer -= diff; if(PhaseTimer >= diff) PhaseTimer -= diff; //need to count the phase timer while spouting too if(OrientationUpdated != -1) return; //Whirl directly after a Spout and at random times if(WhirlTimer < diff) { WhirlTimer = rand()%5000 + 15000; DoCast(m_creature,SPELL_WHIRL); }else WhirlTimer -= diff; if(PhaseTimer < diff) { DoCast(m_creature,SPELL_SUBMERGE); PhaseTimer = 60000; Submerged = true; }else PhaseTimer -= diff; if(GeyserTimer < diff) { Unit* target = NULL; target = SelectUnit(SELECT_TARGET_RANDOM,1); GeyserTimer = rand()%15000 + 10000; if(target) DoCast(target,SPELL_GEYSER); }else GeyserTimer -= diff; if(WaterboltTimer < diff) { Unit* target = NULL; int i = 0; bool meleeTarget = false; target = SelectUnit(SELECT_TARGET_TOPAGGRO,0); if (!target) target = m_creature->getVictim(); while (target) { if( m_creature->IsWithinDistInMap(target, 6)) { meleeTarget = true; break; } target = SelectUnit(SELECT_TARGET_TOPAGGRO,i); i++; } if(!meleeTarget) { DoCast(m_creature->getVictim(),SPELL_WATERBOLT); WaterboltTimer = 3000; } else DoMeleeAttackIfReady(); // WTF ? (1) }else WaterboltTimer -= diff; DoMeleeAttackIfReady(); //(1) } else { if(PhaseTimer < diff) { Submerged = false; m_creature->RemoveAllAuras(); m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); m_creature->RemoveFlag(UNIT_NPC_EMOTESTATE, EMOTE_STATE_SUBMERGED); m_creature->RemoveFlag(UNIT_FIELD_BYTES_1,9); DoCast(m_creature, SPELL_EMERGE); Spawned = false; SpoutTimer = 5000; PhaseTimer = 120000; return; } else { /*if(!m_creature->isInCombat()) m_creature->SetInCombat();*/ PhaseTimer -= diff; } if(!Spawned) { m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); SummonAdd(MOBID_COILFANG_AMBUSHER,AddPos[0][0],AddPos[0][1],AddPos[0][2]); SummonAdd(MOBID_COILFANG_AMBUSHER,AddPos[1][0],AddPos[1][1],AddPos[1][2]); SummonAdd(MOBID_COILFANG_AMBUSHER,AddPos[2][0],AddPos[2][1],AddPos[2][2]); SummonAdd(MOBID_COILFANG_AMBUSHER,AddPos[3][0],AddPos[3][1],AddPos[3][2]); SummonAdd(MOBID_COILFANG_AMBUSHER,AddPos[4][0],AddPos[4][1],AddPos[4][2]); SummonAdd(MOBID_COILFANG_AMBUSHER,AddPos[5][0],AddPos[5][1],AddPos[5][2]); SummonAdd(MOBID_COILFANG_GUARDIAN,AddPos[6][0],AddPos[6][1],AddPos[6][2]); SummonAdd(MOBID_COILFANG_GUARDIAN,AddPos[7][0],AddPos[7][1],AddPos[7][2]); SummonAdd(MOBID_COILFANG_GUARDIAN,AddPos[8][0],AddPos[8][1],AddPos[8][2]); Spawned = true; } } }
void UpdateAI(const uint32 diff) { //Inhibitmagic_Timer if (Inhibitmagic_Timer < diff) { float dist; Map *map = m_creature->GetMap(); Map::PlayerList const &PlayerList = map->GetPlayers(); for(Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) if (Player* i_pl = i->getSource()) if (i_pl->isAlive() && (dist = i_pl->IsWithinDist(m_creature, 45))) { i_pl->RemoveAurasDueToSpell(SPELL_INHIBITMAGIC); m_creature->AddAura(SPELL_INHIBITMAGIC, i_pl); if(dist < 35) m_creature->AddAura(SPELL_INHIBITMAGIC, i_pl); if(dist < 25) m_creature->AddAura(SPELL_INHIBITMAGIC, i_pl); if(dist < 15) m_creature->AddAura(SPELL_INHIBITMAGIC, i_pl); } Inhibitmagic_Timer = 3000+(rand()%1000); }else Inhibitmagic_Timer -= diff; //Return since we have no target if (!UpdateVictim() ) return; //Attractmagic_Timer if (Attractmagic_Timer < diff) { DoCast(m_creature,SPELL_ATTRACTMAGIC); Attractmagic_Timer = 30000; Carnivorousbite_Timer = 1500; }else Attractmagic_Timer -= diff; //Carnivorousbite_Timer if (Carnivorousbite_Timer < diff) { DoCast(m_creature,SPELL_CARNIVOROUSBITE); Carnivorousbite_Timer = 10000; }else Carnivorousbite_Timer -= diff; //FocusFire_Timer if (FocusFire_Timer < diff) { // Summon Focus Fire & Emote Unit *target = SelectUnit(SELECT_TARGET_RANDOM,1); if (target && target->GetTypeId() == TYPEID_PLAYER && target->isAlive()) { focusedTarget = target; m_creature->SummonCreature(ENTRY_FOCUS_FIRE,target->GetPositionX(),target->GetPositionY(),target->GetPositionZ(),0,TEMPSUMMON_TIMED_DESPAWN,5500); // Emote std::string *emote = new std::string("focuses on "); emote->append(target->GetName()); emote->append("!"); DoTextEmote(emote->c_str(),NULL,true); delete emote; } FocusFire_Timer = 15000+(rand()%5000); }else FocusFire_Timer -= diff; DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { if (currentEvent != TYPE_NARALEX_PART3) npc_escortAI::UpdateAI(diff); if (!pInstance) return; if (eventTimer <= diff) { eventTimer = 0; if (pInstance->GetData(currentEvent) == IN_PROGRESS) { switch (currentEvent) { case TYPE_NARALEX_PART1: if (eventProgress == 1) { ++eventProgress; DoScriptText(SAY_TEMPLE_OF_PROMISE, me); me->SummonCreature(NPC_DEVIATE_RAVAGER, -82.1763f, 227.874f, -93.3233f, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 5000); me->SummonCreature(NPC_DEVIATE_RAVAGER, -72.9506f, 216.645f, -93.6756f, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 5000); } break; case TYPE_NARALEX_PART2: if (eventProgress == 1) { ++eventProgress; DoScriptText(SAY_BANISH_THE_SPIRITS, me); DoCast(me, SPELL_SERPENTINE_CLEANSING); //CAST_AI(npc_escort::npc_escortAI, me->AI())->SetCanDefend(false); eventTimer = 30000; me->SummonCreature(NPC_DEVIATE_VIPER, -61.5261f, 273.676f, -92.8442f, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 5000); me->SummonCreature(NPC_DEVIATE_VIPER, -58.4658f, 280.799f, -92.8393f, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 5000); me->SummonCreature(NPC_DEVIATE_VIPER, -50.002f, 278.578f, -92.8442f, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 5000); } else if (eventProgress == 2) { //CAST_AI(npc_escort::npc_escortAI, me->AI())->SetCanDefend(true); DoScriptText(SAY_CAVERNS_PURIFIED, me); pInstance->SetData(TYPE_NARALEX_PART2, DONE); if (me->HasAura(SPELL_SERPENTINE_CLEANSING)) me->RemoveAura(SPELL_SERPENTINE_CLEANSING); } break; case TYPE_NARALEX_PART3: if (eventProgress == 1) { ++eventProgress; eventTimer = 4000; me->SetStandState(UNIT_STAND_STATE_KNEEL); DoScriptText(SAY_EMERALD_DREAM, me); } else if (eventProgress == 2) { ++eventProgress; eventTimer = 15000; //CAST_AI(npc_escort::npc_escortAI, me->AI())->SetCanDefend(false); if (Creature* naralex = pInstance->instance->GetCreature(pInstance->GetData64(DATA_NARALEX))) DoCast(naralex, SPELL_NARALEXS_AWAKENING, true); DoScriptText(EMOTE_AWAKENING_RITUAL, me); } else if (eventProgress == 3) { ++eventProgress; eventTimer = 15000; if (Creature* naralex = pInstance->instance->GetCreature(pInstance->GetData64(DATA_NARALEX))) DoScriptText(EMOTE_TROUBLED_SLEEP, naralex); me->SummonCreature(NPC_DEVIATE_MOCCASIN, 135.943f, 199.701f, -103.529f, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 15000); me->SummonCreature(NPC_DEVIATE_MOCCASIN, 151.08f, 221.13f, -103.609f, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 15000); me->SummonCreature(NPC_DEVIATE_MOCCASIN, 128.007f, 227.428f, -97.421f, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 15000); } else if (eventProgress == 4) { ++eventProgress; eventTimer = 30000; if (Creature* naralex = pInstance->instance->GetCreature(pInstance->GetData64(DATA_NARALEX))) DoScriptText(EMOTE_WRITHE_IN_AGONY, naralex); me->SummonCreature(NPC_NIGHTMARE_ECTOPLASM, 133.413f, 207.188f, -102.469f, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 15000); me->SummonCreature(NPC_NIGHTMARE_ECTOPLASM, 142.857f, 218.645f, -102.905f, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 15000); me->SummonCreature(NPC_NIGHTMARE_ECTOPLASM, 105.102f, 227.211f, -102.752f, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 15000); me->SummonCreature(NPC_NIGHTMARE_ECTOPLASM, 153.372f, 235.149f, -102.826f, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 15000); me->SummonCreature(NPC_NIGHTMARE_ECTOPLASM, 149.524f, 251.113f, -102.558f, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 15000); me->SummonCreature(NPC_NIGHTMARE_ECTOPLASM, 136.208f, 266.466f, -102.977f, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 15000); me->SummonCreature(NPC_NIGHTMARE_ECTOPLASM, 126.167f, 274.759f, -102.962f, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 15000); } else if (eventProgress == 5) { ++eventProgress; if (Creature* naralex = pInstance->instance->GetCreature(pInstance->GetData64(DATA_NARALEX))) DoScriptText(EMOTE_HORRENDOUS_VISION, naralex); me->SummonCreature(NPC_MUTANUS_THE_DEVOURER, 150.872f, 262.905f, -103.503f, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 300000); DoScriptText(SAY_MUTANUS_THE_DEVOURER, me); pInstance->SetData(TYPE_MUTANUS_THE_DEVOURER, IN_PROGRESS); } else if (eventProgress == 6 && pInstance->GetData(TYPE_MUTANUS_THE_DEVOURER) == DONE) { ++eventProgress; eventTimer = 3000; if (Creature* naralex = pInstance->instance->GetCreature(pInstance->GetData64(DATA_NARALEX))) { AchievementEntry const *AchievWC = GetAchievementStore()->LookupEntry(ACHIEVEMENT_WAILING_CAVERNS); if (AchievWC) { Map* pMap = me->GetMap(); if (pMap && pMap->IsDungeon()) { Map::PlayerList const &players = pMap->GetPlayers(); for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) itr->getSource()->CompletedAchievement(AchievWC); } } if (me->HasAura(SPELL_NARALEXS_AWAKENING)) me->RemoveAura(SPELL_NARALEXS_AWAKENING); naralex->SetStandState(UNIT_STAND_STATE_STAND); DoScriptText(SAY_I_AM_AWAKE, naralex); } DoScriptText(SAY_NARALEX_AWAKES, me); } else if (eventProgress == 7) { ++eventProgress; eventTimer = 6000; if (Creature* naralex = pInstance->instance->GetCreature(pInstance->GetData64(DATA_NARALEX))) DoScriptText(SAY_THANK_YOU, naralex); } else if (eventProgress == 8) { ++eventProgress; eventTimer = 8000; if (Creature* naralex = pInstance->instance->GetCreature(pInstance->GetData64(DATA_NARALEX))) { DoScriptText(SAY_FAREWELL, naralex); naralex->AddAura(SPELL_FLIGHT_FORM, naralex); } SetRun(); me->SetStandState(UNIT_STAND_STATE_STAND); me->AddAura(SPELL_FLIGHT_FORM, me); } else if (eventProgress == 9) { ++eventProgress; eventTimer = 1500; if (Creature* naralex = pInstance->instance->GetCreature(pInstance->GetData64(DATA_NARALEX))) naralex->GetMotionMaster()->MovePoint(25, naralex->GetPositionX(), naralex->GetPositionY(), naralex->GetPositionZ()); } else if (eventProgress == 10) { ++eventProgress; eventTimer = 2500; if (Creature* naralex = pInstance->instance->GetCreature(pInstance->GetData64(DATA_NARALEX))) { naralex->GetMotionMaster()->MovePoint(0, 117.095512f, 247.107971f, -96.167870f); naralex->GetMotionMaster()->MovePoint(1, 90.388809f, 276.135406f, -83.389801f); } me->GetMotionMaster()->MovePoint(26, 117.095512f, 247.107971f, -96.167870f); me->GetMotionMaster()->MovePoint(27, 144.375443f, 281.045837f, -82.477135f); } else if (eventProgress == 11) { if (Creature* naralex = pInstance->instance->GetCreature(pInstance->GetData64(DATA_NARALEX))) naralex->SetVisible(false); me->SetVisible(false); pInstance->SetData(TYPE_NARALEX_PART3, DONE); } break; } } } else eventTimer -= diff; }
void UpdateEscortAI(const uint32 diff) { if (!m_pInstance) return; Unit* pPlayer = GetPlayerForEscort(); if (!pPlayer) return; EventStarter = pPlayer; Unit* Naralex = Unit::GetUnit(*m_creature, m_pInstance->GetData64(DATA_NARALEX)); if (!Naralex) return; if (Event_Timer && Event_Timer <= diff) { switch (Point) { case 0: { Debug(Point); Map *map = m_creature->GetMap(); if (map && map->IsDungeon()) { Map::PlayerList const &PlayerList = map->GetPlayers(); if (!PlayerList.isEmpty()) { for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) { if (i->getSource()->isAlive() && (i->getSource()->GetDistance(m_creature)<30)) m_creature->CastSpell(i->getSource(),SPELL_MARK,false); } } } SetEscortPaused(false); Event_Timer = 0; break; } case 1: Debug(Point); SetEscortPaused(false); Event_Timer = 0; break; case 15: Debug(Point); switch (Subevent_Phase) { case 0: DoScriptText(SAY_BEFORE_CIRCLE,m_creature); Subevent_Phase = 1; Event_Timer = 2000; break; case 1: m_creature->CastSpell(m_creature,SPELL_CLEANSING,false); Subevent_Phase = 2; Event_Timer = 30000; break; case 2: for (int i=0; i <3; ++i) { SummonAttacker(MOB_DEVIATE_VIPER,Position[i][0],Position[i][1],Position[i][2]); } Subevent_Phase = 3; Event_Timer = 2000; break; case 3: if (!m_creature->isInCombat() && !pPlayer->isInCombat()) { DoScriptText(SAY_AFTER_CIRCLE,m_creature); Point = 16; Event_Timer = 2000; SetEscortPaused(false); break; } else { Event_Timer = 2000; Subevent_Phase = 3; break; } } break; case 30: Debug(Point); SetEscortPaused(true); switch (Subevent_Phase) { case 0: DoScriptText(SAY_BEFORE_RITUAL,m_creature); Subevent_Phase = 1; Event_Timer = 2000; break; case 1: m_creature->CastSpell(m_creature,SPELL_AWAKENING,false); DoScriptText(EMOTE_DISCIPLE_1,m_creature); Subevent_Phase = 2; Event_Timer = 4000; break; case 2: DoScriptText(EMOTE_NARALEX_1, Naralex); Subevent_Phase = 3; Event_Timer = 5000; break; case 3: for (int i = 3; i <6; ++i) { SummonAttacker(MOB_DEVIATE_MOCCASIN, Position[i][0],Position[i][1],Position[i][2]); } Event_Timer = 40000; Subevent_Phase = 4; break; case 4: for (int i = 3; i <10; ++i) { SummonAttacker(MOB_NIGHTMARE_ECTOPLASM, Position[i][0],Position[i][1],Position[i][2]); } Event_Timer = 40000; Subevent_Phase = 5; break; case 5: Subevent_Phase = 6; Event_Timer = 10000; DoScriptText(EMOTE_NARALEX_2,Naralex); DoScriptText(SAY_BEFORE_MUTANOUS,m_creature); break; case 6: SummonAttacker(MOB_MUTANOUS_DEVOURER, Position[4][0],Position[4][1],Position[4][2]); Subevent_Phase = 7; Event_Timer = 2000; break; case 7: if (m_pInstance->GetData(TYPE_MUTANOUS) == DONE) { Naralex->SetByteValue(UNIT_FIELD_BYTES_1,0,UNIT_STAND_STATE_SIT); DoScriptText(SAY_NARALEX_AWAKEN,Naralex); m_creature->InterruptNonMeleeSpells(false,SPELL_AWAKENING); m_creature->RemoveAurasDueToSpell(SPELL_AWAKENING); m_pInstance->SetData(TYPE_DISCIPLE,DONE); Event_Timer = 2000; Subevent_Phase = 8; break; }else { Event_Timer = 2000; Subevent_Phase = 7; break; } case 8: DoScriptText(SAY_DISCIPLE_FINAL,m_creature); Subevent_Phase = 9; Event_Timer = 5000; break; case 9: DoScriptText(SAY_NARALEX_FINAL1,Naralex); Naralex->SetByteValue(UNIT_FIELD_BYTES_1,0,UNIT_STAND_STATE_STAND); Event_Timer = 5000; Subevent_Phase = 10; break; case 10: DoScriptText(SAY_NARALEX_FINAL2,Naralex); m_creature->CastSpell(m_creature,SPELL_SHAPESHIFT,false); Naralex->CastSpell(Naralex,SPELL_SHAPESHIFT,false); Event_Timer = 10000; Subevent_Phase = 11; break; case 11: m_creature->SendMonsterMove(Position[9][0],Position[9][1],Position[9][2],0,MONSTER_MOVE_FLY,5000); Naralex->SendMonsterMove(Position[9][0],Position[9][1],Position[9][2],0,MONSTER_MOVE_FLY,5000); Event_Timer = 5000; Subevent_Phase = 12; break; case 12: m_creature->SetVisibility(VISIBILITY_OFF); Naralex->SetVisibility(VISIBILITY_OFF); break; } break; default: break; } }else Event_Timer -= diff; if (Potion_Timer < diff) { if ((m_creature->GetHealth()/m_creature->GetMaxHealth())<0.8) m_creature->CastSpell(m_creature, SPELL_POTION, false); Potion_Timer = 45000; } else Potion_Timer -= diff; if (m_creature->isInCombat() && m_creature->isInCombat() && m_creature->getVictim()) { if (!Yelled) { DoScriptText(SAY_ATTACKED,m_creature,m_creature->getVictim()); Yelled = true; } if (Sleep_Timer < diff) { if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM,1)) m_creature->CastSpell(target,SPELL_SLEEP,false); Sleep_Timer = 30000; } else Sleep_Timer -= diff; DoMeleeAttackIfReady(); } }
void SetData(uint32 type, uint32 data) { switch(type) { case DATA_RAGEWINTERCHILLEVENT: Encounters[0] = data; break; case DATA_ANETHERONEVENT: Encounters[1] = data; break; case DATA_KAZROGALEVENT: Encounters[2] = data; break; case DATA_AZGALOREVENT: { Encounters[3] = data; if(data==DONE) { if(ArchiYell)break; ArchiYell = true; Creature* pCreature = instance->GetCreatureInMap(Azgalor); if(pCreature) { Creature* pUnit = pCreature->SummonCreature(21987,pCreature->GetPositionX(),pCreature->GetPositionY(),pCreature->GetPositionZ(),0,TEMPSUMMON_TIMED_DESPAWN,10000); Map *map = pCreature->GetMap(); if (map->IsDungeon() && pUnit) { pUnit->SetVisibility(VISIBILITY_OFF); Map::PlayerList const &PlayerList = map->GetPlayers(); if (PlayerList.isEmpty()) return; for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) { if (i->getSource()) { WorldPacket data(SMSG_MESSAGECHAT, 200); pUnit->BuildMonsterChat(&data,CHAT_MSG_MONSTER_YELL,"All of your efforts have been in vain, for the draining of the World Tree has already begun. Soon the heart of your world will beat no more.",0,"Archimonde",i->getSource()->GetGUID()); i->getSource()->GetSession()->SendPacket(&data); WorldPacket data2(SMSG_PLAY_SOUND, 4); data2 << 10986; i->getSource()->GetSession()->SendPacket(&data2); } } } } } } break; case DATA_ARCHIMONDEEVENT: Encounters[4] = data; break; case DATA_RESET_TRASH_COUNT: Trash = 0; break; case DATA_TRASH: if(data) Trash = data; else Trash--; UpdateWorldState(WORLD_STATE_ENEMYCOUNT, Trash); break; case DATA_ALLIANCE_RETREAT: allianceRetreat = data; OpenDoor(HordeGate,true); SaveToDB(); break; case DATA_HORDE_RETREAT: hordeRetreat = data; OpenDoor(ElfGate,true); SaveToDB(); break; case DATA_RAIDDAMAGE: RaidDamage += data; if(RaidDamage >= MINRAIDDAMAGE) RaidDamage = MINRAIDDAMAGE; break; case DATA_RESET_RAIDDAMAGE: RaidDamage = 0; break; } debug_log("SD2: Instance Hyjal: Instance data updated for event %u (Data=%u)",type,data); if(data == DONE) { OUT_SAVE_INST_DATA; std::ostringstream saveStream; saveStream << Encounters[0] << " " << Encounters[1] << " " << Encounters[2] << " " << Encounters[3] << " " << Encounters[4] << " " << allianceRetreat << " " << hordeRetreat << " " << RaidDamage; str_data = saveStream.str(); SaveToDB(); OUT_SAVE_INST_DATA_COMPLETE; } }
void WaypointReached(uint32 i) { if (!instance) return; switch (i) { case 8: SetRun(false); me->SummonCreature(18764, 2181.87f, 112.46f, 89.45f, 0.26f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); break; case 9: DoScriptText(SAY_TH_ARMORY, me); me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, THRALL_WEAPON_MODEL); //me->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO, THRALL_WEAPON_INFO); //me->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+1, 781); me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, THRALL_SHIELD_MODEL); //me->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+2, THRALL_SHIELD_INFO); //me->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+3, 1038); break; case 10: me->SetDisplayId(THRALL_MODEL_EQUIPPED); break; case 11: SetRun(); break; case 15: me->SummonCreature(MOB_ENTRY_RIFLE, 2200.28f, 137.37f, 87.93f, 5.07f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); me->SummonCreature(MOB_ENTRY_WARDEN, 2197.44f, 131.83f, 87.93f, 0.78f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); me->SummonCreature(MOB_ENTRY_VETERAN, 2203.62f, 135.40f, 87.93f, 3.70f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); me->SummonCreature(MOB_ENTRY_VETERAN, 2200.75f, 130.13f, 87.93f, 1.48f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); break; case 21: me->SummonCreature(MOB_ENTRY_RIFLE, 2135.80f, 154.01f, 67.45f, 4.98f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); me->SummonCreature(MOB_ENTRY_WARDEN, 2144.36f, 151.87f, 67.74f, 4.46f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); me->SummonCreature(MOB_ENTRY_VETERAN, 2142.12f, 154.41f, 67.12f, 4.56f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); me->SummonCreature(MOB_ENTRY_VETERAN, 2138.08f, 155.38f, 67.24f, 4.60f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); break; case 25: me->SummonCreature(MOB_ENTRY_RIFLE, 2102.98f, 192.17f, 65.24f, 6.02f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); me->SummonCreature(MOB_ENTRY_WARDEN, 2108.48f, 198.75f, 65.18f, 5.15f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); me->SummonCreature(MOB_ENTRY_VETERAN, 2106.11f, 197.29f, 65.18f, 5.63f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); me->SummonCreature(MOB_ENTRY_VETERAN, 2104.18f, 194.82f, 65.18f, 5.75f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); break; case 29: DoScriptText(SAY_TH_SKARLOC_MEET, me); me->SummonCreature(ENTRY_SCARLOC, 2036.48f, 271.22f, 63.43f, 5.27f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); //temporary, skarloc should rather be triggered to walk up to thrall break; case 30: SetEscortPaused(true); me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); SetRun(false); break; case 31: DoScriptText(SAY_TH_MOUNTS_UP, me); DoMount(); SetRun(); break; case 37: //possibly regular patrollers? If so, remove this and let database handle them me->SummonCreature(MOB_ENTRY_WATCHMAN, 2124.26f, 522.16f, 56.87f, 3.99f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); me->SummonCreature(MOB_ENTRY_WATCHMAN, 2121.69f, 525.37f, 57.11f, 4.01f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); me->SummonCreature(MOB_ENTRY_SENTRY, 2124.65f, 524.55f, 56.63f, 3.98f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); break; case 59: me->SummonCreature(SKARLOC_MOUNT, 2488.64f, 625.77f, 58.26f, 4.71f, TEMPSUMMON_TIMED_DESPAWN, 10000); DoUnmount(); HadMount = false; SetRun(false); break; case 60: me->HandleEmoteCommand(EMOTE_ONESHOT_EXCLAMATION); //make horsie run off SetEscortPaused(true); me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); instance->SetData(TYPE_THRALL_PART2, DONE); SetRun(); break; case 64: SetRun(false); break; case 68: me->SummonCreature(MOB_ENTRY_BARN_PROTECTOR, 2500.22f, 692.60f, 55.50f, 2.84f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); me->SummonCreature(MOB_ENTRY_BARN_LOOKOUT, 2500.13f, 696.55f, 55.51f, 3.38f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); me->SummonCreature(MOB_ENTRY_BARN_GUARDSMAN, 2500.55f, 693.64f, 55.50f, 3.14f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); me->SummonCreature(MOB_ENTRY_BARN_GUARDSMAN, 2500.94f, 695.81f, 55.50f, 3.14f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); break; case 71: SetRun(); break; case 81: SetRun(false); break; case 83: me->SummonCreature(MOB_ENTRY_CHURCH_PROTECTOR, 2627.33f, 646.82f, 56.03f, 4.28f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 5000); me->SummonCreature(MOB_ENTRY_CHURCH_LOOKOUT, 2624.14f, 648.03f, 56.03f, 4.50f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 5000); me->SummonCreature(MOB_ENTRY_CHURCH_GUARDSMAN, 2625.32f, 649.60f, 56.03f, 4.38f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 5000); me->SummonCreature(MOB_ENTRY_CHURCH_GUARDSMAN, 2627.22f, 649.00f, 56.03f, 4.34f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 5000); break; case 84: DoScriptText(SAY_TH_CHURCH_END, me); SetRun(); break; case 91: me->SetWalk(true); SetRun(false); break; case 93: me->SummonCreature(MOB_ENTRY_INN_PROTECTOR, 2652.71f, 660.31f, 61.93f, 1.67f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); me->SummonCreature(MOB_ENTRY_INN_LOOKOUT, 2648.96f, 662.59f, 61.93f, 0.79f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); me->SummonCreature(MOB_ENTRY_INN_GUARDSMAN, 2657.36f, 662.34f, 61.93f, 2.68f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); me->SummonCreature(MOB_ENTRY_INN_GUARDSMAN, 2656.39f, 659.77f, 61.93f, 2.61f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); break; case 94: if (uint64 TarethaGUID = instance->GetData64(DATA_TARETHA)) { if (Unit* Taretha = Unit::GetUnit((*me), TarethaGUID)) DoScriptText(SAY_TA_ESCAPED, Taretha, me); } break; case 95: DoScriptText(SAY_TH_MEET_TARETHA, me); instance->SetData(TYPE_THRALL_PART3, DONE); SetEscortPaused(true); break; case 96: DoScriptText(SAY_TH_EPOCH_WONDER, me); break; case 97: DoScriptText(SAY_TH_EPOCH_KILL_TARETHA, me); SetRun(); break; case 98: //trigger epoch Yell("Thrall! Come outside and face your fate! ....") //from here, thrall should not never be allowed to move to point 106 which he currently does. break; case 106: { //trigger taretha to run down outside if (Creature* Taretha = instance->instance->GetCreature(instance->GetData64(DATA_TARETHA))) { if (Player* player = GetPlayerForEscort()) CAST_AI(npc_escortAI, (Taretha->AI()))->Start(false, true, player->GetGUID()); } //kill credit Creature for quest Map* map = me->GetMap(); Map::PlayerList const& players = map->GetPlayers(); if (!players.isEmpty() && map->IsDungeon()) { for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) { if (Player* player = itr->getSource()) player->KilledMonsterCredit(20156, 0); } } //alot will happen here, thrall and taretha talk, erozion appear at spot to explain me->SummonCreature(EROZION_ENTRY, 2646.47f, 680.416f, 55.38f, 4.16f, TEMPSUMMON_TIMED_DESPAWN, 120000); } break; case 108: //last waypoint, just set Thrall invisible, respawn is turned off me->SetVisible(false); break; } }
void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; // Crush if (Crush_Timer < uiDiff) { DoCastSpellIfCan(m_creature->getVictim(), SPELL_CRUSH); Crush_Timer = 10000; }else Crush_Timer -= uiDiff; // Infected Wound if (InfectedWound_Timer < uiDiff) { DoCastSpellIfCan(m_creature->getVictim(), SPELL_CRUSH); InfectedWound_Timer = 30000; }else InfectedWound_Timer -= uiDiff; // Summon npcs if (Wave_Timer < uiDiff) { SummonWaves(); Wave_Timer = 15000; }else Wave_Timer -= uiDiff; // Consume if (Consume_Timer < uiDiff) { m_creature->CastSpell(m_creature->getVictim(), m_bIsRegularMode ? SPELL_CONSUME : H_SPELL_CONSUME, true); m_creature->CastSpell(m_creature, m_bIsRegularMode ? SPELL_CONSUME_BUFF : H_SPELL_CONSUME_BUFF, true); Consume_Timer = 15000; }else Consume_Timer -= uiDiff; //Corpse Explosion if (CorpseExplode_Timer < uiDiff) { //DoCastSpellIfCan(m_creature->getVictim(), m_bIsRegularMode ? SPELL_CORPSE_EXPLODE : H_SPELL_CORPSE_EXPLODE); if (Creature* pCorpse = GetClosestCreatureWithEntry(m_creature, NPC_DRAKKARI_INVADER, 85.0f)) { if (!pCorpse->isAlive()) { Map *map = pCorpse->GetMap(); if (map->IsDungeon()) { Map::PlayerList const &PlayerList = map->GetPlayers(); if (PlayerList.isEmpty()) return; for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) { if (i->getSource()->isAlive() && pCorpse->GetDistance2d(i->getSource()->GetPositionX(), i->getSource()->GetPositionY()) <= 5) m_creature->DealDamage(i->getSource(), (m_bIsRegularMode ? urand(3770, 4230) : urand(9425, 10575)), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NATURE, NULL, false); } } } } CorpseExplode_Timer = 15000; }else CorpseExplode_Timer -= uiDiff; DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { //Check if we have a target if (!UpdateVictim()) { //No target so we'll use this section to do our random wispers instance wide //WisperTimer if (WisperTimer <= diff) { Map* pMap = me->GetMap(); if (!pMap->IsDungeon()) return; //Play random sound to the zone Map::PlayerList const &PlayerList = pMap->GetPlayers(); if (!PlayerList.isEmpty()) { for (Map::PlayerList::const_iterator itr = PlayerList.begin(); itr != PlayerList.end(); ++itr) { if (Player* pPlr = itr->getSource()) pPlr->PlayDirectSound(RANDOM_SOUND_WHISPER,pPlr); } } //One random wisper every 90 - 300 seconds WisperTimer = urand(90000,300000); } else WisperTimer -= diff; return; } me->SetUInt64Value(UNIT_FIELD_TARGET, 0); //No instance if (!pInst) return; uint32 currentPhase = pInst->GetData(DATA_CTHUN_PHASE); if (currentPhase == PHASE_CTHUN_STOMACH || currentPhase == PHASE_CTHUN_WEAK) { // EyeTentacleTimer if (EyeTentacleTimer <= diff) { //Spawn the 8 Eye Tentacles in the corret spots SpawnEyeTentacle(0, 20); //south SpawnEyeTentacle(10, 10); //south west SpawnEyeTentacle(20, 0); //west SpawnEyeTentacle(10, -10); //north west SpawnEyeTentacle(0, -20); //north SpawnEyeTentacle(-10, -10); //north east SpawnEyeTentacle(-20, 0); // east SpawnEyeTentacle(-10, 10); // south east EyeTentacleTimer = 30000; // every 30sec in phase 2 } else EyeTentacleTimer -= diff; } switch (currentPhase) { //Transition phase case PHASE_CTHUN_TRANSITION: //PhaseTimer if (PhaseTimer <= diff) { //Switch pInst->SetData(DATA_CTHUN_PHASE, PHASE_CTHUN_STOMACH); //Switch to c'thun model me->InterruptNonMeleeSpells(false); DoCast(me, SPELL_TRANSFORM, false); me->SetFullHealth(); me->SetVisible(true); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE); //Emerging phase //AttackStart(Unit::GetUnit(*me, HoldpPlayer)); DoZoneInCombat(); //Place all units in threat list on outside of stomach Stomach_Map.clear(); std::list<HostileReference*>::const_iterator i = me->getThreatManager().getThreatList().begin(); for (; i != me->getThreatManager().getThreatList().end(); ++i) { //Outside stomach Stomach_Map[(*i)->getUnitGuid()] = false; } //Spawn 2 flesh tentacles FleshTentaclesKilled = 0; //Spawn flesh tentacle for (uint8 i = 0; i < 2; i++) { Creature* spawned = me->SummonCreature(MOB_FLESH_TENTACLE, FleshTentaclePos[i], TEMPSUMMON_CORPSE_DESPAWN); if (!spawned) ++FleshTentaclesKilled; } PhaseTimer = 0; } else PhaseTimer -= diff; break; //Body Phase case PHASE_CTHUN_STOMACH: //Remove Target field me->SetUInt64Value(UNIT_FIELD_TARGET, 0); //Weaken if (FleshTentaclesKilled > 1) { pInst->SetData(DATA_CTHUN_PHASE, PHASE_CTHUN_WEAK); DoScriptText(EMOTE_WEAKENED, me); PhaseTimer = 45000; DoCast(me, SPELL_PURPLE_COLORATION, true); UNORDERED_MAP<uint64, bool>::iterator i = Stomach_Map.begin(); //Kick all players out of stomach while (i != Stomach_Map.end()) { //Check for valid player Unit* pUnit = Unit::GetUnit(*me, i->first); //Only move units in stomach if (pUnit && i->second == true) { //Teleport each player out DoTeleportPlayer(pUnit, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()+10, float(rand()%6)); //Cast knockback on them DoCast(pUnit, SPELL_EXIT_STOMACH_KNOCKBACK, true); //Remove the acid debuff pUnit->RemoveAurasDueToSpell(SPELL_DIGESTIVE_ACID); i->second = false; } ++i; } return; } //Stomach acid if (StomachAcidTimer <= diff) { //Apply aura to all players in stomach UNORDERED_MAP<uint64, bool>::iterator i = Stomach_Map.begin(); while (i != Stomach_Map.end()) { //Check for valid player Unit* pUnit = Unit::GetUnit(*me, i->first); //Only apply to units in stomach if (pUnit && i->second == true) { //Cast digestive acid on them DoCast(pUnit, SPELL_DIGESTIVE_ACID, true); //Check if player should be kicked from stomach if (pUnit->IsWithinDist3d(&KickPos, 15.0f)) { //Teleport each player out DoTeleportPlayer(pUnit, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()+10, float(rand()%6)); //Cast knockback on them DoCast(pUnit, SPELL_EXIT_STOMACH_KNOCKBACK, true); //Remove the acid debuff pUnit->RemoveAurasDueToSpell(SPELL_DIGESTIVE_ACID); i->second = false; } } ++i; } StomachAcidTimer = 4000; } else StomachAcidTimer -= diff; //Stomach Enter Timer if (StomachEnterTimer <= diff) { if (Unit *pTarget = SelectRandomNotStomach()) { //Set target in stomach Stomach_Map[pTarget->GetGUID()] = true; pTarget->InterruptNonMeleeSpells(false); pTarget->CastSpell(pTarget, SPELL_MOUTH_TENTACLE, true, NULL, NULL, me->GetGUID()); StomachEnterTarget = pTarget->GetGUID(); StomachEnterVisTimer = 3800; } StomachEnterTimer = 13800; } else StomachEnterTimer -= diff; if (StomachEnterVisTimer && StomachEnterTarget) { if (StomachEnterVisTimer <= diff) { //Check for valid player Unit* pUnit = Unit::GetUnit(*me, StomachEnterTarget); if (pUnit) { DoTeleportPlayer(pUnit, STOMACH_X, STOMACH_Y, STOMACH_Z, STOMACH_O); } StomachEnterTarget = 0; StomachEnterVisTimer = 0; } else StomachEnterVisTimer -= diff; } //GientClawTentacleTimer if (GiantClawTentacleTimer <= diff) { if (Unit *pTarget = SelectRandomNotStomach()) { //Spawn claw tentacle on the random target if (Creature* spawned = me->SummonCreature(MOB_GIANT_CLAW_TENTACLE, *pTarget, TEMPSUMMON_CORPSE_DESPAWN, 500)) if (spawned->AI()) spawned->AI()->AttackStart(pTarget); } //One giant claw tentacle every minute GiantClawTentacleTimer = 60000; } else GiantClawTentacleTimer -= diff; //GiantEyeTentacleTimer if (GiantEyeTentacleTimer <= diff) { if (Unit *pTarget = SelectRandomNotStomach()) { //Spawn claw tentacle on the random target if (Creature* spawned = me->SummonCreature(MOB_GIANT_EYE_TENTACLE, *pTarget, TEMPSUMMON_CORPSE_DESPAWN, 500)) if (spawned->AI()) spawned->AI()->AttackStart(pTarget); } //One giant eye tentacle every minute GiantEyeTentacleTimer = 60000; } else GiantEyeTentacleTimer -= diff; break; //Weakened state case PHASE_CTHUN_WEAK: //PhaseTimer if (PhaseTimer <= diff) { //Switch pInst->SetData(DATA_CTHUN_PHASE, PHASE_CTHUN_STOMACH); //Remove purple coloration me->RemoveAurasDueToSpell(SPELL_PURPLE_COLORATION); //Spawn 2 flesh tentacles FleshTentaclesKilled = 0; //Spawn flesh tentacle for (uint8 i = 0; i < 2; i++) { Creature* spawned = me->SummonCreature(MOB_FLESH_TENTACLE, FleshTentaclePos[i], TEMPSUMMON_CORPSE_DESPAWN); if (!spawned) ++FleshTentaclesKilled; } PhaseTimer = 0; } else PhaseTimer -= diff; break; } }
void UpdateAI(const uint32 diff) { if (WaitTimer) if (WaitTimer <= diff) { if (Intro) { me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); if (MovePhase >= 7) { me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); me->RemoveUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT | MOVEMENTFLAG_LEVITATING); me->HandleEmoteCommand(EMOTE_ONESHOT_LAND); me->GetMotionMaster()->MovePoint(8, IntroWay[7][0], IntroWay[7][1], IntroWay[7][2]); } else { me->GetMotionMaster()->MovePoint(MovePhase, IntroWay[MovePhase][0], IntroWay[MovePhase][1], IntroWay[MovePhase][2]); ++MovePhase; } } if (Flying) { me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); if (MovePhase >= 7) { me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); me->RemoveUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT | MOVEMENTFLAG_LEVITATING); me->HandleEmoteCommand(EMOTE_ONESHOT_LAND); me->GetMotionMaster()->MovePoint(8, IntroWay[7][0], IntroWay[7][1], IntroWay[7][2]); } else { me->GetMotionMaster()->MovePoint(MovePhase, IntroWay[MovePhase][0], IntroWay[MovePhase][1], IntroWay[MovePhase][2]); ++MovePhase; } } WaitTimer = 0; } else WaitTimer -= diff; if (!UpdateVictim()) return; if (Flying) return; // Phase 1 "GROUND FIGHT" if (Phase == 1) { if (Movement) { DoStartMovement(me->getVictim()); Movement = false; } if (BellowingRoarTimer <= diff) { DoCast(me->getVictim(), SPELL_BELLOWING_ROAR); BellowingRoarTimer = urand(30000, 40000); } else BellowingRoarTimer -= diff; if (SmolderingBreathTimer <= diff) { DoCast(me->getVictim(), SPELL_SMOLDERING_BREATH); SmolderingBreathTimer = 20000; } else SmolderingBreathTimer -= diff; if (DistractingAshTimer <= diff) { if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) DoCast(pTarget, SPELL_DISTRACTING_ASH); DistractingAshTimer = urand(15000, 28000); //timer wrong } else DistractingAshTimer -= diff; if (CharredEarthTimer <= diff) { if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) DoCast(pTarget, SPELL_CHARRED_EARTH); CharredEarthTimer = 20000; } else CharredEarthTimer -= diff; if (TailSweepTimer <= diff) { if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) if (!me->HasInArc(float(M_PI), pTarget)) DoCast(pTarget, SPELL_TAIL_SWEEP); TailSweepTimer = 15000; } else TailSweepTimer -= diff; if (SearingCindersTimer <= diff) { if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) DoCast(pTarget, SPELL_SEARING_CINDERS); SearingCindersTimer = 10000; } else SearingCindersTimer -= diff; uint32 Prozent; Prozent = (me->GetHealth() * 100) / me->GetMaxHealth(); if (Prozent < 75 && FlyCount == 0) // first take off 75% TakeOff(); if (Prozent < 50 && FlyCount == 1) // secound take off 50% TakeOff(); if (Prozent < 25 && FlyCount == 2) // third take off 25% TakeOff(); DoMeleeAttackIfReady(); } //Phase 2 "FLYING FIGHT" if (Phase == 2) { if (!RainBones) { if (RainofBonesTimer <= diff && !RainBones) // only once at the beginning of phase 2 { if (!Skeletons) { for (int i = 0; i < 6; i++) DoCast(me->getVictim(), SPELL_SUMMON_SKELETON, true); RainofBonesTimer = 10000; Skeletons = true; } DoCast(me->getVictim(), SPELL_RAIN_OF_BONES); RainBones = true; SmokingBlastTimer = 20000; } else RainofBonesTimer -= diff; } if (RainBones) { if (SmokingBlastTimer <= diff) { DoCast(me->getVictim(), SPELL_SMOKING_BLAST); SmokingBlastTimer = 1500; //timer wrong } else SmokingBlastTimer -= diff; } if (FireballBarrageTimer <= diff) { Map *map = me->GetMap(); if (!map->IsDungeon()) return; Map::PlayerList const &PlayerList = map->GetPlayers(); for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) { if (Player* i_pl = i->GetSource()) if (i_pl->IsAlive() && !me->IsWithinDistInMap(i_pl, 80)) { DoCast(i_pl, SPELL_FIREBALL_BARRAGE); } } FireballBarrageTimer = 20000; } else FireballBarrageTimer -= diff; if (FlyTimer <= diff) //landing { bool bChance = urand(0, 1); if (bChance) me->MonsterYell(YELL_LAND_PHASE_1, LANG_UNIVERSAL, NULL); else me->MonsterYell(YELL_LAND_PHASE_2, LANG_UNIVERSAL, NULL); me->GetMotionMaster()->Clear(false); me->GetMotionMaster()->MovePoint(3, IntroWay[3][0], IntroWay[3][1], IntroWay[3][2]); Flying = true; } else FlyTimer -= diff; } }
void CreatureAI::DoZoneInCombat(Creature* creature /*= NULL*/, float maxRangeToNearestTarget /* = 50.0f*/) { if (!creature) creature = me; if (!creature->CanHaveThreatList()) return; Map* map = creature->GetMap(); if (!map->IsDungeon()) //use IsDungeon instead of Instanceable, in case battlegrounds will be instantiated { sLog->outError("DoZoneInCombat call for map that isn't an instance (creature entry = %d)", creature->GetTypeId() == TYPEID_UNIT ? creature->ToCreature()->GetEntry() : 0); return; } // Xinef: Skip creatures in evade mode if (!creature->HasReactState(REACT_PASSIVE) && !creature->GetVictim() && !creature->IsInEvadeMode()) { if (Unit* nearTarget = creature->SelectNearestTarget(maxRangeToNearestTarget)) creature->AI()->AttackStart(nearTarget); else if (creature->IsSummon()) { if (Unit* summoner = creature->ToTempSummon()->GetSummoner()) { Unit* target = summoner->getAttackerForHelper(); if (!target && summoner->CanHaveThreatList() && !summoner->getThreatManager().isThreatListEmpty()) target = summoner->getThreatManager().getHostilTarget(); if (target && (creature->IsFriendlyTo(summoner) || creature->IsHostileTo(target))) creature->AI()->AttackStart(target); } } } if (!creature->HasReactState(REACT_PASSIVE) && !creature->GetVictim()) { sLog->outError("DoZoneInCombat called for creature that has empty threat list (creature entry = %u)", creature->GetEntry()); return; } Map::PlayerList const& playerList = map->GetPlayers(); if (playerList.isEmpty()) return; for (Map::PlayerList::const_iterator itr = playerList.begin(); itr != playerList.end(); ++itr) { if (Player* player = itr->GetSource()) { if (player->IsGameMaster()) continue; if (player->IsAlive()) { creature->SetInCombatWith(player); player->SetInCombatWith(creature); creature->AddThreat(player, 0.0f); } /* Causes certain things to never leave the threat list (Priest Lightwell, etc): for (Unit::ControlSet::const_iterator itr = player->m_Controlled.begin(); itr != player->m_Controlled.end(); ++itr) { creature->SetInCombatWith(*itr); (*itr)->SetInCombatWith(creature); creature->AddThreat(*itr, 0.0f); }*/ } } }
void UpdateAI(const uint32 uiDiff) { if(m_uiBirthState == 1) if(m_uiBirthTimer < uiDiff) { m_creature->SetVisibility(VISIBILITY_ON); m_creature->setFaction(21); m_uiBirthState = 2; } else m_uiBirthTimer -= uiDiff; if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; if (m_uiBeserkTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_BESERK) == CAST_OK) { m_uiBeserkTimer = 300000; DoScriptText(EMOTE_ENRAGE, m_creature); } } else m_uiBeserkTimer -= uiDiff; if (m_uiPhase == 1) { if (m_uiLifeDrainTimer < uiDiff) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) { if (DoCastSpellIfCan(pTarget, m_bIsRegularMode ? SPELL_LIFE_DRAIN : H_SPELL_LIFE_DRAIN) == CAST_OK) m_uiLifeDrainTimer = 24000; } } else m_uiLifeDrainTimer -= uiDiff; if (m_uiBlizzardTimer < uiDiff) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) { if (DoCastSpellIfCan(pTarget, m_bIsRegularMode ? SPELL_BLIZZARD : H_SPELL_BLIZZARD) == CAST_OK) m_uiBlizzardTimer = urand(17,20)*IN_MILLISECONDS; } } else m_uiBlizzardTimer -= uiDiff; if (m_uiCleaveTimer < uiDiff) { if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_CLEAVE) == CAST_OK) m_uiCleaveTimer = urand(7000, 10000); } else m_uiCleaveTimer -= uiDiff; if (m_uiTailSweepTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, m_bIsRegularMode ? SPELL_TAIL_SWEEP : H_SPELL_TAIL_SWEEP) == CAST_OK) m_uiTailSweepTimer = urand(10000, 15000); } else m_uiTailSweepTimer -= uiDiff; if (m_creature->GetHealthPercent() > 10.0f) { if (m_uiFlyTimer < uiDiff) { m_uiPhase = 2; m_creature->InterruptNonMeleeSpells(false); m_creature->HandleEmote(EMOTE_ONESHOT_LIFTOFF); m_creature->GetMotionMaster()->Clear(false); m_creature->GetMotionMaster()->MoveIdle(); DoCastSpellIfCan(m_creature,11010); m_creature->SetHover(true); DoCastSpellIfCan(m_creature,18430); m_uiIceboltTimer = 4000; m_uiIceboltCount = 0; m_bLandoff = false; DoScriptText(EMOTE_FLY, m_creature); } else m_uiFlyTimer -= uiDiff; } DoMeleeAttackIfReady(); } else // Phase 2 { if (m_uiIceboltCount < m_uiIceboltCountMax) { if (m_uiIceboltTimer < uiDiff) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) { if(DoCastSpellIfCan(pTarget,SPELL_ICEBOLT) == CAST_OK) { targetGUIDs.push_back(pTarget->GetGUID()); ++m_uiIceboltCount; if (m_uiIceboltCount == m_uiIceboltCountMax) { DoScriptText(EMOTE_BREATH, m_creature); m_uiFrostBreathTimer = 8700; if(pFrostBreathTarget) { pFrostBreathTarget->NearTeleportTo(m_creature->GetPositionX(),m_creature->GetPositionY(),pFrostBreathTarget->GetPositionZ(),0); m_creature->CastSpell(pFrostBreathTarget,SPELL_FROST_BREATH_VISUAL,true); } } m_uiIceboltTimer = 4000; } } } else m_uiIceboltTimer -= uiDiff; } else { if (m_bLandoff) { if (m_uiLandTimer < uiDiff) { m_uiPhase = 1; m_creature->HandleEmote(EMOTE_ONESHOT_LAND); m_creature->SetHover(false); m_creature->GetMotionMaster()->Clear(false); m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); m_uiFlyTimer = 45000; DoScriptText(EMOTE_GROUND, m_creature); } else m_uiLandTimer -= uiDiff; } else { if (m_uiFrostBreathTimer < uiDiff) { if(!pFrostBreathTarget) return; Map *map = m_creature->GetMap(); if (!map->IsDungeon()) return; Map::PlayerList const &PlayerList = map->GetPlayers(); //check for each player for(Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) //check for both iceblocks for(std::vector<uint64>::iterator itr = targetGUIDs.begin(); itr!= targetGUIDs.end(); ++itr) //check if player near iceblock { if(Player* pPlayer = m_creature->GetMap()->GetPlayer(*itr)) if(i->getSource()->GetDistance2d(pPlayer) <= 6.0f) { //check if iceblock is closer to breathtarget then player if(pFrostBreathTarget->GetDistanceOrder(pPlayer,i->getSource(),false)) { i->getSource()->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FROST, true); immunePlayerGUIDs.push_back(i->getSource()->GetGUID()); break; } } } if (DoCastSpellIfCan(m_creature, SPELL_FROST_BREATH) == CAST_OK) { //remove frost immunity for(std::vector<uint64>::iterator itr = immunePlayerGUIDs.begin(); itr!= immunePlayerGUIDs.end(); ++itr) { if(Player* pPlayer = m_creature->GetMap()->GetPlayer(*itr)) pPlayer->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FROST, false); } m_uiLandTimer = 4000; m_bLandoff = true; immunePlayerGUIDs.clear(); targetGUIDs.clear(); } } else m_uiFrostBreathTimer -= uiDiff; } } } }