void UpdateAI(const uint32 diff) { if (m_creature->GetHealthPercent() < 30.0f && Potioncd<diff && GCD<diff) { DoCastSpellIfCan (m_creature,HEALINGPOTION); Potioncd = POTIONCD; GCD = 1500; } if (m_creature->GetPower(POWER_MANA)<m_creature->GetMaxPower(POWER_MANA)*0.3 && Evocation_cd<diff && GCD<diff) { DoCastSpellIfCan (m_creature,EVOCATION); Evocation_cd = EVOCATION_CD; GCD = 1500; } if (m_creature->GetPower(POWER_MANA)<m_creature->GetMaxPower(POWER_MANA)*0.3 && Potioncd<diff && GCD<diff) { DoCastSpellIfCan (m_creature,MANAPOTION); Potioncd = POTIONCD; GCD = 1500; } //Always decrease our global cooldown first if (GlobalCooldown > diff) GlobalCooldown -= diff; else GlobalCooldown = 0; //Always decrease ZoneAttackMsgTimer if (ZoneAttackMsgTimer > diff) ZoneAttackMsgTimer -= diff; else ZoneAttackMsgTimer = 0; if (InnerTimer > diff) InnerTimer -= diff; else InnerTimer = 0; if(!(Potioncd < diff)) Potioncd -= diff; if(!(Evocation_cd < diff)) Evocation_cd -= diff; if(!(GCD < diff)) GCD -= diff; if(!m_creature->isAlive()) return; if(!m_creature->HasAura(48073,EFFECT_INDEX_0)) { // Divine Spirit 6 DoCastSpellIfCan(m_creature, 48073); return; } if(!m_creature->HasAura(48168,EFFECT_INDEX_0)) { // Inner Fire 9 DoCastSpellIfCan(m_creature, 48168); return; } //Return since we have no target if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; Unit *target = m_creature->getVictim(); if(target == m_creature->SelectAttackingTarget(ATTACKING_TARGET_TOPAGGRO,0) && !target->isAlive() && !m_creature->IsNonMeleeSpellCasted(false)) { Unit* target2 = NULL; target2 = m_creature->SelectAttackingTarget(ATTACKING_TARGET_TOPAGGRO,1); m_creature->getThreatManager().modifyThreatPercent(target,-100); if(target2 && target2->isAlive()) { m_creature->AddThreat(target2,1); m_creature->Attack(target2,true); AttackStart(target2); return; } else { Reset(); return; } } if(m_creature->IsHostileTo(target)) enemy = target; if(enemy) if(!enemy->isAlive()) enemy = NULL; //Always decrease Help when in combat if (Help > diff) Help -= diff; else Help = 0; //If we are within range melee the target if( m_creature->IsWithinDistInMap(m_creature->getVictim(), ATTACK_DISTANCE)) { //Make sure our attack is ready and we arn't currently casting if( m_creature->isAttackReady() && !m_creature->IsNonMeleeSpellCasted(false)) { int Change = 0; int info = 0; if(enemy) { switch(urand(0, 8)) { case 0: // Mass Dispel info = 32375; break; case 1: // Pain Suppression info = 33206; Change = 1; break; case 2: // Power Infusion info = 10060; Change = 1; break; case 3: // Power Word: Shield info = 41373; Change = 1; break; case 4: // Circle of Healing info = 48089; Change = 1; break; case 5: // Holy Nova info = 59701; break; case 6: // Renew info = 37260; Change = 1; break; case 7: // Empowered Smite info = 41471; break; case 8: // Heal info = 39013; Change = 1; break; }//switch } //65% chance to replace our white hit with a spell if (info && urand(0, 1) == 0 && !GlobalCooldown) { //Cast the spell if (Change == 1)DoCastSpellIfCan(m_creature, info); else DoCastSpellIfCan(enemy, info); //Set our global cooldown GlobalCooldown = CREATURE_COOLDOWN; }//end 50% change else m_creature->AttackerStateUpdate(m_creature->getVictim()); m_creature->resetAttackTimer(); }//end attack ready }// end attack distance /* else { if(!m_creature->IsNonMeleeSpellCasted(false)) { if ((*m_creature).GetMotionMaster()->top()->GetMovementGeneratorType()!=TARGETED_MOTION_TYPE) { (*m_creature).GetMotionMaster()->Clear(false); (*m_creature).GetMotionMaster()->MoveChase(m_creature->getVictim()); } } }//end else */ }
void UpdateAI(const uint32 diff) { if (!UpdateVictim()) return; if (uiPhaseTimer <= diff) { switch (Phase) { case CASTING_FLAME_SPHERES: { Creature* pSpheres[3]; //DoCast(me, SPELL_FLAME_SPHERE_SUMMON_1); pSpheres[0] = DoSpawnCreature(CREATURE_FLAME_SPHERE, 0, 0, 5, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 10*IN_MILLISECONDS); Unit* pSphereTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true); if (pSphereTarget && pSpheres[0]) { float angle, x, y; angle = pSpheres[0]->GetAngle(pSphereTarget); x = pSpheres[0]->GetPositionX() + DATA_SPHERE_DISTANCE * std::cos(angle); y = pSpheres[0]->GetPositionY() + DATA_SPHERE_DISTANCE * std::sin(angle); pSpheres[0]->GetMotionMaster()->MovePoint(0, x, y, pSpheres[0]->GetPositionZ()); } if (IsHeroic()) { //DoCast(me, H_SPELL_FLAME_SPHERE_SUMMON_1); pSpheres[1] = DoSpawnCreature(H_CREATURE_FLAME_SPHERE_1, 0, 0, 5, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 10*IN_MILLISECONDS); //DoCast(me, H_SPELL_FLAME_SPHERE_SUMMON_2); pSpheres[2] = DoSpawnCreature(H_CREATURE_FLAME_SPHERE_2, 0, 0, 5, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 10*IN_MILLISECONDS); if (pSphereTarget && pSpheres[1] && pSpheres[2]) { float angle, x, y; angle = pSpheres[1]->GetAngle(pSphereTarget) + DATA_SPHERE_ANGLE_OFFSET; x = pSpheres[1]->GetPositionX() + DATA_SPHERE_DISTANCE/2 * std::cos(angle); y = pSpheres[1]->GetPositionY() + DATA_SPHERE_DISTANCE/2 * std::sin(angle); pSpheres[1]->GetMotionMaster()->MovePoint(0, x, y, pSpheres[1]->GetPositionZ()); angle = pSpheres[2]->GetAngle(pSphereTarget) - DATA_SPHERE_ANGLE_OFFSET; x = pSpheres[2]->GetPositionX() + DATA_SPHERE_DISTANCE/2 * std::cos(angle); y = pSpheres[2]->GetPositionY() + DATA_SPHERE_DISTANCE/2 * std::sin(angle); pSpheres[2]->GetMotionMaster()->MovePoint(0, x, y, pSpheres[2]->GetPositionZ()); } } Phase = NORMAL; uiPhaseTimer = 0; break; } case JUST_VANISHED: if (Unit* pEmbraceTarget = GetEmbraceTarget()) { me->GetMotionMaster()->Clear(); me->SetSpeed(MOVE_WALK, 2.0f, true); me->GetMotionMaster()->MoveChase(pEmbraceTarget); } Phase = VANISHED; uiPhaseTimer = 1300; break; case VANISHED: if (Unit* pEmbraceTarget = GetEmbraceTarget()) DoCast(pEmbraceTarget, DUNGEON_MODE(SPELL_EMBRACE_OF_THE_VAMPYR, H_SPELL_EMBRACE_OF_THE_VAMPYR)); Talk(SAY_FEED); me->GetMotionMaster()->Clear(); me->SetSpeed(MOVE_WALK, 1.0f, true); me->GetMotionMaster()->MoveChase(me->GetVictim()); Phase = FEEDING; uiPhaseTimer = 20*IN_MILLISECONDS; break; case FEEDING: Phase = NORMAL; uiPhaseTimer = 0; uiEmbraceTarget = 0; break; case NORMAL: if (uiBloodthirstTimer <= diff) { DoCast(me, SPELL_BLOODTHIRST); uiBloodthirstTimer = 10*IN_MILLISECONDS; } else uiBloodthirstTimer -= diff; if (uiFlamesphereTimer <= diff) { // because TARGET_UNIT_TARGET_ENEMY we need a target selected to cast DoCastVictim(SPELL_CONJURE_FLAME_SPHERE); Phase = CASTING_FLAME_SPHERES; uiPhaseTimer = 3*IN_MILLISECONDS + diff; uiFlamesphereTimer = 15*IN_MILLISECONDS; } else uiFlamesphereTimer -= diff; if (uiVanishTimer <= diff) { //Count alive players Unit* target = NULL; std::list<HostileReference*> t_list = me->getThreatManager().getThreatList(); std::vector<Unit*> target_list; for (std::list<HostileReference*>::const_iterator itr = t_list.begin(); itr!= t_list.end(); ++itr) { target = Unit::GetUnit(*me, (*itr)->getUnitGuid()); // exclude pets & totems if (target && target->GetTypeId() == TYPEID_PLAYER && target->isAlive()) target_list.push_back(target); target = NULL; } //He only vanishes if there are 3 or more alive players if (target_list.size() > 2) { Talk(SAY_VANISH); DoCast(me, SPELL_VANISH); Phase = JUST_VANISHED; uiPhaseTimer = 500; if (Unit* pEmbraceTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) uiEmbraceTarget = pEmbraceTarget->GetGUID(); } uiVanishTimer = urand(25*IN_MILLISECONDS, 35*IN_MILLISECONDS); } else uiVanishTimer -= diff; DoMeleeAttackIfReady(); break; } } else uiPhaseTimer -= diff; }
void UpdateAI(const uint32 uiDiff) { if (m_bIsEventInProgress) { if (m_uiTimeOutTimer && m_uiTimeOutTimer < uiDiff) { if (!m_uiPlayerGUID) { //player are expected to use GO within a minute, if not, event will fail. Reset(); return; } m_uiTimeOutTimer = 0; } else m_uiTimeOutTimer -= uiDiff; if (m_uiCheckAliveStateTimer < uiDiff) { if (Unit* pChallenger = Unit::GetUnit(*m_creature, uiChallengerGUID[m_uiChallengerCount])) { if (!pChallenger->isAlive()) { Player* pPlayer = (Player*)Unit::GetUnit(*m_creature, m_uiPlayerGUID); if (pPlayer && !pPlayer->isAlive()) { Reset(); return; } ++m_uiChallengerCount; //count starts at 0 if (m_uiChallengerCount == MAX_CHALLENGER) { if (pPlayer && pPlayer->isAlive()) pPlayer->GroupEventHappens(QUEST_SECOND_TRIAL, m_creature); Reset(); return; } else m_uiEngageTimer = 15000; } } m_uiCheckAliveStateTimer = 2500; } else m_uiCheckAliveStateTimer -= uiDiff; if (m_uiEngageTimer && m_uiEngageTimer < uiDiff) { Unit* pPlayer = Unit::GetUnit(*m_creature, m_uiPlayerGUID); if (pPlayer && pPlayer->isAlive()) { if (Creature* pCreature = (Creature*)Unit::GetUnit(*m_creature, uiChallengerGUID[m_uiChallengerCount])) { DoScriptText(uiSayId[m_uiChallengerCount], m_creature, pPlayer); pCreature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); pCreature->AI()->AttackStart(pPlayer); } } m_uiEngageTimer = 0; } else m_uiEngageTimer -= uiDiff; } }
void UpdateAI(const uint32 /*diff*/) { Unit* temp = Unit::GetUnit((*me), FrostTombGUID); if ((temp && temp->isAlive() && !temp->HasAura(SPELL_FROST_TOMB)) || !temp) me->DealDamage(me, me->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); }
bool AscentScriptCreatureAI::IsValidUnitTarget( Object* pObject, TargetFilter pFilter, float pMinRange, float pMaxRange ) { //Make sure its a valid unit if ( !pObject->IsUnit() ) return false; if ( pObject->GetInstanceID() != _unit->GetInstanceID() ) return false; Unit* UnitTarget = TO_UNIT( pObject ); //Skip dead ( if required ), feign death or invisible targets if ( pFilter & TargetFilter_Corpse ) { if ( UnitTarget->isAlive() || !UnitTarget->IsCreature() || TO_CREATURE( UnitTarget )->creature_info->Rank == ELITE_WORLDBOSS ) return false; } else if ( !UnitTarget->isAlive() ) return false; if ( UnitTarget->IsPlayer() && TO_PLAYER( UnitTarget )->m_isGmInvisible ) return false; if ( UnitTarget->HasFlag( UNIT_FIELD_FLAGS, UNIT_FLAG_FEIGN_DEATH ) ) return false; //Check if we apply target filtering if ( pFilter != TargetFilter_None ) { //Skip units not on threat list if ( ( pFilter & TargetFilter_Aggroed ) && _unit->GetAIInterface()->getThreatByPtr( UnitTarget ) == 0 ) return false; //Skip current attacking target if requested if ( ( pFilter & TargetFilter_NotCurrent ) && UnitTarget == _unit->GetAIInterface()->GetNextTarget() ) return false; //Keep only wounded targets if requested if ( ( pFilter & TargetFilter_Wounded ) && UnitTarget->GetHealthPct() >= 99 ) return false; //Skip targets not in melee range if requested if ( ( pFilter & TargetFilter_InMeleeRange ) && GetRangeToUnit( UnitTarget ) > _unit->GetAIInterface()->_CalcCombatRange( UnitTarget, false ) ) return false; //Skip targets not in strict range if requested if ( ( pFilter & TargetFilter_InRangeOnly ) && ( pMinRange > 0 || pMaxRange > 0 ) ) { float Range = GetRangeToUnit( UnitTarget ); if ( pMinRange > 0 && Range < pMinRange ) return false; if ( pMaxRange > 0 && Range > pMaxRange ) return false; }; //Skip targets not in Line Of Sight if requested if ( ( ~pFilter & TargetFilter_IgnoreLineOfSight ) && !_unit->IsInLineOfSight( UnitTarget ) ) return false; //Handle hostile/friendly if ( ( ~pFilter & TargetFilter_Corpse ) && ( pFilter & TargetFilter_Friendly ) ) { if ( !UnitTarget->CombatStatus.IsInCombat() ) return false; //Skip not-in-combat targets if friendly if ( isHostile( _unit, UnitTarget ) || _unit->GetAIInterface()->getThreatByPtr( UnitTarget ) > 0 ) return false; }; }; return true; //This is a valid unit target };
void UpdateAI(const uint32 diff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; if (ArcingSmashTimer < diff) { DoCastSpellIfCan(m_creature->getVictim(), SPELL_ARCING_SMASH); ArcingSmashTimer = 10000; }else ArcingSmashTimer -= diff; if (FelAcidTimer < diff) { DoCastSpellIfCan(m_creature->getVictim(), SPELL_FEL_ACID); FelAcidTimer = 25000; }else FelAcidTimer -= diff; if (!m_creature->HasAura(SPELL_BERSERK, EFFECT_INDEX_0)) { if (EnrageTimer < diff) { if (DoCastSpellIfCan(m_creature, SPELL_BERSERK) == CAST_OK) DoScriptText(urand(0, 1) ? SAY_ENRAGE1 : SAY_ENRAGE2, m_creature); }else EnrageTimer -= diff; } if (Phase1) { if (BewilderingStrikeTimer < diff) { DoCastSpellIfCan(m_creature->getVictim(), SPELL_BEWILDERING_STRIKE); float mt_threat = m_creature->getThreatManager().getThreat(m_creature->getVictim()); if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_TOPAGGRO, 1)) m_creature->AddThreat(target, mt_threat); BewilderingStrikeTimer = 20000; }else BewilderingStrikeTimer -= diff; if (EjectTimer < diff) { DoCastSpellIfCan(m_creature->getVictim(), SPELL_EJECT1); m_creature->getThreatManager().modifyThreatPercent(m_creature->getVictim(), -40); EjectTimer = 15000; }else EjectTimer -= diff; if (AcidicWoundTimer < diff) { DoCastSpellIfCan(m_creature->getVictim(), SPELL_ACIDIC_WOUND); AcidicWoundTimer = 10000; }else AcidicWoundTimer -= diff; if (BloodboilTimer < diff) { if (BloodboilCount < 5) // Only cast it five times. { //CastBloodboil(); // Causes issues on windows, so is commented out. DoCastSpellIfCan(m_creature->getVictim(), SPELL_BLOODBOIL); ++BloodboilCount; BloodboilTimer = 10000*BloodboilCount; } }else BloodboilTimer -= diff; } if (!Phase1) { if (AcidGeyserTimer < diff) { DoCastSpellIfCan(m_creature->getVictim(), SPELL_ACID_GEYSER); AcidGeyserTimer = 30000; }else AcidGeyserTimer -= diff; if (EjectTimer < diff) { DoCastSpellIfCan(m_creature->getVictim(), SPELL_EJECT2); EjectTimer = 15000; }else EjectTimer -= diff; } if (PhaseChangeTimer < diff) { if (Phase1) { Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0); if (target && target->isAlive()) { Phase1 = false; TargetThreat = m_creature->getThreatManager().getThreat(target); m_targetGuid = target->GetObjectGuid(); target->CastSpell(m_creature, SPELL_TAUNT_GURTOGG, true); if (m_creature->getThreatManager().getThreat(target)) m_creature->getThreatManager().modifyThreatPercent(target, -100); m_creature->AddThreat(target, 50000000.0f); // If VMaps are disabled, this spell can call the whole instance DoCastSpellIfCan(m_creature, SPELL_INSIGNIFIGANCE, CAST_TRIGGERED); DoCastSpellIfCan(target, SPELL_FEL_RAGE_TARGET, CAST_TRIGGERED); DoCastSpellIfCan(target, SPELL_FEL_RAGE_2, CAST_TRIGGERED); /* These spells do not work, comment them out for now. DoCastSpellIfCan(target, SPELL_FEL_RAGE_2, CAST_TRIGGERED); DoCastSpellIfCan(target, SPELL_FEL_RAGE_3, CAST_TRIGGERED);*/ //Cast this without triggered so that it appears in combat logs and shows visual. DoCastSpellIfCan(m_creature, SPELL_FEL_RAGE_SELF); DoScriptText(urand(0, 1) ? SAY_SPECIAL1 : SAY_SPECIAL2, m_creature); AcidGeyserTimer = 1000; PhaseChangeTimer = 30000; } }else // Encounter is a loop pretty much. Phase 1 -> Phase 2 -> Phase 1 -> Phase 2 till death or enrage { if (m_targetGuid) RevertThreatOnTarget(m_targetGuid); m_targetGuid.Clear(); Phase1 = true; BloodboilTimer = 10000; BloodboilCount = 0; AcidicWoundTimer += 2000; ArcingSmashTimer += 2000; FelAcidTimer += 2000; EjectTimer += 2000; PhaseChangeTimer = 60000; } }else PhaseChangeTimer -= diff; //Enrage if (m_uiEnrageTimer < diff) { DoCast(m_creature, SPELL_ENRAGE); m_uiEnrageTimer = 60000; }else m_uiEnrageTimer -= diff; DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { if(!m_creature->SelectHostilTarget() || !m_creature->getVictim() ) return; if(pInstance && !pInstance->GetData(DATA_MOROES_EVENT)) EnterEvadeMode(); if(!Enrage && m_creature->GetHealth()*100 / m_creature->GetMaxHealth() < 30) { DoCast(m_creature, SPELL_FRENZY); Enrage = true; } if (CheckAdds_Timer < diff) { for (uint8 i = 0; i < 4; ++i) { Unit* Temp = NULL; if (AddGUID[i]) { Temp = Unit::GetUnit((*m_creature),AddGUID[i]); if (Temp && Temp->isAlive()) if (!Temp->SelectHostilTarget() || !Temp->getVictim() ) ((Creature*)Temp)->AI()->AttackStart(m_creature->getVictim()); } } CheckAdds_Timer = 5000; }else CheckAdds_Timer -= diff; if (!Enrage) { //Cast Vanish, then Garrote random victim if (Vanish_Timer < diff) { m_creature->setFaction(35); m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); DoCast(m_creature, SPELL_VANISH); InVanish = true; Vanish_Timer = 30000; Wait_Timer = 5000; }else Vanish_Timer -= diff; if (InVanish) { if (Wait_Timer < diff) { switch(rand()%2) { case 0: DoYell(SAY_SPECIAL_1, LANG_UNIVERSAL, NULL); DoPlaySoundToSet(m_creature, SOUND_SPECIAL_1); break; case 1: DoYell(SAY_SPECIAL_2, LANG_UNIVERSAL, NULL); DoPlaySoundToSet(m_creature, SOUND_SPECIAL_2); break; } Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0); if (target) target->CastSpell(target, SPELL_GARROTE,true); m_creature->setFaction(16); m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); m_creature->AI()->AttackStart(m_creature->getVictim()); InVanish = false; }else Wait_Timer -= diff; } //Blind highest aggro, and attack second highest if (Gouge_Timer < diff) { DoCast(m_creature->getVictim(), SPELL_GOUGE); if (m_creature->getThreatManager().getThreat(m_creature->getVictim())) m_creature->getThreatManager().modifyThreatPercent(m_creature->getVictim(),-100); Gouge_Timer = 40000; }else Gouge_Timer -= diff; if (Blind_Timer < diff) { Unit* target = NULL; std::list<HostilReference*> t_list = m_creature->getThreatManager().getThreatList(); if (t_list.empty()) return; std::vector<Unit*> target_list; for (std::list<HostilReference*>::iterator itr = t_list.begin(); itr!= t_list.end(); ++itr) { target = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid()); if (target && target->GetDistance2d(m_creature) < 5) target_list.push_back(target); } if (target_list.size()) target = *(target_list.begin()+rand()%target_list.size()); if (target) DoCast(target, SPELL_BLIND); Blind_Timer = 40000; }else Blind_Timer -= diff; } if (!InVanish) DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 uiDiff) { if (m_bSummonKilrek) { if (m_uiSummonKilrekTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_SUMMON_IMP) == CAST_OK) { m_uiSummonKilrekTimer = 45000; m_bSummonKilrek = false; } } else m_uiSummonKilrekTimer -= uiDiff; } if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; if (m_uiSacrifice_Timer < uiDiff) { Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1); if (pTarget && pTarget->isAlive() && pTarget->GetTypeId() == TYPEID_PLAYER) { DoCastSpellIfCan(pTarget, SPELL_SACRIFICE, CAST_TRIGGERED); if (Creature* pChains = m_creature->SummonCreature(NPC_DEMONCHAINS, pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 21000)) { if (mob_demon_chainAI* pDemonAI = dynamic_cast<mob_demon_chainAI*>(pChains->AI())) pDemonAI->m_uiSacrificeGUID = pTarget->GetGUID(); pChains->CastSpell(pChains, SPELL_DEMON_CHAINS, true); DoScriptText(urand(0, 1) ? SAY_SACRIFICE1 : SAY_SACRIFICE2, m_creature); m_uiSacrifice_Timer = 30000; } } } else m_uiSacrifice_Timer -= uiDiff; if (m_uiShadowbolt_Timer < uiDiff) { DoCastSpellIfCan(m_creature->getVictim(), SPELL_SHADOW_BOLT); m_uiShadowbolt_Timer = 10000; } else m_uiShadowbolt_Timer -= uiDiff; if (!m_bSummonedPortals) { if (m_uiSummon_Timer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_FIENDISH_PORTAL, CAST_INTERRUPT_PREVIOUS) == CAST_OK) { DoScriptText(urand(0, 1) ? SAY_SUMMON1 : SAY_SUMMON2, m_creature); m_bSummonedPortals = true; } } else m_uiSummon_Timer -= uiDiff; } if (!m_bBerserk) { if (m_uiBerserk_Timer < uiDiff) { DoCastSpellIfCan(m_creature, SPELL_BERSERK, CAST_INTERRUPT_PREVIOUS); m_bBerserk = true; } else m_uiBerserk_Timer -= uiDiff; } DoMeleeAttackIfReady(); }
void WorldSession::HandlePetAction(WorldPacket& recv_data) { ObjectGuid petGuid; uint32 data; ObjectGuid targetGuid; recv_data >> petGuid; recv_data >> data; recv_data >> targetGuid; uint32 spellid = UNIT_ACTION_BUTTON_ACTION(data); uint8 flag = UNIT_ACTION_BUTTON_TYPE(data); // delete = 0x07 CastSpell = C1 DETAIL_LOG("HandlePetAction: %s flag is %u, spellid is %u, target %s.", petGuid.GetString().c_str(), uint32(flag), spellid, targetGuid.GetString().c_str()); // used also for charmed creature/player Unit* pet = _player->GetMap()->GetUnit(petGuid); if (!pet) { sLog.outError("HandlePetAction: %s not exist.", petGuid.GetString().c_str()); return; } if (GetPlayer()->GetObjectGuid() != pet->GetCharmerOrOwnerGuid()) { sLog.outError("HandlePetAction: %s isn't controlled by %s.", petGuid.GetString().c_str(), GetPlayer()->GetGuidStr().c_str()); return; } if (!pet->isAlive()) return; if (pet->GetTypeId() == TYPEID_PLAYER) { // controller player can only do melee attack if (!(flag == ACT_COMMAND && spellid == COMMAND_ATTACK)) return; } else if (((Creature*)pet)->IsPet()) { // pet can have action bar disabled if (((Pet*)pet)->GetModeFlags() & PET_MODE_DISABLE_ACTIONS) return; } CharmInfo* charmInfo = pet->GetCharmInfo(); if (!charmInfo) { sLog.outError("WorldSession::HandlePetAction: object (GUID: %u TypeId: %u) is considered pet-like but doesn't have a charminfo!", pet->GetGUIDLow(), pet->GetTypeId()); return; } switch (flag) { case ACT_COMMAND: // 0x07 switch (spellid) { case COMMAND_STAY: // flat=1792 // STAY pet->StopMoving(); pet->GetMotionMaster()->Clear(false); pet->GetMotionMaster()->MoveIdle(); charmInfo->SetCommandState(COMMAND_STAY); break; case COMMAND_FOLLOW: // spellid=1792 // FOLLOW pet->AttackStop(); pet->GetMotionMaster()->MoveFollow(_player, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE); charmInfo->SetCommandState(COMMAND_FOLLOW); break; case COMMAND_ATTACK: // spellid=1792 // ATTACK { Unit* TargetUnit = _player->GetMap()->GetUnit(targetGuid); if (!TargetUnit) return; // not let attack friendly units. if (GetPlayer()->IsFriendlyTo(TargetUnit)) return; // Not let attack through obstructions if (!pet->IsWithinLOSInMap(TargetUnit)) return; // This is true if pet has no target or has target but targets differs. if (pet->getVictim() != TargetUnit) { if (pet->getVictim()) pet->AttackStop(); if (pet->hasUnitState(UNIT_STAT_CONTROLLED)) { pet->Attack(TargetUnit, true); pet->SendPetAIReaction(); } else { pet->GetMotionMaster()->Clear(); if (((Creature*)pet)->AI()) ((Creature*)pet)->AI()->AttackStart(TargetUnit); // 10% chance to play special pet attack talk, else growl if (((Creature*)pet)->IsPet() && ((Pet*)pet)->getPetType() == SUMMON_PET && pet != TargetUnit && roll_chance_i(10)) pet->SendPetTalk((uint32)PET_TALK_ATTACK); else { // 90% chance for pet and 100% chance for charmed creature pet->SendPetAIReaction(); } } } break; } case COMMAND_ABANDON: // abandon (hunter pet) or dismiss (summoned pet) if (((Creature*)pet)->IsPet()) { Pet* p = (Pet*)pet; if (p->getPetType() == HUNTER_PET) p->Unsummon(PET_SAVE_AS_DELETED, _player); else // dismissing a summoned pet is like killing them (this prevents returning a soulshard...) p->SetDeathState(CORPSE); } else // charmed _player->Uncharm(); break; default: sLog.outError("WORLD: unknown PET flag Action %i and spellid %i.", uint32(flag), spellid); } break; case ACT_REACTION: // 0x6 switch (spellid) { case REACT_PASSIVE: // passive case REACT_DEFENSIVE: // recovery case REACT_AGGRESSIVE: // activete charmInfo->SetReactState(ReactStates(spellid)); break; } break; case ACT_DISABLED: // 0x81 spell (disabled), ignore case ACT_PASSIVE: // 0x01 case ACT_ENABLED: // 0xC1 spell { Unit* unit_target = NULL; if (targetGuid) unit_target = _player->GetMap()->GetUnit(targetGuid); // do not cast unknown spells SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellid); if (!spellInfo) { sLog.outError("WORLD: unknown PET spell id %i", spellid); return; } if (pet->GetCharmInfo() && pet->GetCharmInfo()->GetGlobalCooldownMgr().HasGlobalCooldown(spellInfo)) return; for (int i = 0; i < MAX_EFFECT_INDEX; ++i) { if (spellInfo->EffectImplicitTargetA[i] == TARGET_ALL_ENEMY_IN_AREA || spellInfo->EffectImplicitTargetA[i] == TARGET_ALL_ENEMY_IN_AREA_INSTANT || spellInfo->EffectImplicitTargetA[i] == TARGET_ALL_ENEMY_IN_AREA_CHANNELED) return; } // do not cast not learned spells if (!pet->HasSpell(spellid) || IsPassiveSpell(spellInfo)) return; pet->clearUnitState(UNIT_STAT_MOVING); Spell* spell = new Spell(pet, spellInfo, false); SpellCastResult result = spell->CheckPetCast(unit_target); // auto turn to target unless possessed if (result == SPELL_FAILED_UNIT_NOT_INFRONT && !pet->HasAuraType(SPELL_AURA_MOD_POSSESS)) { if (unit_target) { pet->SetInFront(unit_target); if (unit_target->GetTypeId() == TYPEID_PLAYER) pet->SendCreateUpdateToPlayer((Player*)unit_target); } else if (Unit* unit_target2 = spell->m_targets.getUnitTarget()) { pet->SetInFront(unit_target2); if (unit_target2->GetTypeId() == TYPEID_PLAYER) pet->SendCreateUpdateToPlayer((Player*)unit_target2); } if (Unit* powner = pet->GetCharmerOrOwner()) if (powner->GetTypeId() == TYPEID_PLAYER) pet->SendCreateUpdateToPlayer((Player*)powner); result = SPELL_CAST_OK; } if (result == SPELL_CAST_OK) { ((Creature*)pet)->AddCreatureSpellCooldown(spellid); unit_target = spell->m_targets.getUnitTarget(); // 10% chance to play special pet attack talk, else growl // actually this only seems to happen on special spells, fire shield for imp, torment for voidwalker, but it's stupid to check every spell if (((Creature*)pet)->IsPet() && (((Pet*)pet)->getPetType() == SUMMON_PET) && (pet != unit_target) && (urand(0, 100) < 10)) pet->SendPetTalk((uint32)PET_TALK_SPECIAL_SPELL); else { pet->SendPetAIReaction(); } if (unit_target && !GetPlayer()->IsFriendlyTo(unit_target) && !pet->HasAuraType(SPELL_AURA_MOD_POSSESS)) { // This is true if pet has no target or has target but targets differs. if (pet->getVictim() != unit_target) { if (pet->getVictim()) pet->AttackStop(); pet->GetMotionMaster()->Clear(); if (((Creature*)pet)->AI()) ((Creature*)pet)->AI()->AttackStart(unit_target); } } spell->prepare(&(spell->m_targets)); } else { if (pet->HasAuraType(SPELL_AURA_MOD_POSSESS)) Spell::SendCastResult(GetPlayer(), spellInfo, 0, result); else { Unit* owner = pet->GetCharmerOrOwner(); if (owner && owner->GetTypeId() == TYPEID_PLAYER) Spell::SendCastResult((Player*)owner, spellInfo, 0, result, true); } if (!((Creature*)pet)->HasSpellCooldown(spellid)) GetPlayer()->SendClearCooldown(spellid, pet); spell->finish(false); delete spell; } break; } default: sLog.outError("WORLD: unknown PET flag Action %i and spellid %i.", uint32(flag), spellid); } }
void UpdateAI(const uint32 diff) { if (Phase == NORMAL) { //Return since we have no target if (!UpdateVictim()) return; if (uiSinsterStrikeTimer <= diff) { DoCast(me->getVictim(), SPELL_SINSTER_STRIKE); uiSinsterStrikeTimer = urand(5 * IN_MILLISECONDS, 9 * IN_MILLISECONDS); } else uiSinsterStrikeTimer -= diff; if (uiCallFlamesTimer <= diff) { if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) { DoCast(pTarget, SPELL_CALL_FLAMES); uiCallFlamesTimer = urand(8 * IN_MILLISECONDS, 12 * IN_MILLISECONDS); } } else uiCallFlamesTimer -= diff; if (!bSacrificed) { if (uiRitualOfSwordTimer <= diff) { if (Unit* pSacrificeTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) { DoScriptText( RAND(SAY_SACRIFICE_PLAYER_1, SAY_SACRIFICE_PLAYER_2, SAY_SACRIFICE_PLAYER_3, SAY_SACRIFICE_PLAYER_4, SAY_SACRIFICE_PLAYER_5), me); DoCast(pSacrificeTarget, SPELL_RITUAL_OF_THE_SWORD); //Spell doesn't teleport DoTeleportPlayer(pSacrificeTarget, 296.632f, -346.075f, 90.63f, 4.6f); me->SetUnitMovementFlags(MOVEMENTFLAG_CAN_FLY); DoTeleportTo(296.632f, -346.075f, 120.85f); Phase = SACRIFICING; if (pInstance) { pInstance->SetData64(DATA_SACRIFICED_PLAYER, pSacrificeTarget->GetGUID()); for (uint8 i = 0; i < 3; ++i) if (Creature* pSummon = me->SummonCreature(CREATURE_RITUAL_CHANNELER, RitualChannelerPos[i], TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 360000)) pSummon->AI()->DoAction(0); } bSacrificed = true; } } else uiRitualOfSwordTimer -= diff; } DoMeleeAttackIfReady(); } else //SACRIFICING { if (uiSacrificeTimer <= diff) { Unit* pSacrificeTarget = pInstance ? Unit::GetUnit( *me, pInstance->GetData64( DATA_SACRIFICED_PLAYER)) : NULL; if (pInstance && !summons.empty() && pSacrificeTarget && pSacrificeTarget->isAlive()) me->Kill(pSacrificeTarget, false); // durability damage? //go down Phase = NORMAL; pSacrificeTarget = NULL; me->SetUnitMovementFlags(MOVEMENTFLAG_WALKING); if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) me->GetMotionMaster()->MoveChase(pTarget); uiSacrificeTimer = 8 * IN_MILLISECONDS; } else uiSacrificeTimer -= diff; } }
void guardAI::UpdateAI(const uint32 diff) { //Always decrease our global cooldown first if (GlobalCooldown > diff) GlobalCooldown -= diff; else GlobalCooldown = 0; //Always decrease ZoneAttackMsgTimer if (ZoneAttackMsgTimer > diff) ZoneAttackMsgTimer -= diff; else ZoneAttackMsgTimer = 0; //Always decrease Bandage if (Bandage > diff) Bandage -= diff; else Bandage = 0; //Always decrease OffHand if (OffHand > diff) OffHand -= diff; else OffHand = 0; //Always decrease Potion if (Potion > diff) Potion -= diff; else Potion = 0; if(!m_creature->isAlive()) return; if (!m_creature->isInCombat() && !(m_creature->GetEntry() == 2041 || m_creature->GetEntry() == 4423)) { int temp1 = m_creature->GetPower(POWER_RAGE); int temp2 = temp1; temp1 = temp2 - 3; if(temp1 > 0) m_creature->SetPower(POWER_RAGE,temp1); else m_creature->SetPower(POWER_RAGE,0); } //Return since we have no target if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; Unit *target = m_creature->getVictim(); if(target == m_creature->SelectAttackingTarget(ATTACKING_TARGET_TOPAGGRO,0) && !target->isAlive() && !m_creature->IsNonMeleeSpellCasted(false)) { Unit* target2 = NULL; target2 = m_creature->SelectAttackingTarget(ATTACKING_TARGET_TOPAGGRO,1); m_creature->getThreatManager().modifyThreatPercent(target,-100); if(target2 && target2->isAlive()) { m_creature->AddThreat(target2,1); m_creature->Attack(target2,true); AttackStart(target2); return; } else { Reset(); return; } } if(m_creature->IsHostileTo(target)) enemy = target; if(enemy) if(!enemy->isAlive()) enemy = NULL; //Always decrease Help when in combat if (Help > diff) Help -= diff; else Help = 0; if(!Help && !(m_creature->GetEntry() == 2041 || m_creature->GetEntry() == 4423)) { int entry = m_creature->GetEntry(); float x; float y; float z; float X; float Y; float Z; m_creature->GetPosition(x,y,z); m_creature->getVictim()->GetPosition(X,Y,Z); if(x > X) X = x + 20; else X = x - 20; if(y > Y) Y = y + 20; else Y = y - 20; m_creature->GetRespawnCoord(x,y,z); if(entry != 12480 && entry != 12481) { Helper = DoSpawnCreature(entry, (float) (X - x), (float) (Y - y), (float) (Z -z), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); /* Helper = DoSpawnCreature(entry, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); */ if(Helper && enemy) ((CreatureAI*)Helper->AI())->AttackStart(enemy); }else { Helper = DoSpawnCreature(68, (float) (X - x + 3), (float) (Y - y - 3), (float) (Z -z), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); if(Helper && enemy) ((CreatureAI*)Helper->AI())->AttackStart(enemy); Creature* Helper2 = NULL; Helper2 = DoSpawnCreature(68, (float) (X - x - 3), (float) (Y - y + 3), (float) (Z -z), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); if(Helper2 && enemy) ((CreatureAI*)Helper2->AI())->AttackStart(enemy); Creature* Helper3 = NULL; Helper3 = DoSpawnCreature(68, (float) (X - x + 3), (float) (Y - y + 3), (float) (Z -z), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); if(Helper3 && enemy) ((CreatureAI*)Helper3->AI())->AttackStart(enemy); } Help = urand(45000, 75000); } // Make sure our attack is ready and we arn't currently casting if (m_creature->isAttackReady() && !m_creature->IsNonMeleeSpellCasted(false)) { if(m_creature->getVictim() && m_creature->SelectHostileTarget() && m_creature->GetEntry() == 3084 && OffHand > 0 && OffHand < 500) { m_creature->HandleEmoteCommand(EMOTE_ONESHOT_ATTACKOFF); m_creature->AttackerStateUpdate(m_creature->getVictim()); m_creature->resetAttackTimer(); OffHand = 0; } //If we are within range melee the target if (m_creature->IsWithinDistInMap(m_creature->getVictim(), ATTACK_DISTANCE)) { if(_Aggro != 2 && m_creature->GetEntry() != 2041 && m_creature->GetEntry() != 5624) { _Aggro = 2; DoCastSpellIfCan(m_creature,2457); return; } if(m_creature->GetHealthPercent() > 39.0f && m_creature->HasAura(2458,EFFECT_INDEX_0) && m_creature->GetEntry() != 2041 && m_creature->GetEntry() != 5624) { DoCastSpellIfCan(m_creature,2457); return; } bool Healing = false; int info = 0; int Change = 0; //Select a healing spell if less than 30% hp if (m_creature->GetHealthPercent() < 40.0f) { if(Potion == 0 && !Healing) { Potion = 60000; info = 17534; Healing = true; } else { if(Bandage == 0 && !Healing) { Bandage = 60000; info = 38919; Healing = true; } else if(m_creature->HasAura(2457,EFFECT_INDEX_0)) { info = 2458; Change = 3; } }//if bandage }//if health <40% else { if(!m_creature->HasAura(2048,EFFECT_INDEX_0) && m_creature->GetPower(POWER_RAGE) > 100) { info = 2048; Change = 3; } else { if(enemy && !enemy->HasAura(25203,EFFECT_INDEX_0) && m_creature->GetPower(POWER_RAGE) > 100) { info = 25203; Change = 4; } //select a hostile spell else { if(enemy && m_creature->GetPower(POWER_RAGE) > 100) { switch(urand(0, 7)) { case 0: info = 29707; break; case 1: info = 11574; break; case 2: info = 30022; break; case 3: info = 11597; break; case 4: if(m_creature->HasAura(2457,EFFECT_INDEX_0)) info = 25248; else info = 20569; break; case 5: if(m_creature->HasAura(2457,EFFECT_INDEX_0)) info = 20560; else info = 6554; break; case 6: if(m_creature->HasAura(2457,EFFECT_INDEX_0)) info = 11581; else info = 1680; break; case 7: info = 11597; break; }//switch }//if rage }//else hostile spell }//if no demoralizing }//if no battle shout if(m_creature->GetEntry() == 4423) info = 0; if(m_creature->GetEntry() == 5624) { info = 0; if(!m_creature->HasAura(41924,EFFECT_INDEX_0)) DoCastSpellIfCan(m_creature, 41924); } //50% chance to replace our white hit with a spell if (info && urand(0, 1) == 0 && !GlobalCooldown) { //Cast the spell if (Healing)DoCastSpellIfCan(m_creature, info); else { if(Change == 3) { DoCastSpellIfCan(m_creature, info); } else { if(Change == 4) DoCastSpellIfCan(enemy, info); else DoCastSpellIfCan(enemy, info); } } //Set our global cooldown GlobalCooldown = GENERIC_CREATURE_COOLDOWN; } else m_creature->AttackerStateUpdate(m_creature->getVictim()); m_creature->resetAttackTimer(); if(m_creature->GetEntry() == 3084) OffHand = 1000; } } else { //Only run this code if we arn't already casting if (!m_creature->IsNonMeleeSpellCasted(false)) { bool Healing = false; SpellEntry const *info = NULL; //Select a healing spell if less than 30% hp ONLY 33% of the time if (m_creature->GetHealthPercent() < 30.0f && !urand(0, 2)) info = SelectSpell(m_creature, -1, -1, SELECT_TARGET_ANY_FRIEND, 0, 0, 0, 0, SELECT_EFFECT_HEALING); //No healing spell available, See if we can cast a ranged spell (Range must be greater than ATTACK_DISTANCE) if (info) Healing = true; else info = SelectSpell(m_creature->getVictim(), -1, -1, SELECT_TARGET_ANY_ENEMY, 0, 0, ATTACK_DISTANCE, 0, SELECT_EFFECT_DONTCARE); //Found a spell, check if we arn't on cooldown if (info && !GlobalCooldown) { //If we are currently moving stop us and set the movement generator if ((*m_creature).GetMotionMaster()->GetCurrentMovementGeneratorType()!=IDLE_MOTION_TYPE) { (*m_creature).GetMotionMaster()->Clear(false); (*m_creature).GetMotionMaster()->MoveIdle(); } //Cast spell if (Healing) DoCastSpell(m_creature,info); else DoCastSpell(m_creature->getVictim(),info); //Set our global cooldown GlobalCooldown = GENERIC_CREATURE_COOLDOWN; } //If no spells available and we arn't moving run to target else if ((*m_creature).GetMotionMaster()->GetCurrentMovementGeneratorType()!=CHASE_MOTION_TYPE) { //Cancel our current spell and then mutate new movement generator m_creature->InterruptNonMeleeSpells(false); (*m_creature).GetMotionMaster()->Clear(false); (*m_creature).GetMotionMaster()->MoveChase(m_creature->getVictim()); } } } }
void UpdateAI(const uint32 diff) { if (!UpdateVictim()) return; if(phase == 2 && boss_phase == 1) { events.RescheduleEvent(EVENT_SHIELD_OF_RUNES, 27000); events.RescheduleEvent(EVENT_RUNE_OF_POWER, 60000); events.RescheduleEvent(EVENT_RUNE_OF_DEATH, 30000); boss_phase++; } if(phase == 3 && boss_phase == 2) { events.RescheduleEvent(EVENT_SHIELD_OF_RUNES, 27000); events.RescheduleEvent(EVENT_RUNE_OF_POWER, 60000); events.RescheduleEvent(EVENT_RUNE_OF_DEATH, 30000); events.RescheduleEvent(EVENT_RUNE_OF_SUMMONING, urand(20000,30000)); } events.Update(diff); while (uint32 eventId = events.ExecuteEvent()) { switch(eventId) { case EVENT_ENRAGE: DoScriptText(SAY_MOLGEIM_BERSERK, me); DoCast(SPELL_BERSERK); break; case EVENT_RUNE_OF_POWER: // Improve target selection; random alive friendly { Unit *pTarget = DoSelectLowestHpFriendly(60); if (!pTarget || (pTarget && !pTarget->isAlive())) pTarget = me; me->SummonCreature(33705, pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ() , 0 , TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 60000); // Fais pop la rune events.ScheduleEvent(EVENT_RUNE_OF_POWER, 60000); break; } case EVENT_SHIELD_OF_RUNES: DoCast(me, RAID_MODE(SPELL_SHIELD_OF_RUNES, SPELL_SHIELD_OF_RUNES_H)); events.ScheduleEvent(EVENT_SHIELD_OF_RUNES, urand(27000,34000)); break; case EVENT_RUNE_OF_DEATH: DoScriptText(SAY_MOLGEIM_RUNE_DEATH, me); if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM)) DoCast(pTarget, SPELL_RUNE_OF_DEATH); events.ScheduleEvent(EVENT_RUNE_OF_DEATH, urand(30000,40000)); break; case EVENT_RUNE_OF_SUMMONING: DoScriptText(SAY_MOLGEIM_SUMMON, me); if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM)) // DoCast(pTarget, SPELL_RUNE_OF_SUMMONING); events.ScheduleEvent(EVENT_RUNE_OF_SUMMONING, urand(20000,30000)); break; } } DoMeleeAttackIfReady(); }
void hyjalAI::UpdateAI(const uint32 diff) { if (IsDummy) { if (MassTeleportTimer < diff && DoMassTeleport) { DoCast(me, SPELL_MASS_TELEPORT, false); DoMassTeleport = false; } else MassTeleportTimer -= diff; return; } if (DoHide) { DoHide = false; switch (me->GetEntry()) { case JAINA: if (instance && instance->GetData(DATA_ALLIANCE_RETREAT)) { me->SetVisible(false); HideNearPos(me->GetPositionX(), me->GetPositionY()); HideNearPos(5037.76f, -1889.71f); for (uint8 i = 0; i < 92; ++i)//summon fires me->SummonGameObject(FLAMEOBJECT, AllianceFirePos[i][0], AllianceFirePos[i][1], AllianceFirePos[i][2], AllianceFirePos[i][3], AllianceFirePos[i][4], AllianceFirePos[i][5], AllianceFirePos[i][6], AllianceFirePos[i][7], 0); } else me->SetVisible(true); break; case THRALL: //thrall if (instance && instance->GetData(DATA_HORDE_RETREAT)) { me->SetVisible(false); HideNearPos(me->GetPositionX(), me->GetPositionY()); HideNearPos(5563, -2763.19f); HideNearPos(5542.2f, -2629.36f); for (uint8 i = 0; i < 65; ++i)//summon fires me->SummonGameObject(FLAMEOBJECT, HordeFirePos[i][0], HordeFirePos[i][1], HordeFirePos[i][2], HordeFirePos[i][3], HordeFirePos[i][4], HordeFirePos[i][5], HordeFirePos[i][6], HordeFirePos[i][7], 0); } else me->SetVisible(true); break; } } if (DoRespawn) { if (RespawnTimer <= diff) { DoRespawn = false; RespawnNearPos(me->GetPositionX(), me->GetPositionY()); if (Faction == 0) { RespawnNearPos(5037.76f, -1889.71f); } else if (Faction == 1) { RespawnNearPos(5563, -2763.19f); RespawnNearPos(5542.2f, -2629.36f); } me->SetVisible(true); } else { RespawnTimer -= diff; me->SetVisible(false); } return; } if (Overrun) DoOverrun(Faction, diff); if (bRetreat) { if (RetreatTimer <= diff) { IsDummy = true; bRetreat = false; HideNearPos(me->GetPositionX(), me->GetPositionY()); switch (me->GetEntry()) { case JAINA://jaina HideNearPos(5037.76f, -1889.71f); break; case THRALL://thrall HideNearPos(5563, -2763.19f); HideNearPos(5542.2f, -2629.36f); HideNearPos(5603.75f, -2853.12f); break; } me->SetVisible(false); } else RetreatTimer -= diff; } if (!EventBegun) return; if (Summon) { if (instance && EnemyCount) { EnemyCount = instance->GetData(DATA_TRASH); if (!EnemyCount) NextWaveTimer = 5000; } if (NextWaveTimer <= diff) { if (Faction == 0) SummonNextWave(AllianceWaves, WaveCount, AllianceBase); else if (Faction == 1) SummonNextWave(HordeWaves, WaveCount, HordeBase); ++WaveCount; } else NextWaveTimer -= diff; } if (CheckTimer <= diff) { for (uint8 i = 0; i < 2; ++i) { if (BossGUID[i]) { Unit* unit = Unit::GetUnit((*me), BossGUID[i]); if (unit && (!unit->isAlive())) { if (BossGUID[i] == BossGUID[0]) { Talk(INCOMING); FirstBossDead = true; } else if (BossGUID[i] == BossGUID[1]) { Talk(SUCCESS); SecondBossDead = true; } EventBegun = false; CheckTimer = 0; me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); BossGUID[i] = 0; if (instance) instance->DoUpdateWorldState(WORLD_STATE_ENEMY, 0); // Reset world state for enemies to disable it } } } CheckTimer = 5000; } else CheckTimer -= diff; if (!UpdateVictim()) return; for (uint8 i = 0; i < HYJAL_AI_MAX_SPELLS; ++i) { if (Spells[i].SpellId) { if (SpellTimer[i] <= diff) { if (me->IsNonMeleeSpellCasted(false)) me->InterruptNonMeleeSpells(false); Unit* target = NULL; switch (Spells[i].TargetType) { case TARGETTYPE_SELF: target = me; break; case TARGETTYPE_RANDOM: target = SelectTarget(SELECT_TARGET_RANDOM, 0); break; case TARGETTYPE_VICTIM: target = me->getVictim(); break; } if (target && target->isAlive()) { DoCast(target, Spells[i].SpellId); SpellTimer[i] = Spells[i].Cooldown; } } else SpellTimer[i] -= diff; } } DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { //Inhibitmagic_Timer if (Inhibitmagic_Timer <= diff) { float dist; Map *map = me->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->GetDistance(me)) < 45) { i_pl->RemoveAurasDueToSpell(SPELL_INHIBITMAGIC); me->AddAura(SPELL_INHIBITMAGIC, i_pl); if (dist < 35) me->AddAura(SPELL_INHIBITMAGIC, i_pl); if (dist < 25) me->AddAura(SPELL_INHIBITMAGIC, i_pl); if (dist < 15) me->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(me, SPELL_ATTRACTMAGIC); Attractmagic_Timer = 30000; Carnivorousbite_Timer = 1500; } else Attractmagic_Timer -= diff; //Carnivorousbite_Timer if (Carnivorousbite_Timer <= diff) { DoCast(me, SPELL_CARNIVOROUSBITE); Carnivorousbite_Timer = 10000; } else Carnivorousbite_Timer -= diff; //FocusFire_Timer if (FocusFire_Timer <= diff) { // Summon Focus Fire & Emote Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 1); if (pTarget && pTarget->GetTypeId() == TYPEID_PLAYER && pTarget->isAlive()) { focusedTarget = pTarget; me->SummonCreature(ENTRY_FOCUS_FIRE, pTarget->GetPositionX(),pTarget->GetPositionY(),pTarget->GetPositionZ(),0, TEMPSUMMON_TIMED_DESPAWN, 5500); // Emote std::string *emote = new std::string(EMOTE_FOCUSES_ON); emote->append(pTarget->GetName()); emote->append("!"); const char* text = emote->c_str(); me->MonsterTextEmote(text, 0, true); delete emote; } FocusFire_Timer = 15000+(rand()%5000); } else FocusFire_Timer -= diff; DoMeleeAttackIfReady(); }
void instance_blackwing_lair::Update(uint32 uiDiff) { //IN_PROGRESS = Razorgore Phase 1 if (GetData(TYPE_RAZORGORE) == IN_PROGRESS) { if (m_uiRazorgoreSummonTimer <= uiDiff) { if (Creature* pRazorgore = GetSingleCreatureFromStorage(NPC_RAZORGORE)) { for (uint32 i = 0; i < 8; i++) { /* SPAWNS BY VALUE * =========== * 0 = nothing * 1 - 3 = orc * 4 = dragon */ uint8 orcCount = 0; if (m_uiOrcSummoned < MAX_BLACKWING_ORC) orcCount = 3; uint8 dragonCount = 0; if (m_uiDragonkinSummoned < MAX_BLACKWING_DRAGONKIN) dragonCount = 1; if (orcCount || dragonCount) { uint32 spawnType = urand(1, orcCount + dragonCount); if (!orcCount) spawnType = 4; Creature* spawnedOrcs = 0; Creature* spawnedDragon = 0; if (spawnType < 4) { ++m_uiOrcSummoned; spawnedOrcs = pRazorgore->SummonCreature(urand(0, 1) ? NPC_BLACKWING_LEGIONNAIRE : NPC_BLACKWING_MAGE, Corner[i].x, Corner[i].y, Corner[i].z, Corner[i].o, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000); } else { ++m_uiDragonkinSummoned; spawnedDragon = pRazorgore->SummonCreature(NPC_DEATH_TALON_DRAGONSPAWN, Corner[i].x, Corner[i].y, Corner[i].z, Corner[i].o, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000); } //All adds have initial aggro on the Razorgore controller. The mage types will run to the center of the room and start to attack the controller with their ranged fireballs Unit* pController = pRazorgore->GetCharmerOrOwner(); if (spawnedOrcs) { razorgoreAdds.push_back(spawnedOrcs); if (pController && pController->isAlive()) spawnedOrcs->AI()->AttackStart(pController); else { if (Unit* pTarget = spawnedOrcs->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) spawnedOrcs->AI()->AttackStart(pTarget); } } if (spawnedDragon) { razorgoreAdds.push_back(spawnedDragon); if (pRazorgore->isAlive()) { spawnedDragon->AI()->AttackStart(pRazorgore); spawnedDragon->AddThreat(pRazorgore, 100.0f); } else { if (Unit* pTarget = spawnedDragon->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) spawnedDragon->AI()->AttackStart(pTarget); } } } } } m_uiRazorgoreSummonTimer = TIMER_NEXT_ADD_SPAWN; } else m_uiRazorgoreSummonTimer -= uiDiff; } /*if (GetData(TYPE_RAZORGORE) == DONE) { HandleGameObject(GO_PORTCULLIS_RAZORGORE, true); for(auto& creature : m_lBlackwingGuardsman) { if (Creature* guardsman = instance->GetCreature(creature)) guardsman->ForcedDespawn(); } if (Creature* grethok = GetSingleCreatureFromStorage(NPC_GRETHOK_THE_CONTROLLER)) grethok->ForcedDespawn(); }*/ if (m_uiChromaggusPullTimer) { if (m_uiChromaggusPullTimer <= uiDiff) { if (Creature* pChromaggus = GetSingleCreatureFromStorage(NPC_CHROMAGGUS)) { pChromaggus->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); pChromaggus->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); pChromaggus->SetInCombatWithZone(); } m_uiChromaggusPullTimer = 0; } else m_uiChromaggusPullTimer -= uiDiff; } if (m_uiGuardsmanManager && !m_uiGuardsmanManager) { if (m_uiGuardsmanManagerTimer <= uiDiff) { for (auto& creature : m_lBlackwingGuardsman) { if (Creature* pGuardsmans = instance->GetCreature(creature)) { if (pGuardsmans->isDead() && GetData(TYPE_RAZORGORE) != DONE && GetData(TYPE_RAZORGORE) != SPECIAL && GetData(TYPE_RAZORGORE) != IN_PROGRESS && GetData(TYPE_RAZORGORE) != FAIL) pGuardsmans->Respawn(); m_uiGuardsmanManager = false; } } m_uiGuardsmanManagerTimer = 30000; } else m_uiGuardsmanManagerTimer -= uiDiff; } if (m_uiGrethokManager && !m_uiGrethokManager) { if (m_uiGrethokManagerTimer <= uiDiff) { if (Creature* pGrethok = GetSingleCreatureFromStorage(NPC_GRETHOK_THE_CONTROLLER)) { if (pGrethok->isDead() && GetData(TYPE_RAZORGORE) != DONE && GetData(TYPE_RAZORGORE) != SPECIAL && GetData(TYPE_RAZORGORE) != IN_PROGRESS && GetData(TYPE_RAZORGORE) != FAIL) pGrethok->Respawn(); m_uiGrethokManager = false; } m_uiGrethokManagerTimer = 30000; } else m_uiGrethokManagerTimer -= uiDiff; } if (m_uiRazorgorManager) { if (m_uiRazorgorManagerTimer <= uiDiff) { if (Creature* pRazorgore = GetSingleCreatureFromStorage(NPC_RAZORGORE)) { if (pRazorgore->isDead() && GetData(TYPE_RAZORGORE) != DONE) SetData(TYPE_RAZORGORE, DONE); m_uiRazorgorManager = false; } m_uiRazorgorManagerTimer = 30000; } else m_uiRazorgorManagerTimer -= uiDiff; } if (m_uiVealManager) { if (m_uiVealManagerTimer <= uiDiff) { if (Creature* pVeal = GetSingleCreatureFromStorage(NPC_VAELASTRASZ)) { if (pVeal->isDead() && GetData(TYPE_VAELASTRASZ) != DONE) SetData(TYPE_VAELASTRASZ, DONE); m_uiVealManager = false; } m_uiVealManagerTimer = 30000; } else m_uiVealManagerTimer -= uiDiff; } /*if (m_uiLashLayerManager) { if (m_uiLashLayerManagerTimer <= uiDiff) { if (Creature* pLash = GetSingleCreatureFromStorage(NPC_LASHLAYER)) { if (pLash->isDead() && GetData(TYPE_LASHLAYER) != DONE) SetData(TYPE_LASHLAYER, DONE); m_uiLashLayerManager = false; } m_uiLashLayerManagerTimer = 30000; } else m_uiLashLayerManagerTimer -= uiDiff; }*/ if (m_uiChromaggusManager) { if (m_uiChromaggusManagerTimer <= uiDiff) { if (Creature* pChromaggus = GetSingleCreatureFromStorage(NPC_CHROMAGGUS)) { if (pChromaggus->isDead() && GetData(TYPE_CHROMAGGUS) != DONE) SetData(TYPE_CHROMAGGUS, DONE); m_uiChromaggusManager = false; } m_uiChromaggusManagerTimer = 30000; } else m_uiChromaggusManagerTimer -= uiDiff; }
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { Unit* caster = GetCaster(); if (caster && caster->isAlive() && GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_DEATH) caster->CastSpell(caster, SPELL_LEECH_POISON_PCT, true); }
void UpdateAI(const uint32 diff) { if (!UpdateVictim()) return; if (StormCount) { Unit* target = Unit::GetUnit(*me, CloudGUID); if (!target || !target->isAlive()) { EnterEvadeMode(); return; } else if (Unit* Cyclone = Unit::GetUnit(*me, CycloneGUID)) Cyclone->CastSpell(target, 25160, true); // keep casting or... if (StormSequenceTimer <= diff) HandleStormSequence(target); else StormSequenceTimer -= diff; return; } if (Enrage_Timer <= diff) { me->MonsterYell(SAY_ONENRAGE, LANG_UNIVERSAL, 0); DoPlaySoundToSet(me, SOUND_ONENRAGE); DoCast(me, SPELL_BERSERK, true); Enrage_Timer = 600000; } else Enrage_Timer -= diff; if (StaticDisruption_Timer <= diff) { Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1); if (!target) target = me->getVictim(); TargetGUID = target->GetGUID(); DoCast(target, SPELL_STATIC_DISRUPTION, false); me->SetInFront(me->getVictim()); StaticDisruption_Timer = (10+rand()%8)*1000; // < 20s /*if (float dist = me->IsWithinDist3d(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 5.0f) dist = 5.0f; SDisruptAOEVisual_Timer = 1000 + floor(dist / 30 * 1000.0f);*/ } else StaticDisruption_Timer -= diff; if (GustOfWind_Timer <= diff) { Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1); if (!target) target = me->getVictim(); DoCast(target, SPELL_GUST_OF_WIND); GustOfWind_Timer = urand(20, 30) * 1000; //20 to 30 seconds(bosskillers) } else GustOfWind_Timer -= diff; if (CallLighting_Timer <= diff) { DoCast(me->getVictim(), SPELL_CALL_LIGHTNING); CallLighting_Timer = urand(12, 17) * 1000; //totaly random timer. can't find any info on this } else CallLighting_Timer -= diff; if (!isRaining && ElectricalStorm_Timer < uint32(8000 + rand() % 5000)) { SetWeather(WEATHER_STATE_HEAVY_RAIN, 0.9999f); isRaining = true; } if (ElectricalStorm_Timer <= diff) { Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 50, true); if (!target) { EnterEvadeMode(); return; } target->CastSpell(target, 44007, true);//cloud visual DoCast(target, SPELL_ELECTRICAL_STORM, false);//storm cyclon + visual float x, y, z; target->GetPosition(x, y, z); if (target) { target->SetUnitMovementFlags(MOVEMENTFLAG_LEVITATING); target->MonsterMoveWithSpeed(x, y, me->GetPositionZ()+15, 0); } Unit* Cloud = me->SummonTrigger(x, y, me->GetPositionZ()+16, 0, 15000); if (Cloud) { CloudGUID = Cloud->GetGUID(); Cloud->SetUnitMovementFlags(MOVEMENTFLAG_LEVITATING); Cloud->StopMoving(); Cloud->SetFloatValue(OBJECT_FIELD_SCALE_X, 1.0f); Cloud->setFaction(35); Cloud->SetMaxHealth(9999999); Cloud->SetHealth(9999999); Cloud->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); } ElectricalStorm_Timer = 60000; //60 seconds(bosskillers) StormCount = 1; StormSequenceTimer = 0; } else ElectricalStorm_Timer -= diff; if (SummonEagles_Timer <= diff) { me->MonsterYell(SAY_ONSUMMON, LANG_UNIVERSAL, 0); DoPlaySoundToSet(me, SOUND_ONSUMMON); float x, y, z; me->GetPosition(x, y, z); for (uint8 i = 0; i < 8; ++i) { Unit* bird = Unit::GetUnit(*me, BirdGUIDs[i]); if (!bird) //they despawned on die { if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) { x = target->GetPositionX() + irand(-10, 10); y = target->GetPositionY() + irand(-10, 10); z = target->GetPositionZ() + urand(16, 20); if (z > 95) z = 95.0f - urand(0, 5); } Creature* creature = me->SummonCreature(MOB_SOARING_EAGLE, x, y, z, 0, TEMPSUMMON_CORPSE_DESPAWN, 0); if (creature) { creature->AddThreat(me->getVictim(), 1.0f); creature->AI()->AttackStart(me->getVictim()); BirdGUIDs[i] = creature->GetGUID(); } } } SummonEagles_Timer = 999999; } else SummonEagles_Timer -= diff; DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { if (!UpdateVictim()) return; if (!DrainingCrystal) { uint32 maxPowerMana = me->GetMaxPower(POWER_MANA); if (maxPowerMana && ((me->GetPower(POWER_MANA)*100 / maxPowerMana) < 10)) { if (DrainLifeTimer <= diff) { DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0), SPELL_DRAIN_LIFE); DrainLifeTimer = 10000; } else DrainLifeTimer -= diff; // Heroic only if (IsHeroic()) { if (DrainManaTimer <= diff) { DoCast(SelectTarget(SELECT_TARGET_RANDOM, 1), SPELL_DRAIN_MANA); DrainManaTimer = 10000; } else DrainManaTimer -= diff; } } if (FelExplosionTimer <= diff) { if (!me->IsNonMeleeSpellCasted(false)) { DoCast(me, SPELL_FEL_EXPLOSION); FelExplosionTimer = 2000; } } else FelExplosionTimer -= diff; // If below 10% mana, start recharging maxPowerMana = me->GetMaxPower(POWER_MANA); if (maxPowerMana && ((me->GetPower(POWER_MANA)*100 / maxPowerMana) < 10)) { if (DrainCrystalTimer <= diff) { SelectNearestCrystal(); if (IsHeroic()) DrainCrystalTimer = urand(10000, 15000); else DrainCrystalTimer = urand(20000, 25000); } else DrainCrystalTimer -= diff; } } else { if (IsDraining) { if (EmpowerTimer <= diff) { IsDraining = false; DrainingCrystal = false; DoScriptText(SAY_EMPOWERED, me); Unit* CrystalChosen = Unit::GetUnit(*me, CrystalGUID); if (CrystalChosen && CrystalChosen->isAlive()) // Use Deal Damage to kill it, not setDeathState. CrystalChosen->Kill(CrystalChosen); CrystalGUID = 0; me->GetMotionMaster()->Clear(); me->GetMotionMaster()->MoveChase(me->getVictim()); } else EmpowerTimer -= diff; } } DoMeleeAttackIfReady(); // No need to check if we are draining crystal here, as the spell has a stun. }
void UpdateAI(const uint32 diff) { if (!UpdateVictim()) return; events.Update(diff); while (uint32 eventId = events.ExecuteEvent()) { switch(eventId) { case EVENT_HATEFUL: { //Cast Hateful strike on the player with the highest //amount of HP within melee distance uint32 MostHP = 0; Unit* pMostHPTarget = NULL; std::list<HostileReference*> m_threatlist = me->getThreatManager().getThreatList(); m_threatlist.resize(RAID_MODE(2,3)); // Picks 2 (3) highest threat targets as Hateful Strike candidates std::list<HostileReference*>::const_iterator i = m_threatlist.begin(); for (; i != me->getThreatManager().getThreatList().end(); ++i) { Unit *pTarget = (*i)->getTarget(); if (pTarget->isAlive() && pTarget != me->getVictim() && pTarget->GetHealth() > MostHP && me->IsWithinMeleeRange(pTarget)) { MostHP = pTarget->GetHealth(); pMostHPTarget = pTarget; } } if (!pMostHPTarget) pMostHPTarget = me->getVictim(); DoCast(pMostHPTarget, RAID_MODE(SPELL_HATEFUL_STRIKE,H_SPELL_HATEFUL_STRIKE), true); /// wowhead article: "GREATLY boosts threat of the Hateful Strike candidates" /// but i have no data (bonus threat percent, ect) for this "GREAT boost"... events.ScheduleEvent(EVENT_HATEFUL, 1200); break; } case EVENT_BERSERK: DoCast(me, SPELL_BERSERK, true); DoScriptText(EMOTE_BERSERK, me); events.ScheduleEvent(EVENT_SLIME, 2000); break; case EVENT_SLIME: DoCast(me->getVictim(), SPELL_SLIME_BOLT); events.ScheduleEvent(EVENT_SLIME, 2000); break; } } if (!Enraged && HealthBelowPct(5)) { DoCast(me, SPELL_FRENZY, true); DoScriptText(EMOTE_ENRAGE, me); Enraged = true; } DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { if (Intro && !Done) { if (AggroTimer <= diff) { me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); DoScriptText(SAY_AGGRO, me); me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_NONE); Done = true; if (AggroTargetGUID) { Unit* pUnit = Unit::GetUnit((*me), AggroTargetGUID); if (pUnit) AttackStart(pUnit); DoZoneInCombat(); } else { EnterEvadeMode(); return; } } else AggroTimer -= diff; } if (!UpdateVictim() || !Done) return; if (SummonShadowsTimer <= diff) { //MindControlGhost(); for (uint8 i = 0; i < 2; ++i) { Creature* Shadow = NULL; float X = CalculateRandomLocation(me->GetPositionX(), 10); Shadow = me->SummonCreature(CREATURE_SHADOWY_CONSTRUCT, X, me->GetPositionY(), me->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 0); if (Shadow) { Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1); if (!target) target = me->getVictim(); if (target) Shadow->AI()->AttackStart(target); } } SummonShadowsTimer = 60000; } else SummonShadowsTimer -= diff; if (SummonDoomBlossomTimer <= diff) { if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) { float X = CalculateRandomLocation(target->GetPositionX(), 20); float Y = CalculateRandomLocation(target->GetPositionY(), 20); float Z = target->GetPositionZ(); Z = me->GetMap()->GetHeight(X, Y, Z); Creature* DoomBlossom = me->SummonCreature(CREATURE_DOOM_BLOSSOM, X, Y, Z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 20000); if (DoomBlossom) { DoomBlossom->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); DoomBlossom->setFaction(me->getFaction()); DoomBlossom->AddThreat(target, 1.0f); CAST_AI(mob_doom_blossom::mob_doom_blossomAI, DoomBlossom->AI())->SetTeronGUID(me->GetGUID()); target->CombatStart(DoomBlossom); SetThreatList(DoomBlossom); SummonDoomBlossomTimer = 35000; } } } else SummonDoomBlossomTimer -= diff; if (IncinerateTimer <= diff) { Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1); if (!target) target = me->getVictim(); if (target) { DoScriptText(RAND(SAY_SPECIAL1, SAY_SPECIAL2), me); DoCast(target, SPELL_INCINERATE); IncinerateTimer = 20000 + rand()%31 * 1000; } } else IncinerateTimer -= diff; if (CrushingShadowsTimer <= diff) { Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0); if (target && target->isAlive()) DoCast(target, SPELL_CRUSHING_SHADOWS); CrushingShadowsTimer = 10000 + rand()%16 * 1000; } else CrushingShadowsTimer -= diff; /*** NOTE FOR FUTURE DEV: UNCOMMENT BELOW ONLY IF MIND CONTROL IS FULLY IMPLEMENTED **/ /*if (ShadowOfDeathTimer <= diff) { Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 1); if (!target) target = me->getVictim(); if (target && target->isAlive() && target->GetTypeId() == TYPEID_PLAYER) { DoCast(target, SPELL_SHADOW_OF_DEATH); GhostGUID = target->GetGUID(); ShadowOfDeathTimer = 30000; SummonShadowsTimer = 53000; // Make it VERY close but slightly less so that we can check if the aura is still on the player } } else ShadowOfDeathTimer -= diff;*/ if (RandomYellTimer <= diff) { DoScriptText(RAND(SAY_SPELL1, SAY_SPELL2), me); RandomYellTimer = 50000 + rand()%51 * 1000; } else RandomYellTimer -= diff; if (!me->HasAura(SPELL_BERSERK)) { if (EnrageTimer <= diff) { DoCast(me, SPELL_BERSERK); DoScriptText(SAY_ENRAGE, me); } else EnrageTimer -= diff; } DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { //Only if not incombat check if the event is started if (!me->isInCombat() && pInstance && pInstance->GetData(DATA_KARATHRESSEVENT)) { Unit* pTarget = Unit::GetUnit((*me), pInstance->GetData64(DATA_KARATHRESSEVENT_STARTER)); if (pTarget) { AttackStart(pTarget); } } //Return since we have no target if (!UpdateVictim()) return; //someone evaded! if (pInstance && !pInstance->GetData(DATA_KARATHRESSEVENT)) { EnterEvadeMode(); return; } //WaterBoltVolley_Timer if (WaterBoltVolley_Timer <= diff) { DoCast(me->getVictim(), SPELL_WATER_BOLT_VOLLEY); WaterBoltVolley_Timer = 30000; } else WaterBoltVolley_Timer -= diff; //TidalSurge_Timer if (TidalSurge_Timer <= diff) { DoCast(me->getVictim(), SPELL_TIDAL_SURGE); // Hacky way to do it - won't trigger elseways me->getVictim()->CastSpell(me->getVictim(), SPELL_TIDAL_SURGE_FREEZE, true); TidalSurge_Timer = 15000+rand()%5000; } else TidalSurge_Timer -= diff; //Cyclone_Timer if (Cyclone_Timer <= diff) { //DoCast(me, SPELL_SUMMON_CYCLONE); // Doesn't work Cyclone_Timer = 30000+rand()%10000; Creature* Cyclone = me->SummonCreature(CREATURE_CYCLONE, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), float(rand()%5), TEMPSUMMON_TIMED_DESPAWN, 15000); if (Cyclone) { CAST_CRE(Cyclone)->SetFloatValue(OBJECT_FIELD_SCALE_X, 3.0f); Cyclone->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); Cyclone->setFaction(me->getFaction()); Cyclone->CastSpell(Cyclone, SPELL_CYCLONE_CYCLONE, true); Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0); if (pTarget) { Cyclone->AI()->AttackStart(pTarget); } } } else Cyclone_Timer -= diff; //Heal_Timer if (Heal_Timer <= diff) { // It can be cast on any of the mobs Unit* pUnit = NULL; while (pUnit == NULL || !pUnit->isAlive()) { pUnit = selectAdvisorUnit(); } if (pUnit && pUnit->isAlive()) DoCast(pUnit, SPELL_HEAL); Heal_Timer = 60000; } else Heal_Timer -= diff; DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { if (!UpdateVictim()) return; if (HealthBelowPct(10) && !Enraged) { Enraged = true; DoCast(me, SPELL_ENRAGE, true); DoScriptText(SAY_ENRAGE, me); } //Randomly cast one beam. if (BeamTimer <= diff) { Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0); if (!target || !target->isAlive()) return; BeamTimer = 9000; switch (CurrentBeam) { case 0: DoCast(target, SPELL_BEAM_SINISTER); break; case 1: DoCast(target, SPELL_BEAM_VILE); break; case 2: DoCast(target, SPELL_BEAM_WICKED); break; case 3: DoCast(target, SPELL_BEAM_SINFUL); break; } ++BeamCount; uint32 Beam = CurrentBeam; if (BeamCount > 3) while (CurrentBeam == Beam) CurrentBeam = rand()%3; } else BeamTimer -= diff; // Random Prismatic Shield every 15 seconds. if (PrismaticShieldTimer <= diff) { uint32 random = rand()%6; if (PrismaticAuras[random]) DoCast(me, PrismaticAuras[random]); PrismaticShieldTimer = 15000; } else PrismaticShieldTimer -= diff; // Select 3 random targets (can select same target more than once), teleport to a random location then make them cast explosions until they get away from each other. if (FatalAttractionTimer <= diff) { ExplosionCount = 0; TeleportPlayers(); DoScriptText(RAND(SAY_SPELL2, SAY_SPELL3), me); FatalAttractionExplodeTimer = 2000; FatalAttractionTimer = urand(40, 71) * 1000; } else FatalAttractionTimer -= diff; if (FatalAttractionExplodeTimer <= diff) { // Just make them explode three times... they're supposed to keep exploding while they are in range, but it'll take too much code. I'll try to think of an efficient way for it later. if (ExplosionCount < 3) { for (uint8 i = 0; i < 3; ++i) { Unit* unit = NULL; if (TargetGUID[i]) { unit = Unit::GetUnit((*me), TargetGUID[i]); if (unit) unit->CastSpell(unit, SPELL_ATTRACTION, true); TargetGUID[i] = 0; } } ++ExplosionCount; FatalAttractionExplodeTimer = 1000; } else { FatalAttractionExplodeTimer = FatalAttractionTimer + 2000; ExplosionCount = 0; } } else FatalAttractionExplodeTimer -= diff; if (ShriekTimer <= diff) { DoCast(me->getVictim(), SPELL_SILENCING_SHRIEK); ShriekTimer = 25000+rand()%10 * 1000; } else ShriekTimer -= diff; if (SaberTimer <= diff) { DoCast(me->getVictim(), SPELL_SABER_LASH); SaberTimer = 25000+rand()%10 * 1000; } else SaberTimer -= diff; //Enrage if (!me->HasAura(SPELL_BERSERK)) { if (EnrageTimer <= diff) { DoCast(me, SPELL_BERSERK); DoScriptText(SAY_ENRAGE, me); } else EnrageTimer -= diff; } //Random taunts if (RandomYellTimer <= diff) { DoScriptText(RAND(SAY_TAUNT1, SAY_TAUNT2, SAY_TAUNT3), me); RandomYellTimer = urand(60, 151) * 1000; } else RandomYellTimer -= diff; DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { if (!CanDoSomething()) return; if (pInstance && !pInstance->GetData(TYPE_MOROES)) EnterEvadeMode(); if (!Enrage && me->GetHealth()*100 / me->GetMaxHealth() < 30) { DoCastMe( SPELL_FRENZY); Enrage = true; } if (CheckAdds_Timer < diff) { for (uint8 i = 0; i < 4; ++i) { Unit* Temp = NULL; if (AddGUID[i]) { Temp = Unit::GetUnit((*me),AddGUID[i]); if (Temp && Temp->isAlive()) if (!Temp->SelectHostileTarget() || !Temp->getVictim()) ((Creature*)Temp)->AI()->AttackStart(me->getVictim()); } } CheckAdds_Timer = 5000; } else CheckAdds_Timer -= diff; if (!Enrage) { //Cast Vanish, then Garrote random victim if (Vanish_Timer < diff) { me->setFaction(35); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); DoCastMe( SPELL_VANISH); InVanish = true; Vanish_Timer = 30000; Wait_Timer = 5000; } else Vanish_Timer -= diff; if (InVanish) { if (Wait_Timer < diff) { DoScriptText(urand(0, 1) ? SAY_SPECIAL_1 : SAY_SPECIAL_2, me); if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0)) target->CastSpell(target, SPELL_GARROTE, true); me->setFaction(16); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); me->AI()->AttackStart(me->getVictim()); InVanish = false; } else Wait_Timer -= diff; } //Gouge highest aggro, and attack second highest if (Gouge_Timer < diff) { DoCastVictim( SPELL_GOUGE); Gouge_Timer = 40000; } else Gouge_Timer -= diff; if (Blind_Timer < diff) { Unit* target = NULL; std::list<HostileReference*> t_list = me->getThreatManager().getThreatList(); if (t_list.empty()) return; std::vector<Unit*> target_list; for (ThreatList::const_iterator itr = t_list.begin(); itr!= t_list.end(); ++itr) { target = Unit::GetUnit(*me, (*itr)->getUnitGuid()); if (target && target->IsWithinDist(me, ATTACK_DISTANCE, false)) target_list.push_back(target); } if (target_list.size()) target = *(target_list.begin()+rand()%target_list.size()); if (target) DoCast(target, SPELL_BLIND); Blind_Timer = 40000; } else Blind_Timer -= diff; } if (!InVanish) DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { if(Intro == INTRO_IN_PROGRESS) { if(AggroTimer < diff) { m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_NONE); Intro = INTRO_DONE; } else AggroTimer -= diff; } if(!UpdateVictim() || Intro == INTRO_IN_PROGRESS) return; if (CheckTimer < diff) { if(!m_creature->IsWithinDistInMap(&wLoc, 90)) EnterEvadeMode(); else DoZoneInCombat(); m_creature->SetSpeed(MOVE_RUN, 2.5); CheckTimer = 1500; } else CheckTimer -= diff; if(SummonDoomBlossomTimer < diff) { AddSpellToCast(m_creature, 40188); SummonDoomBlossomTimer = 25000+rand()%15000; } else SummonDoomBlossomTimer -= diff; if(IncinerateTimer < diff) { Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0, 200, true, m_creature->getVictimGUID()); if(!target) target = m_creature->getVictim(); if(target) { AddSpellToCastWithScriptText(target, SPELL_INCINERATE, RAND(SAY_SPECIAL1, SAY_SPECIAL2)); IncinerateTimer = urand(5000, 40000); } } else IncinerateTimer -= diff; if(CrushingShadowsTimer < diff) { AddSpellToCastWithScriptText(m_creature, SPELL_CRUSHING_SHADOWS, SAY_SPELL3); CrushingShadowsTimer = urand(17000, 42000); } else CrushingShadowsTimer -= diff; if(ShadowOfDeathTimer < diff) { Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0, 100, true, m_creature->getVictimGUID()); if(target && target->isAlive() && !target->HasAura(SPELL_SHADOW_OF_DEATH, 0) && !target->HasAura(40282, 0) ) { AddSpellToCast(target, SPELL_SHADOW_OF_DEATH, false, true); ShadowOfDeathTimer = 30000; } } else ShadowOfDeathTimer -= diff; if(RandomYellTimer < diff) { DoScriptText(RAND(SAY_SPELL1, SAY_SPELL2), m_creature); RandomYellTimer = 50000 + rand()%51000; } else RandomYellTimer -= diff; if(!m_creature->HasAura(SPELL_BERSERK, 0)) { if(EnrageTimer < diff) { AddSpellToCastWithScriptText(m_creature, SPELL_BERSERK, SAY_ENRAGE); } else EnrageTimer -= diff; } CastNextSpellIfAnyAndReady(); DoMeleeAttackIfReady(); }
void UpdateFollowerAI(const uint32 uiDiff) override { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) { if (HasFollowState(STATE_FOLLOW_POSTEVENT)) { if (m_uiEndEventTimer < uiDiff) { if (!pSpraggle || !pSpraggle->isAlive()) { SetFollowComplete(); return; } switch (m_uiEndEventProgress) { case 1: DoScriptText(SAY_RIN_END_1, m_creature); m_uiEndEventTimer = 3000; break; case 2: DoScriptText(SAY_SPR_END_2, pSpraggle); m_uiEndEventTimer = 5000; break; case 3: DoScriptText(SAY_RIN_END_3, m_creature); m_uiEndEventTimer = 1000; break; case 4: DoScriptText(EMOTE_RIN_END_4, m_creature); SetFaint(); m_uiEndEventTimer = 9000; break; case 5: DoScriptText(EMOTE_RIN_END_5, m_creature); ClearFaint(); m_uiEndEventTimer = 1000; break; case 6: DoScriptText(SAY_RIN_END_6, m_creature); m_uiEndEventTimer = 3000; break; case 7: DoScriptText(SAY_SPR_END_7, pSpraggle); m_uiEndEventTimer = 10000; break; case 8: DoScriptText(EMOTE_RIN_END_8, m_creature); m_uiEndEventTimer = 5000; break; case 9: SetFollowComplete(); break; } ++m_uiEndEventProgress; } else m_uiEndEventTimer -= uiDiff; } else if (HasFollowState(STATE_FOLLOW_INPROGRESS)) { if (!HasFollowState(STATE_FOLLOW_PAUSED)) { if (m_uiFaintTimer < uiDiff) { SetFaint(); m_uiFaintTimer = urand(60000, 120000); } else m_uiFaintTimer -= uiDiff; } } return; } DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { if (!UpdateVictim()) return; //Only do this if we haven't spawned nef yet if (SpawnedAdds < 42) { //ShadowBoltTimer if (ShadowBoltTimer <= diff) { if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) DoCast(pTarget, SPELL_SHADOWBOLT); ShadowBoltTimer = urand(3000,10000); } else ShadowBoltTimer -= diff; //FearTimer if (FearTimer <= diff) { if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) DoCast(pTarget, SPELL_FEAR); FearTimer = 10000 + (rand()%10000); } else FearTimer -= diff; //Add spawning mechanism if (AddSpawnTimer <= diff) { //Spawn 2 random types of creatures at the 2 locations uint32 CreatureID; Creature* Spawned = NULL; Unit* pTarget = NULL; //1 in 3 chance it will be a chromatic if (urand(0,2) == 0) CreatureID = CREATURE_CHROMATIC_DRAKANOID; else CreatureID = DrakType1; ++SpawnedAdds; //Spawn Creature and force it to start attacking a random target Spawned = me->SummonCreature(CreatureID,ADD_X1,ADD_Y1,ADD_Z1,5.000f,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,5000); pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true); if (pTarget && Spawned) { Spawned->AI()->AttackStart(pTarget); Spawned->setFaction(103); } //1 in 3 chance it will be a chromatic if (urand(0,2) == 0) CreatureID = CREATURE_CHROMATIC_DRAKANOID; else CreatureID = DrakType2; ++SpawnedAdds; Spawned = me->SummonCreature(CreatureID,ADD_X2,ADD_Y2,ADD_Z2,5.000f,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,5000); pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true); if (pTarget && Spawned) { Spawned->AI()->AttackStart(pTarget); Spawned->setFaction(103); } //Begin phase 2 by spawning Nefarian and what not if (SpawnedAdds >= 42) { //Teleport Victor Nefarius way out of the map //MapManager::Instance().GetMap(me->GetMapId(), me)->CreatureRelocation(me,0,0,-5000,0); //Inturrupt any spell casting me->InterruptNonMeleeSpells(false); //Root self DoCast(me, 33356); //Make super invis DoCast(me, 8149); //Teleport self to a hiding spot (this causes errors in the blizzlike log but no real issues) DoTeleportTo(HIDE_X,HIDE_Y,HIDE_Z); me->addUnitState(UNIT_STAT_FLEEING); //Spawn nef and have him attack a random target Creature* Nefarian = me->SummonCreature(CREATURE_NEFARIAN,NEF_X,NEF_Y,NEF_Z,0,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,120000); pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true); if (pTarget && Nefarian) { Nefarian->AI()->AttackStart(pTarget); Nefarian->setFaction(103); NefarianGUID = Nefarian->GetGUID(); } else error_log("BSCR: Blackwing Lair: Unable to spawn nefarian properly."); } AddSpawnTimer = 4000; } else AddSpawnTimer -= diff; } else if (NefarianGUID) { if (NefCheckTime <= diff) { Unit* Nefarian = Unit::GetCreature((*me),NefarianGUID); //If nef is dead then we die to so the players get out of combat //and cannot repeat the event if (!Nefarian || !Nefarian->isAlive()) { NefarianGUID = 0; me->ForcedDespawn(); } NefCheckTime = 2000; } else NefCheckTime -= diff; } }
void UpdateFollowerAI(const uint32 diff) { if(!UpdateVictim()) { //we are doing the post-event, or... if(HasFollowState(STATE_FOLLOW_POSTEVENT)) { if(m_uiPostEventTimer <= diff) { m_uiPostEventTimer = 5000; Unit* pTorta = Unit::GetUnit(*me, TortaGUID); if(!pTorta || !pTorta->isAlive()) { //something happened, so just complete SetFollowComplete(); return; } switch(m_uiPhasePostEvent) { case 1: DoScriptText(SAY_TOOG_POST_1, me); break; case 2: DoScriptText(SAY_TORT_POST_2, pTorta); break; case 3: DoScriptText(SAY_TOOG_POST_3, me); break; case 4: DoScriptText(SAY_TORT_POST_4, pTorta); break; case 5: DoScriptText(SAY_TOOG_POST_5, me); break; case 6: DoScriptText(SAY_TORT_POST_6, pTorta); me->GetMotionMaster()->MovePoint(POINT_ID_TO_WATER, m_afToWaterLoc[0], m_afToWaterLoc[1], m_afToWaterLoc[2]); break; } ++m_uiPhasePostEvent; } else m_uiPostEventTimer -= diff; } //...we are doing regular speech check else if(HasFollowState(STATE_FOLLOW_INPROGRESS)) { if(m_uiCheckSpeechTimer <= diff) { m_uiCheckSpeechTimer = 5000; if(urand(0, 9) > 8) DoScriptText(RAND(SAY_TOOG_THIRST, SAY_TOOG_WORRIED), me); } else m_uiCheckSpeechTimer -= diff; } return; } DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { if (!UpdateVictim()) return; // Pounding if (Pounding_Timer <= diff) { DoCast(m_creature->getVictim(), SPELL_POUNDING); DoScriptText(RAND(SAY_POUNDING1,SAY_POUNDING2), m_creature); Pounding_Timer = 15000; //cast time(3000) + cooldown time(12000) } else Pounding_Timer -= diff; // Arcane Orb if (ArcaneOrb_Timer <= diff) { Unit *pTarget = NULL; std::list<HostilReference *> t_list = m_creature->getThreatManager().getThreatList(); std::vector<Unit *> target_list; for (std::list<HostilReference *>::iterator itr = t_list.begin(); itr!= t_list.end(); ++itr) { pTarget = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid()); if (!pTarget) continue; // exclude pets & totems if (pTarget->GetTypeId() != TYPEID_PLAYER) continue; //18 yard radius minimum if (pTarget && pTarget->GetTypeId() == TYPEID_PLAYER && pTarget->isAlive() && !pTarget->IsWithinDist(m_creature, 18, false)) target_list.push_back(pTarget); pTarget = NULL; } if (target_list.size()) pTarget = *(target_list.begin()+rand()%target_list.size()); else pTarget = m_creature->getVictim(); if (pTarget) m_creature->CastSpell(pTarget->GetPositionX(),pTarget->GetPositionY(),pTarget->GetPositionZ(), SPELL_ARCANE_ORB, false, NULL, NULL, NULL, pTarget); ArcaneOrb_Timer = 3000; } else ArcaneOrb_Timer -= diff; // Single Target knock back, reduces aggro if (KnockAway_Timer <= diff) { DoCast(m_creature->getVictim(), SPELL_KNOCK_AWAY); //Drop 25% aggro if (DoGetThreat(m_creature->getVictim())) DoModifyThreatPercent(m_creature->getVictim(),-25); KnockAway_Timer = 30000; } else KnockAway_Timer -= diff; //Berserk if (Berserk_Timer < diff && !Enraged) { DoCast(m_creature, SPELL_BERSERK); Enraged = true; } else Berserk_Timer -= diff; DoMeleeAttackIfReady(); EnterEvadeIfOutOfCombatArea(diff); }
void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; // Mortal Wound if (m_uiMortalWoundTimer < uiDiff) { DoCast(m_creature->getVictim(), SPELL_MORTALWOUND); m_uiMortalWoundTimer = 10000; } else m_uiMortalWoundTimer -= uiDiff; //Decimate_Timer if (m_uiDecimateTimer < uiDiff) { DoCast(m_creature->getVictim(),SPELL_DECIMATE); // need core support // workaround below std::list<HostileReference*> t_list = m_creature->getThreatManager().getThreatList(); if (t_list.size()) { //begin + 1 , so we don't target the one with the highest threat std::list<HostileReference*>::iterator itr = t_list.begin(); std::advance(itr, 1); for(; itr!= t_list.end(); ++itr) { Unit *target = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid()); if (target && target->isAlive() && target->GetTypeId() == TYPEID_PLAYER && (target->GetHealth() > target->GetMaxHealth() * 0.05)) target->SetHealth(target->GetMaxHealth() * 0.05); } } // Move Zombies if (!m_lZombieGUIDList.empty()) { for(std::list<uint64>::iterator itr = m_lZombieGUIDList.begin(); itr != m_lZombieGUIDList.end(); ++itr) if (Creature* pTemp = (Creature*)Unit::GetUnit(*m_creature, *itr)) if (pTemp->isAlive()) { ((mob_zombie_chowsAI*)pTemp->AI())->bIsForceMove = true; if (m_creature->GetHealth() > m_creature->GetMaxHealth() * 0.05) // remove when SPELL_DECIMATE is working pTemp->SetHealth(pTemp->GetMaxHealth() * 0.02); pTemp->AddThreat(m_creature, 1000000000.0f); // force move toward to Gluth } } m_uiDecimateTimer = (m_bIsRegularMode ? 100000 : 120000); }else m_uiDecimateTimer -= uiDiff; // Enrage if (m_uiEnrageTimer < uiDiff) { DoCast(m_creature, m_bIsRegularMode ? SPELL_ENRAGE : SPELL_ENRAGE_H); m_uiEnrageTimer = 60000; } else m_uiEnrageTimer -= uiDiff; if (RangeCheck_Timer < uiDiff) { if (!m_lZombieGUIDList.empty()) { for(std::list<uint64>::iterator itr = m_lZombieGUIDList.begin(); itr != m_lZombieGUIDList.end(); ++itr) if (Creature* pTemp = (Creature*)Unit::GetUnit(*m_creature, *itr)) if (pTemp->isAlive() && m_creature->IsWithinDistInMap(pTemp, ATTACK_DISTANCE)) { DoScriptText(EMOTE_ZOMBIE, m_creature); m_creature->SetHealth(m_creature->GetHealth() + m_creature->GetMaxHealth() * 0.05); pTemp->ForcedDespawn(); } } RangeCheck_Timer = 1000; }else RangeCheck_Timer -= uiDiff; //Summon_Timer if (Summon_Timer < uiDiff) { for(uint8 i = 0; i < (m_bIsRegularMode ? 1 : 2); i++) { if (Creature* pZombie = m_creature->SummonCreature(NPC_ZOMBIE_CHOW,ADD_1X,ADD_1Y,ADD_1Z,0,TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,80000)) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) { pZombie->AddThreat(pTarget); m_lZombieGUIDList.push_back(pZombie->GetGUID()); } } } Summon_Timer = 10000; } else Summon_Timer -= uiDiff; // Berserk if (m_uiBerserkTimer < uiDiff) { DoCastSpellIfCan(m_creature, SPELL_BERSERK, CAST_TRIGGERED); m_uiBerserkTimer = MINUTE*5*IN_MILLISECONDS; } else m_uiBerserkTimer -= uiDiff; DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; switch(m_uiPhase) { case PHASE_ATTACKING: if (m_uiCheckoutMana_Timer <= uiDiff) { m_uiCheckoutMana_Timer = 1500; if (m_creature->GetPower(POWER_MANA) * 100 / m_creature->GetMaxPower(POWER_MANA) > 75.0f) { DoCastSpellIfCan(m_creature, SPELL_ENERGIZE); DoScriptText(EMOTE_ENERGIZING, m_creature); m_uiPhase = PHASE_ENERGIZING; return; } } else m_uiCheckoutMana_Timer -= uiDiff; if (m_uiSummonManaFiends_Timer <= uiDiff) { DoCastSpellIfCan(m_creature->getVictim(), SPELL_SUMMON_MANAFIEND_1, CAST_TRIGGERED); DoCastSpellIfCan(m_creature->getVictim(), SPELL_SUMMON_MANAFIEND_2, CAST_TRIGGERED); DoCastSpellIfCan(m_creature->getVictim(), SPELL_SUMMON_MANAFIEND_3, CAST_TRIGGERED); m_uiSummonManaFiends_Timer = 90000; } else m_uiSummonManaFiends_Timer -= uiDiff; if (m_uiManaDrain_Timer <= uiDiff) { m_uiManaDrain_Timer = urand(2000, 6000); // choose random target with mana std::list<Unit*> lTargets; ThreatList const& threatlist = m_creature->getThreatManager().getThreatList(); if (threatlist.empty()) return; for (ThreatList::const_iterator itr = threatlist.begin(); itr != threatlist.end(); ++itr) { Unit* pUnit = m_creature->GetMap()->GetUnit((*itr)->getUnitGuid()); if (pUnit && pUnit->isAlive() && pUnit->GetPower(POWER_MANA)) lTargets.push_back(pUnit); } if (lTargets.empty()) return; std::list<Unit*>::iterator itr = lTargets.begin(); std::advance(itr, urand(0, lTargets.size()-1)); DoCastSpellIfCan(*itr, SPELL_DRAIN_MANA); } else m_uiManaDrain_Timer -= uiDiff; if (m_uiTrample_Timer <= uiDiff) { DoCastSpellIfCan(m_creature->getVictim(), SPELL_TRAMPLE); m_uiTrample_Timer = 15000; } else m_uiTrample_Timer -= uiDiff; DoMeleeAttackIfReady(); break; case PHASE_ENERGIZING: if (m_uiCheckoutMana_Timer <= uiDiff) { m_uiCheckoutMana_Timer = 1500; if (m_creature->GetPower(POWER_MANA) == m_creature->GetMaxPower(POWER_MANA)) { m_creature->RemoveAurasDueToSpell(SPELL_ENERGIZE); DoCastSpellIfCan(m_creature, SPELL_ARCANE_ERUPTION); DoScriptText(EMOTE_MANA_FULL, m_creature); m_uiPhase = PHASE_ATTACKING; return; } } else m_uiCheckoutMana_Timer -= uiDiff; break; } }