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* map = me->GetMap(); if (!map->IsDungeon()) return; //Play random sound to the zone Map::PlayerList const &PlayerList = map->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->SetTarget(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->SetTarget(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* target = SelectRandomNotStomach()) { //Set target in stomach Stomach_Map[target->GetGUID()] = true; target->InterruptNonMeleeSpells(false); target->CastSpell(target, SPELL_MOUTH_TENTACLE, true, NULL, NULL, me->GetGUID()); StomachEnterTarget = target->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* target = SelectRandomNotStomach()) { //Spawn claw tentacle on the random target if (Creature* spawned = me->SummonCreature(MOB_GIANT_CLAW_TENTACLE, *target, TEMPSUMMON_CORPSE_DESPAWN, 500)) if (spawned->AI()) spawned->AI()->AttackStart(target); } //One giant claw tentacle every minute GiantClawTentacleTimer = 60000; } else GiantClawTentacleTimer -= diff; //GiantEyeTentacleTimer if (GiantEyeTentacleTimer <= diff) { if (Unit* target = SelectRandomNotStomach()) { //Spawn claw tentacle on the random target if (Creature* spawned = me->SummonCreature(MOB_GIANT_EYE_TENTACLE, *target, TEMPSUMMON_CORPSE_DESPAWN, 500)) if (spawned->AI()) spawned->AI()->AttackStart(target); } //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) { //Check if we have a target if (!UpdateVictim()) return; //No instance if (!pInst) return; uint32 currentPhase = pInst->GetData(DATA_CTHUN_PHASE); if (currentPhase == PHASE_EYE_GREEN_BEAM || currentPhase == PHASE_EYE_RED_BEAM) { // 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 = 45000; } else EyeTentacleTimer -= diff; } switch (currentPhase) { case PHASE_EYE_GREEN_BEAM: //BeamTimer if (BeamTimer <= diff) { //SPELL_GREEN_BEAM if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) { me->InterruptNonMeleeSpells(false); DoCast(target, SPELL_GREEN_BEAM); //Correctly update our target me->SetTarget(target->GetGUID()); } //Beam every 3 seconds BeamTimer = 3000; } else BeamTimer -= diff; //ClawTentacleTimer if (ClawTentacleTimer <= diff) { if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) { Creature* Spawned = NULL; //Spawn claw tentacle on the random target Spawned = me->SummonCreature(MOB_CLAW_TENTACLE, *target, TEMPSUMMON_CORPSE_DESPAWN, 500); if (Spawned && Spawned->AI()) Spawned->AI()->AttackStart(target); } //One claw tentacle every 12.5 seconds ClawTentacleTimer = 12500; } else ClawTentacleTimer -= diff; //PhaseTimer if (PhaseTimer <= diff) { //Switch to Dark Beam pInst->SetData(DATA_CTHUN_PHASE, PHASE_EYE_RED_BEAM); me->InterruptNonMeleeSpells(false); me->SetReactState(REACT_PASSIVE); //Remove any target me->SetTarget(0); //Select random target for dark beam to start on if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) { //Face our target DarkGlareAngle = me->GetAngle(target); DarkGlareTickTimer = 1000; DarkGlareTick = 0; ClockWise = RAND(true, false); } //Add red coloration to C'thun DoCast(me, SPELL_RED_COLORATION, true); //Freeze animation DoCast(me, SPELL_FREEZE_ANIM); me->SetOrientation(DarkGlareAngle); me->StopMoving(); //Darkbeam for 35 seconds PhaseTimer = 35000; } else PhaseTimer -= diff; break; case PHASE_EYE_RED_BEAM: if (DarkGlareTick < 35) { if (DarkGlareTickTimer <= diff) { //Set angle and cast if (ClockWise) me->SetOrientation(DarkGlareAngle + DarkGlareTick * M_PI / 35); else me->SetOrientation(DarkGlareAngle - DarkGlareTick * M_PI / 35); me->StopMoving(); //Actual dark glare cast, maybe something missing here? DoCast(me, SPELL_DARK_GLARE, false); //Increase tick ++DarkGlareTick; //1 second per tick DarkGlareTickTimer = 1000; } else DarkGlareTickTimer -= diff; } //PhaseTimer if (PhaseTimer <= diff) { //Switch to Eye Beam pInst->SetData(DATA_CTHUN_PHASE, PHASE_EYE_GREEN_BEAM); BeamTimer = 3000; ClawTentacleTimer = 12500; //4 per Eye beam phase (unsure if they spawn during Dark beam) me->InterruptNonMeleeSpells(false); //Remove Red coloration from c'thun me->RemoveAurasDueToSpell(SPELL_RED_COLORATION); me->RemoveAurasDueToSpell(SPELL_FREEZE_ANIM); //set it back to aggressive me->SetReactState(REACT_AGGRESSIVE); //Eye Beam for 50 seconds PhaseTimer = 50000; } else PhaseTimer -= diff; break; //Transition phase case PHASE_CTHUN_TRANSITION: //Remove any target me->SetTarget(0); me->SetHealth(0); me->SetVisible(false); break; //Dead phase case PHASE_CTHUN_DONE: Creature* pPortal= me->FindNearestCreature(MOB_CTHUN_PORTAL, 10); if (pPortal) pPortal->DespawnOrUnsummon(); me->DespawnOrUnsummon(); break; } }
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 *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()) { //Play random sound to the zone i_pl->SendPlaySound(RANDOM_SOUND_WHISPER, true); } } //One random wisper every 90 - 300 seconds WisperTimer = 90000 + (rand()% 210000); } else WisperTimer -= diff; return; } me->SetUInt64Value(UNIT_FIELD_TARGET, 0); //No instance if (!pInst) return; switch (pInst->GetData(DATA_CTHUN_PHASE)) { //Transition phase case 2: { //PhaseTimer if (PhaseTimer <= diff) { //Switch pInst->SetData(DATA_CTHUN_PHASE, 3); //Switch to c'thun model me->InterruptNonMeleeSpells(false); DoCast(me, SPELL_TRANSFORM, false); me->SetHealth(me->GetMaxHealth()); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE); //Emerging phase //AttackStart(Unit::GetUnit(*me, HoldPlayer)); DoZoneInCombat(); //Place all units in threat list on outside of stomach Stomach_Map.clear(); std::list<HostileReference*>::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; Creature* Spawned; //Spawn flesh tentacle Spawned = (Creature*)me->SummonCreature(MOB_FLESH_TENTACLE, TENTACLE_POS1_X, TENTACLE_POS1_Y, TENTACLE_POS1_Z, TENTACLE_POS1_O, TEMPSUMMON_CORPSE_DESPAWN, 0); if (!Spawned) FleshTentaclesKilled++; else ((flesh_tentacleAI*)(Spawned->AI()))->SpawnedByCthun(me->GetGUID()); //Spawn flesh tentacle Spawned = (Creature*)me->SummonCreature(MOB_FLESH_TENTACLE, TENTACLE_POS2_X, TENTACLE_POS2_Y, TENTACLE_POS2_Z, TENTACLE_POS2_O, TEMPSUMMON_CORPSE_DESPAWN, 0); if (!Spawned) FleshTentaclesKilled++; else ((flesh_tentacleAI*)(Spawned->AI()))->SpawnedByCthun(me->GetGUID()); PhaseTimer = 0; } else PhaseTimer -= diff; }break; //Body Phase case 3: { //Remove Target field me->SetUInt64Value(UNIT_FIELD_TARGET, 0); //Weaken if (FleshTentaclesKilled > 1) { pInst->SetData(DATA_CTHUN_PHASE, 4); DoScriptText(EMOTE_WEAKENED, me); PhaseTimer = 45000; DoCast(me, SPELL_RED_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->GetDistance(KICK_X, KICK_Y, KICK_Z) < 15) { //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) { Unit* pTarget = NULL; pTarget = SelectRandomNotStomach(); if (pTarget) { //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) { Unit* pTarget = NULL; pTarget = SelectRandomNotStomach(); if (pTarget) { Creature* Spawned = NULL; //Spawn claw tentacle on the random target Spawned = (Creature*)me->SummonCreature(MOB_GIANT_CLAW_TENTACLE,pTarget->GetPositionX(),pTarget->GetPositionY(),pTarget->GetPositionZ(),0,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,500); if (Spawned) Spawned->AI()->AttackStart(pTarget); } //One giant claw tentacle every minute GiantClawTentacleTimer = 60000; } else GiantClawTentacleTimer -= diff; //GiantEyeTentacleTimer if (GiantEyeTentacleTimer <= diff) { Unit* pTarget = NULL; pTarget = SelectRandomNotStomach(); if (pTarget) { Creature* Spawned = NULL; //Spawn claw tentacle on the random target Spawned = (Creature*)me->SummonCreature(MOB_GIANT_EYE_TENTACLE,pTarget->GetPositionX(),pTarget->GetPositionY(),pTarget->GetPositionZ(),0,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,500); if (Spawned) Spawned->AI()->AttackStart(pTarget); } //One giant eye tentacle every minute GiantEyeTentacleTimer = 60000; } else GiantEyeTentacleTimer -= diff; //EyeTentacleTimer if (EyeTentacleTimer <= diff) { //Spawn the 8 Eye Tentacles in the corret spots SpawnEyeTentacle(0, 25); //south SpawnEyeTentacle(12, 12); //south west SpawnEyeTentacle(25, 0); //west SpawnEyeTentacle(12, -12); //north west SpawnEyeTentacle(0, -25); //north SpawnEyeTentacle(-12, -12); //north east SpawnEyeTentacle(-25, 0); // east SpawnEyeTentacle(-12, 12); // south east //These spawn at every 30 seconds EyeTentacleTimer = 30000; } else EyeTentacleTimer -= diff; }break; //Weakened state case 4: { //PhaseTimer if (PhaseTimer <= diff) { //Switch pInst->SetData(DATA_CTHUN_PHASE, 3); //Remove red coloration me->RemoveAurasDueToSpell(SPELL_RED_COLORATION); //Spawn 2 flesh tentacles FleshTentaclesKilled = 0; Creature* Spawned; //Spawn flesh tentacle Spawned = (Creature*)me->SummonCreature(MOB_FLESH_TENTACLE, TENTACLE_POS1_X, TENTACLE_POS1_Y, TENTACLE_POS1_Z, TENTACLE_POS1_O, TEMPSUMMON_CORPSE_DESPAWN, 0); if (!Spawned) FleshTentaclesKilled++; else ((flesh_tentacleAI*)(Spawned->AI()))->SpawnedByCthun(me->GetGUID()); //Spawn flesh tentacle Spawned = (Creature*)me->SummonCreature(MOB_FLESH_TENTACLE, TENTACLE_POS2_X, TENTACLE_POS2_Y, TENTACLE_POS2_Z, TENTACLE_POS2_O, TEMPSUMMON_CORPSE_DESPAWN, 0); if (!Spawned) FleshTentaclesKilled++; else ((flesh_tentacleAI*)(Spawned->AI()))->SpawnedByCthun(me->GetGUID()); PhaseTimer = 0; } else PhaseTimer -= diff; } } }
void UpdateAI(const uint32 diff) { //Check if we have a target if (!UpdateVictim()) return; //No instance if (!pInst) return; switch (pInst->GetData(DATA_CTHUN_PHASE)) { case 0: { //BeamTimer if (BeamTimer <= diff) { //SPELL_GREEN_BEAM Unit* pTarget = NULL; pTarget = SelectUnit(SELECT_TARGET_RANDOM,0); if (pTarget) { me->InterruptNonMeleeSpells(false); DoCast(pTarget,SPELL_GREEN_BEAM); //Correctly update our target me->SetUInt64Value(UNIT_FIELD_TARGET, pTarget->GetGUID()); } //Beam every 3 seconds BeamTimer = 3000; } else BeamTimer -= diff; //ClawTentacleTimer if (ClawTentacleTimer <= diff) { Unit* pTarget = NULL; pTarget = SelectUnit(SELECT_TARGET_RANDOM,0); if (pTarget) { Creature* Spawned = NULL; //Spawn claw tentacle on the random target Spawned = (Creature*)me->SummonCreature(MOB_CLAW_TENTACLE,pTarget->GetPositionX(),pTarget->GetPositionY(),pTarget->GetPositionZ(),0,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,500); if (Spawned) Spawned->AI()->AttackStart(pTarget); } //One claw tentacle every 12.5 seconds ClawTentacleTimer = 12500; } else ClawTentacleTimer -= diff; //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 //No point actually putting a timer here since //These shouldn't trigger agian until after phase shifts EyeTentacleTimer = 45000; } else EyeTentacleTimer -= diff; //PhaseTimer if (PhaseTimer <= diff) { //Switch to Dark Beam pInst->SetData(DATA_CTHUN_PHASE, 1); me->InterruptNonMeleeSpells(false); //Select random target for dark beam to start on Unit* pTarget = NULL; pTarget = SelectUnit(SELECT_TARGET_RANDOM,0); if (pTarget) { //Correctly update our target me->SetUInt64Value(UNIT_FIELD_TARGET, pTarget->GetGUID()); //Face our target DarkGlareAngle = me->GetAngle(pTarget); DarkGlareTickTimer = 1000; DarkGlareTick = 0; ClockWise = rand()%2; } //Add red coloration to C'thun DoCast(me,SPELL_RED_COLORATION); //Freeze animation me->setEmoteState(53); //Darkbeam for 35 seconds PhaseTimer = 35000; } else PhaseTimer -= diff; } break; case 1: { //EyeTentacleTimer if (DarkGlareTick < 35) { if (DarkGlareTickTimer <= diff) { //Remove any target me->SetUInt64Value(UNIT_FIELD_TARGET, 0); //Set angle and cast if (ClockWise) me->SetOrientation(DarkGlareAngle + ((float)DarkGlareTick*PI/35)); else me->SetOrientation(DarkGlareAngle - ((float)DarkGlareTick*PI/35)); me->StopMoving(); //Actual dark glare cast, maybe something missing here? me->CastSpell(me, SPELL_DARK_GLARE, false); //Increase tick DarkGlareTick++; //1 second per tick DarkGlareTickTimer = 1000; } else DarkGlareTickTimer -= diff; } //PhaseTimer if (PhaseTimer <= diff) { //Switch to Eye Beam pInst->SetData(DATA_CTHUN_PHASE, 0); BeamTimer = 3000; EyeTentacleTimer = 45000; //Always spawns 5 seconds before Dark Beam ClawTentacleTimer = 12500; //4 per Eye beam phase (unsure if they spawn durring Dark beam) me->InterruptNonMeleeSpells(false); //Remove Red coloration from c'thun me->RemoveAurasDueToSpell(SPELL_RED_COLORATION); //Freeze animation me->setEmoteState(0); me->SetUInt32Value(UNIT_FIELD_FLAGS, 0); //Eye Beam for 50 seconds PhaseTimer = 50000; } else PhaseTimer -= diff; }break; //Transition phase case 2: { //Remove any target me->SetUInt64Value(UNIT_FIELD_TARGET, 0); me->SetHealth(0); } //Dead phase case 5: { me->DealDamage(me, me->GetMaxHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NONE, NULL, false); } } }
void UpdateAI(const uint32 uiDiff) { // Check if we have a target if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; // No instance if (!m_pInstance) return; switch (m_pInstance->GetData(TYPE_CTHUN_PHASE)) { case PHASE_EYE_NORMAL: { // m_uiBeamTimer if (m_uiBeamTimer < uiDiff) { // SPELL_GREEN_BEAM if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) { m_creature->InterruptNonMeleeSpells(false); DoCastSpellIfCan(pTarget, SPELL_GREEN_BEAM); // Correctly update our target m_creature->SetTargetGuid(pTarget->GetObjectGuid()); } //Beam every 3 seconds m_uiBeamTimer = 3000; } else m_uiBeamTimer -= uiDiff; // m_uiClawTentacleTimer if (m_uiClawTentacleTimer < uiDiff) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) { // Spawn claw tentacle on the random target if (Creature* pSummoned = m_creature->SummonCreature(MOB_CLAW_TENTACLE, pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 500)) pSummoned->AI()->AttackStart(pTarget); } // One claw tentacle every 12.5 seconds m_uiClawTentacleTimer = 12500; } else m_uiClawTentacleTimer -= uiDiff; // m_uiEyeTentacleTimer if (m_uiEyeTentacleTimer < uiDiff) { //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 // No point actually putting a timer here since // These shouldn't trigger agian until after phase shifts m_uiEyeTentacleTimer = 45000; } else m_uiEyeTentacleTimer -= uiDiff; // m_uiPhaseTimer if (m_uiPhaseTimer < uiDiff) { //Switch to Dark Beam m_pInstance->SetData(TYPE_CTHUN_PHASE, PHASE_EYE_DARK_GLARE); m_creature->InterruptNonMeleeSpells(false); // Select random target for dark beam to start on if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) { // Correctly update our target m_creature->SetTargetGuid(pTarget->GetObjectGuid()); // Face our target m_fDarkGlareAngle = m_creature->GetAngle(pTarget); m_uiDarkGlareTickTimer = 1000; m_uiDarkGlareTick = 0; m_bClockWise = urand(0, 1); } // Add red coloration to C'thun DoCastSpellIfCan(m_creature, SPELL_RED_COLORATION); // Freeze animation // Darkbeam for 35 seconds m_uiPhaseTimer = 35000; } else m_uiPhaseTimer -= uiDiff; break; } case PHASE_EYE_DARK_GLARE: { // Dark Glare if (m_uiDarkGlareTick < 35) { if (m_uiDarkGlareTickTimer < uiDiff) { // Remove any target m_creature->SetTargetGuid(ObjectGuid()); // Set angle and cast m_creature->SetOrientation(m_fDarkGlareAngle + (m_bClockWise ? 1 : -1) * ((float)m_uiDarkGlareTick*M_PI_F/35)); m_creature->StopMoving(); // Actual dark glare cast, maybe something missing here? DoCastSpellIfCan(m_creature, SPELL_DARK_GLARE); // Increase tick ++m_uiDarkGlareTick; // 1 second per tick m_uiDarkGlareTickTimer = 1000; } else m_uiDarkGlareTickTimer -= uiDiff; } // m_uiPhaseTimer if (m_uiPhaseTimer < uiDiff) { // Switch to Eye Beam m_pInstance->SetData(TYPE_CTHUN_PHASE, PHASE_EYE_NORMAL); m_uiBeamTimer = 3000; m_uiEyeTentacleTimer = 45000; //Always spawns 5 seconds before Dark Beam m_uiClawTentacleTimer = 12500; //4 per Eye beam phase (unsure if they spawn durring Dark beam) m_creature->InterruptNonMeleeSpells(false); // Remove Red coloration from C'thun m_creature->RemoveAurasDueToSpell(SPELL_RED_COLORATION); // Freeze animation m_creature->SetUInt32Value(UNIT_FIELD_FLAGS, 0); // Eye Beam for 50 seconds m_uiPhaseTimer = 50000; } else m_uiPhaseTimer -= uiDiff; break; } // Transition phase case PHASE_TRANSITION: { // Remove any target m_creature->SetTargetGuid(ObjectGuid()); m_creature->SetHealth(0); // Do not kill yet, to be able to reset on evade break; } // Dead phase case PHASE_FINISH: { m_creature->DealDamage(m_creature, m_creature->GetMaxHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NONE, NULL, false); return; } } }
void UpdateAI(const uint32 uiDiff) { // Check if we have a target if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) { // No target so we'll use this section to do our random wispers instance wide // WisperTimer if (m_uiWisperTimer < uiDiff) { if (!m_creature->GetMap()->IsDungeon()) return; // Play random sound to the map m_creature->GetMap()->PlayDirectSoundToMap(RANDOM_SOUND_WHISPER); // One random wisper every 90 - 300 seconds m_uiWisperTimer = urand(90000, 300000); } else m_uiWisperTimer -= uiDiff; return; } m_creature->SetTargetGuid(ObjectGuid()); // No instance if (!m_pInstance) return; switch (m_pInstance->GetData(TYPE_CTHUN_PHASE)) { // Transition phase case PHASE_TRANSITION: { // PhaseTimer if (m_uiPhaseTimer < uiDiff) { // Switch m_pInstance->SetData(TYPE_CTHUN_PHASE, PHASE_CTHUN); // Switch to C'thun model m_creature->InterruptNonMeleeSpells(false); DoCastSpellIfCan(m_creature, SPELL_TRANSFORM); m_creature->SetHealth(m_creature->GetMaxHealth()); m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE); // Emerging phase m_creature->SetInCombatWithZone(); // Place all units in threat list on outside of stomach m_mStomachMap.clear(); ThreatList const& tList = m_creature->getThreatManager().getThreatList(); for (ThreatList::const_iterator i = tList.begin();i != tList.end(); ++i) { // Outside stomach, only players if ((*i)->getUnitGuid().IsPlayer()) m_mStomachMap[(*i)->getUnitGuid()] = false; } // Spawn 2 flesh tentacles m_uiFleshTentaclesKilled = 0; // Spawn flesh tentacle Creature* pSpawned = m_creature->SummonCreature(MOB_FLESH_TENTACLE, TENTACLE_POS1_X, TENTACLE_POS1_Y, TENTACLE_POS1_Z, TENTACLE_POS1_O, TEMPSUMMON_CORPSE_DESPAWN, 0); if (!pSpawned) ++m_uiFleshTentaclesKilled; else { if (flesh_tentacleAI* pTentacleAI = dynamic_cast<flesh_tentacleAI*>(pSpawned->AI())) pTentacleAI->SpawnedByCthun(m_creature); } // Spawn flesh tentacle pSpawned = m_creature->SummonCreature(MOB_FLESH_TENTACLE, TENTACLE_POS2_X, TENTACLE_POS2_Y, TENTACLE_POS2_Z, TENTACLE_POS2_O, TEMPSUMMON_CORPSE_DESPAWN, 0); if (!pSpawned) ++m_uiFleshTentaclesKilled; else { if (flesh_tentacleAI* pTentacleAI = dynamic_cast<flesh_tentacleAI*>(pSpawned->AI())) pTentacleAI->SpawnedByCthun(m_creature); } m_uiPhaseTimer = 0; } else m_uiPhaseTimer -= uiDiff; break; } // Body Phase case PHASE_CTHUN: { // Weaken if (m_uiFleshTentaclesKilled > 1) { m_pInstance->SetData(TYPE_CTHUN_PHASE, PHASE_CTHUN_WEAKENED); DoScriptText(EMOTE_WEAKENED, m_creature); m_uiPhaseTimer = 45000; DoCastSpellIfCan(m_creature, SPELL_RED_COLORATION, CAST_TRIGGERED); // Kick all players out of stomach for (StomachMap::iterator itr = m_mStomachMap.begin(); itr != m_mStomachMap.end(); ++itr) { // Check for valid player Player* pPlayer = m_creature->GetMap()->GetPlayer(itr->first); if (pPlayer && itr->second == true) { // Teleport each player out DoTeleportPlayer(pPlayer, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ()+10, rand()%6); // Cast knockback on them DoCastSpellIfCan(pPlayer, SPELL_EXIT_STOMACH_KNOCKBACK, CAST_TRIGGERED); // Remove the acid debuff pPlayer->RemoveAurasDueToSpell(SPELL_DIGESTIVE_ACID); itr->second = false; } } return; } // Stomach acid if (m_uiStomachAcidTimer < uiDiff) { // Apply aura to all players in stomach for (StomachMap::iterator itr = m_mStomachMap.begin(); itr != m_mStomachMap.end(); ++itr) { // Check for valid player Player* pPlayer = m_creature->GetMap()->GetPlayer(itr->first); // Only apply to units in stomach if (pPlayer && itr->second == true) { // Cast digestive acid on them DoCastSpellIfCan(pPlayer, SPELL_DIGESTIVE_ACID, CAST_TRIGGERED); // Check if player should be kicked from stomach if (pPlayer->IsWithinDist3d(KICK_X, KICK_Y, KICK_Z, 10.0f)) { // Teleport each player out DoTeleportPlayer(pPlayer, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ()+10, rand()%6); // Cast knockback on them DoCastSpellIfCan(pPlayer, SPELL_EXIT_STOMACH_KNOCKBACK, CAST_TRIGGERED); // Remove the acid debuff pPlayer->RemoveAurasDueToSpell(SPELL_DIGESTIVE_ACID); itr->second = false; } } } m_uiStomachAcidTimer = 4000; } else m_uiStomachAcidTimer -= uiDiff; // Stomach Enter Timer if (m_uiStomachEnterTimer < uiDiff) { if (Player* pTarget = SelectRandomNotStomach()) { // Set target in stomach m_mStomachMap[pTarget->GetObjectGuid()] = true; pTarget->InterruptNonMeleeSpells(false); pTarget->CastSpell(pTarget, SPELL_MOUTH_TENTACLE, true, NULL, NULL, m_creature->GetObjectGuid()); m_stomachEnterTargetGuid = pTarget->GetObjectGuid(); m_uiStomachEnterVisTimer = 3800; } m_uiStomachEnterTimer = 13800; } else m_uiStomachEnterTimer -= uiDiff; if (m_uiStomachEnterVisTimer && m_stomachEnterTargetGuid) { if (m_uiStomachEnterVisTimer <= uiDiff) { // Check for valid player if (Player* pPlayer = m_creature->GetMap()->GetPlayer(m_stomachEnterTargetGuid)) DoTeleportPlayer(pPlayer, STOMACH_X, STOMACH_Y, STOMACH_Z, STOMACH_O); m_stomachEnterTargetGuid.Clear(); m_uiStomachEnterVisTimer = 0; // Note that actually C'Thun cannot be soloed, so kill all players, if no player left outside of stomach bool bKillAllPlayer = true; for (StomachMap::iterator itr = m_mStomachMap.begin(); itr != m_mStomachMap.end(); ++itr) { Player* pPlayer = m_creature->GetMap()->GetPlayer(itr->first); if (itr->second == false && pPlayer) { bKillAllPlayer = false; break; } } if (bKillAllPlayer) { for (StomachMap::iterator itr = m_mStomachMap.begin(); itr != m_mStomachMap.end(); ++itr) { if (Player* pPlayer = m_creature->GetMap()->GetPlayer(itr->first)) m_creature->DealDamage(pPlayer, pPlayer->GetMaxHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NONE, NULL, false); } EnterEvadeMode(); return; } } else m_uiStomachEnterVisTimer -= uiDiff; } // GientClawTentacleTimer if (m_uiGiantClawTentacleTimer < uiDiff) { if (Player* pTarget = SelectRandomNotStomach()) { // Spawn claw tentacle on the random target if (Creature* pSummoned = m_creature->SummonCreature(MOB_GIANT_CLAW_TENTACLE, pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 500)) pSummoned->AI()->AttackStart(pTarget); } // One giant claw tentacle every minute m_uiGiantClawTentacleTimer = 60000; } else m_uiGiantClawTentacleTimer -= uiDiff; // GiantEyeTentacleTimer if (m_uiGiantEyeTentacleTimer < uiDiff) { if (Player* pTarget = SelectRandomNotStomach()) { // Spawn claw tentacle on the random target if (Creature* pSummoned = m_creature->SummonCreature(MOB_GIANT_EYE_TENTACLE, pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 500)) pSummoned->AI()->AttackStart(pTarget); } // One giant eye tentacle every minute m_uiGiantEyeTentacleTimer = 60000; } else m_uiGiantEyeTentacleTimer -= uiDiff; // EyeTentacleTimer if (m_uiEyeTentacleTimer < uiDiff) { // Spawn the 8 Eye Tentacles in the corret spots SpawnEyeTentacle(0, 25); //south SpawnEyeTentacle(12, 12); //south west SpawnEyeTentacle(25, 0); //west SpawnEyeTentacle(12, -12); //north west SpawnEyeTentacle(0, -25); //north SpawnEyeTentacle(-12, -12); //north east SpawnEyeTentacle(-25, 0); // east SpawnEyeTentacle(-12, 12); // south east //These spawn at every 30 seconds m_uiEyeTentacleTimer = 30000; } else m_uiEyeTentacleTimer -= uiDiff; break; } // Weakened state case PHASE_CTHUN_WEAKENED: { // PhaseTimer if (m_uiPhaseTimer < uiDiff) { // Switch m_pInstance->SetData(TYPE_CTHUN_PHASE, PHASE_CTHUN); // Remove red coloration m_creature->RemoveAurasDueToSpell(SPELL_RED_COLORATION); // Spawn 2 flesh tentacles m_uiFleshTentaclesKilled = 0; // Spawn flesh tentacle Creature* pSpawned = m_creature->SummonCreature(MOB_FLESH_TENTACLE, TENTACLE_POS1_X, TENTACLE_POS1_Y, TENTACLE_POS1_Z, TENTACLE_POS1_O, TEMPSUMMON_CORPSE_DESPAWN, 0); if (!pSpawned) ++m_uiFleshTentaclesKilled; else { if (flesh_tentacleAI* pTentacleAI = dynamic_cast<flesh_tentacleAI*>(pSpawned->AI())) pTentacleAI->SpawnedByCthun(m_creature); } pSpawned = NULL; // Spawn flesh tentacle pSpawned = m_creature->SummonCreature(MOB_FLESH_TENTACLE, TENTACLE_POS2_X, TENTACLE_POS2_Y, TENTACLE_POS2_Z, TENTACLE_POS2_O, TEMPSUMMON_CORPSE_DESPAWN, 0); if (!pSpawned) ++m_uiFleshTentaclesKilled; else { if (flesh_tentacleAI* pTentacleAI = dynamic_cast<flesh_tentacleAI*>(pSpawned->AI())) pTentacleAI->SpawnedByCthun(m_creature); } m_uiPhaseTimer = 0; } else m_uiPhaseTimer -= uiDiff; } } }