void OnPeriodic(AuraEffect const* /*aurEff*/) { // Every 5 seconds Unit* target = GetTarget(); Unit* caster = GetCaster(); // If our player is no longer sit, remove all auras if (target->getStandState() != UNIT_STAND_STATE_SIT) { target->RemoveAura(SPELL_ROMANTIC_PICNIC_ACHIEV); target->RemoveAura(GetAura()); return; } target->CastSpell(target, SPELL_BASKET_CHECK, false); // unknown use, it targets Romantic Basket target->CastSpell(target, RAND(SPELL_MEAL_EAT_VISUAL, SPELL_DRINK_VISUAL), false); bool foundSomeone = false; // For nearby players, check if they have the same aura. If so, cast Romantic Picnic (45123) // required by achievement and "hearts" visual std::list<Player*> playerList; Trinity::AnyPlayerInObjectRangeCheck checker(target, INTERACTION_DISTANCE*2); Trinity::PlayerListSearcher<Trinity::AnyPlayerInObjectRangeCheck> searcher(target, playerList, checker); target->VisitNearbyWorldObject(INTERACTION_DISTANCE*2, searcher); for (std::list<Player*>::const_iterator itr = playerList.begin(); itr != playerList.end(); ++itr) { if ((*itr) != target && (*itr)->HasAura(GetId())) // && (*itr)->getStandState() == UNIT_STAND_STATE_SIT) { if (caster) { caster->CastSpell(*itr, SPELL_ROMANTIC_PICNIC_ACHIEV, true); caster->CastSpell(target, SPELL_ROMANTIC_PICNIC_ACHIEV, true); } foundSomeone = true; // break; } } if (!foundSomeone && target->HasAura(SPELL_ROMANTIC_PICNIC_ACHIEV)) target->RemoveAura(SPELL_ROMANTIC_PICNIC_ACHIEV); }
bool PlagueSpray(uint32 i, Spell * pSpell) { if( !pSpell->p_caster ) return true; Unit * target = pSpell->GetUnitTarget(); if( !target || target->GetEntry() != 23652 || !target->isAlive()) return true; else if(!target || target->GetEntry() != 23652 || !target->HasAura(40467)) return false; Player * pPlayer = pSpell->p_caster; QuestLogEntry * en = pPlayer->GetQuestLogForEntry( 11307 ); if( en && en->GetMobCount( 0 ) < en->GetQuest()->required_mobcount[0] ) { en->SetMobCount( 0, en->GetMobCount( 0 ) + 1 ); en->SendUpdateAddKill( 0 ); en->UpdatePlayerFields(); } return true; }
void UpdateAI (const uint32 diff) { if (!instance) return; if (CheckTimer <= diff) { Unit* vashj = Unit::GetUnit((*me), instance->GetData64(DATA_LADYVASHJ)); if (vashj && vashj->isAlive()) { // start visual channel if (!Casted || !vashj->HasAura(SPELL_MAGIC_BARRIER)) { DoCast(vashj, SPELL_MAGIC_BARRIER, true); Casted = true; } } CheckTimer = 1000; } else CheckTimer -= diff; }
void CastExplosion() { DoZoneInCombat(); // make sure everyone is in threatlist std::vector<Unit*> targets; std::list<HostileReference*>::const_iterator i = me->getThreatManager().getThreatList().begin(); for (; i != me->getThreatManager().getThreatList().end(); ++i) { Unit* target = (*i)->getTarget(); if (target->GetTypeId() != TYPEID_PLAYER) continue; if (target->HasAura(SPELL_ICEBOLT)) { target->ApplySpellImmune(0, IMMUNITY_ID, SPELL_FROST_EXPLOSION, true); targets.push_back(target); continue; } for (IceBlockMap::const_iterator itr = iceblocks.begin(); itr != iceblocks.end(); ++itr) { if (GameObject* go = GameObject::GetGameObject(*me, itr->second)) { float angle = me->GetAngle(go) - me->GetAngle(target); float dist = me->GetExactDist2d(target->GetPositionX(), target->GetPositionY()) - me->GetExactDist2d(go->GetPositionX(), go->GetPositionY()); if (angle > -0.04f && angle < 0.04f && dist < 5.0f && dist >= 0.0f) { target->ApplySpellImmune(0, IMMUNITY_ID, SPELL_FROST_EXPLOSION, true); targets.push_back(target); break; } } } } me->CastSpell(me, SPELL_FROST_EXPLOSION, true); for (std::vector<Unit*>::const_iterator itr = targets.begin(); itr != targets.end(); ++itr) (*itr)->ApplySpellImmune(0, IMMUNITY_ID, SPELL_FROST_EXPLOSION, false); }
bool Pet::UpdateStats(Stats stat) { if (stat > STAT_SPIRIT) return false; // value = ((base_value * base_pct) + total_value) * total_pct float value = GetTotalStatValue(stat); Unit *owner = GetOwner(); if (stat == STAT_STAMINA) { if (owner && (getPetType() == HUNTER_PET || owner->getClass() == CLASS_WARLOCK || owner->getClass() == CLASS_MAGE)) { value += float(owner->GetStat(stat)) * 0.3f; if (getPetType() == HUNTER_PET && owner->HasAura(38297,1)) value += 52; } } //warlock's and mage's pets gain 30% of owner's intellect else if (stat == STAT_INTELLECT && getPetType() == SUMMON_PET) { if (owner && (owner->getClass() == CLASS_WARLOCK || owner->getClass() == CLASS_MAGE)) value += float(owner->GetStat(stat)) * 0.3f; } SetStat(stat, int32(value)); switch (stat) { case STAT_STRENGTH: UpdateAttackPowerAndDamage(); break; case STAT_AGILITY: UpdateArmor(); break; case STAT_STAMINA: UpdateMaxHealth(); break; case STAT_INTELLECT: UpdateMaxPower(POWER_MANA); break; case STAT_SPIRIT: default: break; } return true; }
void UpdateAI(const uint32 diff) { if (!UpdateVictim()) return; if (uiGripOfSladRanTimer <= diff) { Unit* target = me->getVictim(); uiGripOfSladRanTimer = urand(3, 6)*IN_MILLISECONDS; if (!target) return; if (!target->HasAura(SPELL_GRIP_OF_SLAD_RAN)) { me->AddAura(SPELL_GRIP_OF_SLAD_RAN, target); return; } if (Aura* grip = target->GetAura(SPELL_GRIP_OF_SLAD_RAN)) { if (grip->GetStackAmount() < 5) { grip->SetStackAmount(grip->GetStackAmount() + 1); } else { target->RemoveAurasDueToSpell(SPELL_GRIP_OF_SLAD_RAN, me->GetGUID()); target->CastSpell(target, SPELL_SNAKE_WRAP, true); if (TempSummon* _me = me->ToTempSummon()) if (Creature* sladran = _me->GetSummoner()->ToCreature()) sladran->AI()->SetGUID(target->GetGUID() ,DATA_SNAKES_WHYD_IT_HAVE_TO_BE_SNAKES); me->DespawnOrUnsummon(); } } } else uiGripOfSladRanTimer -= diff; }
void HandleOnHit() { SpellInfo const* chargeProto = sSpellMgr->GetSpellInfo(SPELL_WARRIOR_CHARGE_SPELLBOOK_SPELL); Unit* caster = GetCaster(); if (chargeProto && caster && caster->ToPlayer()) { Player* player = caster->ToPlayer(); // Juggernaut charge cd if (caster->HasAura(SPELL_WARRIOR_JUGGERNAUT_CRIT_BONUS_TALENT) && !player->HasSpellCooldown(SPELL_WARRIOR_CHARGE_SPELLBOOK_SPELL)) { WorldPacket data(SMSG_SPELL_COOLDOWN, 8 + 1 + 4); data << uint64(player->GetGUID()); data << uint8(0x1); // flags (0x1, 0x2) data << uint32(chargeProto->Id); // 15 base sec - 2 from talent data << uint32(13000); // in m.secs player->GetSession()->SendPacket(&data); } } }
void CastExplosion() { DoZoneInCombat(); // make sure everyone is in threatlist std::vector<Unit*> targets; std::list<HostilReference*>::iterator i = me->getThreatManager().getThreatList().begin(); for (; i != me->getThreatManager().getThreatList().end(); ++i) { Unit *pTarget = (*i)->getTarget(); if (pTarget->GetTypeId() != TYPEID_PLAYER) continue; if (pTarget->HasAura(SPELL_ICEBOLT)) { pTarget->ApplySpellImmune(0, IMMUNITY_ID, SPELL_FROST_EXPLOSION, true); targets.push_back(pTarget); continue; } for (IceBlockMap::iterator itr = iceblocks.begin(); itr != iceblocks.end(); ++itr) { if (GameObject* pGo = GameObject::GetGameObject(*me, itr->second)) { if (pGo->IsInBetween(me, pTarget, 2.0f) && me->GetExactDist2d(pTarget->GetPositionX(), pTarget->GetPositionY()) - me->GetExactDist2d(pGo->GetPositionX(), pGo->GetPositionY()) < 5.0f) { pTarget->ApplySpellImmune(0, IMMUNITY_ID, SPELL_FROST_EXPLOSION, true); targets.push_back(pTarget); break; } } } } me->CastSpell(me, SPELL_FROST_EXPLOSION, true); for (std::vector<Unit*>::iterator itr = targets.begin(); itr != targets.end(); ++itr) (*itr)->ApplySpellImmune(0, IMMUNITY_ID, SPELL_FROST_EXPLOSION, false); }
void CastSinisterReflection() { DoScriptText(RAND(SAY_KJ_REFLECTION1,SAY_KJ_REFLECTION2), me); for (uint8 i = 0; i < 4; ++i) { float x,y,z; Unit *pTarget = NULL; for (uint8 z = 0; z < 6; ++z) { pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true); if (!pTarget || !pTarget->HasAura(SPELL_VENGEANCE_OF_THE_BLUE_FLIGHT,0)) break; } if (pTarget) { pTarget->GetPosition(x,y,z); if (Creature* pSinisterReflection = me->SummonCreature(CREATURE_SINISTER_REFLECTION, x,y,z,0, TEMPSUMMON_CORPSE_DESPAWN, 0)) { pSinisterReflection->SetDisplayId(pTarget->GetDisplayId()); pSinisterReflection->AI()->AttackStart(pTarget); } } } }
bool PlayerbotShamanAI::HealGroup (Unit *target, uint8 hp, uint8 &countNeedHeal) { Player *m_bot = GetPlayerBot(); if (countNeedHeal < 2) { return false; } Unit *rTarget = DoSelectLowestHpFriendly(30,500); if (!rTarget || rTarget->isDead() || rTarget->GetHealth() * 100 / rTarget->GetMaxHealth() > 80 ) { return false; } if (hp < 65 && RIPTIDE && rTarget->HasAura(RIPTIDE,m_bot->GetGUID()) && CastSpell(CHAIN_HEAL, rTarget)) { return true; } if (hp < 85 && CastSpell(RIPTIDE, rTarget)) { return true; } if (hp < 75 && CastSpell(CHAIN_HEAL, rTarget,true,true)) { return true; } return false; }
void HandleDamage() { Unit* caster = GetCaster(); if (caster->GetTypeId() != TYPEID_PLAYER) return; Unit* target = GetHitUnit(); int32 damage = GetHitDamage(); // Glyph cooldown reset when target was failed to kill if (AuraEffect* glyph = caster->GetDummyAuraEffect(SPELLFAMILY_PRIEST, 1980, EFFECT_0)) if (target && target->GetHealthPct() <= glyph->GetAmount() && !caster->HasAura(95652)) if (int32(target->GetHealth()) > damage) { caster->ToPlayer()->RemoveSpellCooldown(32379, true); caster->CastSpell(caster, 95652, true); } // Pain and Suffering reduces damage if (AuraEffect* aurEff = caster->GetDummyAuraEffect(SPELLFAMILY_PRIEST, PRIEST_ICON_ID_PAIN_AND_SUFFERING, EFFECT_1)) AddPct(damage, aurEff->GetAmount()); caster->CastCustomSpell(caster, SPELL_PRIEST_SHADOW_WORD_DEATH, &damage, 0, 0, true); }
void UpdateAI(uint32 diff) { events.Update(diff); while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_IMMOLATION_TRAP_TRIGGER: //Riplimb and Rageface has a higher Priority than Players... if(GetRiplimb() && GetRiplimb()->GetDistance(me) <= 3.0f && !GetRiplimb()->HasAura(RAID_MODE(SPELL_WARY_10N, SPELL_WARY_25N, SPELL_WARY_10H, SPELL_WARY_25H)) && GetRiplimb()->IsAlive() && GetShannox()->AI()->GetData(DATA_PHASE) == PHASE_SHANNOX_HAS_SPEER) tempTarget = GetRiplimb(); else if (GetRageface() && GetRageface()->GetDistance(me) <= 3.0f && !GetRageface()->HasAura(RAID_MODE(SPELL_WARY_10N, SPELL_WARY_25N, SPELL_WARY_10H, SPELL_WARY_25H)) && GetRageface()->IsAlive()) tempTarget = GetRageface(); else tempTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 1.0f, true); if (!tempTarget || tempTarget->HasAura(CRYSTAL_PRISON_EFFECT)) // If no Target exists try to get a new Target in 0,5s events.ScheduleEvent(EVENT_IMMOLATION_TRAP_TRIGGER, 500); else { DoCast(tempTarget,RAID_MODE(SPELL_IMMOLATION_TRAP_10N, SPELL_IMMOLATION_TRAP_25N,SPELL_IMMOLATION_TRAP_10H, SPELL_IMMOLATION_TRAP_25H)); // Cast Spell Wary on Dogs if(tempTarget->GetEntry() == NPC_RIPLIMB || tempTarget->GetEntry() == NPC_RAGEFACE) tempTarget->AddAura(RAID_MODE(SPELL_WARY_10N, SPELL_WARY_25N, SPELL_WARY_10H, SPELL_WARY_25H),tempTarget); me->DisappearAndDie(); } break; default: break; } } }
void UpdateAI(const uint32 diff) { if(!UpdateVictim() || (me->hasUnitState(UNIT_STAT_CASTING))) return; if(uiNaturesFuryTimer <= 0) { Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true); //Prevent casting natures fury on a target that is already affected if(pTarget && !pTarget->HasAura(RAID_MODE(RAID_10_SPELL_NATURES_FURY, RAID_25_SPELL_NATURES_FURY))) DoCast(pTarget, RAID_MODE(RAID_10_SPELL_NATURES_FURY, RAID_25_SPELL_NATURES_FURY)); me->AddAura(SPELL_CONSERVATORS_GRIP, me); uiNaturesFuryTimer = 5000; } else uiNaturesFuryTimer -= diff; if(uiSpawnHealthySporeTimer <= 0 && healthySporesSpawned < 10) { for (uint32 i = 0; i < 2; ++i) { Position pos; me->GetRandomNearPosition(pos, 25); me->SummonCreature(NPC_HEALTHY_SPORE, pos, TEMPSUMMON_TIMED_DESPAWN, 20000); } uiSpawnHealthySporeTimer = 2000; } else uiSpawnHealthySporeTimer -= diff; if(uiSpawnPauseTimer <= 0) { healthySporesSpawned = 0; uiSpawnPauseTimer = 20000; uiSpawnHealthySporeTimer = 0; } else uiSpawnPauseTimer -= diff; DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 uiDiff) { Unit* target = Unit::GetPlayer(*me, m_uiTargetGUID); if (!target || !target->isAlive() || !target->HasAura(SPELL_MARK)) { if (Creature* pAnubarak = Unit::GetCreature((*me), instance->GetData64(NPC_ANUBARAK))) pAnubarak->CastSpell(pAnubarak, SPELL_SPIKE_TELE, false); me->DisappearAndDie(); return; } if (m_uiIncreaseSpeedTimer) { if (m_uiIncreaseSpeedTimer <= uiDiff) { switch (m_uiSpeed) { case 0: DoCast(me, SPELL_SPIKE_SPEED1); DoCast(me, SPELL_SPIKE_TRAIL); m_uiSpeed = 1; m_uiIncreaseSpeedTimer = 7*IN_MILLISECONDS; break; case 1: DoCast(me, SPELL_SPIKE_SPEED2); m_uiSpeed = 2; m_uiIncreaseSpeedTimer = 7*IN_MILLISECONDS; break; case 2: DoCast(me, SPELL_SPIKE_SPEED3); m_uiIncreaseSpeedTimer = 0; break; } } else m_uiIncreaseSpeedTimer -= uiDiff; } }
void Pet::UpdateArmor() { float value = 0.0f; float bonus_armor = 0.0f; UnitMods unitMod = UNIT_MOD_ARMOR; Unit *owner = GetOwner(); // hunter and warlock pets gain 35% of owner's armor value if (owner && (getPetType() == HUNTER_PET || getPetType() == SUMMON_PET && owner->getClass() == CLASS_WARLOCK)) { bonus_armor = 0.35f * float(owner->GetArmor()); // Leggings of Beast Mastery if (getPetType() == HUNTER_PET && owner->HasAura(38297, 1)) bonus_armor += 490; } value = GetModifierValue(unitMod, BASE_VALUE); value *= GetModifierValue(unitMod, BASE_PCT); value += GetStat(STAT_AGILITY) * 2.0f; value += GetModifierValue(unitMod, TOTAL_VALUE) + bonus_armor; value *= GetModifierValue(unitMod, TOTAL_PCT); SetArmor(int32(value)); }
void FilterTargets(std::list<WorldObject*>& targets) { if (targets.empty()) return; Unit* caster = GetCaster(); if (caster->HasAura(SPELL_DK_SCENT_OF_BLOOD)) return; for (auto target : targets) { if (bpDuration && ffDuration) break; if (Unit* unit = target->ToUnit()) { if (Aura const* bp = unit->GetAura(SPELL_DK_BLOOD_PLAGUE, caster->GetGUID())) bpDuration = bp->GetDuration(); if (Aura const* ff = unit->GetAura(SPELL_DK_FROST_FEVER, caster->GetGUID())) ffDuration = ff->GetDuration(); } } }
void UpdateAI(const uint32 diff) { //Check if we have a target if (!UpdateVictim()) return; //KillSelfTimer if (KillSelfTimer <= diff) { me->Kill(me); return; } else KillSelfTimer -= diff; //MindflayTimer if (MindflayTimer <= diff) { Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0); if (target && !target->HasAura(SPELL_DIGESTIVE_ACID)) DoCast(target, SPELL_MIND_FLAY); //Mindflay every 10 seconds MindflayTimer = 10000; } else MindflayTimer -= diff; }
void HandleDummy(SpellEffIndex /*effIndex*/) { Unit* caster = GetCaster(); Unit* target = GetHitUnit(); if (ffDuration) caster->CastSpell(target, SPELL_DK_FROST_FEVER, true); if (bpDuration) caster->CastSpell(target, SPELL_DK_BLOOD_PLAGUE, true); if (!caster->HasAura(SPELL_DK_SCENT_OF_BLOOD)) { if (Aura* bp = target->GetAura(SPELL_DK_BLOOD_PLAGUE, caster->GetGUID())) { bp->SetDuration(bpDuration); bp->SetMaxDuration(bpDuration); } if (Aura* ff = target->GetAura(SPELL_DK_FROST_FEVER, caster->GetGUID())) { ff->SetDuration(ffDuration); ff->SetMaxDuration(ffDuration); } } }
void UpdateAI(const uint32 diff) { //Check if we have a target if (!UpdateVictim()) return; //EvadeTimer if (!me->IsWithinMeleeRange(me->getVictim())) { if (EvadeTimer <= diff) { if (Unit* p = Unit::GetUnit(*me, Portal)) p->Kill(p); //Dissapear and reappear at new position me->SetVisible(false); Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0); if (!target) { me->Kill(me); return; } if (!target->HasAura(SPELL_DIGESTIVE_ACID)) { me->GetMap()->CreatureRelocation(me, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0); if (Creature* pPortal = me->SummonCreature(MOB_GIANT_PORTAL, *me, TEMPSUMMON_CORPSE_DESPAWN)) { pPortal->SetReactState(REACT_PASSIVE); Portal = pPortal->GetGUID(); } GroundRuptureTimer = 500; HamstringTimer = 2000; ThrashTimer = 5000; EvadeTimer = 5000; AttackStart(target); } me->SetVisible(true); } else EvadeTimer -= diff; } //GroundRuptureTimer if (GroundRuptureTimer <= diff) { DoCast(me->getVictim(), SPELL_GROUND_RUPTURE); GroundRuptureTimer = 30000; } else GroundRuptureTimer -= diff; //ThrashTimer if (ThrashTimer <= diff) { DoCast(me->getVictim(), SPELL_THRASH); ThrashTimer = 10000; } else ThrashTimer -= diff; //HamstringTimer if (HamstringTimer <= diff) { DoCast(me->getVictim(), SPELL_HAMSTRING); HamstringTimer = 10000; } else HamstringTimer -= diff; DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 uiDiff) { //Return since we have no target if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; if (m_uiPhase == PHASE_1 || m_uiPhase == PHASE_3) { //m_uiShockBlast_Timer if (m_uiShockBlast_Timer < uiDiff) { //Randomly used in m_uiPhases 1 and 3 on Vashj's target, it's a Shock spell doing 8325-9675 nature damage and stunning the target for 5 seconds, during which she will not attack her target but switch to the next person on the aggro list. DoCastSpellIfCan(m_creature->getVictim(), SPELL_SHOCK_BLAST); m_uiShockBlast_Timer = urand(1000, 15000); //random cooldown }else m_uiShockBlast_Timer -= uiDiff; //m_uiStaticCharge_Timer if (m_uiStaticCharge_Timer < uiDiff) { //Used on random people (only 1 person at any given time) in m_uiPhases 1 and 3, it's a debuff doing 2775 to 3225 Nature damage to the target and everybody in about 5 yards around it, every 1 seconds for 30 seconds. It can be removed by Cloak of Shadows, Iceblock, Divine Shield, etc, but not by Cleanse or Dispel Magic. Unit *pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0); //cast Static Charge every 2 seconds for 20 seconds if (pTarget && !pTarget->HasAura(SPELL_STATIC_CHARGE_TRIGGER)) DoCastSpellIfCan(pTarget, SPELL_STATIC_CHARGE_TRIGGER); m_uiStaticCharge_Timer = urand(10000, 30000); }else m_uiStaticCharge_Timer -= uiDiff; //m_uiEntangle_Timer if (m_uiEntangle_Timer < uiDiff) { if (!m_bEntangle) { //Used in m_uiPhases 1 and 3, it casts Entangling Roots on everybody in a 15 yard radius of Vashj, immobilzing them for 10 seconds and dealing 500 damage every 2 seconds. It's not a magic effect so it cannot be dispelled, but is removed by various buffs such as Cloak of Shadows or Blessing of Freedom. DoCastSpellIfCan(m_creature->getVictim(), SPELL_ENTANGLE); m_bEntangle = true; m_uiEntangle_Timer = 10000; } else { CastShootOrMultishot(); m_bEntangle = false; m_uiEntangle_Timer = urand(20000, 25000); } }else m_uiEntangle_Timer -= uiDiff; //m_uiPhase 1 if (m_uiPhase == PHASE_1) { //m_uiPhase 2 begins when Vashj hits 70%. She will run to the middle of her platform and surround herself in a shield making her invulerable. if (m_creature->GetHealthPercent() <= 70.0f) { DoScriptText(SAY_PHASE2, m_creature); if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == CHASE_MOTION_TYPE) { //set false, so MoveChase is not triggered in AttackStart SetCombatMovement(false); m_creature->GetMotionMaster()->MovementExpired(); m_creature->GetMotionMaster()->MovePoint(POINT_MOVE_CENTER, afMiddlePos[0], afMiddlePos[1], afMiddlePos[2]); } m_uiPhase = PHASE_2; return; } } //m_uiPhase PHASE_3 else { //m_uiSummonSporebat_Timer if (m_uiSummonSporebat_Timer < uiDiff) { m_creature->SummonCreature(NPC_TOXIC_SPOREBAT, afSporebatPos[0], afSporebatPos[1], afSporebatPos[2], afSporebatPos[3], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); //summon sporebats faster and faster if (m_uiSummonSporebat_StaticTimer > 1000) m_uiSummonSporebat_StaticTimer -= 1000; m_uiSummonSporebat_Timer = m_uiSummonSporebat_StaticTimer; }else m_uiSummonSporebat_Timer -= uiDiff; } //Melee attack DoMeleeAttackIfReady(); //m_uiCheck_Timer - used to check if somebody is in melee range if (m_uiCheck_Timer < uiDiff) { bool bInMeleeRange = false; ThreatList const& tList = m_creature->getThreatManager().getThreatList(); for (ThreatList::const_iterator itr = tList.begin();itr != tList.end(); ++itr) { Unit* pTarget = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid()); //if in melee range if (pTarget && pTarget->IsWithinDistInMap(m_creature, ATTACK_DISTANCE)) { bInMeleeRange = true; break; } } //if nobody is in melee range if (!bInMeleeRange) CastShootOrMultishot(); m_uiCheck_Timer = 1500; }else m_uiCheck_Timer -= uiDiff; } //m_uiPhase PHASE_2 else { //m_uiForkedLightning_Timer if (m_uiForkedLightning_Timer < uiDiff) { //Used constantly in m_uiPhase 2, it shoots out completely randomly targeted bolts of lightning which hit everybody in a roughtly 60 degree cone in front of Vashj for 2313-2687 nature damage. Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0); if (!pTarget) pTarget = m_creature->getVictim(); DoCastSpellIfCan(pTarget, SPELL_FORKED_LIGHTNING); m_uiForkedLightning_Timer = urand(3000, 9000); }else m_uiForkedLightning_Timer -= uiDiff; //NPC_ENCHANTED_ELEMENTAL if (m_uiEnchantedElemental_Timer < uiDiff) { if (Creature* pElemental = m_creature->SummonCreature(NPC_ENCHANTED_ELEMENTAL, afElementPos[m_uiEnchantedElemental_Pos][0], afElementPos[m_uiEnchantedElemental_Pos][1], afElementPos[m_uiEnchantedElemental_Pos][2], afElementPos[m_uiEnchantedElemental_Pos][3], TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 60000)) pElemental->GetMotionMaster()->MoveFollow(m_creature, 0.0f, 0.0f); if (m_uiEnchantedElemental_Pos == 7) m_uiEnchantedElemental_Pos = 0; else ++m_uiEnchantedElemental_Pos; m_uiEnchantedElemental_Timer = urand(10000, 15000); }else m_uiEnchantedElemental_Timer -= uiDiff; //NPC_TAINTED_ELEMENTAL if (m_uiTaintedElemental_Timer < uiDiff) { uint32 uiPos = urand(0,7); m_creature->SummonCreature(NPC_TAINTED_ELEMENTAL, afElementPos[uiPos][0], afElementPos[uiPos][1], afElementPos[uiPos][2], afElementPos[uiPos][3], TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 15000); m_uiTaintedElemental_Timer = 120000; }else m_uiTaintedElemental_Timer -= uiDiff; //NPC_COILFANG_ELITE if (m_uiCoilfangElite_Timer < uiDiff) { uint32 uiPos = urand(0,2); m_creature->SummonCreature(NPC_COILFANG_ELITE, afCoilfangElitePos[uiPos][0], afCoilfangElitePos[uiPos][1], afCoilfangElitePos[uiPos][2], afCoilfangElitePos[uiPos][3], TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 45000); //wowwiki says 50 seconds, bosskillers says 45 m_uiCoilfangElite_Timer = urand(45000, 50000); }else m_uiCoilfangElite_Timer -= uiDiff; //NPC_COILFANG_STRIDER if (m_uiCoilfangStrider_Timer < uiDiff) { uint32 uiPos = urand(0,2); m_creature->SummonCreature(NPC_COILFANG_STRIDER, afCoilfangStriderPos[uiPos][0], afCoilfangStriderPos[uiPos][1], afCoilfangStriderPos[uiPos][2], afCoilfangStriderPos[uiPos][3], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); //wowwiki says 60 seconds, bosskillers says 60-70 m_uiCoilfangStrider_Timer = urand(60000, 70000); }else m_uiCoilfangStrider_Timer -= uiDiff; //m_uiCheck_Timer if (m_uiCheck_Timer < uiDiff) { //Start m_uiPhase 3 if (m_pInstance && m_pInstance->GetData(TYPE_VASHJ_PHASE3_CHECK) == DONE) { DoScriptText(SAY_PHASE3, m_creature); //set life 50%, not correct. Must remove 5% for each generator switched off m_creature->SetHealth(m_creature->GetMaxHealth()/2); m_creature->RemoveAurasDueToSpell(SPELL_MAGIC_BARRIER); SetCombatMovement(true); //return to chase top aggro if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() != CHASE_MOTION_TYPE) m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); m_uiPhase = PHASE_3; } m_uiCheck_Timer = 1000; }else m_uiCheck_Timer -= uiDiff; } }
void UpdateAI(uint32 diff) { //Return since we have no target if (!UpdateVictim()) return; switch (Phase) { case SKELETAL: if (uiCurseOfLifeTimer < diff) { if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) DoCast(target, SPELL_CURSE_OF_LIFE); uiCurseOfLifeTimer = urand(10*IN_MILLISECONDS, 15*IN_MILLISECONDS); } else uiCurseOfLifeTimer -= diff; if (uiShadowVolleyTimer < diff) { DoCastVictim(SPELL_SHADOW_VOLLEY); uiShadowVolleyTimer = urand(8*IN_MILLISECONDS, 10*IN_MILLISECONDS); } else uiShadowVolleyTimer -= diff; if (uiRainOfFireTimer < diff) { DoCastAOE(SPELL_RAIN_OF_FIRE); uiRainOfFireTimer = urand(14*IN_MILLISECONDS, 18*IN_MILLISECONDS); } else uiRainOfFireTimer -= diff; if (uiPhaseTimer < diff) { DoCast(SPELL_DECAY_FLESH); Phase = GOING_FLESH; uiPhaseTimer = 6*IN_MILLISECONDS; } else uiPhaseTimer -= diff; DoMeleeAttackIfReady(); break; case GOING_FLESH: if (uiPhaseTimer < diff) { Talk(SAY_FLESH); me->SetDisplayId(MODEL_FLESH); std::list<Unit*> playerList; SelectTargetList(playerList, 5, SELECT_TARGET_TOPAGGRO, 0, true); for (std::list<Unit*>::const_iterator itr = playerList.begin(); itr != playerList.end(); ++itr) { Unit* temp = (*itr); me->AddAura(SPELL_GIFT_OF_THARON_JA, temp); temp->SetDisplayId(MODEL_SKELETON); } uiPhaseTimer = 20*IN_MILLISECONDS; uiLightningBreathTimer = urand(3*IN_MILLISECONDS, 4*IN_MILLISECONDS); uiEyeBeamTimer = urand(4*IN_MILLISECONDS, 8*IN_MILLISECONDS); uiPoisonCloudTimer = urand(6*IN_MILLISECONDS, 7*IN_MILLISECONDS); Phase = FLESH; } else uiPhaseTimer -= diff; break; case FLESH: if (uiLightningBreathTimer < diff) { if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) DoCast(target, SPELL_LIGHTNING_BREATH); uiLightningBreathTimer = urand(6*IN_MILLISECONDS, 7*IN_MILLISECONDS); } else uiLightningBreathTimer -= diff; if (uiEyeBeamTimer < diff) { if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) DoCast(target, SPELL_EYE_BEAM); uiEyeBeamTimer = urand(4*IN_MILLISECONDS, 6*IN_MILLISECONDS); } else uiEyeBeamTimer -= diff; if (uiPoisonCloudTimer < diff) { DoCastAOE(SPELL_POISON_CLOUD); uiPoisonCloudTimer = urand(10*IN_MILLISECONDS, 12*IN_MILLISECONDS); } else uiPoisonCloudTimer -= diff; if (uiPhaseTimer < diff) { DoCast(SPELL_RETURN_FLESH); Phase = GOING_SKELETAL; uiPhaseTimer = 6*IN_MILLISECONDS; } else uiPhaseTimer -= diff; DoMeleeAttackIfReady(); break; case GOING_SKELETAL: if (uiPhaseTimer < diff) { Talk(SAY_SKELETON); me->DeMorph(); Phase = SKELETAL; uiPhaseTimer = 20*IN_MILLISECONDS; uiCurseOfLifeTimer = 1*IN_MILLISECONDS; uiRainOfFireTimer = urand(14*IN_MILLISECONDS, 18*IN_MILLISECONDS); uiShadowVolleyTimer = urand(8*IN_MILLISECONDS, 10*IN_MILLISECONDS); std::list<Unit*> playerList; SelectTargetList(playerList, 5, SELECT_TARGET_TOPAGGRO, 0, true); for (std::list<Unit*>::const_iterator itr = playerList.begin(); itr != playerList.end(); ++itr) { Unit* temp = (*itr); if (temp->HasAura(SPELL_GIFT_OF_THARON_JA)) temp->RemoveAura(SPELL_GIFT_OF_THARON_JA); temp->DeMorph(); } } else uiPhaseTimer -= diff; break; } }
void UpdateAI(const uint32 diff) { //Sounds OOC, Kiljaeden Orders if(!m_creature->getVictim()) { if(m_uiKJOrdersTimer < diff) { switch (rand()%5) { case 0: DoPlaySoundToSet(m_creature, SAY_KJ_OFFCOMBAT1); break; case 1: DoPlaySoundToSet(m_creature, SAY_KJ_OFFCOMBAT2); break; case 2: DoPlaySoundToSet(m_creature, SAY_KJ_OFFCOMBAT3); break; case 3: DoPlaySoundToSet(m_creature, SAY_KJ_OFFCOMBAT4); break; case 4: DoPlaySoundToSet(m_creature, SAY_KJ_OFFCOMBAT5); break; } m_uiKJOrdersTimer = 30000; }else m_uiKJOrdersTimer -= diff; } /*//Rebirth After Phase1 if(pInstance && pInstance->GetData(DATA_KILJAEDEN) == IN_PROGRESS) { m_creature->setFaction(14); m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); //pInstance->SetData(DATA_KILJAEDEN_EVENT, IN_PROGRESS); //pInstance->SetData(DATA_DECIVER, NOT_STARTED); }*/ if(!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; //dragon cast blue shield for(uint8 i=0; i<4; ++i) { if(Unit* Dragon = Unit::GetUnit(*m_creature, DragonGUID[i])) if(Dragon && Dragon->HasAura(SPELL_SHIELD_OF_BLUE)) { m_uiCancelShieldTimer = 5000; std::list<HostileReference *> t_list = m_creature->getThreatManager().getThreatList(); for(std::list<HostileReference *>::iterator itr = t_list.begin(); itr!= t_list.end(); ++itr) { Unit *TargetedPlayer = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid()); if (TargetedPlayer && TargetedPlayer->GetTypeId() == TYPEID_PLAYER && TargetedPlayer->IsWithinDistInMap(Dragon, 10) && !TargetedPlayer->HasAura(AURA_BLUESHIELD)) TargetedPlayer->CastSpell(TargetedPlayer,AURA_BLUESHIELD,true); } } } //stop blue shield if(m_uiCancelShieldTimer < diff) { std::list<HostileReference *> t_list = m_creature->getThreatManager().getThreatList(); for(std::list<HostileReference *>::iterator itr = t_list.begin(); itr!= t_list.end(); ++itr) { Unit *ShieldedPlayer1 = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid()); if (ShieldedPlayer1 && ShieldedPlayer1->GetTypeId() == TYPEID_PLAYER && ShieldedPlayer1->HasAura(AURA_BLUESHIELD)) { ShieldedPlayer1->RemoveAurasDueToSpell(AURA_BLUESHIELD); } } m_uiCancelShieldTimer = 300000; }else m_uiCancelShieldTimer -= diff; //Kalecgos and Anvena Event if((m_uiKalecgosAnvenaTimer < diff) && m_bIsAnvena) { switch(m_uiKalecgosAnvenaCount) { case 0: DoPlaySoundToSet(m_creature, SAY_KALECGOS_AWAKEN); m_uiKalecgosAnvenaTimer = 5000; break; case 1: DoPlaySoundToSet(m_creature, SAY_ANVEENA_IMPRISONED); m_uiKalecgosAnvenaTimer = 3000; break; case 2: DoPlaySoundToSet(m_creature, SAY_KALECGOS_LETGO); m_uiKalecgosAnvenaTimer = 6000; break; case 5: DoPlaySoundToSet(m_creature, SAY_ANVEENA_LOST); m_uiKalecgosAnvenaTimer = 4000; break; case 4: DoPlaySoundToSet(m_creature, SAY_KALECGOS_FOCUS); m_uiKalecgosAnvenaTimer = 8000; break; case 3: DoPlaySoundToSet(m_creature, SAY_ANVEENA_KALEC); m_uiKalecgosAnvenaTimer = 5000; break; case 6: DoPlaySoundToSet(m_creature, SAY_KALECGOS_FATE); m_uiKalecgosAnvenaTimer = 5000; break; case 7: DoPlaySoundToSet(m_creature, SAY_ANVEENA_GOODBYE); m_creature->CastSpell(m_creature, SPELL_SACRIFICE_OF_ANVEENA, false); m_uiKalecgosAnvenaTimer = 5000; break; case 9: DoPlaySoundToSet(m_creature, SAY_KALECGOS_GOODBYE); ; m_bIsAnvena = false; break; case 8: DoPlaySoundToSet(m_creature, SAY_KALECGOS_ENCOURAGE); m_uiKalecgosAnvenaTimer = 14000; break; } ++m_uiKalecgosAnvenaCount; } m_uiKalecgosAnvenaTimer -= diff; //Kalecgos Event working if((m_uiKalecgosTimer < diff) && !m_bIsKalecgosSpawned) { DoPlaySoundToSet(m_creature, SAY_KALECGOS_JOIN); Kalecgos = m_creature->SummonCreature(ID_KALECGOS, m_creature->GetPositionX()-25, m_creature->GetPositionY()-25, m_creature->GetPositionZ()+10, 0.686f, TEMPSUMMON_TIMED_DESPAWN, 600000); Kalecgos->setFaction(35); //Kalecgos need to start shhooting arcane bolt into Kiljaeden //Dragon->AI()->AttackStart(m_creature); m_bIsKalecgosSpawned = true; }m_uiKalecgosTimer -= diff; //Shield Orb At Start each phases working /* if(m_uiShieldOrbTimer < diff && !m_bPhase5) { uint8 l=1; if(m_bPhase3) l=2; if(m_bPhase4) l=3; for(uint8 k=0; k<l; ++k) { Creature* ShieldOrb = m_creature->SummonCreature(ID_SHIELDORB, m_creature->GetPositionX()+urand(1,15), m_creature->GetPositionY()+urand(1,15), m_creature->GetPositionZ()+15, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000); if(ShieldOrb) ShieldOrb->AI()->AttackStart(m_creature->getVictim()); } m_uiShieldOrbTimer = 50000; }else m_uiShieldOrbTimer -= diff;*/ //Sinister Reflects Attack Spell Timer if(m_uiSinnisterCastTimer < diff) { uint8 m_uiSinisterCount = 4; /*if(m_bPhase3) m_uiSinisterCount = 4; if(m_bPhase4) m_uiSinisterCount = 8; if(m_bPhase5) m_uiSinisterCount = 12;*/ for(uint8 i=0; i<m_uiSinisterCount; ++i) { if(Unit* Sinister = Unit::GetUnit(*m_creature, m_uiSinisterGUID[i][0])) { if(Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0)) Sinister->CastSpell(target, m_uiSinisterGUID[i][1], true); } } m_uiSinnisterCastTimer = 8000; }else m_uiSinnisterCastTimer -= diff; //Phase4 //armageddon if((m_uiAramageddonTimer < diff) && m_bPhase4) { uint8 h=3; if(m_bPhase5) h=5; if(!m_bPhase5 && m_bDarknessOfSoulsCasting) h=0; for(uint8 i=0; i<h; ++i) { if(Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0)) Creature* Armagedon = m_creature->SummonCreature(ID_ARMAGEDON, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 15000); } m_uiAramageddonTimer = 14000; }else m_uiAramageddonTimer -= diff; if((m_uiShadowSpikeEndsTimer < diff) && m_bShadowSpikeEnds && m_bPhase3) { if(Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0)) { cShadowSpike = m_creature->SummonCreature(ID_SHADOWSPIKE, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 6000); cShadowSpike->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); cShadowSpike->setFaction(14); //target->CastSpell(target, SPELL_SHADOWSPIKE_EXP, false); } ++m_uiSpikesCount; if(m_uiSpikesCount > 9) m_bShadowSpikeEnds = false; m_uiShadowSpikeEndsTimer = 3000; }else m_uiShadowSpikeEndsTimer -= diff; if(m_bShadowSpikeEnds) return; if(m_uiDarknessExplosionTimer < diff && m_bDarknessOfSoulsCasting) { m_creature->CastSpell(m_creature->getVictim(), SPELL_DARKNESS_EXPLOSION, true); m_bDarknessOfSoulsCasting = false; m_uiDarknessExplosionTimer = 600000; m_uiDarknessOfSoulsTimer = 45000; if(m_bPhase5) m_uiDarknessOfSoulsTimer = 25000; }else m_uiDarknessExplosionTimer -= diff; if(m_bDarknessOfSoulsCasting) return; // darkness of a thousand souls from phase 3 on if(m_uiDarknessOfSoulsTimer < diff && m_bPhase3) { switch (rand()%3) { case 0: DoPlaySoundToSet(m_creature, SAY_KJ_DARKNESS1); break; case 1: DoPlaySoundToSet(m_creature, SAY_KJ_DARKNESS2); break; case 2: DoPlaySoundToSet(m_creature, SAY_KJ_DARKNESS3); break; } m_creature->CastSpell(m_creature, SPELL_DARKNESS_OF_SOULS, true); m_bDarknessOfSoulsCasting = true; m_uiDarknessExplosionTimer = 8500; }else m_uiDarknessOfSoulsTimer -= diff; // After Each Phase Dragons Are Spawned if((m_uiOrbTimer < diff) && !m_bBoolOrb) { for(uint8 i=0; i<4; ++i) DragonGUID[i] = 0; switch (rand()%4) { case 0: DoPlaySoundToSet(m_creature, SAY_KALEC_ORB_READY1); break; case 1: DoPlaySoundToSet(m_creature, SAY_KALEC_ORB_READY2); break; case 2: DoPlaySoundToSet(m_creature, SAY_KALEC_ORB_READY3); break; case 3: DoPlaySoundToSet(m_creature, SAY_KALEC_ORB_READY4); break; } uint8 m_uiMaxDragons = 1; if(m_bPhase5) m_uiMaxDragons = 4; for(uint8 i=0; i<m_uiMaxDragons; ++i) { Creature* Dragon = m_creature->SummonCreature(ID_DRAGON, m_creature->GetPositionX()+urand(5,20), m_creature->GetPositionY()+urand(5,20), m_creature->GetPositionZ(), 0, TEMPSUMMON_CORPSE_DESPAWN, 20000); DragonGUID[i] = Dragon->GetGUID(); } m_bBoolOrb = true; }else m_uiOrbTimer -= diff; //FireBloom Damage WorkArround if (m_uiFireBloomCheck < diff) { if(m_uiFireBloomCount < 10) for(uint8 i=0; i<5; ++i) { if(Unit* FireTarget = Unit::GetUnit(*m_creature, m_uiFireBloomTarget[i])) FireTarget->CastSpell(FireTarget, SPELL_FIREBLOOM_EFF, true); } ++m_uiFireBloomCount; m_uiFireBloomCheck = 2000; }else m_uiFireBloomCheck -= diff; //Phase 3 init if(((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) <= 85) && !m_bPhase3) { DoPlaySoundToSet(m_creature, SAY_KJ_PHASE3); if(Unit* victim = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0)) if (victim && (victim->GetTypeId() == TYPEID_PLAYER)) Sinister(((Player*)victim),0,4); m_creature->MonsterYell("entering phase 3",LANG_UNIVERSAL,0); m_uiSinnisterCastTimer = 10000; m_uiShadowSpikeTimer = 30000; m_uiFlameDartTimer = 40000; m_uiDarknessOfSoulsTimer = 45000; m_bShadowSpikeEnds = false; m_bDarknessOfSoulsCasting = false; m_bPhase3 = true; //DragonsTimer m_uiOrbTimer = 35000; m_bBoolOrb = false; } //phase 4 init if(((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) <= 55) && !m_bPhase4) { DoPlaySoundToSet(m_creature, SAY_KJ_PHASE4); if(Unit* victim = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0)) if (victim && (victim->GetTypeId() == TYPEID_PLAYER)) Sinister(((Player*)victim),4,8); m_creature->MonsterYell("entering phase 4",LANG_UNIVERSAL,0); m_uiAramageddonTimer = 2000; //100% ok m_bPhase4 = true; m_uiDarknessOfSoulsTimer = 45000; //DragonsTimer m_uiOrbTimer = 35000; m_bBoolOrb = false; } //phase 5 init if(((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) <= 25) && !m_bPhase5) { DoPlaySoundToSet(m_creature, SAY_KJ_PHASE5); if(Unit* victim = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0)) if (victim && (victim->GetTypeId() == TYPEID_PLAYER)) Sinister(((Player*)victim),8,12); m_creature->MonsterYell("entering phase 5",LANG_UNIVERSAL,0); m_uiShadowSpikeTimer = 1000; m_uiDarknessOfSoulsTimer = 45000; m_bPhase5 = true; //DragonsTimer m_uiOrbTimer = 35000; m_bBoolOrb = false; //Kalecgos and Anvena Event m_uiKalecgosAnvenaTimer = 20000; m_bIsAnvena = true; m_uiKalecgosAnvenaCount = 0; Creature* Anveena = m_creature->SummonCreature(ID_ANVEENA, m_creature->GetPositionX()+urand(20,30), m_creature->GetPositionY()+urand(20,30), m_creature->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 120000); Anveena->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); Anveena->setFaction(35); } //spells used from phase 3 on if(m_bPhase3) { if(m_uiShadowSpikeTimer < diff) { DoCast(m_creature->getVictim(), SPELL_SHADOWSPIKE); m_bShadowSpikeEnds = true; m_uiShadowSpikeEndsTimer = 500; m_uiSpikesCount = 0; m_uiShadowSpikeTimer = 90000; }else m_uiShadowSpikeTimer -= diff; //flame dart if(m_uiFlameDartTimer < diff ) { DoCast(m_creature->getVictim(), SPELL_FLAMEDARTS); m_uiFlameDartTimer = 33000; }else m_uiFlameDartTimer -= diff; } //Phase2 // legion lightning all phases if(m_uiLegionLightingTimer < diff) { DoCast(m_creature->getVictim(), SPELL_LEGION_LIGHTING); m_uiLegionLightingTimer = 11000; }else m_uiLegionLightingTimer -= diff; // fire bloom all phases if(m_uiFireBloomTimer < diff) { for(uint8 i=0; i<5; ++i) { Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0); m_uiFireBloomTarget[i] = target->GetGUID(); m_uiFireBloomCount = 0; //DoCast(target, SPELL_FIREBLOOM, true); } m_uiFireBloomTimer = 25000; }else m_uiFireBloomTimer -= diff; // soul flay all phases if(m_uiSoulFlayTimer < diff) { DoCast(m_creature->getVictim(), SPELL_SOULFLAY); m_uiSoulFlayTimer = 7000; }else m_uiSoulFlayTimer -= diff; DoMeleeAttackIfReady(); }
void Guardian::UpdateAttackPowerAndDamage(bool ranged) { if (ranged) return; float val = 0.0f; float bonusAP = 0.0f; UnitMods unitMod = UNIT_MOD_ATTACK_POWER; if (GetEntry() == ENTRY_IMP) // imp's attack power val = GetStat(STAT_STRENGTH) - 10.0f; else val = 2 * GetStat(STAT_STRENGTH) - 20.0f; Unit* owner = GetOwner(); if (owner && owner->GetTypeId() == TYPEID_PLAYER) { if (isHunterPet()) //hunter pets benefit from owner's attack power { float mod = 1.0f; //Hunter contribution modifier if (isPet()) { PetSpellMap::const_iterator itr = ToPet()->m_spells.find(62758); //Wild Hunt rank 1 if (itr == ToPet()->m_spells.end()) itr = ToPet()->m_spells.find(62762); //Wild Hunt rank 2 if (itr != ToPet()->m_spells.end()) // If pet has Wild Hunt { SpellInfo const* sProto = sSpellMgr->GetSpellInfo(itr->first); // Then get the SpellProto and add the dummy effect value mod += CalculatePct(1.0f, sProto->Effects[1].CalcValue()); } } bonusAP = owner->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.22f * mod; SetBonusDamage(int32(owner->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.1287f * mod)); } //demons benefit from warlocks shadow or fire damage else if (isPet() && !IsPetGhoul()) { int32 fire = int32(owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + SPELL_SCHOOL_FIRE)) - owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG + SPELL_SCHOOL_FIRE); int32 shadow = int32(owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + SPELL_SCHOOL_SHADOW)) - owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG + SPELL_SCHOOL_SHADOW); int32 maximum = (fire > shadow) ? fire : shadow; if (maximum < 0) maximum = 0; SetBonusDamage(int32(maximum * 0.15f)); bonusAP = maximum * 0.57f; } //water elementals benefit from mage's frost damage else if (GetEntry() == ENTRY_WATER_ELEMENTAL) { int32 frost = int32(owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + SPELL_SCHOOL_FROST)) - owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG + SPELL_SCHOOL_FROST); if (frost < 0) frost = 0; SetBonusDamage(int32(frost * 0.4f)); } } SetModifierValue(UNIT_MOD_ATTACK_POWER, BASE_VALUE, val + bonusAP); //in BASE_VALUE of UNIT_MOD_ATTACK_POWER for creatures we store data of meleeattackpower field in DB float base_attPower = GetModifierValue(unitMod, BASE_VALUE) * GetModifierValue(unitMod, BASE_PCT); float attPowerMod = GetModifierValue(unitMod, TOTAL_VALUE); float attPowerMultiplier = GetModifierValue(unitMod, TOTAL_PCT) - 1.0f; // Animal Handler rank 1, 2 if (owner->HasAura(34453) || owner->HasAura(34454)) { SpellInfo const* sProto = sSpellMgr->GetSpellInfo((owner->HasAura(34453)) ? 34453 : 34454); attPowerMultiplier += ((float)sProto->Effects[EFFECT_1].CalcValue() / 100); } //UNIT_FIELD_(RANGED)_ATTACK_POWER field SetInt32Value(UNIT_FIELD_ATTACK_POWER, (int32)base_attPower); //UNIT_FIELD_(RANGED)_ATTACK_POWER_MODS field SetInt32Value(UNIT_FIELD_ATTACK_POWER_MODS, (int32)attPowerMod); //UNIT_FIELD_(RANGED)_ATTACK_POWER_MULTIPLIER field SetFloatValue(UNIT_FIELD_ATTACK_POWER_MULTIPLIER, attPowerMultiplier); //automatically update weapon damage after attack power modification UpdateDamagePhysical(BASE_ATTACK); }
void FrostBombTrigger() { Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM,0); if (pTarget && !pTarget->HasAura(SPELL_ICE_TOMB)) DoCast(pTarget, SPELL_FROST_BOMB_TRIGGER); }
void UpdateAI(const uint32 diff) { if(!CanAttack && Intro) { if(AggroTimer < diff) { CanAttack = true; m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); AggroTimer=19000; }else { AggroTimer-=diff; return; } } //to prevent abuses during phase 2 if(Phase == 2 && !m_creature->getVictim() && InCombat) { EnterEvadeMode(); return; } //Return since we have no target if (!UpdateVictim() ) return; if(Phase == 1 || Phase == 3) { //ShockBlast_Timer if (ShockBlast_Timer < diff) { //Shock Burst //Randomly used in Phases 1 and 3 on Vashj's target, it's a Shock spell doing 8325-9675 nature damage and stunning the target for 5 seconds, during which she will not attack her target but switch to the next person on the aggro list. DoCast(m_creature->getVictim(), SPELL_SHOCK_BLAST); m_creature->TauntApply(m_creature->getVictim()); ShockBlast_Timer = 1000+rand()%14000; //random cooldown }else ShockBlast_Timer -= diff; //StaticCharge_Timer if(StaticCharge_Timer < diff) { //Static Charge //Used on random people (only 1 person at any given time) in Phases 1 and 3, it's a debuff doing 2775 to 3225 Nature damage to the target and everybody in about 5 yards around it, every 1 seconds for 30 seconds. It can be removed by Cloak of 3s, Iceblock, Divine Shield, etc, but not by Cleanse or Dispel Magic. Unit *target = NULL; target = SelectUnit(SELECT_TARGET_RANDOM, 0); if(target && !target->HasAura(SPELL_STATIC_CHARGE_TRIGGER, 0) && target->GetTypeId() == TYPEID_PLAYER && !target->isDead()) //cast Static Charge every 2 seconds for 20 seconds DoCast(target, SPELL_STATIC_CHARGE_TRIGGER); StaticCharge_Timer = 10000+rand()%20000; //blizzlike }else StaticCharge_Timer -= diff; //Entangle_Timer if (Entangle_Timer < diff) { if(!Entangle) { //Entangle //Used in Phases 1 and 3, it casts Entangling Roots on everybody in a 15 yard radius of Vashj, immobilzing them for 10 seconds and dealing 500 damage every 2 seconds. It's not a magic effect so it cannot be dispelled, but is removed by various buffs such as Cloak of Shadows or Blessing of Freedom. DoCast(m_creature->getVictim(), SPELL_ENTANGLE); Entangle = true; Entangle_Timer = 10000; } else { CastShootOrMultishot(); Entangle = false; Entangle_Timer = 20000+rand()%5000; } }else Entangle_Timer -= diff; //Phase 1 if(Phase == 1) { //Start phase 2 if ((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 70) { //Phase 2 begins when Vashj hits 70%. She will run to the middle of her platform and surround herself in a shield making her invulerable. Phase = 2; m_creature->GetMotionMaster()->Clear(); DoTeleportTo(MIDDLE_X, MIDDLE_Y, MIDDLE_Z); Creature *pCreature; for(uint8 i = 0; i < 4; i++) { pCreature = m_creature->SummonCreature(SHIED_GENERATOR_CHANNEL, ShieldGeneratorChannelPos[i][0], ShieldGeneratorChannelPos[i][1], ShieldGeneratorChannelPos[i][2], ShieldGeneratorChannelPos[i][3], TEMPSUMMON_CORPSE_DESPAWN, 0); if (pCreature) ShieldGeneratorChannel[i] = pCreature->GetGUID(); } DoScriptText(SAY_PHASE2, m_creature); } } //Phase 3 else { //SummonSporebat_Timer if(SummonSporebat_Timer < diff) { Creature *Sporebat = NULL; Sporebat = m_creature->SummonCreature(TOXIC_SPOREBAT, SPOREBAT_X, SPOREBAT_Y, SPOREBAT_Z, SPOREBAT_O, TEMPSUMMON_CORPSE_DESPAWN, 0); if(Sporebat) { Unit *target = NULL; target = SelectUnit(SELECT_TARGET_RANDOM, 0); if(target) Sporebat->AI()->AttackStart(target); } //summon sporebats faster and faster if(SummonSporebat_StaticTimer > 1000) SummonSporebat_StaticTimer -= 1000; SummonSporebat_Timer = SummonSporebat_StaticTimer; if(SummonSporebat_Timer < 5000) SummonSporebat_Timer = 5000; }else SummonSporebat_Timer -= diff; } //Melee attack DoMeleeAttackIfReady(); //Check_Timer - used to check if somebody is in melee range if(Check_Timer < diff) { bool InMeleeRange = false; Unit *target; std::list<HostilReference *> t_list = m_creature->getThreatManager().getThreatList(); for(std::list<HostilReference *>::iterator itr = t_list.begin(); itr!= t_list.end(); ++itr) { target = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid()); //if in melee range if(target && target->IsWithinDistInMap(m_creature, 5)) { InMeleeRange = true; break; } } //if nobody is in melee range if(!InMeleeRange) CastShootOrMultishot(); Check_Timer = 5000; }else Check_Timer -= diff; } //Phase 2 else { //ForkedLightning_Timer if(ForkedLightning_Timer < diff) { //Forked Lightning //Used constantly in Phase 2, it shoots out completely randomly targeted bolts of lightning which hit everybody in a roughtly 60 degree cone in front of Vashj for 2313-2687 nature damage. Unit *target = NULL; target = SelectUnit(SELECT_TARGET_RANDOM, 0); if(!target) target = m_creature->getVictim(); DoCast(target, SPELL_FORKED_LIGHTNING); ForkedLightning_Timer = 2000+rand()%6000; //blizzlike }else ForkedLightning_Timer -= diff; //EnchantedElemental_Timer if(EnchantedElemental_Timer < diff) { Creature *Elemental; Elemental = m_creature->SummonCreature(ENCHANTED_ELEMENTAL, ElementPos[EnchantedElemental_Pos][0], ElementPos[EnchantedElemental_Pos][1], ElementPos[EnchantedElemental_Pos][2], ElementPos[EnchantedElemental_Pos][3], TEMPSUMMON_CORPSE_DESPAWN, 0); if(EnchantedElemental_Pos == 7) EnchantedElemental_Pos = 0; else EnchantedElemental_Pos++; EnchantedElemental_Timer = 10000+rand()%5000; }else EnchantedElemental_Timer -= diff; //TaintedElemental_Timer if(TaintedElemental_Timer < diff) { Creature *Tain_Elemental; uint32 pos = rand()%8; Tain_Elemental = m_creature->SummonCreature(TAINTED_ELEMENTAL, ElementPos[pos][0], ElementPos[pos][1], ElementPos[pos][2], ElementPos[pos][3], TEMPSUMMON_DEAD_DESPAWN, 0); TaintedElemental_Timer = 120000; }else TaintedElemental_Timer -= diff; //CoilfangElite_Timer if(CoilfangElite_Timer < diff) { uint32 pos = rand()%3; Creature* CoilfangElite = NULL; CoilfangElite = m_creature->SummonCreature(COILFANG_ELITE, CoilfangElitePos[pos][0], CoilfangElitePos[pos][1], CoilfangElitePos[pos][2], CoilfangElitePos[pos][3], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); if(CoilfangElite) { Unit *target = NULL; target = SelectUnit(SELECT_TARGET_RANDOM, 0); if(target) CoilfangElite->AI()->AttackStart(target); else if(m_creature->getVictim()) CoilfangElite->AI()->AttackStart(m_creature->getVictim()); } CoilfangElite_Timer = 45000+rand()%5000; }else CoilfangElite_Timer -= diff; //CoilfangStrider_Timer if(CoilfangStrider_Timer < diff) { uint32 pos = rand()%3; Creature* CoilfangStrider = NULL; CoilfangStrider = m_creature->SummonCreature(COILFANG_STRIDER, CoilfangStriderPos[pos][0], CoilfangStriderPos[pos][1], CoilfangStriderPos[pos][2], CoilfangStriderPos[pos][3], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); if(CoilfangStrider) { Unit *target = NULL; target = SelectUnit(SELECT_TARGET_RANDOM, 0); if(target) CoilfangStrider->AI()->AttackStart(target); else if(m_creature->getVictim()) CoilfangStrider->AI()->AttackStart(m_creature->getVictim()); } CoilfangStrider_Timer = 60000+rand()%10000; }else CoilfangStrider_Timer -= diff; //Check_Timer if(Check_Timer < diff) { //Start Phase 3 if(pInstance && pInstance->GetData(DATA_CANSTARTPHASE3)) { //set life 50% m_creature->SetHealth(m_creature->GetMaxHealth()/2); m_creature->RemoveAurasDueToSpell(SPELL_MAGIC_BARRIER); DoScriptText(SAY_PHASE3, m_creature); Phase = 3; //return to the tank m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); } // check item tainted core. if player has item, cast root. if not has item and is rooted, remove root InstanceMap::PlayerList const &playerliste = ((InstanceMap*)m_creature->GetMap())->GetPlayers(); InstanceMap::PlayerList::const_iterator it; Map::PlayerList const &PlayerList = ((InstanceMap*)m_creature->GetMap())->GetPlayers(); for(Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) { Player* i_pl = i->getSource(); { if(i_pl->HasItemCount(31088, 1, false)) { if(i_pl->HasAura(39666,0)) i_pl->RemoveAurasDueToSpell(39666); // cloak of shadowx if(!i_pl->HasAura(38132,0)) i_pl->CastSpell(i_pl, 38132, false); // spell root } else if(i_pl->HasAura(38132,0)) i_pl->RemoveAurasDueToSpell(38132); } } Check_Timer = 1000; }else Check_Timer -= diff; } }
void UpdateAI(uint32 diff) override { if (!CanAttack && Intro) { if (AggroTimer <= diff) { CanAttack = true; me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); AggroTimer=19000; } else { AggroTimer-=diff; return; } } // to prevent abuses during phase 2 if (Phase == 2 && !me->GetVictim() && me->IsInCombat()) { EnterEvadeMode(); return; } // Return since we have no target if (!UpdateVictim()) return; if (Phase == 1 || Phase == 3) { // ShockBlastTimer if (ShockBlastTimer <= diff) { // Shock Burst // Randomly used in Phases 1 and 3 on Vashj's target, it's a Shock spell doing 8325-9675 nature damage and stunning the target for 5 seconds, during which she will not attack her target but switch to the next person on the aggro list. DoCastVictim(SPELL_SHOCK_BLAST); me->TauntApply(me->GetVictim()); ShockBlastTimer = 1000 + rand32() % 14000; // random cooldown } else ShockBlastTimer -= diff; // StaticChargeTimer if (StaticChargeTimer <= diff) { // Static Charge // Used on random people (only 1 person at any given time) in Phases 1 and 3, it's a debuff doing 2775 to 3225 Nature damage to the target and everybody in about 5 yards around it, every 1 seconds for 30 seconds. It can be removed by Cloak of Shadows, Iceblock, Divine Shield, etc, but not by Cleanse or Dispel Magic. Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 200, true); if (target && !target->HasAura(SPELL_STATIC_CHARGE_TRIGGER)) DoCast(target, SPELL_STATIC_CHARGE_TRIGGER); // cast Static Charge every 2 seconds for 20 seconds StaticChargeTimer = 10000 + rand32() % 20000; } else StaticChargeTimer -= diff; // EntangleTimer if (EntangleTimer <= diff) { if (!Entangle) { // Entangle // Used in Phases 1 and 3, it casts Entangling Roots on everybody in a 15 yard radius of Vashj, immobilzing them for 10 seconds and dealing 500 damage every 2 seconds. It's not a magic effect so it cannot be dispelled, but is removed by various buffs such as Cloak of Shadows or Blessing of Freedom. DoCastVictim(SPELL_ENTANGLE); Entangle = true; EntangleTimer = 10000; } else { CastShootOrMultishot(); Entangle = false; EntangleTimer = 20000 + rand32() % 5000; } } else EntangleTimer -= diff; // Phase 1 if (Phase == 1) { // Start phase 2 if (HealthBelowPct(70)) { // Phase 2 begins when Vashj hits 70%. She will run to the middle of her platform and surround herself in a shield making her invulerable. Phase = 2; me->GetMotionMaster()->Clear(); DoTeleportTo(MIDDLE_X, MIDDLE_Y, MIDDLE_Z); for (uint8 i = 0; i < 4; ++i) if (Creature* creature = me->SummonCreature(SHIED_GENERATOR_CHANNEL, ShieldGeneratorChannelPos[i][0], ShieldGeneratorChannelPos[i][1], ShieldGeneratorChannelPos[i][2], ShieldGeneratorChannelPos[i][3], TEMPSUMMON_CORPSE_DESPAWN, 0)) ShieldGeneratorChannel[i] = creature->GetGUID(); Talk(SAY_PHASE2); } } // Phase 3 else { // SummonSporebatTimer if (SummonSporebatTimer <= diff) { if (Creature* sporebat = me->SummonCreature(TOXIC_SPOREBAT, SPOREBAT_X, SPOREBAT_Y, SPOREBAT_Z, SPOREBAT_O, TEMPSUMMON_CORPSE_DESPAWN, 0)) if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) sporebat->AI()->AttackStart(target); // summon sporebats faster and faster if (SummonSporebatStaticTimer > 1000) SummonSporebatStaticTimer -= 1000; SummonSporebatTimer = SummonSporebatStaticTimer; if (SummonSporebatTimer < 5000) SummonSporebatTimer = 5000; } else SummonSporebatTimer -= diff; } // Melee attack DoMeleeAttackIfReady(); // CheckTimer - used to check if somebody is in melee range if (CheckTimer <= diff) { bool inMeleeRange = false; std::list<HostileReference*> t_list = me->getThreatManager().getThreatList(); for (std::list<HostileReference*>::const_iterator itr = t_list.begin(); itr!= t_list.end(); ++itr) { Unit* target = ObjectAccessor::GetUnit(*me, (*itr)->getUnitGuid()); if (target && target->IsWithinDistInMap(me, 5)) // if in melee range { inMeleeRange = true; break; } } // if nobody is in melee range if (!inMeleeRange) CastShootOrMultishot(); CheckTimer = 5000; } else CheckTimer -= diff; } // Phase 2 else { // ForkedLightningTimer if (ForkedLightningTimer <= diff) { // Forked Lightning // Used constantly in Phase 2, it shoots out completely randomly targeted bolts of lightning which hit everybody in a roughtly 60 degree cone in front of Vashj for 2313-2687 nature damage. Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0); if (!target) target = me->GetVictim(); DoCast(target, SPELL_FORKED_LIGHTNING); ForkedLightningTimer = 2000 + rand32() % 6000; } else ForkedLightningTimer -= diff; // EnchantedElementalTimer if (EnchantedElementalTimer <= diff) { me->SummonCreature(ENCHANTED_ELEMENTAL, ElementPos[EnchantedElementalPos][0], ElementPos[EnchantedElementalPos][1], ElementPos[EnchantedElementalPos][2], ElementPos[EnchantedElementalPos][3], TEMPSUMMON_CORPSE_DESPAWN, 0); if (EnchantedElementalPos == 7) EnchantedElementalPos = 0; else ++EnchantedElementalPos; EnchantedElementalTimer = 10000 + rand32() % 5000; } else EnchantedElementalTimer -= diff; // TaintedElementalTimer if (TaintedElementalTimer <= diff) { uint32 pos = rand32() % 8; me->SummonCreature(TAINTED_ELEMENTAL, ElementPos[pos][0], ElementPos[pos][1], ElementPos[pos][2], ElementPos[pos][3], TEMPSUMMON_DEAD_DESPAWN, 0); TaintedElementalTimer = 120000; } else TaintedElementalTimer -= diff; // CoilfangEliteTimer if (CoilfangEliteTimer <= diff) { uint32 pos = rand32() % 3; Creature* coilfangElite = me->SummonCreature(COILFANG_ELITE, CoilfangElitePos[pos][0], CoilfangElitePos[pos][1], CoilfangElitePos[pos][2], CoilfangElitePos[pos][3], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); if (coilfangElite) { if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) coilfangElite->AI()->AttackStart(target); else if (me->GetVictim()) coilfangElite->AI()->AttackStart(me->GetVictim()); } CoilfangEliteTimer = 45000 + rand32() % 5000; } else CoilfangEliteTimer -= diff; // CoilfangStriderTimer if (CoilfangStriderTimer <= diff) { uint32 pos = rand32() % 3; if (Creature* CoilfangStrider = me->SummonCreature(COILFANG_STRIDER, CoilfangStriderPos[pos][0], CoilfangStriderPos[pos][1], CoilfangStriderPos[pos][2], CoilfangStriderPos[pos][3], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000)) { if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) CoilfangStrider->AI()->AttackStart(target); else if (me->GetVictim()) CoilfangStrider->AI()->AttackStart(me->GetVictim()); } CoilfangStriderTimer = 60000 + rand32() % 10000; } else CoilfangStriderTimer -= diff; // CheckTimer if (CheckTimer <= diff) { // Start Phase 3 if (instance->GetData(DATA_CANSTARTPHASE3)) { // set life 50% me->SetHealth(me->CountPctFromMaxHealth(50)); me->RemoveAurasDueToSpell(SPELL_MAGIC_BARRIER); Talk(SAY_PHASE3); Phase = 3; // return to the tank me->GetMotionMaster()->MoveChase(me->GetVictim()); } CheckTimer = 1000; } else CheckTimer -= diff; } }
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); }
void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { Unit* target = GetTarget(); if (!target->HasAura(DK_SPELL_BLOOD_PRESENCE)) target->RemoveAura(DK_SPELL_IMPROVED_BLOOD_PRESENCE_TRIGGERED); }
void UpdateAI(const uint32 uiDiff) override { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; // Shimmer Timer Timer if (m_uiShimmerTimer < uiDiff) { // Remove old vulnerability spell if (m_uiCurrentVulnerabilitySpell) m_creature->RemoveAurasDueToSpell(m_uiCurrentVulnerabilitySpell); // Cast new random vurlnabilty on self uint32 aSpellId[] = {SPELL_FIRE_VULNERABILITY, SPELL_FROST_VULNERABILITY, SPELL_SHADOW_VULNERABILITY, SPELL_NATURE_VULNERABILITY, SPELL_ARCANE_VULNERABILITY}; uint32 uiSpell = aSpellId[urand(0, 4)]; if (DoCastSpellIfCan(m_creature, uiSpell) == CAST_OK) { m_uiCurrentVulnerabilitySpell = uiSpell; DoScriptText(EMOTE_SHIMMER, m_creature); m_uiShimmerTimer = 45000; } } else m_uiShimmerTimer -= uiDiff; // Breath One Timer if (m_uiBreathOneTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, m_uiBreathOneSpell) == CAST_OK) m_uiBreathOneTimer = 60000; } else m_uiBreathOneTimer -= uiDiff; // Breath Two Timer if (m_uiBreathTwoTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, m_uiBreathTwoSpell) == CAST_OK) m_uiBreathTwoTimer = 60000; } else m_uiBreathTwoTimer -= uiDiff; // Affliction Timer if (m_uiAfflictionTimer < uiDiff) { uint32 m_uiSpellAfflict = 0; switch (urand(0, 4)) { case 0: m_uiSpellAfflict = SPELL_BROODAF_BLUE; break; case 1: m_uiSpellAfflict = SPELL_BROODAF_BLACK; break; case 2: m_uiSpellAfflict = SPELL_BROODAF_RED; break; case 3: m_uiSpellAfflict = SPELL_BROODAF_BRONZE; break; case 4: m_uiSpellAfflict = SPELL_BROODAF_GREEN; break; } GuidVector vGuids; m_creature->FillGuidsListFromThreatList(vGuids); for (GuidVector::const_iterator i = vGuids.begin(); i != vGuids.end(); ++i) { Unit* pUnit = m_creature->GetMap()->GetUnit(*i); if (pUnit) { // Cast affliction DoCastSpellIfCan(pUnit, m_uiSpellAfflict, CAST_TRIGGERED); // Chromatic mutation if target is effected by all afflictions if (pUnit->HasAura(SPELL_BROODAF_BLUE, EFFECT_INDEX_0) && pUnit->HasAura(SPELL_BROODAF_BLACK, EFFECT_INDEX_0) && pUnit->HasAura(SPELL_BROODAF_RED, EFFECT_INDEX_0) && pUnit->HasAura(SPELL_BROODAF_BRONZE, EFFECT_INDEX_0) && pUnit->HasAura(SPELL_BROODAF_GREEN, EFFECT_INDEX_0)) { // target->RemoveAllAuras(); // DoCastSpellIfCan(target,SPELL_CHROMATIC_MUT_1); // Chromatic mutation is causing issues // Assuming it is caused by a lack of core support for Charm // So instead we instant kill our target // WORKAROUND if (pUnit->GetTypeId() == TYPEID_PLAYER) m_creature->CastSpell(pUnit, 5, false); } } } m_uiAfflictionTimer = 10000; } else m_uiAfflictionTimer -= uiDiff; // Frenzy Timer if (m_uiFrenzyTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_FRENZY) == CAST_OK) { DoScriptText(EMOTE_GENERIC_FRENZY_KILL, m_creature); m_uiFrenzyTimer = urand(10000, 15000); } } else m_uiFrenzyTimer -= uiDiff; // Enrage if not already enraged and below 20% if (!m_bEnraged && m_creature->GetHealthPercent() < 20.0f) { DoCastSpellIfCan(m_creature, SPELL_ENRAGE); m_bEnraged = true; } DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { if (!UpdateVictim()) return; //Shimmer_Timer Timer if (Shimmer_Timer <= diff) { //Remove old vulnerabilty spell if (CurrentVurln_Spell) me->RemoveAurasDueToSpell(CurrentVurln_Spell); //Cast new random vulnerabilty on self uint32 spell; do { spell = RAND(SPELL_FIRE_VULNERABILITY, SPELL_FROST_VULNERABILITY, SPELL_SHADOW_VULNERABILITY, SPELL_NATURE_VULNERABILITY, SPELL_ARCANE_VULNERABILITY); }while (spell == CurrentVurln_Spell); // Endlosschleife Wahrscheinlichkeit -> 0 DoCast(me, spell); CurrentVurln_Spell = spell; DoScriptText(EMOTE_SHIMMER, me); Shimmer_Timer = 45000; } else Shimmer_Timer -= diff; //Breath1_Timer if (Breath1_Timer <= diff) { DoCast(me->getVictim(), Breath1_Spell); Breath1_Timer = 60000; } else Breath1_Timer -= diff; //Breath2_Timer if (Breath2_Timer <= diff) { DoCast(me->getVictim(), Breath2_Spell); Breath2_Timer = 60000; } else Breath2_Timer -= diff; //Affliction_Timer if (Affliction_Timer <= diff) { std::list<HostileReference*> threatlist = me->getThreatManager().getThreatList(); for (std::list<HostileReference*>::const_iterator i = threatlist.begin(); i != threatlist.end(); ++i) { Unit* pUnit; if ((*i) && (*i)->getSource()) { pUnit = Unit::GetUnit((*me), (*i)->getUnitGuid()); if (pUnit) { //Cast affliction DoCast(pUnit, RAND(SPELL_BROODAF_BLUE, SPELL_BROODAF_BLACK, SPELL_BROODAF_RED, SPELL_BROODAF_BRONZE, SPELL_BROODAF_GREEN), true); //Chromatic mutation if target is effected by all afflictions if (pUnit->HasAura(SPELL_BROODAF_BLUE) && pUnit->HasAura(SPELL_BROODAF_BLACK) && pUnit->HasAura(SPELL_BROODAF_RED) && pUnit->HasAura(SPELL_BROODAF_BRONZE) && pUnit->HasAura(SPELL_BROODAF_GREEN)) { if (pUnit->GetTypeId() == TYPEID_PLAYER) { pUnit->RemoveAurasDueToSpell(SPELL_BROODAF_BLUE); pUnit->RemoveAurasDueToSpell(SPELL_BROODAF_BLACK); pUnit->RemoveAurasDueToSpell(SPELL_BROODAF_RED); pUnit->RemoveAurasDueToSpell(SPELL_BROODAF_BRONZE); pUnit->RemoveAurasDueToSpell(SPELL_BROODAF_GREEN); DoCast(pUnit, SPELL_CHROMATIC_MUT_1, true); } //Chromatic mutation is causing issues //Assuming it is caused by a lack of core support for Charm //So instead we instant kill our target //WORKAROUND //if (pUnit->GetTypeId() == TYPEID_PLAYER) // pUnit->CastSpell(pUnit, 5, false); } } } } Affliction_Timer = 10000; } else Affliction_Timer -= diff; //Frenzy_Timer if (Frenzy_Timer <= diff) { DoCast(me, SPELL_FRENZY); DoScriptText(EMOTE_FRENZY, me); Frenzy_Timer = urand(10000, 15000); } else Frenzy_Timer -= diff; //Enrage if not already enraged and below 20% if (!Enraged && HealthBelowPct(20)) { DoCast(me, SPELL_ENRAGE); Enraged = true; } DoMeleeAttackIfReady(); }