void Pet::UpdateAttackPowerAndDamage(bool ranged) { if(ranged) return; float val = 0.0f; float bonusAP = 0.0f; UnitMods unitMod = UNIT_MOD_ATTACK_POWER; if(GetEntry() == 416) // 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(getPetType() == HUNTER_PET) //hunter pets benefit from owner's attack power { bonusAP = owner->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.22f; SetBonusDamage( int32(owner->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.1287f)); } //demons benefit from warlocks shadow or fire damage else if(getPetType() == SUMMON_PET && owner->getClass() == CLASS_WARLOCK) { 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(getPetType() == SUMMON_PET && owner->getClass() == CLASS_MAGE) { 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; //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 Pet::UpdateArmor() { float value = 0.0f; float bonus_armor = 0.0f; UnitMods unitMod = UNIT_MOD_ARMOR; Unit *owner = GetOwner(); // chained, use original owner instead if (owner && owner->GetTypeId() == TYPEID_UNIT && ((Creature*)owner)->GetEntry() == GetEntry()) if (Unit *creator = GetCreator()) owner = creator; // hunter and warlock and shaman pets gain 35% of owner's armor value if (owner && (getPetType() == HUNTER_PET || (getPetType() == SUMMON_PET && (owner->getClass() == CLASS_WARLOCK || owner->getClass() == CLASS_SHAMAN)))) bonus_armor = 0.35f * float(owner->GetArmor()); value = GetModifierValue(unitMod, BASE_VALUE); value *= GetModifierValue(unitMod, BASE_PCT); value += GetStat(STAT_AGILITY); value += GetModifierValue(unitMod, TOTAL_VALUE) + bonus_armor; value *= GetModifierValue(unitMod, TOTAL_PCT); SetArmor(int32(value)); }
bool Guardian::UpdateStats(Stats stat) { // value = ((base_value * base_pct) + total_value) * total_pct float value = GetTotalStatValue(stat); ApplyStatBuffMod(stat, m_statFromOwner[stat], false); float ownersBonus = 0.0f; Unit* owner = GetOwner(); // Handle Death Knight Glyphs and Talents float mod = 0.75f; if (IsPetGhoul() && (stat == STAT_STAMINA || stat == STAT_STRENGTH)) { if (stat == STAT_STAMINA) mod = 0.3f; // Default Owner's Stamina scale else mod = 0.7f; // Default Owner's Strength scale ownersBonus = float(owner->GetStat(stat)) * mod; value += ownersBonus; } else if (stat == STAT_STAMINA) { ownersBonus = CalculatePct(owner->GetStat(STAT_STAMINA), 30); value += ownersBonus; } //warlock's and mage's pets gain 30% of owner's intellect else if (stat == STAT_INTELLECT) { if (owner->getClass() == CLASS_WARLOCK || owner->getClass() == CLASS_MAGE) { ownersBonus = CalculatePct(owner->GetStat(stat), 30); value += ownersBonus; } } /* else if (stat == STAT_STRENGTH) { if (IsPetGhoul()) value += float(owner->GetStat(stat)) * 0.3f; } */ SetStat(stat, int32(value)); m_statFromOwner[stat] = ownersBonus; ApplyStatBuffMod(stat, m_statFromOwner[stat], true); switch (stat) { case STAT_STRENGTH: UpdateAttackPowerAndDamage(); break; case STAT_AGILITY: UpdateArmor(); break; case STAT_STAMINA: UpdateMaxHealth(); break; case STAT_INTELLECT: UpdateMaxPower(POWER_MANA); break; default: break; } return true; }
bool Guardian::UpdateStats(Stats stat) { if (stat >= MAX_STATS) return false; // value = ((base_value * base_pct) + total_value) * total_pct float value = GetTotalStatValue(stat); ApplyStatBuffMod(stat, m_statFromOwner[stat], false); float ownersBonus = 0.0f; Unit *owner = GetOwner(); if (stat == STAT_STAMINA) { if (owner->getClass() == CLASS_WARLOCK && isPet() || isHunterPet()) { // TOTAL_PCT should be applied after ownersBonus UnitMods unitMod = UnitMods(UNIT_MOD_STAT_START + stat); value *= (1.0f / m_auraModifiersGroup[unitMod][TOTAL_PCT]) ; ownersBonus = CalculatePct(owner->GetStat(stat), 30); value += ownersBonus; value *= m_auraModifiersGroup[unitMod][TOTAL_PCT]; } } else if (stat == STAT_INTELLECT) { // Warlock and Mage pets gain 30% of owners intellect if (owner->getClass() == CLASS_WARLOCK || owner->getClass() == CLASS_MAGE) { // TOTAL_PCT should be applied after ownersBonus UnitMods unitMod = UnitMods(UNIT_MOD_STAT_START + stat); value *= (1.0f / m_auraModifiersGroup[unitMod][TOTAL_PCT]) ; ownersBonus = CalculatePct(owner->GetStat(stat), 30); value += ownersBonus; value *= m_auraModifiersGroup[unitMod][TOTAL_PCT]; } } SetStat(stat, int32(value)); m_statFromOwner[stat] = ownersBonus; ApplyStatBuffMod(stat, m_statFromOwner[stat], true); 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; }
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(); // chained, use original owner instead if (owner && owner->GetTypeId() == TYPEID_UNIT && ((Creature*)owner)->GetEntry() == GetEntry()) { if (Unit* creator = GetCreator()) owner = creator; } if (stat == STAT_STAMINA) { if(owner && owner->GetTypeId() == TYPEID_PLAYER && owner->getClass() == CLASS_WARLOCK) value += float(owner->GetStat(stat)) * 0.75f; else if (owner) value += float(owner->GetStat(stat)) * 0.3f; } // 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; } // deathknight's ghoul gain 100% of owner's strength else if (stat == STAT_STRENGTH && getPetType() == SUMMON_PET) { if (owner && (owner->getClass() == CLASS_DEATH_KNIGHT)) { value += float(owner->GetStat(stat)) * 1.0f; } } 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; }
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) { float scale_coeff = 0.3f; switch (owner->getClass()) { case CLASS_HUNTER: scale_coeff = 0.45f; break; case CLASS_WARLOCK: scale_coeff = 0.75f; break; } value += float(owner->GetStat(stat)) * scale_coeff; } } //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 HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo) { PreventDefaultAction(); uint32 spellId; Unit* caster = eventInfo.GetActor(); Unit* target = eventInfo.GetProcTarget(); switch (target->getClass()) { case CLASS_PALADIN: case CLASS_PRIEST: case CLASS_SHAMAN: case CLASS_DRUID: spellId = SPELL_PALADIN_HOLY_POWER_MP5; break; case CLASS_MAGE: case CLASS_WARLOCK: spellId = SPELL_PALADIN_HOLY_POWER_SPELL_POWER; break; case CLASS_HUNTER: case CLASS_ROGUE: spellId = SPELL_PALADIN_HOLY_POWER_ATTACK_POWER; break; case CLASS_WARRIOR: spellId = SPELL_PALADIN_HOLY_POWER_ARMOR; break; default: return; } caster->CastSpell(target, spellId, true); }
void JustSummoned(Creature* pSummoned) { Unit* pTarget = NULL; uint8 uiHealer = 0; for (uint8 j = 1; j <= 4; ++j) { switch (j) { case 1: uiHealer = CLASS_PRIEST; break; case 2: uiHealer = CLASS_PALADIN; break; case 3: uiHealer = CLASS_DRUID; break; case 4: uiHealer = CLASS_SHAMAN; break; } ThreatList const& lThreatList = m_creature->getThreatManager().getThreatList(); for (ThreatList::const_iterator i = lThreatList.begin(); i != lThreatList.end(); ++i) { Unit* pTemp = m_creature->GetMap()->GetUnit((*i)->getUnitGuid()); if (pTemp && pTemp->GetTypeId() == TYPEID_PLAYER && pTemp->getClass() == uiHealer) { pTarget = pTemp; break; } } if (pTarget) break; } if (!pTarget) if (pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) pSummoned->AI()->AttackStart(pTarget); }
void HandleDummy(SpellEffIndex /*effIndex*/) { Unit* pCaster = GetCaster(); if (pCaster->GetTypeId() != TYPEID_PLAYER) return; std::vector<uint32> possibleSpells; switch (pCaster->getClass()) { case CLASS_WARLOCK: case CLASS_MAGE: case CLASS_PRIEST: possibleSpells.push_back(SPELL_FLASK_OF_THE_NORTH_SP); break; case CLASS_DEATH_KNIGHT: case CLASS_WARRIOR: possibleSpells.push_back(SPELL_FLASK_OF_THE_NORTH_STR); break; case CLASS_ROGUE: case CLASS_HUNTER: possibleSpells.push_back(SPELL_FLASK_OF_THE_NORTH_AP); break; case CLASS_DRUID: case CLASS_PALADIN: possibleSpells.push_back(SPELL_FLASK_OF_THE_NORTH_SP); possibleSpells.push_back(SPELL_FLASK_OF_THE_NORTH_STR); break; case CLASS_SHAMAN: possibleSpells.push_back(SPELL_FLASK_OF_THE_NORTH_SP); possibleSpells.push_back(SPELL_FLASK_OF_THE_NORTH_AP); break; } pCaster->CastSpell(pCaster, possibleSpells[irand(0, (possibleSpells.size() - 1))], true, NULL); }
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 (owner) { switch(stat) { case STAT_STAMINA: // warlock's pets gain 75% of owner's stamina if (getPetType() == SUMMON_PET && owner->getClass() == CLASS_WARLOCK) value += owner->GetStat(stat) * 0.75f; else { if (getPetType() == SUMMON_PET || getPetType() == HUNTER_PET || owner->getClass() == CLASS_DEATH_KNIGHT) value += owner->GetStat(stat) * 0.3f; } break; case STAT_INTELLECT: // warlock's and mage's pets gain 30% of owner's intellect if (getPetType() == SUMMON_PET && (owner->getClass() == CLASS_WARLOCK || owner->getClass() == CLASS_MAGE)) value += owner->GetStat(stat) * 0.3f; break; }; } 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; }
bool Guardian::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 && (IsHunterPet() || owner->getClass() == CLASS_WARLOCK)) value += float(owner->GetStat(stat)) * 0.3f; } //warlock's and mage's pets gain 30% of owner's intellect else if (stat == STAT_INTELLECT && IsPet()) { 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 Pet::UpdateResistances(uint32 school) { if (school > SPELL_SCHOOL_NORMAL) { float value = GetTotalAuraModValue(UnitMods(UNIT_MOD_RESISTANCE_START + school)); Unit *owner = GetOwner(); // hunter and warlock pets gain 40% of owner's resistance if (owner && (getPetType() == HUNTER_PET || getPetType() == SUMMON_PET && owner->getClass() == CLASS_WARLOCK)) value += float(owner->GetResistance(SpellSchools(school))) * 0.4f; // Void Star Talisman's resistance bonus if (owner && getPetType() == SUMMON_PET && owner->getClass() == CLASS_WARLOCK) if (Aura *aura = owner->GetAura(37386, 0)) value += float(aura->GetModifierValue()); SetResistance(SpellSchools(school), int32(value)); } else UpdateArmor(); }
bool ManaTide(uint32 i, Spell* s) { Unit* unitTarget = s->GetUnitTarget(); if(unitTarget == NULL || unitTarget->IsDead() || unitTarget->getClass() == WARRIOR || unitTarget->getClass() == ROGUE) return false; uint32 gain = (uint32)(unitTarget->GetMaxPower(POWER_TYPE_MANA) * 0.06); unitTarget->Energize(unitTarget, 16191, gain, POWER_TYPE_MANA); return true; }
void Pet::UpdateDamagePhysical(WeaponAttackType attType) { if (attType > BASE_ATTACK) return; UnitMods unitMod = UNIT_MOD_DAMAGE_MAINHAND; float att_speed = float(GetAttackTime(BASE_ATTACK))/1000.0f; float base_value = GetModifierValue(unitMod, BASE_VALUE) + GetTotalAttackPowerValue(attType)/ 14.0f * att_speed; float base_pct = GetModifierValue(unitMod, BASE_PCT); float total_value = GetModifierValue(unitMod, TOTAL_VALUE); float total_pct = GetModifierValue(unitMod, TOTAL_PCT); float weapon_mindamage = GetWeaponDamageRange(BASE_ATTACK, MINDAMAGE); float weapon_maxdamage = GetWeaponDamageRange(BASE_ATTACK, MAXDAMAGE); // Pet's base damage changes depending on happiness if (getPetType() == HUNTER_PET && attType == BASE_ATTACK) { switch(GetHappinessState()) { case HAPPY: // 125% of normal damage total_pct *= 1.25f; break; case CONTENT: // 100% of normal damage, nothing to modify break; case UNHAPPY: // 75% of normal damage total_pct *= 0.75f; break; } } else if (getPetType() == SUMMON_PET) { Unit* owner = GetOwner(); if (owner && owner->getClass() == CLASS_PRIEST) total_value += 0.3f * owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + SPELL_SCHOOL_SHADOW); } float mindamage = ((base_value + weapon_mindamage) * base_pct + total_value) * total_pct; float maxdamage = ((base_value + weapon_maxdamage) * base_pct + total_value) * total_pct; SetStatFloatValue(UNIT_FIELD_MINDAMAGE, mindamage); SetStatFloatValue(UNIT_FIELD_MAXDAMAGE, maxdamage); }
void Pet::UpdateResistances(uint32 school) { if (school > SPELL_SCHOOL_NORMAL) { float value = GetTotalAuraModValue(UnitMods(UNIT_MOD_RESISTANCE_START + school)); Unit* owner = GetOwner(); // hunter and warlock pets gain 40% of owner's resistance if (owner && (getPetType() == HUNTER_PET || (getPetType() == SUMMON_PET && owner->getClass() == CLASS_WARLOCK))) { value += float(owner->GetResistance(SpellSchools(school))) * 0.4f; } SetResistance(SpellSchools(school), int32(value)); } else { UpdateArmor(); } }
void Guardian::UpdateResistances(uint32 school) { if (school > SPELL_SCHOOL_NORMAL) { float value = GetTotalAuraModValue(UnitMods(UNIT_MOD_RESISTANCE_START + school)); Unit* owner = GetOwner(); // hunter and warlock pets gain 40% of owner's resistance if (owner && (isHunterPet() || (isPet() && owner->getClass() == CLASS_WARLOCK))) value += float(owner->GetResistance(SpellSchools(school))) * 0.4f; SetResistance(SpellSchools(school), int32(value)); } else UpdateArmor(); }
void Pet::UpdateArmor() { 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()); float 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 Pet::UpdateResistances(uint32 school) { if (school > SPELL_SCHOOL_NORMAL) { float value = GetTotalAuraModValue(UnitMods(UNIT_MOD_RESISTANCE_START + school)); Unit *owner = GetOwner(); // chained, use original owner instead if (owner && owner->GetTypeId() == TYPEID_UNIT && ((Creature*)owner)->GetEntry() == GetEntry()) if (Unit *creator = GetCreator()) owner = creator; // hunter and warlock pets gain 40% of owner's resistance if (owner && (getPetType() == HUNTER_PET || (getPetType() == SUMMON_PET && owner->getClass() == CLASS_WARLOCK))) value += float(owner->GetResistance(SpellSchools(school))) * 0.4f; SetResistance(SpellSchools(school), int32(value)); } else UpdateArmor(); }
bool Guardian::UpdateStats(Stats stat) { if (stat >= MAX_STATS) return false; // value = ((base_value * base_pct) + total_value) * total_pct float value = GetTotalStatValue(stat); ApplyStatBuffMod(stat, m_statFromOwner[stat], false); float ownersBonus = 0.0f; Unit* owner = GetOwner(); // Handle Death Knight Glyphs and Talents float mod = 0.75f; if (IsPetGhoul() && (stat == STAT_STAMINA || stat == STAT_STRENGTH)) { if (stat == STAT_STAMINA) mod = 0.3f; // Default Owner's Stamina scale else mod = 0.7f; // Default Owner's Strength scale // Check just if owner has Ravenous Dead since it's effect is not an aura AuraEffect const* aurEff = owner->GetAuraEffect(SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE, SPELLFAMILY_DEATHKNIGHT, 3010, 0); if (aurEff) { SpellInfo const* spellInfo = aurEff->GetSpellInfo(); // Then get the SpellProto and add the dummy effect value AddPct(mod, spellInfo->Effects[EFFECT_1].CalcValue(owner)); // Ravenous Dead edits the original scale } // Glyph of the Ghoul aurEff = owner->GetAuraEffect(58686, 0); if (aurEff) mod += CalculatePct(1.0f, aurEff->GetAmount()); // Glyph of the Ghoul adds a flat value to the scale mod ownersBonus = float(owner->GetStat(stat)) * mod; value += ownersBonus; } else if (stat == STAT_STAMINA) { ownersBonus = CalculatePct(owner->GetStat(STAT_STAMINA), 30); value += ownersBonus; } //warlock's and mage's pets gain 30% of owner's intellect else if (stat == STAT_INTELLECT) { if (owner->getClass() == CLASS_WARLOCK || owner->getClass() == CLASS_MAGE) { ownersBonus = CalculatePct(owner->GetStat(stat), 30); value += ownersBonus; } } /* else if (stat == STAT_STRENGTH) { if (IsPetGhoul()) value += float(owner->GetStat(stat)) * 0.3f; } */ SetStat(stat, int32(value)); m_statFromOwner[stat] = ownersBonus; ApplyStatBuffMod(stat, m_statFromOwner[stat], true); 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 (TargetTimer <= diff && Enslaved == false) { EnslaveTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true); TargetTimer = 1000; } else TargetTimer -= diff; if (EnslaveEndTimer <= diff && Enslaved == true) { me->SetReactState(REACT_AGGRESSIVE); EnslaveTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true); EnslaveTarget->RemoveAurasDueToSpell(SPELL_ENSLAVE); EnslaveTarget->RemoveAurasDueToSpell(SPELL_ENSLAVE_BUFF); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); Enslaved = false; EnslaveTimer = 30000; AbsorbMagicTimer = 20000; MindFogTimer = urand(6000,12000); UnrelentingAgonyTimer = 10000; EnslaveEndTimer = 90000; } else EnslaveEndTimer -= diff; if (EnslaveTimer <= diff && Enslaved == false) { if (EnslaveTarget) { DoZoneInCombat(); me->SetReactState(REACT_PASSIVE); DoCast(EnslaveTarget, SPELL_ENSLAVE); DoCast(EnslaveTarget, SPELL_ENSLAVE_BUFF); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); DoScriptText(RAND(SAY_MIND_CONTROL_1,SAY_MIND_CONTROL_2,SAY_MIND_CONTROL_3), me); Enslaved = true; EnslaveTimer = 180000; AbsorbMagicTimer = 180000; MindFogTimer = 180000; UnrelentingAgonyTimer = 180000; EnslaveEndTimer = DUNGEON_MODE(60000,30000); CastTimer = 2000; } EnslaveTimer = 1000; } else EnslaveTimer -= diff; if (EnslaveTarget && Enslaved == true) if (EnslaveTarget->HealthBelowPct(50)) { me->SetReactState(REACT_AGGRESSIVE); EnslaveTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true); EnslaveTarget->RemoveAurasDueToSpell(SPELL_ENSLAVE); EnslaveTarget->RemoveAurasDueToSpell(SPELL_ENSLAVE_BUFF); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); Enslaved = false; EnslaveTimer = 30000; AbsorbMagicTimer = 20000; MindFogTimer = urand(6000,12000); UnrelentingAgonyTimer = 10000; } if (CastTimer <= diff && Enslaved == true) { if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, NotCharmedTargetSelector())) { switch(EnslaveTarget->getClass()) { case CLASS_DRUID: if (urand(0,1)) EnslaveTarget->CastSpell(pTarget, 8921, false); else EnslaveTarget->CastSpell(me, 774, false); break; case CLASS_HUNTER: EnslaveTarget->CastSpell(pTarget, RAND(2643, 1978), false); break; case CLASS_MAGE: EnslaveTarget->CastSpell(pTarget, RAND(44614, 30455), false); break; case CLASS_WARLOCK: EnslaveTarget->CastSpell(pTarget, RAND(980, 686), true); break; case CLASS_WARRIOR: EnslaveTarget->CastSpell(pTarget, RAND(46924, 845), false); break; case CLASS_PALADIN: if (urand(0,1)) EnslaveTarget->CastSpell(pTarget, 853, false); else EnslaveTarget->CastSpell(me, 20473, false); break; case CLASS_PRIEST: if (urand(0,1)) EnslaveTarget->CastSpell(pTarget, 34914, false); else EnslaveTarget->CastSpell(me, 139, false); break; case CLASS_SHAMAN: if (urand(0,1)) EnslaveTarget->CastSpell(pTarget, 421, false); else EnslaveTarget->CastSpell(me, 61295, false); break; case CLASS_ROGUE: EnslaveTarget->CastSpell(pTarget, RAND(16511, 1329), false); break; case CLASS_DEATH_KNIGHT: if (urand(0,1)) EnslaveTarget->CastSpell(pTarget, 45462, true); else EnslaveTarget->CastSpell(pTarget, 49184, true); break; } } CastTimer = 3000; } else CastTimer -= diff; if (AbsorbMagicTimer <= diff && Enslaved == false) { DoCast(me, SPELL_ABSORB_MAGIC); AbsorbMagicTimer = urand(15000,20000); } else AbsorbMagicTimer -= diff; if (MindFogTimer <= diff && Enslaved == false) { DoCast(me, SPELL_MIND_FOG_SUMMON); DoScriptText(SAY_MIND_FOG, me); MindFogTimer = 18000; } else MindFogTimer -= diff; if (UnrelentingAgonyTimer <= diff && Enslaved == false) { DoCastAOE(SPELL_UNRELENTING_AGONY); UnrelentingAgonyTimer = 20000; } else UnrelentingAgonyTimer -= diff; DoMeleeAttackIfReady(); }
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) { float scale_coeff = 0.3f; switch (owner->getClass()) { case CLASS_HUNTER: scale_coeff = 0.4493f; break; case CLASS_WARLOCK: { CreatureInfo const *cinfo = GetCreatureInfo(); CreatureFamily petFamily = (CreatureFamily) cinfo->family; switch (petFamily) { case CREATURE_FAMILY_FELHUNTER: value += float(owner->GetStat(stat)) * 0.7125f; break; case CREATURE_FAMILY_VOIDWALKER: value += float(owner->GetStat(stat)) * 0.825f; break; case CREATURE_FAMILY_FELGUARD: value += float(owner->GetStat(stat)) * 0.825f; break; case CREATURE_FAMILY_SUCCUBUS: value += float(owner->GetStat(stat)) * 0.6825f; break; case CREATURE_FAMILY_IMP: value += float(owner->GetStat(stat)) * 0.63f; break; default: value += float(owner->GetStat(stat)) * 0.3f; break; } break; } case CLASS_DEATH_KNIGHT: scale_coeff = 0.3928f; break; } value += float(owner->GetStat(stat)) * scale_coeff; } } //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; }
bool Guardian::UpdateStats(Stats stat) { if (stat >= MAX_STATS) return false; // value = ((base_value * base_pct) + total_value) * total_pct float value = GetTotalStatValue(stat); ApplyStatBuffMod(stat, m_statFromOwner[stat], false); float ownersBonus = 0.0f; Unit *owner = GetOwner(); // Handle Death Knight Glyphs and Talents float mod = 0.75f; if (IsPetGhoul() && (stat == STAT_STAMINA || stat == STAT_STRENGTH)) { switch (stat) { case STAT_STAMINA: mod = 0.3f; break; // Default Owner's Stamina scale case STAT_STRENGTH: mod = 0.7f; break; // Default Owner's Strength scale default: break; } // Ravenous Dead AuraEffect const *aurEff = NULL; // Check just if owner has Ravenous Dead since it's effect is not an aura aurEff = owner->GetAuraEffect(SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE, SPELLFAMILY_DEATHKNIGHT, 3010, 0); if (aurEff) { SpellEntry const* sProto = aurEff->GetSpellProto(); // Then get the SpellProto and add the dummy effect value mod += mod * (SpellMgr::CalculateSpellEffectAmount(sProto, 1) / 100.0f); // Ravenous Dead edits the original scale } // Glyph of the Ghoul aurEff = owner->GetAuraEffect(58686, 0); if (aurEff) mod += (aurEff->GetAmount() / 100.0f); // Glyph of the Ghoul adds a flat value to the scale mod ownersBonus = float(owner->GetStat(stat)) * mod; value += ownersBonus; } else if (stat == STAT_STAMINA) { if (owner->getClass() == CLASS_WARLOCK && isPet()) { ownersBonus = float(owner->GetStat(STAT_STAMINA)) * 0.75f; value += ownersBonus; } else { mod = 0.45f; if (isPet()) { switch(ToPet()->GetTalentType()) { case PET_TALENT_TYPE_NOT_HUNTER_PET: break; case PET_TALENT_TYPE_FEROCITY: mod = 0.67f; break; case PET_TALENT_TYPE_TENACITY: mod = 0.78f; break; case PET_TALENT_TYPE_CUNNING: mod = 0.725f; break; } 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 { SpellEntry const* sProto = sSpellStore.LookupEntry(itr->first); // Then get the SpellProto and add the dummy effect value mod += mod * (SpellMgr::CalculateSpellEffectAmount(sProto, 0) / 100.0f); } } ownersBonus = float(owner->GetStat(stat)) * mod; value += ownersBonus; } } //warlock's and mage's pets gain 30% of owner's intellect else if (stat == STAT_INTELLECT) { if (owner->getClass() == CLASS_WARLOCK || owner->getClass() == CLASS_MAGE) { ownersBonus = float(owner->GetStat(stat)) * 0.3f; value += ownersBonus; } } /* else if (stat == STAT_STRENGTH) { if (IsPetGhoul()) value += float(owner->GetStat(stat)) * 0.3f; } */ SetStat(stat, int32(value)); m_statFromOwner[stat] = ownersBonus; ApplyStatBuffMod(stat, m_statFromOwner[stat], true); 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; }
bool Guardian::UpdateStats(Stats stat) { if (stat >= MAX_STATS) return false; // value = ((base_value * base_pct) + total_value) * total_pct float value = GetTotalStatValue(stat); Unit *owner = GetOwner(); // Handle Death Knight Glyphs and Talents if (IsPetGhoul() && (stat == STAT_STAMINA || stat == STAT_STRENGTH)) { float mod = 0.0f; switch (stat) { case STAT_STAMINA: mod = 0.3f; break; // Default Owner's Stamina scale case STAT_STRENGTH: mod = 0.7f; break; // Default Owner's Strength scale default: break; } // Ravenous Dead AuraEffect const *aurEff; // Check just if owner has Ravenous Dead since it's effect is not an aura if (aurEff = owner->GetAuraEffect(SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE, SPELLFAMILY_DEATHKNIGHT, 3010, 0)) { SpellEntry const* sProto = aurEff->GetSpellProto(); // Then get the SpellProto and add the dummy effect value mod += mod * (sProto->EffectBasePoints[1] / 100.0f); // Ravenous Dead edits the original scale } // Glyph of the Ghoul if (aurEff = owner->GetAuraEffect(58686, 0)) mod += (aurEff->GetAmount() / 100.0f); // Glyph of the Ghoul adds a flat value to the scale mod value += float(owner->GetStat(stat)) * mod; } else if (stat == STAT_STAMINA) { if (owner->getClass() == CLASS_WARLOCK && isPet()) value += float(owner->GetStat(STAT_STAMINA)) * 0.75f; else value += float(owner->GetStat(stat)) * 0.3f; } //warlock's and mage's pets gain 30% of owner's intellect else if (stat == STAT_INTELLECT) { if (owner->getClass() == CLASS_WARLOCK || owner->getClass() == CLASS_MAGE) value += float(owner->GetStat(stat)) * 0.3f; } /* else if (stat == STAT_STRENGTH) { if (IsPetGhoul()) 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 WorldSession::HandleMirrorImageDataRequest(WorldPackets::Spells::GetMirrorImageData& getMirrorImageData) { ObjectGuid guid = getMirrorImageData.UnitGUID; // Get unit for which data is needed by client Unit* unit = ObjectAccessor::GetUnit(*_player, guid); if (!unit) return; if (!unit->HasAuraType(SPELL_AURA_CLONE_CASTER)) return; // Get creator of the unit (SPELL_AURA_CLONE_CASTER does not stack) Unit* creator = unit->GetAuraEffectsByType(SPELL_AURA_CLONE_CASTER).front()->GetCaster(); if (!creator) return; if (Player* player = creator->ToPlayer()) { WorldPackets::Spells::MirrorImageComponentedData mirrorImageComponentedData; mirrorImageComponentedData.UnitGUID = guid; mirrorImageComponentedData.DisplayID = creator->GetDisplayId(); mirrorImageComponentedData.RaceID = creator->getRace(); mirrorImageComponentedData.Gender = creator->getGender(); mirrorImageComponentedData.ClassID = creator->getClass(); Guild* guild = player->GetGuild(); mirrorImageComponentedData.SkinColor = player->GetByteValue(PLAYER_BYTES, PLAYER_BYTES_OFFSET_SKIN_ID); mirrorImageComponentedData.FaceVariation = player->GetByteValue(PLAYER_BYTES, PLAYER_BYTES_OFFSET_FACE_ID); mirrorImageComponentedData.HairVariation = player->GetByteValue(PLAYER_BYTES, PLAYER_BYTES_OFFSET_HAIR_STYLE_ID); mirrorImageComponentedData.HairColor = player->GetByteValue(PLAYER_BYTES, PLAYER_BYTES_OFFSET_HAIR_COLOR_ID); mirrorImageComponentedData.BeardVariation = player->GetByteValue(PLAYER_BYTES_2, PLAYER_BYTES_2_OFFSET_FACIAL_STYLE); mirrorImageComponentedData.GuildGUID = (guild ? guild->GetGUID() : ObjectGuid::Empty); mirrorImageComponentedData.ItemDisplayID.reserve(11); static EquipmentSlots const itemSlots[] = { EQUIPMENT_SLOT_HEAD, EQUIPMENT_SLOT_SHOULDERS, EQUIPMENT_SLOT_BODY, EQUIPMENT_SLOT_CHEST, EQUIPMENT_SLOT_WAIST, EQUIPMENT_SLOT_LEGS, EQUIPMENT_SLOT_FEET, EQUIPMENT_SLOT_WRISTS, EQUIPMENT_SLOT_HANDS, EQUIPMENT_SLOT_TABARD, EQUIPMENT_SLOT_BACK, EQUIPMENT_SLOT_END }; // Display items in visible slots for (auto const& slot : itemSlots) { uint32 itemDisplayId; if ((slot == EQUIPMENT_SLOT_HEAD && player->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_HIDE_HELM)) || (slot == EQUIPMENT_SLOT_BACK && player->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_HIDE_CLOAK))) itemDisplayId = 0; else if (Item const* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot)) itemDisplayId = item->GetDisplayId(); else itemDisplayId = 0; mirrorImageComponentedData.ItemDisplayID.push_back(itemDisplayId); } SendPacket(mirrorImageComponentedData.Write()); } else { WorldPackets::Spells::MirrorImageCreatureData mirrorImageCreatureData; mirrorImageCreatureData.UnitGUID = guid; mirrorImageCreatureData.DisplayID = creator->GetDisplayId(); SendPacket(mirrorImageCreatureData.Write()); } }
void UpdateAI(const uint32 diff) { if (!UpdateVictim()) return; if (ResetTimer <= diff) { if (me->IsWithinDist3d(119.223f, 1035.45f, 29.4481f, 10)) { EnterEvadeMode(); return; } ResetTimer = 5000; } else ResetTimer -= diff; if (CheckAddState_Timer <= diff) { for (uint8 i = 0; i < 4; ++i) if (Creature *pTemp = Unit::GetCreature(*me, AddGUID[i])) if (pTemp->isAlive() && !pTemp->getVictim()) pTemp->AI()->AttackStart(me->getVictim()); CheckAddState_Timer = 5000; } else CheckAddState_Timer -= diff; if (DrainPower_Timer <= diff) { DoCast(me, SPELL_DRAIN_POWER, true); Map *map = me->GetMap(); if (!map->IsDungeon()) return; Map::PlayerList const &PlayerList = map->GetPlayers(); for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) { if (Player* i_pl = i->getSource()) if (i_pl->isAlive())me->AddAura(44132, me); //+1% Damage for each active player on boss (+ActivePlayer_Stack) } //me->AddAura(44132, me); me->MonsterYell(YELL_DRAIN_POWER, LANG_UNIVERSAL, NULL); DoPlaySoundToSet(me, SOUND_YELL_DRAIN_POWER); DrainPower_Timer = urand(40000,55000); // must cast in 60 sec, or buff/debuff will disappear } else DrainPower_Timer -= diff; if (SpiritBolts_Timer <= diff) { if (DrainPower_Timer < 12000) // channel 10 sec SpiritBolts_Timer = 13000; // cast drain power first else { DoCast(me, SPELL_SPIRIT_BOLTS, true); me->MonsterYell(YELL_SPIRIT_BOLTS, LANG_UNIVERSAL, NULL); DoPlaySoundToSet(me, SOUND_YELL_SPIRIT_BOLTS); SpiritBolts_Timer = 40000; SiphonSoul_Timer = 10000; // ready to drain PlayerAbility_Timer = 99999; } } else SpiritBolts_Timer -= diff; if (SiphonSoul_Timer <= diff) { Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 70, true); Unit *trigger = DoSpawnCreature(MOB_TEMP_TRIGGER, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN, 30000); if (!pTarget || !trigger) { EnterEvadeMode(); return; } else { trigger->SetDisplayId(11686); trigger->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); trigger->CastSpell(pTarget, SPELL_SIPHON_SOUL, true); trigger->GetMotionMaster()->MoveChase(me); //DoCast(pTarget, SPELL_SIPHON_SOUL, true); //me->SetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT, pTarget->GetGUID()); //me->SetUInt32Value(UNIT_CHANNEL_SPELL, SPELL_SIPHON_SOUL); PlayerGUID = pTarget->GetGUID(); PlayerAbility_Timer = urand(8000,10000); PlayerClass = pTarget->getClass() - 1; if (PlayerClass == 10) PlayerClass = 9; // druid else if (PlayerClass == 4 && pTarget->HasSpell(15473)) PlayerClass = 5; // shadow priest SiphonSoul_Timer = 99999; // buff lasts 30 sec } } else SiphonSoul_Timer -= diff; if (PlayerAbility_Timer <= diff) { //Unit *pTarget = Unit::GetUnit(*me, PlayerGUID); //if (pTarget && pTarget->isAlive()) //{ UseAbility(); PlayerAbility_Timer = urand(8000,10000); //} } else PlayerAbility_Timer -= diff; DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { if (!UpdateVictim()) { return; } if (CrystalSpikes) if (CRYSTAL_SPIKES_Timer < diff) { SpikeXY[0][0] = BaseX+(SPIKE_DISTANCE*CrystalSpikes_Count*cos(BaseO)); SpikeXY[0][1] = BaseY+(SPIKE_DISTANCE*CrystalSpikes_Count*sin(BaseO)); SpikeXY[1][0] = BaseX-(SPIKE_DISTANCE*CrystalSpikes_Count*cos(BaseO)); SpikeXY[1][1] = BaseY-(SPIKE_DISTANCE*CrystalSpikes_Count*sin(BaseO)); SpikeXY[2][0] = BaseX+(SPIKE_DISTANCE*CrystalSpikes_Count*cos(BaseO-(M_PI/2))); SpikeXY[2][1] = BaseY+(SPIKE_DISTANCE*CrystalSpikes_Count*sin(BaseO-(M_PI/2))); SpikeXY[3][0] = BaseX-(SPIKE_DISTANCE*CrystalSpikes_Count*cos(BaseO-(M_PI/2))); SpikeXY[3][1] = BaseY-(SPIKE_DISTANCE*CrystalSpikes_Count*sin(BaseO-(M_PI/2))); for (uint8 i = 0; i < 4; i++) Creature* Spike = m_creature->SummonCreature(MOB_CRYSTAL_SPIKE, SpikeXY[i][0], SpikeXY[i][1], BaseZ, 0, TEMPSUMMON_TIMED_DESPAWN, 7000); if (++CrystalSpikes_Count >= 13) CrystalSpikes = false; CRYSTAL_SPIKES_Timer = 200; }else CRYSTAL_SPIKES_Timer -= diff; if (!Frenzy && (m_creature->GetHealth() < m_creature->GetMaxHealth() * 0.25)) { DoCast(m_creature, SPELL_FRENZY); Frenzy = true; } if (SPELL_TRAMPLE_Timer < diff) { DoCast(m_creature, HeroicMode ? SPELL_TRAMPLE_H : SPELL_TRAMPLE_N); SPELL_TRAMPLE_Timer = 10000; }else SPELL_TRAMPLE_Timer -= diff; if (SPELL_SPELL_REFLECTION_Timer < diff) { DoScriptText(SAY_REFLECT, m_creature); DoCast(m_creature, SPELL_SPELL_REFLECTION); SPELL_SPELL_REFLECTION_Timer = 30000; }else SPELL_SPELL_REFLECTION_Timer -= diff; if (SPELL_CRYSTAL_SPIKES_Timer < diff) { DoScriptText(SAY_CRYSTAL_SPIKES, m_creature); CrystalSpikes = true; CrystalSpikes_Count = 1; CRYSTAL_SPIKES_Timer = 0; BaseX = m_creature->GetPositionX(); BaseY = m_creature->GetPositionY(); BaseZ = m_creature->GetPositionZ(); BaseO = m_creature->GetOrientation(); SPELL_CRYSTAL_SPIKES_Timer = 20000; }else SPELL_CRYSTAL_SPIKES_Timer -=diff; if (HeroicMode && (SPELL_SUMMON_CRYSTALLINE_TANGLER_Timer < diff)) { Creature* Crystalline_Tangler = m_creature->SummonCreature(MOB_CRYSTALLINE_TANGLER, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), m_creature->GetOrientation(), TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 1000); if (Crystalline_Tangler) { Unit* target = NULL; uint8 Healer = 0; for (uint8 j = 1; j<=4; j++) { switch (j) { case 1: Healer = CLASS_PRIEST; break; case 2: Healer = CLASS_PALADIN; break; case 3: Healer = CLASS_DRUID; break; case 4: Healer = CLASS_SHAMAN; break; } std::list<HostilReference*>::iterator i = m_creature->getThreatManager().getThreatList().begin(); for (; i != m_creature->getThreatManager().getThreatList().end(); ++i) { Unit* pTemp = Unit::GetUnit((*m_creature),(*i)->getUnitGuid()); if (pTemp && pTemp->GetTypeId() == TYPEID_PLAYER && pTemp->getClass() == Healer) { target = pTemp; break; } } if (target) break; } if (!target) target = SelectUnit(SELECT_TARGET_RANDOM, 0); if (target) { Crystalline_Tangler->AI()->AttackStart(target); Crystalline_Tangler->getThreatManager().addThreat(target, 1000000000.0f); } } SPELL_SUMMON_CRYSTALLINE_TANGLER_Timer = 17000; }else SPELL_SUMMON_CRYSTALLINE_TANGLER_Timer -=diff; DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { if (!UpdateVictim()) { return; } if (bCrystalSpikes) { if (uiCrystalSpikesTimer2 <= diff) { fSpikeXY[0][0] = fBaseX+(SPIKE_DISTANCE*uiCrystalSpikesCount*cos(fBaseO)); fSpikeXY[0][1] = fBaseY+(SPIKE_DISTANCE*uiCrystalSpikesCount*sin(fBaseO)); fSpikeXY[1][0] = fBaseX-(SPIKE_DISTANCE*uiCrystalSpikesCount*cos(fBaseO)); fSpikeXY[1][1] = fBaseY-(SPIKE_DISTANCE*uiCrystalSpikesCount*sin(fBaseO)); fSpikeXY[2][0] = fBaseX+(SPIKE_DISTANCE*uiCrystalSpikesCount*cos(fBaseO-(M_PI/2))); fSpikeXY[2][1] = fBaseY+(SPIKE_DISTANCE*uiCrystalSpikesCount*sin(fBaseO-(M_PI/2))); fSpikeXY[3][0] = fBaseX-(SPIKE_DISTANCE*uiCrystalSpikesCount*cos(fBaseO-(M_PI/2))); fSpikeXY[3][1] = fBaseY-(SPIKE_DISTANCE*uiCrystalSpikesCount*sin(fBaseO-(M_PI/2))); for (uint8 i = 0; i < 4; ++i) me->SummonCreature(MOB_CRYSTAL_SPIKE, fSpikeXY[i][0], fSpikeXY[i][1], fBaseZ, 0, TEMPSUMMON_TIMED_DESPAWN, 7*IN_MILLISECONDS); if (++uiCrystalSpikesCount >= 13) bCrystalSpikes = false; uiCrystalSpikesTimer2 = 200; } else uiCrystalSpikesTimer2 -= diff; } if (!bFrenzy && HealthBelowPct(25)) { DoCast(me, SPELL_FRENZY); bFrenzy = true; } if (uiTrampleTimer <= diff) { DoCast(me, SPELL_TRAMPLE); uiTrampleTimer = 10*IN_MILLISECONDS; } else uiTrampleTimer -= diff; if (uiSpellReflectionTimer <= diff) { DoScriptText(SAY_REFLECT, me); DoCast(me, SPELL_SPELL_REFLECTION); uiSpellReflectionTimer = 30*IN_MILLISECONDS; } else uiSpellReflectionTimer -= diff; if (uiCrystalSpikesTimer <= diff) { DoScriptText(SAY_CRYSTAL_SPIKES, me); bCrystalSpikes = true; uiCrystalSpikesCount = 1; uiCrystalSpikesTimer2 = 0; fBaseX = me->GetPositionX(); fBaseY = me->GetPositionY(); fBaseZ = me->GetPositionZ(); fBaseO = me->GetOrientation(); uiCrystalSpikesTimer = 20*IN_MILLISECONDS; } else uiCrystalSpikesTimer -= diff; if (IsHeroic() && (uiSummonCrystallineTanglerTimer <= diff)) { Creature* Crystalline_Tangler = me->SummonCreature(MOB_CRYSTALLINE_TANGLER, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation(), TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 1000); if (Crystalline_Tangler) { Unit *pTarget = NULL; uint8 Healer = 0; for (uint8 j = 1; j <= 4; j++) { switch (j) { case 1: Healer = CLASS_PRIEST; break; case 2: Healer = CLASS_PALADIN; break; case 3: Healer = CLASS_DRUID; break; case 4: Healer = CLASS_SHAMAN; break; } std::list<HostileReference*>::const_iterator i = me->getThreatManager().getThreatList().begin(); for (; i != me->getThreatManager().getThreatList().end(); ++i) { Unit* pTemp = Unit::GetUnit((*me), (*i)->getUnitGuid()); if (pTemp && pTemp->GetTypeId() == TYPEID_PLAYER && pTemp->getClass() == Healer) { pTarget = pTemp; break; } } if (pTarget) break; } if (!pTarget) pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0); if (pTarget) { Crystalline_Tangler->AI()->AttackStart(pTarget); Crystalline_Tangler->getThreatManager().addThreat(pTarget, 1000000000.0f); } } uiSummonCrystallineTanglerTimer = 17*IN_MILLISECONDS; } else uiSummonCrystallineTanglerTimer -= diff; DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { if (!UpdateVictim()) return; if (ResetTimer <= diff) { if (me->IsWithinDist3d(119.223f, 1035.45f, 29.4481f, 10)) { EnterEvadeMode(); return; } ResetTimer = 5000; } else ResetTimer -= diff; if (CheckAddState_Timer <= diff) { for (uint8 i = 0; i < 4; ++i) if (Creature* temp = Unit::GetCreature(*me, AddGUID[i])) if (temp->isAlive() && !temp->getVictim()) temp->AI()->AttackStart(me->getVictim()); CheckAddState_Timer = 5000; } else CheckAddState_Timer -= diff; if (DrainPower_Timer <= diff) { DoCast(me, SPELL_DRAIN_POWER, true); me->MonsterYell(YELL_DRAIN_POWER, LANG_UNIVERSAL, 0); DoPlaySoundToSet(me, SOUND_YELL_DRAIN_POWER); DrainPower_Timer = urand(40000, 55000); // must cast in 60 sec, or buff/debuff will disappear } else DrainPower_Timer -= diff; if (SpiritBolts_Timer <= diff) { if (DrainPower_Timer < 12000) // channel 10 sec SpiritBolts_Timer = 13000; // cast drain power first else { DoCast(me, SPELL_SPIRIT_BOLTS, false); me->MonsterYell(YELL_SPIRIT_BOLTS, LANG_UNIVERSAL, 0); DoPlaySoundToSet(me, SOUND_YELL_SPIRIT_BOLTS); SpiritBolts_Timer = 40000; SiphonSoul_Timer = 10000; // ready to drain PlayerAbility_Timer = 99999; } } else SpiritBolts_Timer -= diff; if (SiphonSoul_Timer <= diff) { Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 70, true); Unit* trigger = DoSpawnCreature(MOB_TEMP_TRIGGER, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN, 30000); if (!target || !trigger) { EnterEvadeMode(); return; } else { trigger->SetDisplayId(11686); trigger->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); trigger->CastSpell(target, SPELL_SIPHON_SOUL, true); trigger->GetMotionMaster()->MoveChase(me); //DoCast(target, SPELL_SIPHON_SOUL, true); //me->SetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT, target->GetGUID()); //me->SetUInt32Value(UNIT_CHANNEL_SPELL, SPELL_SIPHON_SOUL); PlayerGUID = target->GetGUID(); PlayerAbility_Timer = urand(8000, 10000); PlayerClass = target->getClass() - 1; if (PlayerClass == CLASS_DRUID-1) PlayerClass = CLASS_DRUID; else if (PlayerClass == CLASS_PRIEST-1 && target->HasSpell(15473)) PlayerClass = CLASS_PRIEST; // shadow priest SiphonSoul_Timer = 99999; // buff lasts 30 sec } } else SiphonSoul_Timer -= diff; if (PlayerAbility_Timer <= diff) { //Unit* target = Unit::GetUnit(*me, PlayerGUID); //if (target && target->isAlive()) //{ UseAbility(); PlayerAbility_Timer = urand(8000, 10000); //} } else PlayerAbility_Timer -= diff; DoMeleeAttackIfReady(); }
// is Resource heavy, do not spam or use heavily in loop Unit *PlayerbotClassAI::FindMainTankInRaid(Player *gPlayer) { // check if original main tank is still alive. No point regetting main // tank b/c chances are slim that it will not get reset in the middle of a fight. // But if main tank dies, try to find next best canidate if (mainTank!=NULL && mainTank->isAlive()) { return mainTank; } if (!gPlayer) return NULL; Group *pGroup = gPlayer->GetGroup(); if (!pGroup) return NULL; uint64 pLeaderGuid = pGroup->GetLeaderGUID(); Unit *pPlayer = NULL; // Check if set in raid if (pGroup->isRaidGroup()) { QueryResult result = CharacterDatabase.PQuery("SELECT memberGuid FROM group_member WHERE memberFlags='%u' AND guid = '%u'",MEMBER_FLAG_MAINTANK, pGroup->GetGUID()); if(result) { uint64 pGuid = MAKE_NEW_GUID(result->Fetch()->GetInt32(),0,HIGHGUID_PLAYER); pPlayer = sObjectMgr->GetPlayer(pGuid); if (pPlayer && pGroup->IsMember(pGuid) && pPlayer->isAlive()){ mainTank = pPlayer; return pPlayer; } } } // if could not find tank try assuming // Assume the one with highest health is the main tank uint32 maxhpfound=0; std::list<Unit*> unitList; gPlayer->GetRaidMember(unitList,30); if (!unitList.empty()){ for (std::list<Unit*>::iterator itr = unitList.begin() ; itr!=unitList.end();++itr) { //Player *tPlayer = GetPlayerBot()->GetObjPlayer((*itr)->GetGUID()); Unit *tPlayer = sObjectMgr->GetPlayer((*itr)->GetGUID()); if (tPlayer == NULL) continue; if (tPlayer->isDead()) continue; if (GetPlayerBot()->GetAreaId() != tPlayer->GetAreaId()) continue; //if(tPlayer->GetGUID() == GetPlayerBot()->GetGUID()) continue; if (GetPlayerBot()->GetDistance(tPlayer) > 50) continue; if (tPlayer->GetMaxHealth() > maxhpfound) { maxhpfound = tPlayer->GetMaxHealth(); pPlayer=tPlayer; } // Also check pets if ( (tPlayer->getClass() == (uint8) CLASS_HUNTER || tPlayer->getClass() == (uint8) CLASS_WARLOCK) && IS_PET_GUID(tPlayer->GetPetGUID()) ) { Pet* tpet = ObjectAccessor::GetPet(*tPlayer, tPlayer->GetPetGUID()); if (!tpet || !tpet->IsInWorld() || !tpet->isDead()) continue; if (tpet->GetArmor() > tPlayer->GetArmor()) //Probably a tanking capable pet.. { if (tpet->GetMaxHealth() > maxhpfound) { maxhpfound = tpet->GetMaxHealth(); pPlayer=tpet; } else if (tPlayer->GetGUID() == pPlayer->GetGUID()) {pPlayer = tpet;} //set pet as tank instead of owner } } } } mainTank = pPlayer; return pPlayer; }
void TempSummon::InitStats(uint32 duration) { ASSERT(!isPet()); m_timer = duration; m_lifetime = duration; if (m_type == TEMPSUMMON_MANUAL_DESPAWN) m_type = (duration == 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN; Unit* owner = GetSummoner(); if (owner && isTrigger() && m_spells[0]) { setFaction(owner->getFaction()); SetLevel(owner->getLevel()); if (owner->GetTypeId() == TYPEID_PLAYER) m_ControlledByPlayer = true; } if (!m_Properties) return; // Fix Force of Nature treants stats if (owner && owner->getClass() == CLASS_DRUID && owner->HasSpell(106737)) { float damage = 0.0f; switch (GetEntry()) { case ENTRY_TREANT_RESTO: case ENTRY_TREANT_BALANCE: SetMaxHealth(owner->CountPctFromMaxHealth(40)); break; case ENTRY_TREANT_GUARDIAN: SetMaxHealth(owner->CountPctFromMaxHealth(40)); // (Attack power / 14 * 2 * 0.75) * 0.2f damage = ((owner->GetTotalAttackPowerValue(BASE_ATTACK) / 14.0f) * 2.0f * 0.75f) * 0.2f; SetStatFloatValue(UNIT_FIELD_MINDAMAGE, damage); SetStatFloatValue(UNIT_FIELD_MAXDAMAGE, damage); case ENTRY_TREANT_FERAL: SetMaxHealth(owner->CountPctFromMaxHealth(40)); // Attack power / 14 * 2 * 0.75 damage = (owner->GetTotalAttackPowerValue(BASE_ATTACK) / 14.0f) * 2.0f * 0.75f; SetStatFloatValue(UNIT_FIELD_MINDAMAGE, damage); SetStatFloatValue(UNIT_FIELD_MAXDAMAGE, damage); default: break; } } if (owner) { if (uint32 slot = m_Properties->Slot) { if (owner->m_SummonSlot[slot] && owner->m_SummonSlot[slot] != GetGUID()) { Creature* oldSummon = GetMap()->GetCreature(owner->m_SummonSlot[slot]); if (oldSummon && oldSummon->IsSummon()) oldSummon->ToTempSummon()->UnSummon(); } owner->m_SummonSlot[slot] = GetGUID(); } } if (m_Properties->Faction) setFaction(m_Properties->Faction); else if (IsVehicle() && owner) // properties should be vehicle setFaction(owner->getFaction()); }