int hero::GetNthSpell(int type, int n) { int nSeen = 0; for(int i = 0; i < NUM_SPELLS; i++) { if(HasSpell(i)) { if(type == ATTR_COMBAT_SPELL || !type && gsSpellInfo[i].attributes & ATTR_COMBAT_SPELL || type == SPELL_CATEGORY_ADVENTURE && !(gsSpellInfo[i].attributes & ATTR_COMBAT_SPELL)) { ++nSeen; } if (n == nSeen) return i; } } return SPELL_NONE; }
void Player::SendCastResult(uint32 SpellId, uint8 ErrorMessage, uint8 MultiCast, uint32 Extra) { WorldPacket data(SMSG_CAST_FAILED, 80); if(!HasSpell(SpellId)) data.SetOpcode(SMSG_PET_CAST_FAILED); data << uint8(MultiCast); data << uint32(SpellId); data << uint8(ErrorMessage); if(Extra) data << uint32(Extra); m_session->SendPacket(&data); }
//See MainSpec enum in PlayerbotAI.h for details on class return values uint32 Player::GetSpec() { uint32 row = 0, spec = 0; Player* player = m_session->GetPlayer(); uint32 classMask = player->getClassMask(); for (unsigned int i = 0; i < sTalentStore.GetNumRows(); ++i) { TalentEntry const* talentInfo = sTalentStore.LookupEntry(i); if (!talentInfo) continue; TalentTabEntry const* talentTabInfo = sTalentTabStore.LookupEntry(talentInfo->TalentTab); if (!talentTabInfo) continue; if ((classMask & talentTabInfo->ClassMask) == 0) continue; uint32 curtalent_maxrank = 0; for (int32 k = MAX_TALENT_RANK - 1; k > -1; --k) { if (talentInfo->RankID[k] && HasSpell(talentInfo->RankID[k])) { if (row == 0 && spec == 0) spec = talentInfo->TalentTab; if (talentInfo->Row > row) { row = talentInfo->Row; spec = talentInfo->TalentTab; } } } } //Return the tree with the deepest talent return spec; }
int hero::GetNumSpells(int type) { int numCombat = 0; int numAdventure = 0; for(int i = 0; i < NUM_SPELLS; i++) { if(HasSpell(i)) { if(gsSpellInfo[i].attributes & ATTR_COMBAT_SPELL) numCombat++; else numAdventure++; } } switch(type) { case SPELL_CATEGORY_COMBAT: return numCombat; case SPELL_CATEGORY_ADVENTURE: return numAdventure; case SPELL_CATEGORY_ALL: return numCombat+numAdventure; default: return 0; } }
void CPlayer::FillGreenSpellList() { uint32 trainerid = 0; switch (getClass()) { case CLASS_WARRIOR: trainerid = 26332; break; case CLASS_PALADIN: trainerid = 26327; break; case CLASS_HUNTER: trainerid = 26325; break; case CLASS_ROGUE: trainerid = 26329; break; case CLASS_PRIEST: trainerid = 26328; break; case CLASS_SHAMAN: trainerid = 26330; break; case CLASS_MAGE: trainerid = 26326; break; case CLASS_WARLOCK: trainerid = 26331; break; case CLASS_DRUID: trainerid = 26324; break; default: break; } if (!trainerid) return; Custom::SpellContainer* allSpellContainer = sCustom.GetCachedSpellContainer(getClass()); if (!allSpellContainer) { allSpellContainer = new Custom::SpellContainer; Custom::SpellContainer classSpellContainer = sCustom.GetSpellContainerByCreatureEntry(trainerid); for (auto& itr : classSpellContainer) allSpellContainer->push_back(itr); sCustom.CacheSpellContainer(getClass(), allSpellContainer); } if (allSpellContainer->empty()) return; m_DelayedSpellLearn.clear(); for (auto itr = allSpellContainer->cbegin(); itr != allSpellContainer->cend(); ++itr) { TrainerSpell const* tSpell = &*itr; TrainerSpellState state = GetTrainerSpellState(tSpell, tSpell->reqLevel); if (state == TRAINER_SPELL_GREEN) { if (IsInWorld()) { bool CastLearned = false; if (SpellEntry const* spellInfo = sSpellStore.LookupEntry(tSpell->spell)) { for (auto i = 0; i < MAX_EFFECT_INDEX; ++i) { if (spellInfo->Effect[i] == SPELL_EFFECT_LEARN_SPELL) { CastLearned = true; if (!HasSpell(spellInfo->EffectTriggerSpell[i])) m_DelayedSpellLearn.push_back(spellInfo->EffectTriggerSpell[i]); } } } if (!CastLearned) m_DelayedSpellLearn.push_back(tSpell->spell); } } } }
bool Pet::UpdateStats(Stats stat) { if (stat > STAT_SPIRIT) return false; // value = ((base_value * base_pct) + total_value) * total_pct float value = GetTotalStatValue(stat); CreatureInfo const *cinfo = GetCreatureInfo(); 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 (owner && owner->GetTypeId() == TYPEID_PLAYER) { float scale_coeff = 0.0f; switch(stat) { case STAT_STRENGTH: { if (owner->getClass() == CLASS_DEATH_KNIGHT) { if (getPetType() == SUMMON_PET) { scale_coeff = 0.7f; // Ravenous Dead if (SpellEntry const* spell = ((Player*)owner)->GetKnownTalentRankById(1934)) scale_coeff *= 1.0f + spell->CalculateSimpleValue(EFFECT_INDEX_1) / 100.0f; // Glyph of Ghoul if (Aura *glyph = owner->GetDummyAura(58686)) scale_coeff += glyph->GetModifier()->m_amount / 100.0f; } } break; } case STAT_STAMINA: { scale_coeff = 0.3f; switch (owner->getClass()) { case CLASS_HUNTER: { scale_coeff = 0.45f; //Wild Hunt uint32 bonus_id = 0; if (HasSpell(62762)) bonus_id = 62762; else if (HasSpell(62758)) bonus_id = 62758; if (const SpellEntry *bonusProto = sSpellStore.LookupEntry(bonus_id)) scale_coeff *= 1 + bonusProto->CalculateSimpleValue(EFFECT_INDEX_0) / 100.0f; break; } case CLASS_WARLOCK: { scale_coeff = 0.75f; break; } case CLASS_DEATH_KNIGHT: { if (getPetType() == SUMMON_PET) { // Ravenous Dead if (owner->GetTypeId() == TYPEID_PLAYER) if (SpellEntry const* spell = ((Player*)owner)->GetKnownTalentRankById(1934)) scale_coeff *= 1.0f + spell->CalculateSimpleValue(EFFECT_INDEX_1) / 100.0f; // Glyph of Ghoul if (Aura *glyph = owner->GetDummyAura(58686)) scale_coeff += glyph->GetModifier()->m_amount / 100.0f; } break; } case CLASS_DRUID: { //For treants, use 70% of stamina / 3 treants, guessed scale_coeff = 0.7f / 3.0f; break; } } break; } case STAT_INTELLECT: { //warlock's and mage's pets gain 30% of owner's intellect if (getPetType() == SUMMON_PET) { if (owner && (owner->getClass() == CLASS_WARLOCK || owner->getClass() == CLASS_MAGE) ) scale_coeff = 0.3f; } break; } } value += float(owner->GetStat(stat)) * scale_coeff; } 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::UpdateAttackPowerAndDamage(bool ranged) { if (ranged) return; float val = 0.0f; float bonusAP = 0.0f; UnitMods unitMod = UNIT_MOD_ATTACK_POWER; val = (GetStat(STAT_STRENGTH) - 20.0f) * 2; 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 (owner && owner->GetTypeId()==TYPEID_PLAYER) { if (getPetType() == HUNTER_PET) //hunter pets benefit from owner's attack power { float ap_coeff = 0.22f; float sp_coeff = 0.1287f; //Wild Hunt uint32 bonus_id = 0; if (HasSpell(62762)) bonus_id = 62762; else if (HasSpell(62758)) bonus_id = 62758; if (const SpellEntry *bonusProto = sSpellStore.LookupEntry(bonus_id)) { ap_coeff *= 1 + bonusProto->CalculateSimpleValue(EFFECT_INDEX_1) / 100.0f; sp_coeff *= 1 + bonusProto->CalculateSimpleValue(EFFECT_INDEX_1) / 100.0f; } bonusAP = owner->GetTotalAttackPowerValue(RANGED_ATTACK) * ap_coeff; SetBonusDamage( int32(owner->GetTotalAttackPowerValue(RANGED_ATTACK) * sp_coeff)); } else if (getPetType() == SUMMON_PET) { switch(owner->getClass()) { case CLASS_WARLOCK: { //demons benefit from warlocks shadow or fire damage 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; break; } case CLASS_MAGE: { //water elementals benefit from mage's frost damage 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)); break; } case CLASS_SHAMAN: { float coeff = 0.3f; //Glyph of Feral Spirit if (Aura *glyph = owner->GetDummyAura(63271)) coeff += glyph->GetModifier()->m_amount / 100.0f; bonusAP += coeff * owner->GetTotalAttackPowerValue(BASE_ATTACK); break; } case CLASS_DRUID: { //Guessed float coeff = 0.55f; int32 sp = int32(owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + SPELL_SCHOOL_NATURE)) - owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG + SPELL_SCHOOL_NATURE); bonusAp += coeff * sp; break; } } } else if (getPetType() == GUARDIAN_PET) if (owner->getClass() == CLASS_DEATH_KNIGHT) bonusAP += owner->GetTotalAttackPowerValue(BASE_ATTACK) * 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); }