void Item::SetItemRandomProperties(int32 randomPropId) { if (!randomPropId) return; if (randomPropId > 0) { ItemRandomPropertiesEntry const *item_rand = sItemRandomPropertiesStore.LookupEntry(randomPropId); if (item_rand) { if (GetInt32Value(ITEM_FIELD_RANDOM_PROPERTIES_ID) != int32(item_rand->ID)) { SetInt32Value(ITEM_FIELD_RANDOM_PROPERTIES_ID, item_rand->ID); SetState(ITEM_CHANGED, GetOwner()); } for (uint32 i = PROP_ENCHANTMENT_SLOT_2; i < PROP_ENCHANTMENT_SLOT_2 + 3; ++i) SetEnchantment(EnchantmentSlot(i), item_rand->enchant_id[i - PROP_ENCHANTMENT_SLOT_2], 0, 0); } } else { ItemRandomSuffixEntry const *item_rand = sItemRandomSuffixStore.LookupEntry(-randomPropId); if (item_rand) { if (GetInt32Value(ITEM_FIELD_RANDOM_PROPERTIES_ID) != -int32(item_rand->ID) || !GetItemSuffixFactor()) { SetInt32Value(ITEM_FIELD_RANDOM_PROPERTIES_ID, -int32(item_rand->ID)); UpdateItemSuffixFactor(); SetState(ITEM_CHANGED, GetOwner()); } for (uint32 i = PROP_ENCHANTMENT_SLOT_0; i < PROP_ENCHANTMENT_SLOT_0 + 3; ++i) SetEnchantment(EnchantmentSlot(i), item_rand->enchant_id[i - PROP_ENCHANTMENT_SLOT_0], 0, 0); } } }
void Creature::UpdateAttackPowerAndDamage(bool ranged) { UnitMods unitMod_pos = ranged ? UNIT_MOD_ATTACK_POWER_RANGED_POS : UNIT_MOD_ATTACK_POWER_POS; UnitMods unitMod_neg = ranged ? UNIT_MOD_ATTACK_POWER_RANGED_NEG : UNIT_MOD_ATTACK_POWER_NEG; uint16 index = UNIT_FIELD_ATTACK_POWER; uint16 index_mod_pos = UNIT_FIELD_ATTACK_POWER_MOD_POS; uint16 index_mod_neg = UNIT_FIELD_ATTACK_POWER_MOD_NEG; uint16 index_mult = UNIT_FIELD_ATTACK_POWER_MULTIPLIER; if (ranged) { index = UNIT_FIELD_RANGED_ATTACK_POWER; index_mod_pos = UNIT_FIELD_RANGED_ATTACK_POWER_MOD_POS; index_mod_neg = UNIT_FIELD_RANGED_ATTACK_POWER_MOD_NEG; index_mult = UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER; } float base_attPower = (GetModifierValue(unitMod_pos, BASE_VALUE) - GetModifierValue(unitMod_neg, BASE_VALUE)) * (GetModifierValue(unitMod_pos, BASE_PCT) + (1 - GetModifierValue(unitMod_neg, BASE_PCT))); float attPowerMod_pos = GetModifierValue(unitMod_pos, TOTAL_VALUE); float attPowerMod_neg = GetModifierValue(unitMod_neg, TOTAL_VALUE); float attPowerMultiplier = (GetModifierValue(unitMod_pos, TOTAL_PCT) + (1 - GetModifierValue(unitMod_neg, TOTAL_PCT))) - 1.0f; SetInt32Value(index, (uint32)base_attPower); //UNIT_FIELD_(RANGED)_ATTACK_POWER field SetInt32Value(index_mod_pos, (uint32)attPowerMod_pos); //UNIT_FIELD_(RANGED)_ATTACK_POWER_MODS field SetInt32Value(index_mod_neg, (uint32)attPowerMod_neg); //UNIT_FIELD_(RANGED)_ATTACK_POWER_MODS field SetFloatValue(index_mult, attPowerMultiplier); //UNIT_FIELD_(RANGED)_ATTACK_POWER_MULTIPLIER field //automatically update weapon damage after attack power modification if (ranged) UpdateDamagePhysical(RANGED_ATTACK); else { UpdateDamagePhysical(BASE_ATTACK); UpdateDamagePhysical(OFF_ATTACK); } }
void Player::UpdateMastery() { if (HasAuraType(SPELL_AURA_MASTERY)) { if(HasAura(76671)) GetAura(76671)->RecalculateAmountOfEffects();//Paladin Protection Mastery if(HasAura(77514)) GetAura(77514)->RecalculateAmountOfEffects();//DK Frost Mastery if(HasAura(48517)) GetAura(48517)->RecalculateAmountOfEffects();// Druid Balance Mastery if(HasAura(48518)) GetAura(48518)->RecalculateAmountOfEffects();// Druid Balance Mastery if(HasAura(76857)) GetAura(76857)->RecalculateAmountOfEffects();// Warrior Protection Mastery SetInt32Value(PLAYER_FIELD_COMBAT_RATING_1 + CR_MASTERY, m_baseRatingValue[CR_MASTERY]); SetFloatValue(PLAYER_MASTERY, GetMasteryPoints()); } }
void Creature::UpdateAttackPowerAndDamage(bool ranged) { UnitMods unitMod = ranged ? UNIT_MOD_ATTACK_POWER_RANGED : UNIT_MOD_ATTACK_POWER; uint16 index = UNIT_FIELD_ATTACK_POWER; uint16 index_mult = UNIT_FIELD_ATTACK_POWER_MULTIPLIER; if (ranged) { index = UNIT_FIELD_RANGED_ATTACK_POWER; index_mult = UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER; } float base_attPower = GetModifierValue(unitMod, BASE_VALUE) * GetModifierValue(unitMod, BASE_PCT); float attPowerMultiplier = GetModifierValue(unitMod, TOTAL_PCT) - 1.0f; SetInt32Value(index, (uint32)base_attPower); //UNIT_FIELD_(RANGED)_ATTACK_POWER field SetFloatValue(index_mult, attPowerMultiplier); //UNIT_FIELD_(RANGED)_ATTACK_POWER_MULTIPLIER field //automatically update weapon damage after attack power modification if (ranged) UpdateDamagePhysical(RANGED_ATTACK); else { UpdateDamagePhysical(BASE_ATTACK); UpdateDamagePhysical(OFF_ATTACK); } }
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)); } //ghouls benefit from deathknight's attack power else if(getPetType() == SUMMON_PET && owner->getClass() == CLASS_DEATH_KNIGHT) { bonusAP = owner->GetTotalAttackPowerValue(BASE_ATTACK) * 0.22f; SetBonusDamage( int32(owner->GetTotalAttackPowerValue(BASE_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 Player::UpdateAttackPowerAndDamage(bool ranged ) { float val2 = 0.0f; float level = float(getLevel()); UnitMods unitMod = ranged ? UNIT_MOD_ATTACK_POWER_RANGED : UNIT_MOD_ATTACK_POWER; uint16 index = UNIT_FIELD_ATTACK_POWER; uint16 index_mod = UNIT_FIELD_ATTACK_POWER_MODS; uint16 index_mult = UNIT_FIELD_ATTACK_POWER_MULTIPLIER; if(ranged) { index = UNIT_FIELD_RANGED_ATTACK_POWER; index_mod = UNIT_FIELD_RANGED_ATTACK_POWER_MODS; index_mult = UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER; switch(getClass()) { case CLASS_HUNTER: val2 = level * 2.0f + GetStat(STAT_AGILITY) - 10.0f; break; case CLASS_ROGUE: val2 = level + GetStat(STAT_AGILITY) - 10.0f; break; case CLASS_WARRIOR:val2 = level + GetStat(STAT_AGILITY) - 10.0f; break; case CLASS_DRUID: switch(GetShapeshiftForm()) { case FORM_CAT: case FORM_BEAR: case FORM_DIREBEAR: val2 = 0.0f; break; default: val2 = GetStat(STAT_AGILITY) - 10.0f; break; } break; default: val2 = GetStat(STAT_AGILITY) - 10.0f; break; } } else { switch(getClass()) { case CLASS_WARRIOR: val2 = level*3.0f + GetStat(STAT_STRENGTH)*2.0f - 20.0f; break; case CLASS_PALADIN: val2 = level*3.0f + GetStat(STAT_STRENGTH)*2.0f - 20.0f; break; case CLASS_DEATH_KNIGHT: val2 = level*3.0f + GetStat(STAT_STRENGTH)*2.0f - 20.0f; break; case CLASS_ROGUE: val2 = level*2.0f + GetStat(STAT_STRENGTH) + GetStat(STAT_AGILITY) - 20.0f; break; case CLASS_HUNTER: val2 = level*2.0f + GetStat(STAT_STRENGTH) + GetStat(STAT_AGILITY) - 20.0f; break; case CLASS_SHAMAN: val2 = level*2.0f + GetStat(STAT_STRENGTH) + GetStat(STAT_AGILITY) - 20.0f; break; case CLASS_DRUID: { ShapeshiftForm form = GetShapeshiftForm(); //Check if Predatory Strikes is skilled float mLevelBonus = 0.0f; float mBonusWeaponAtt = 0.0f; switch(form) { case FORM_CAT: case FORM_BEAR: case FORM_DIREBEAR: case FORM_MOONKIN: { Unit::AuraList const& mDummy = GetAurasByType(SPELL_AURA_DUMMY); for(Unit::AuraList::const_iterator itr = mDummy.begin(); itr != mDummy.end(); ++itr) { if((*itr)->GetSpellProto()->SpellIconID != 1563) continue; // Predatory Strikes (effect 0) if ((*itr)->GetEffIndex() == EFFECT_INDEX_0 && IsInFeralForm()) mLevelBonus = getLevel() * (*itr)->GetModifier()->m_amount / 100.0f; // Predatory Strikes (effect 1) else if ((*itr)->GetEffIndex() == EFFECT_INDEX_1) mBonusWeaponAtt = (*itr)->GetModifier()->m_amount * m_baseFeralAP / 100.0f; if (mLevelBonus != 0.0f && mBonusWeaponAtt != 0.0f) break; } break; } default: break; } switch(form) { case FORM_CAT: val2 = GetStat(STAT_STRENGTH)*2.0f + GetStat(STAT_AGILITY) - 20.0f + mLevelBonus + m_baseFeralAP + mBonusWeaponAtt; break; case FORM_BEAR: case FORM_DIREBEAR: val2 = GetStat(STAT_STRENGTH)*2.0f - 20.0f + mLevelBonus + m_baseFeralAP + mBonusWeaponAtt; break; case FORM_MOONKIN: val2 = GetStat(STAT_STRENGTH)*2.0f - 20.0f + m_baseFeralAP + mBonusWeaponAtt; break; default: val2 = GetStat(STAT_STRENGTH)*2.0f - 20.0f; break; } break; } case CLASS_MAGE: val2 = GetStat(STAT_STRENGTH) - 10.0f; break; case CLASS_PRIEST: val2 = GetStat(STAT_STRENGTH) - 10.0f; break; case CLASS_WARLOCK: val2 = GetStat(STAT_STRENGTH) - 10.0f; break; } } SetModifierValue(unitMod, BASE_VALUE, val2); float base_attPower = GetModifierValue(unitMod, BASE_VALUE) * GetModifierValue(unitMod, BASE_PCT); float attPowerMod = GetModifierValue(unitMod, TOTAL_VALUE); //add dynamic flat mods if( ranged ) { if ((getClassMask() & CLASSMASK_WAND_USERS)==0) { AuraList const& mRAPbyStat = GetAurasByType(SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT); for(AuraList::const_iterator i = mRAPbyStat.begin();i != mRAPbyStat.end(); ++i) attPowerMod += int32(GetStat(Stats((*i)->GetModifier()->m_miscvalue)) * (*i)->GetModifier()->m_amount / 100.0f); } } else { AuraList const& mAPbyStat = GetAurasByType(SPELL_AURA_MOD_ATTACK_POWER_OF_STAT_PERCENT); for(AuraList::const_iterator i = mAPbyStat.begin();i != mAPbyStat.end(); ++i) attPowerMod += int32(GetStat(Stats((*i)->GetModifier()->m_miscvalue)) * (*i)->GetModifier()->m_amount / 100.0f); AuraList const& mAPbyArmor = GetAurasByType(SPELL_AURA_MOD_ATTACK_POWER_OF_ARMOR); for(AuraList::const_iterator iter = mAPbyArmor.begin(); iter != mAPbyArmor.end(); ++iter) // always: ((*i)->GetModifier()->m_miscvalue == 1 == SPELL_SCHOOL_MASK_NORMAL) attPowerMod += int32(GetArmor() / (*iter)->GetModifier()->m_amount); } float attPowerMultiplier = GetModifierValue(unitMod, TOTAL_PCT) - 1.0f; SetInt32Value(index, (uint32)base_attPower); //UNIT_FIELD_(RANGED)_ATTACK_POWER field SetInt32Value(index_mod, (uint32)attPowerMod); //UNIT_FIELD_(RANGED)_ATTACK_POWER_MODS field SetFloatValue(index_mult, attPowerMultiplier); //UNIT_FIELD_(RANGED)_ATTACK_POWER_MULTIPLIER field //automatically update weapon damage after attack power modification if(ranged) { UpdateDamagePhysical(RANGED_ATTACK); } else { UpdateDamagePhysical(BASE_ATTACK); if(CanDualWield() && haveOffhandWeapon()) //allow update offhand damage only if player knows DualWield Spec and has equipped offhand weapon UpdateDamagePhysical(OFF_ATTACK); } if (IsInWorld()) { CallForAllControlledUnits(ApplyScalingBonusWithHelper(SCALING_TARGET_ATTACKPOWER, 0, false),CONTROLLED_PET|CONTROLLED_GUARDIANS); CallForAllControlledUnits(ApplyScalingBonusWithHelper(SCALING_TARGET_SPELLDAMAGE, 0, false),CONTROLLED_PET|CONTROLLED_GUARDIANS); CallForAllControlledUnits(ApplyScalingBonusWithHelper(SCALING_TARGET_DAMAGE, 0, false),CONTROLLED_PET|CONTROLLED_GUARDIANS); } }
bool Item::LoadFromDB(uint32 guid, uint64 owner_guid, QueryResult_AutoPtr result, uint32 entry) { // 0 1 2 3 4 5 6 7 8 9 10 //result = CharacterDatabase.PQuery("SELECT creatorGuid, giftCreatorGuid, count, duration, charges, flags, enchantments, randomPropertyId, durability, playedTime, text FROM item_instance WHERE guid = '%u'", guid); // create item before any checks for store correct guid // and allow use "FSetState(ITEM_REMOVED); SaveToDB();" for deleting item from DB Object::_Create(guid, 0, HIGHGUID_ITEM); // Set entry, MUST be before proto check SetEntry(entry); SetFloatValue(OBJECT_FIELD_SCALE_X, 1.0f); ItemPrototype const* proto = GetProto(); if (!proto) return false; if (!result) { sLog.outError("Item (GUID: %u owner: %u) not found in table `item_instance`, can't load. ", guid, GUID_LOPART(owner_guid)); return false; } // set owner (not if item is only loaded for gbank/auction/mail if (owner_guid != 0) SetOwnerGUID(owner_guid); Field *fields = result->Fetch(); bool need_save = false; // need explicit save data at load fixes SetUInt64Value(ITEM_FIELD_CREATOR, MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER)); SetUInt64Value(ITEM_FIELD_GIFTCREATOR, MAKE_NEW_GUID(fields[1].GetUInt32(), 0, HIGHGUID_PLAYER)); SetCount(fields[2].GetUInt32()); uint32 duration = fields[3].GetUInt32(); SetUInt32Value(ITEM_FIELD_DURATION, duration); // update duration if need, and remove if not need if ((proto->Duration == 0) != (duration == 0)) { SetUInt32Value(ITEM_FIELD_DURATION, abs(proto->Duration)); need_save = true; } Tokens tokens = StrSplit(fields[4].GetCppString(), " "); if (tokens.size() == MAX_ITEM_PROTO_SPELLS) for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i) SetSpellCharges(i, atoi(tokens[i].c_str())); SetUInt32Value(ITEM_FIELD_FLAGS, fields[5].GetUInt32()); // Remove bind flag for items vs NO_BIND set if (IsSoulBound() && proto->Bonding == NO_BIND) { ApplyModFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_BINDED, false); need_save = true; } _LoadIntoDataField(fields[6].GetString(), ITEM_FIELD_ENCHANTMENT_1_1, MAX_ENCHANTMENT_SLOT * MAX_ENCHANTMENT_OFFSET); SetInt32Value(ITEM_FIELD_RANDOM_PROPERTIES_ID, fields[7].GetInt32()); // recalculate suffix factor if (GetItemRandomPropertyId() < 0) UpdateItemSuffixFactor(); uint32 durability = fields[8].GetUInt32(); SetUInt32Value(ITEM_FIELD_DURABILITY, durability); // update max durability (and durability) if need SetUInt32Value(ITEM_FIELD_MAXDURABILITY, proto->MaxDurability); if (durability > proto->MaxDurability) { SetUInt32Value(ITEM_FIELD_DURABILITY, proto->MaxDurability); need_save = true; } SetUInt32Value(ITEM_FIELD_CREATE_PLAYED_TIME, fields[9].GetUInt32()); SetText(fields[10].GetCppString()); if (need_save) // normal item changed state set not work at loading { std::ostringstream ss; ss << "UPDATE item_instance SET duration = " << GetUInt32Value(ITEM_FIELD_DURABILITY) << ", flags = " << GetUInt32Value(ITEM_FIELD_FLAGS) << ", durability = " << GetUInt32Value(ITEM_FIELD_DURABILITY) << " WHERE guid = " << guid; CharacterDatabase.Execute(ss.str().c_str()); } return true; }
void Player::UpdateAttackPowerAndDamage(bool ranged) { float val2 = 0.0f; float level = float(getLevel()); ChrClassesEntry const* entry = sChrClassesStore.LookupEntry(getClass()); UnitMods unitMod = ranged ? UNIT_MOD_ATTACK_POWER_RANGED : UNIT_MOD_ATTACK_POWER; uint16 index = UNIT_FIELD_ATTACK_POWER; if (ranged) { index = UNIT_FIELD_RANGED_ATTACK_POWER; val2 = (level + std::max(GetStat(STAT_AGILITY) - 10.0f, 0.0f)) * entry->RAPPerAgility; } else { float strengthValue = std::max((GetStat(STAT_STRENGTH) - 10.0f) * entry->APPerStrenth, 0.0f); float agilityValue = std::max((GetStat(STAT_AGILITY) - 10.0f) * entry->APPerAgility, 0.0f); SpellShapeshiftFormEntry const* form = sSpellShapeshiftFormStore.LookupEntry(GetShapeshiftForm()); // Directly taken from client, SHAPESHIFT_FLAG_AP_FROM_STRENGTH ? if (form && form->flags1 & 0x20) agilityValue += std::max((GetStat(STAT_AGILITY) - 10.0f) * entry->APPerStrenth, 0.0f); val2 = strengthValue + agilityValue; } SetModifierValue(unitMod, BASE_VALUE, val2); float base_attPower = GetModifierValue(unitMod, BASE_VALUE) * GetModifierValue(unitMod, BASE_PCT); float attPowerMod = GetModifierValue(unitMod, TOTAL_VALUE); //add dynamic flat mods if (!ranged) { AuraEffectList const& mAPbyArmor = GetAuraEffectsByType(SPELL_AURA_MOD_ATTACK_POWER_OF_ARMOR); for (AuraEffectList::const_iterator iter = mAPbyArmor.begin(); iter != mAPbyArmor.end(); ++iter) // always: ((*i)->GetModifier()->m_miscvalue == 1 == SPELL_SCHOOL_MASK_NORMAL) attPowerMod += int32(GetArmor() / (*iter)->GetAmount()); } SetInt32Value(index, (uint32)base_attPower); //UNIT_FIELD_(RANGED)_ATTACK_POWER field Pet* pet = GetPet(); //update pet's AP Guardian* guardian = GetGuardianPet(); //automatically update weapon damage after attack power modification if (ranged) { UpdateDamagePhysical(RANGED_ATTACK); if (pet && pet->IsHunterPet()) // At ranged attack change for hunter pet pet->UpdateAttackPowerAndDamage(); } else { UpdateDamagePhysical(BASE_ATTACK); if (CanDualWield() && haveOffhandWeapon()) //allow update offhand damage only if player knows DualWield Spec and has equipped offhand weapon UpdateDamagePhysical(OFF_ATTACK); if (getClass() == CLASS_SHAMAN || getClass() == CLASS_PALADIN) // mental quickness UpdateSpellDamageAndHealingBonus(); if (pet && pet->IsPetGhoul()) // At melee attack power change for DK pet pet->UpdateAttackPowerAndDamage(); if (guardian && guardian->IsSpiritWolf()) // At melee attack power change for Shaman feral spirit guardian->UpdateAttackPowerAndDamage(); } }
void Player::UpdateAttackPowerAndDamage(bool ranged) { float val2 = 0.0f; float level = float(getLevel()); UnitMods unitMod = ranged ? UNIT_MOD_ATTACK_POWER_RANGED : UNIT_MOD_ATTACK_POWER; uint16 index = UNIT_FIELD_ATTACK_POWER; uint16 index_mod = UNIT_FIELD_ATTACK_POWER_MODS; uint16 index_mult = UNIT_FIELD_ATTACK_POWER_MULTIPLIER; if (ranged) { index = UNIT_FIELD_RANGED_ATTACK_POWER; index_mod = UNIT_FIELD_RANGED_ATTACK_POWER_MODS; index_mult = UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER; switch (getClass()) { case CLASS_HUNTER: val2 = level * 2.0f + GetStat(STAT_AGILITY) - 10.0f; break; case CLASS_ROGUE: val2 = level + GetStat(STAT_AGILITY) - 10.0f; break; case CLASS_WARRIOR: val2 = level + GetStat(STAT_AGILITY) - 10.0f; break; case CLASS_DRUID: switch (GetShapeshiftForm()) { case FORM_CAT: case FORM_BEAR: case FORM_DIREBEAR: val2 = 0.0f; break; default: val2 = GetStat(STAT_AGILITY) - 10.0f; break; } break; default: val2 = GetStat(STAT_AGILITY) - 10.0f; break; } } else { switch (getClass()) { case CLASS_WARRIOR: val2 = level * 3.0f + GetStat(STAT_STRENGTH) * 2.0f - 20.0f; break; case CLASS_PALADIN: val2 = level * 3.0f + GetStat(STAT_STRENGTH) * 2.0f - 20.0f; break; case CLASS_DEATH_KNIGHT: val2 = level * 3.0f + GetStat(STAT_STRENGTH) * 2.0f - 20.0f; break; case CLASS_ROGUE: val2 = level * 2.0f + GetStat(STAT_STRENGTH) + GetStat(STAT_AGILITY) - 20.0f; break; case CLASS_HUNTER: val2 = level * 2.0f + GetStat(STAT_STRENGTH) + GetStat(STAT_AGILITY) - 20.0f; break; case CLASS_SHAMAN: val2 = level * 2.0f + GetStat(STAT_STRENGTH) + GetStat(STAT_AGILITY) - 20.0f; break; case CLASS_DRUID: { // Check if Predatory Strikes is skilled float mLevelMult = 0.0f; float weapon_bonus = 0.0f; if (IsInFeralForm()) { Unit::AuraEffectList const& mDummy = GetAuraEffectsByType(SPELL_AURA_DUMMY); for (Unit::AuraEffectList::const_iterator itr = mDummy.begin(); itr != mDummy.end(); ++itr) { AuraEffect* aurEff = *itr; if (aurEff->GetSpellInfo()->SpellIconID == 1563) { switch (aurEff->GetEffIndex()) { case 0: // Predatory Strikes (effect 0) mLevelMult = CalculatePct(1.0f, aurEff->GetAmount()); break; case 1: // Predatory Strikes (effect 1) if (Item* mainHand = m_items[EQUIPMENT_SLOT_MAINHAND]) { // also gains % attack power from equipped weapon ItemTemplate const* proto = mainHand->GetTemplate(); if (!proto) continue; weapon_bonus = CalculatePct(float(proto->getFeralBonus()), aurEff->GetAmount()); } break; default: break; } } } } switch (GetShapeshiftForm()) { case FORM_CAT: val2 = getLevel() * (mLevelMult + 2.0f) + GetStat(STAT_STRENGTH) * 2.0f + GetStat(STAT_AGILITY) - 20.0f + weapon_bonus + m_baseFeralAP; break; case FORM_BEAR: case FORM_DIREBEAR: val2 = getLevel() * (mLevelMult + 3.0f) + GetStat(STAT_STRENGTH) * 2.0f - 20.0f + weapon_bonus + m_baseFeralAP; break; case FORM_MOONKIN: val2 = getLevel() * (mLevelMult + 1.5f) + GetStat(STAT_STRENGTH) * 2.0f - 20.0f + m_baseFeralAP; break; default: val2 = GetStat(STAT_STRENGTH) * 2.0f - 20.0f; break; } break; } case CLASS_MAGE: val2 = GetStat(STAT_STRENGTH) - 10.0f; break; case CLASS_PRIEST: val2 = GetStat(STAT_STRENGTH) - 10.0f; break; case CLASS_WARLOCK: val2 = GetStat(STAT_STRENGTH) - 10.0f; break; } } SetModifierValue(unitMod, BASE_VALUE, val2); float base_attPower = GetModifierValue(unitMod, BASE_VALUE) * GetModifierValue(unitMod, BASE_PCT); float attPowerMod = GetModifierValue(unitMod, TOTAL_VALUE); //add dynamic flat mods if (ranged) { if ((getClassMask() & CLASSMASK_WAND_USERS) == 0) { AuraEffectList const& mRAPbyStat = GetAuraEffectsByType(SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT); for (AuraEffectList::const_iterator i = mRAPbyStat.begin(); i != mRAPbyStat.end(); ++i) attPowerMod += CalculatePct(GetStat(Stats((*i)->GetMiscValue())), (*i)->GetAmount()); } } else { AuraEffectList const& mAPbyStat = GetAuraEffectsByType(SPELL_AURA_MOD_ATTACK_POWER_OF_STAT_PERCENT); for (AuraEffectList::const_iterator i = mAPbyStat.begin(); i != mAPbyStat.end(); ++i) attPowerMod += CalculatePct(GetStat(Stats((*i)->GetMiscValue())), (*i)->GetAmount()); AuraEffectList const& mAPbyArmor = GetAuraEffectsByType(SPELL_AURA_MOD_ATTACK_POWER_OF_ARMOR); for (AuraEffectList::const_iterator iter = mAPbyArmor.begin(); iter != mAPbyArmor.end(); ++iter) // always: ((*i)->GetModifier()->m_miscvalue == 1 == SPELL_SCHOOL_MASK_NORMAL) attPowerMod += int32(GetArmor() / (*iter)->GetAmount()); } float attPowerMultiplier = GetModifierValue(unitMod, TOTAL_PCT) - 1.0f; SetInt32Value(index, (uint32)base_attPower); //UNIT_FIELD_(RANGED)_ATTACK_POWER field SetInt32Value(index_mod, (uint32)attPowerMod); //UNIT_FIELD_(RANGED)_ATTACK_POWER_MODS field SetFloatValue(index_mult, attPowerMultiplier); //UNIT_FIELD_(RANGED)_ATTACK_POWER_MULTIPLIER field Pet* pet = GetPet(); //update pet's AP //automatically update weapon damage after attack power modification if (ranged) { UpdateDamagePhysical(RANGED_ATTACK); if (pet && pet->isHunterPet()) // At ranged attack change for hunter pet pet->UpdateAttackPowerAndDamage(); } else { UpdateDamagePhysical(BASE_ATTACK); if (CanDualWield() && haveOffhandWeapon()) //allow update offhand damage only if player knows DualWield Spec and has equipped offhand weapon UpdateDamagePhysical(OFF_ATTACK); if (getClass() == CLASS_SHAMAN || getClass() == CLASS_PALADIN) // mental quickness UpdateSpellDamageAndHealingBonus(); if (pet && pet->IsPetGhoul()) // At ranged attack change for hunter pet pet->UpdateAttackPowerAndDamage(); } }
void Player::UpdateAttackPowerAndDamage(bool ranged ) { float val2 = 0.0f; float level = float(getLevel()); UnitMods unitMod = ranged ? UNIT_MOD_ATTACK_POWER_RANGED : UNIT_MOD_ATTACK_POWER; uint16 index = UNIT_FIELD_ATTACK_POWER; uint16 index_mod = UNIT_FIELD_ATTACK_POWER_MODS; uint16 index_mult = UNIT_FIELD_ATTACK_POWER_MULTIPLIER; if(ranged) { index = UNIT_FIELD_RANGED_ATTACK_POWER; index_mod = UNIT_FIELD_RANGED_ATTACK_POWER_MODS; index_mult = UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER; switch(getClass()) { case CLASS_HUNTER: val2 = level * 2.0f + GetStat(STAT_AGILITY) - 10.0f; break; case CLASS_ROGUE: val2 = level + GetStat(STAT_AGILITY) - 10.0f; break; case CLASS_WARRIOR:val2 = level + GetStat(STAT_AGILITY) - 10.0f; break; case CLASS_DRUID: switch(m_form) { case FORM_CAT: case FORM_BEAR: case FORM_DIREBEAR: val2 = 0.0f; break; default: val2 = GetStat(STAT_AGILITY) - 10.0f; break; } break; default: val2 = GetStat(STAT_AGILITY) - 10.0f; break; } } else { switch(getClass()) { case CLASS_WARRIOR: val2 = level*3.0f + GetStat(STAT_STRENGTH)*2.0f - 20.0f; break; case CLASS_PALADIN: val2 = level*3.0f + GetStat(STAT_STRENGTH)*2.0f - 20.0f; break; case CLASS_DEATH_KNIGHT: val2 = level*3.0f + GetStat(STAT_STRENGTH)*2.0f - 20.0f; break; case CLASS_ROGUE: val2 = level*2.0f + GetStat(STAT_STRENGTH) + GetStat(STAT_AGILITY) - 20.0f; break; case CLASS_HUNTER: val2 = level*2.0f + GetStat(STAT_STRENGTH) + GetStat(STAT_AGILITY) - 20.0f; break; case CLASS_SHAMAN: val2 = level*2.0f + GetStat(STAT_STRENGTH) + GetStat(STAT_AGILITY) - 20.0f; break; case CLASS_DRUID: { //Check if Predatory Strikes is skilled float mLevelMult = 0.0; switch(m_form) { case FORM_CAT: case FORM_BEAR: case FORM_DIREBEAR: case FORM_MOONKIN: { Unit::AuraList const& mDummy = GetAurasByType(SPELL_AURA_DUMMY); for(Unit::AuraList::const_iterator itr = mDummy.begin(); itr != mDummy.end(); ++itr) { // Predatory Strikes (effect 0) if ((*itr)->GetEffIndex() == EFFECT_INDEX_0 && (*itr)->GetSpellProto()->SpellIconID == 1563) { mLevelMult = (*itr)->GetModifier()->m_amount / 100.0f; break; } } break; } default: break; } switch(m_form) { case FORM_CAT: val2 = getLevel()*(mLevelMult+2.0f) + GetStat(STAT_STRENGTH)*2.0f + GetStat(STAT_AGILITY) - 20.0f + m_baseFeralAP; break; case FORM_BEAR: case FORM_DIREBEAR: val2 = getLevel()*(mLevelMult+3.0f) + GetStat(STAT_STRENGTH)*2.0f - 20.0f + m_baseFeralAP; break; case FORM_MOONKIN: val2 = getLevel()*(mLevelMult+1.5f) + GetStat(STAT_STRENGTH)*2.0f - 20.0f + m_baseFeralAP; break; default: val2 = GetStat(STAT_STRENGTH)*2.0f - 20.0f; break; } break; } case CLASS_MAGE: val2 = GetStat(STAT_STRENGTH) - 10.0f; break; case CLASS_PRIEST: val2 = GetStat(STAT_STRENGTH) - 10.0f; break; case CLASS_WARLOCK: val2 = GetStat(STAT_STRENGTH) - 10.0f; break; } } SetModifierValue(unitMod, BASE_VALUE, val2); float base_attPower = GetModifierValue(unitMod, BASE_VALUE) * GetModifierValue(unitMod, BASE_PCT); float attPowerMod = GetModifierValue(unitMod, TOTAL_VALUE); //add dynamic flat mods if( ranged ) { if ((getClassMask() & CLASSMASK_WAND_USERS)==0) { AuraList const& mRAPbyStat = GetAurasByType(SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT); for(AuraList::const_iterator i = mRAPbyStat.begin();i != mRAPbyStat.end(); ++i) attPowerMod += int32(GetStat(Stats((*i)->GetModifier()->m_miscvalue)) * (*i)->GetModifier()->m_amount / 100.0f); } } else { AuraList const& mAPbyStat = GetAurasByType(SPELL_AURA_MOD_ATTACK_POWER_OF_STAT_PERCENT); for(AuraList::const_iterator i = mAPbyStat.begin();i != mAPbyStat.end(); ++i) attPowerMod += int32(GetStat(Stats((*i)->GetModifier()->m_miscvalue)) * (*i)->GetModifier()->m_amount / 100.0f); AuraList const& mAPbyArmor = GetAurasByType(SPELL_AURA_MOD_ATTACK_POWER_OF_ARMOR); for(AuraList::const_iterator iter = mAPbyArmor.begin(); iter != mAPbyArmor.end(); ++iter) // always: ((*i)->GetModifier()->m_miscvalue == 1 == SPELL_SCHOOL_MASK_NORMAL) attPowerMod += int32(GetArmor() / (*iter)->GetModifier()->m_amount); } float attPowerMultiplier = GetModifierValue(unitMod, TOTAL_PCT) - 1.0f; SetInt32Value(index, (uint32)base_attPower); //UNIT_FIELD_(RANGED)_ATTACK_POWER field SetInt32Value(index_mod, (uint32)attPowerMod); //UNIT_FIELD_(RANGED)_ATTACK_POWER_MODS field SetFloatValue(index_mult, attPowerMultiplier); //UNIT_FIELD_(RANGED)_ATTACK_POWER_MULTIPLIER field //automatically update weapon damage after attack power modification if(ranged) { UpdateDamagePhysical(RANGED_ATTACK); Pet *pet = GetPet(); //update pet's AP if(pet) pet->UpdateAttackPowerAndDamage(); } else { UpdateDamagePhysical(BASE_ATTACK); if(CanDualWield() && haveOffhandWeapon()) //allow update offhand damage only if player knows DualWield Spec and has equipped offhand weapon UpdateDamagePhysical(OFF_ATTACK); } }
void Player::UpdateAttackPowerAndDamage(bool ranged) { float val2 = 0.0f; float level = float(getLevel()); UnitMods unitMod_pos = ranged ? UNIT_MOD_ATTACK_POWER_RANGED_POS : UNIT_MOD_ATTACK_POWER_POS; UnitMods unitMod_neg = ranged ? UNIT_MOD_ATTACK_POWER_RANGED_NEG : UNIT_MOD_ATTACK_POWER_NEG; uint16 index = UNIT_FIELD_ATTACK_POWER; uint16 index_mod_pos = UNIT_FIELD_ATTACK_POWER_MOD_POS; uint16 index_mod_neg = UNIT_FIELD_ATTACK_POWER_MOD_NEG; uint16 index_mult = UNIT_FIELD_ATTACK_POWER_MULTIPLIER; if (ranged) { index = UNIT_FIELD_RANGED_ATTACK_POWER; index_mod_pos = UNIT_FIELD_RANGED_ATTACK_POWER_MOD_POS; index_mod_neg = UNIT_FIELD_RANGED_ATTACK_POWER_MOD_NEG; index_mult = UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER; switch (getClass()) { case CLASS_HUNTER: val2 = level * 2.0f + GetStat(STAT_AGILITY) * 2.0f - 20.0f; break; case CLASS_ROGUE: val2 = level + GetStat(STAT_AGILITY) - 10.0f; break; case CLASS_WARRIOR:val2 = level + GetStat(STAT_AGILITY) - 10.0f; break; case CLASS_DRUID: switch (GetShapeshiftForm()) { case FORM_CAT: case FORM_BEAR: case FORM_DIREBEAR: val2 = 0.0f; break; default: val2 = GetStat(STAT_AGILITY) - 10.0f; break; } break; default: val2 = GetStat(STAT_AGILITY) - 10.0f; break; } } else { switch (getClass()) { case CLASS_WARRIOR: val2 = level * 3.0f + GetStat(STAT_STRENGTH) * 2.0f - 20.0f; break; case CLASS_PALADIN: val2 = level * 3.0f + GetStat(STAT_STRENGTH) * 2.0f - 20.0f; break; case CLASS_DEATH_KNIGHT: val2 = level * 3.0f + GetStat(STAT_STRENGTH) * 2.0f - 20.0f; break; case CLASS_ROGUE: val2 = level * 2.0f + GetStat(STAT_STRENGTH) + GetStat(STAT_AGILITY) * 2.0f - 20.0f; break; case CLASS_HUNTER: val2 = level * 2.0f + GetStat(STAT_STRENGTH) + GetStat(STAT_AGILITY) * 2.0f - 20.0f; break; case CLASS_SHAMAN: val2 = level * 2.0f + GetStat(STAT_STRENGTH) + GetStat(STAT_AGILITY) * 2.0f - 20.0f; break; case CLASS_DRUID: { ShapeshiftForm form = GetShapeshiftForm(); // Check if Predatory Strikes is skilled float mLevelMult = 0.0f; switch (form) { case FORM_CAT: case FORM_BEAR: case FORM_DIREBEAR: case FORM_MOONKIN: { Unit::AuraEffectList const& mDummy = GetAuraEffectsByType(SPELL_AURA_DUMMY); for (Unit::AuraEffectList::const_iterator itr = mDummy.begin(); itr != mDummy.end(); ++itr) { // Predatory Strikes (effect 0) if ((*itr)->GetEffIndex() == 0 && (*itr)->GetSpellProto()->SpellIconID == 1563) { mLevelMult = CalculatePctN(1.0f, (*itr)->GetAmount()); break; } } break; } default: break; } switch (form) { case FORM_CAT: val2 = getLevel() * (mLevelMult + 2.0f) + GetStat(STAT_STRENGTH) * 2.0f - 20.0f + GetStat(STAT_AGILITY) * 2.0f - 20.0f + m_baseFeralAP; break; case FORM_BEAR: case FORM_DIREBEAR: val2 = getLevel() * (mLevelMult + 2.0f) + GetStat(STAT_STRENGTH) * 2.0f - 20.0f + GetStat(STAT_AGILITY) * 2.0f - 20.0f + m_baseFeralAP; break; case FORM_MOONKIN: val2 = getLevel() * (mLevelMult + 1.5f) + GetStat(STAT_STRENGTH) * 2.0f - 20.0f + m_baseFeralAP; break; default: val2 = GetStat(STAT_STRENGTH) * 2.0f - 20.0f; break; } break; } case CLASS_MAGE: val2 = GetStat(STAT_STRENGTH) - 10.0f; break; case CLASS_PRIEST: val2 = GetStat(STAT_STRENGTH) - 10.0f; break; case CLASS_WARLOCK: val2 = GetStat(STAT_STRENGTH) - 10.0f; break; } } SetModifierValue(unitMod_pos, BASE_VALUE, val2); float base_attPower = (GetModifierValue(unitMod_pos, BASE_VALUE) - GetModifierValue(unitMod_neg, BASE_VALUE)) * (GetModifierValue(unitMod_pos, BASE_PCT) - GetModifierValue(unitMod_neg, BASE_PCT)); float attPowerMod_pos = GetModifierValue(unitMod_pos, TOTAL_VALUE); float attPowerMod_neg = GetModifierValue(unitMod_neg, TOTAL_VALUE); //add dynamic flat mods if (ranged) { if ((getClassMask() & CLASSMASK_WAND_USERS) == 0) { AuraEffectList const& mRAPbyStat = GetAuraEffectsByType(SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT); for (AuraEffectList::const_iterator i = mRAPbyStat.begin(); i != mRAPbyStat.end(); ++i) { int32 temp = CalculatePctN(int32(GetStat(Stats((*i)->GetMiscValue()))), ((*i)->GetAmount() / 100)); if(temp > 0) attPowerMod_pos += temp; else attPowerMod_neg -= temp; } } } else { AuraEffectList const& mAPbyStat = GetAuraEffectsByType(SPELL_AURA_MOD_ATTACK_POWER_OF_STAT_PERCENT); for (AuraEffectList::const_iterator i = mAPbyStat.begin(); i != mAPbyStat.end(); ++i) { int32 temp = CalculatePctN(int32(GetStat(Stats((*i)->GetMiscValue()))), ((*i)->GetAmount() / 100)); if(temp > 0) attPowerMod_pos += temp; else attPowerMod_neg -= temp; } AuraEffectList const& mAPbyArmor = GetAuraEffectsByType(SPELL_AURA_MOD_ATTACK_POWER_OF_ARMOR); for (AuraEffectList::const_iterator iter = mAPbyArmor.begin(); iter != mAPbyArmor.end(); ++iter) { // always: ((*i)->GetModifier()->m_miscvalue == 1 == SPELL_SCHOOL_MASK_NORMAL) int32 temp = int32(GetArmor() / (*iter)->GetAmount()); if(temp > 0) attPowerMod_pos += temp; else attPowerMod_neg -= temp; } } float attPowerMultiplier = (GetModifierValue(unitMod_pos, TOTAL_PCT) + (1 - GetModifierValue(unitMod_neg, TOTAL_PCT)))- 1.0f; SetInt32Value(index, (uint32)base_attPower); //UNIT_FIELD_(RANGED)_ATTACK_POWER field SetInt32Value(index_mod_pos, (uint32)attPowerMod_pos); //UNIT_FIELD_(RANGED)_ATTACK_POWER_MOD_POS field SetInt32Value(index_mod_neg, (uint32)attPowerMod_neg); //UNIT_FIELD_(RANGED)_ATTACK_POWER_MOD_NEG field SetFloatValue(index_mult, attPowerMultiplier); //UNIT_FIELD_(RANGED)_ATTACK_POWER_MULTIPLIER field Pet *pet = GetPet(); //update pet's AP //automatically update weapon damage after attack power modification if (ranged) { UpdateDamagePhysical(RANGED_ATTACK); if (pet && pet->isHunterPet()) // At ranged attack change for hunter pet pet->UpdateAttackPowerAndDamage(); } else { UpdateDamagePhysical(BASE_ATTACK); if (CanDualWield() && haveOffhandWeapon()) //allow update offhand damage only if player knows DualWield Spec and has equipped offhand weapon UpdateDamagePhysical(OFF_ATTACK); if (getClass() == CLASS_SHAMAN || getClass() == CLASS_PALADIN) // mental quickness UpdateSpellDamageAndHealingBonus(); if (pet && pet->IsPetGhoul()) // At ranged attack change for hunter pet pet->UpdateAttackPowerAndDamage(); } }
void Player::UpdateAttackPowerAndDamage(bool ranged) { float val2 = 0.0f; float level = float(getLevel()); ChrClassesEntry const* entry = sChrClassesStore.LookupEntry(getClass()); UnitMods unitMod_pos = ranged ? UNIT_MOD_ATTACK_POWER_RANGED_POS : UNIT_MOD_ATTACK_POWER_POS; UnitMods unitMod_neg = ranged ? UNIT_MOD_ATTACK_POWER_RANGED_NEG : UNIT_MOD_ATTACK_POWER_NEG; uint16 index = UNIT_FIELD_ATTACK_POWER; uint16 index_mod_pos = UNIT_FIELD_ATTACK_POWER_MOD_POS; uint16 index_mod_neg = UNIT_FIELD_ATTACK_POWER_MOD_NEG; uint16 index_mult = UNIT_FIELD_ATTACK_POWER_MULTIPLIER; if (ranged) { index = UNIT_FIELD_RANGED_ATTACK_POWER; val2 = (level + std::max(GetStat(STAT_AGILITY) - 10.0f, 0.0f)) * entry->RAPPerAgility; index_mod_pos = UNIT_FIELD_RANGED_ATTACK_POWER_MOD_POS; index_mod_neg = UNIT_FIELD_RANGED_ATTACK_POWER_MOD_NEG; index_mult = UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER; } else { // This is general. float strengthValue = std::max((GetStat(STAT_STRENGTH) - 10.0f) * entry->APPerStrenth, 0.0f); float agilityValue = std::max((GetStat(STAT_AGILITY) - 10.0f) * entry->APPerAgility, 0.0f); // This is specific. switch (getClass()) { case CLASS_HUNTER: // in the case of Rogues, Hunters, and Shamans, each point of Agility will add 2 AP case CLASS_ROGUE: case CLASS_SHAMAN: agilityValue = std::max(GetStat(STAT_AGILITY) * 2, 0.0f); break; case CLASS_WARRIOR: // Warriors, Paladins, and Death Knights will gain 2 AP from each point of Strength. case CLASS_PALADIN: case CLASS_DEATH_KNIGHT: strengthValue = std::max(GetStat(STAT_STRENGTH) * 2, 0.0f); break; case CLASS_DRUID: // Druids will gain 2 AP from Agility in Bear/Cat form. You have NO strenght in Bear form. if (IsInFeralForm()) if (GetShapeshiftForm() == FORM_CAT || GetShapeshiftForm() == FORM_BEAR) agilityValue = std::max(GetStat(STAT_AGILITY) * 2, 0.0f); break; } val2 = strengthValue + agilityValue; } SetModifierValue(unitMod_pos, BASE_VALUE, val2); float base_attPower = (GetModifierValue(unitMod_pos, BASE_VALUE) - GetModifierValue(unitMod_neg, BASE_VALUE)) * (GetModifierValue(unitMod_pos, BASE_PCT) + (1 - GetModifierValue(unitMod_neg, BASE_PCT))); float attPowerMod_pos = GetModifierValue(unitMod_pos, TOTAL_VALUE); float attPowerMod_neg = GetModifierValue(unitMod_neg, TOTAL_VALUE); //add dynamic flat mods if (!ranged) { AuraEffectList const& mAPbyArmor = GetAuraEffectsByType(SPELL_AURA_MOD_ATTACK_POWER_OF_ARMOR); for (AuraEffectList::const_iterator iter = mAPbyArmor.begin(); iter != mAPbyArmor.end(); ++iter) { // always: ((*i)->GetModifier()->m_miscvalue == 1 == SPELL_SCHOOL_MASK_NORMAL) int32 attPowerMod = int32(GetArmor() / (*iter)->GetAmount()); if (attPowerMod > 0) attPowerMod_pos += attPowerMod; else attPowerMod_neg -= attPowerMod; } } float attPowerMultiplier = (GetModifierValue(unitMod_pos, TOTAL_PCT) + (1 - GetModifierValue(unitMod_neg, TOTAL_PCT))) - 1.0f; SetInt32Value(index, (uint32)base_attPower); //UNIT_FIELD_(RANGED)_ATTACK_POWER field SetInt32Value(index_mod_pos, (uint32) attPowerMod_pos); //UNIT_FIELD_(RANGED)_ATTACK_POWER_MOD_POS field SetInt32Value(index_mod_neg, (uint32) attPowerMod_neg); //UNIT_FIELD_(RANGED)_ATTACK_POWER_MOD_NEG field SetFloatValue(index_mult, attPowerMultiplier); //UNIT_FIELD_(RANGED)_ATTACK_POWER_MULTIPLIER field Pet* pet = GetPet(); //update pet's AP Guardian* guardian = GetGuardianPet(); //automatically update weapon damage after attack power modification if (ranged) { UpdateDamagePhysical(RANGED_ATTACK); if (pet && pet->IsHunterPet()) // At ranged attack change for hunter pet pet->UpdateAttackPowerAndDamage(); } else { UpdateDamagePhysical(BASE_ATTACK); if (CanDualWield() && haveOffhandWeapon()) //allow update offhand damage only if player knows DualWield Spec and has equipped offhand weapon UpdateDamagePhysical(OFF_ATTACK); if (getClass() == CLASS_SHAMAN || getClass() == CLASS_PALADIN) // mental quickness UpdateSpellDamageAndHealingBonus(); if (pet && pet->IsPetGhoul()) // At melee attack power change for DK pet pet->UpdateAttackPowerAndDamage(); if (guardian && guardian->IsSpiritWolf()) // At melee attack power change for Shaman feral spirit guardian->UpdateAttackPowerAndDamage(); } }
void Player::UpdateAttackPowerAndDamage(bool ranged) { float val2 = 0.0f; float level = float(getLevel()); ChrClassesEntry const* entry = sChrClassesStore.LookupEntry(getClass()); UnitMods unitMod = ranged ? UNIT_MOD_ATTACK_POWER_RANGED : UNIT_MOD_ATTACK_POWER; uint16 index = UNIT_FIELD_ATTACK_POWER; uint16 index_mod_pos = UNIT_FIELD_ATTACK_POWER_MOD_POS; uint16 index_mod_neg = UNIT_FIELD_ATTACK_POWER_MOD_NEG; uint16 index_mult = UNIT_FIELD_ATTACK_POWER_MULTIPLIER; if (ranged) { index = UNIT_FIELD_RANGED_ATTACK_POWER; index_mod_pos = UNIT_FIELD_RANGED_ATTACK_POWER_MOD_POS; index_mod_neg = UNIT_FIELD_RANGED_ATTACK_POWER_MOD_NEG; index_mult = UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER; val2 = (level + std::max(GetStat(STAT_AGILITY) - 10.0f, 0.0f)) * entry->RAPPerAgility; } else { float strengthValue = std::max((GetStat(STAT_STRENGTH) - 10.0f) * entry->APPerStrenth, 0.0f); float agilityValue = std::max((GetStat(STAT_AGILITY) - 10.0f) * entry->APPerAgility, 0.0f); if (GetShapeshiftForm() == FORM_CAT || GetShapeshiftForm() == FORM_BEAR) agilityValue += std::max((GetStat(STAT_AGILITY) - 10.0f) * 2, 0.0f); val2 = strengthValue + agilityValue; } SetModifierValue(unitMod, BASE_VALUE, val2); 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; //add dynamic flat mods if (!ranged && HasAuraType(SPELL_AURA_MOD_ATTACK_POWER_OF_ARMOR)) { AuraEffectList const& mAPbyArmor = GetAuraEffectsByType(SPELL_AURA_MOD_ATTACK_POWER_OF_ARMOR); for (AuraEffectList::const_iterator iter = mAPbyArmor.begin(); iter != mAPbyArmor.end(); ++iter) { // always: ((*i)->GetModifier()->m_miscvalue == 1 == SPELL_SCHOOL_MASK_NORMAL) int32 temp = int32(GetArmor() / (*iter)->GetAmount()); if (temp > 0) attPowerMod += temp; else attPowerMod -= temp; } } if (HasAuraType(SPELL_AURA_OVERRIDE_AP_BY_SPELL_POWER_PCT)) { int32 ApBySpellPct = 0; int32 spellPower = ToPlayer()->GetBaseSpellPowerBonus(); // SpellPower from Weapon spellPower += std::max(0, int32(ToPlayer()->GetStat(STAT_INTELLECT)) - 10); // SpellPower from intellect AuraEffectList const& mAPFromSpellPowerPct = GetAuraEffectsByType(SPELL_AURA_OVERRIDE_AP_BY_SPELL_POWER_PCT); for (AuraEffectList::const_iterator i = mAPFromSpellPowerPct.begin(); i != mAPFromSpellPowerPct.end(); ++i) ApBySpellPct += CalculatePct(spellPower, (*i)->GetAmount()); if (ApBySpellPct > 0) { SetInt32Value(index, uint32(ApBySpellPct)); //UNIT_FIELD_(RANGED)_ATTACK_POWER field SetFloatValue(index_mult, attPowerMultiplier); //UNIT_FIELD_(RANGED)_ATTACK_POWER_MULTIPLIER field } else { SetInt32Value(index, uint32(base_attPower + attPowerMod)); //UNIT_FIELD_(RANGED)_ATTACK_POWER field SetFloatValue(index_mult, attPowerMultiplier); //UNIT_FIELD_(RANGED)_ATTACK_POWER_MULTIPLIER field } } else { SetInt32Value(index, uint32(base_attPower + attPowerMod)); //UNIT_FIELD_(RANGED)_ATTACK_POWER field SetFloatValue(index_mult, attPowerMultiplier); //UNIT_FIELD_(RANGED)_ATTACK_POWER_MULTIPLIER field } Pet* pet = GetPet(); //update pet's AP //automatically update weapon damage after attack power modification if (ranged) { UpdateDamagePhysical(RANGED_ATTACK); if (pet && pet->isHunterPet()) // At ranged attack change for hunter pet pet->UpdateAttackPowerAndDamage(); } else { UpdateDamagePhysical(BASE_ATTACK); if (CanDualWield() && haveOffhandWeapon()) //allow update offhand damage only if player knows DualWield Spec and has equipped offhand weapon UpdateDamagePhysical(OFF_ATTACK); if (getClass() == CLASS_SHAMAN || getClass() == CLASS_PALADIN) // mental quickness UpdateSpellDamageAndHealingBonus(); if (pet && pet->IsPetGhoul()) // At ranged attack change for hunter pet pet->UpdateAttackPowerAndDamage(); } }
void Player::UpdateAttackPowerAndDamage(bool ranged) { float val2 = 0.0f; float level = float(getLevel()); ChrClassesEntry const* entry = sChrClassesStore.AssertEntry(getClass()); UnitMods unitMod = ranged ? UNIT_MOD_ATTACK_POWER_RANGED : UNIT_MOD_ATTACK_POWER; uint16 index = UNIT_FIELD_ATTACK_POWER; uint16 index_mod = UNIT_FIELD_ATTACK_POWER_MOD_POS; uint16 index_mult = UNIT_FIELD_ATTACK_POWER_MULTIPLIER; if (ranged) { index = UNIT_FIELD_RANGED_ATTACK_POWER; index_mod = UNIT_FIELD_RANGED_ATTACK_POWER_MOD_POS; index_mult = UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER; } if (!HasAuraType(SPELL_AURA_OVERRIDE_ATTACK_POWER_BY_SP_PCT)) { if (!ranged) { float strengthValue = std::max(GetStat(STAT_STRENGTH) * entry->AttackPowerPerStrength, 0.0f); float agilityValue = std::max(GetStat(STAT_AGILITY) * entry->AttackPowerPerAgility, 0.0f); SpellShapeshiftFormEntry const* form = sSpellShapeshiftFormStore.LookupEntry(GetShapeshiftForm()); // Directly taken from client, SHAPESHIFT_FLAG_AP_FROM_STRENGTH ? if (form && form->Flags & 0x20) agilityValue += std::max(GetStat(STAT_AGILITY) * entry->AttackPowerPerStrength, 0.0f); val2 = strengthValue + agilityValue; } else val2 = (level + std::max(GetStat(STAT_AGILITY), 0.0f)) * entry->RangedAttackPowerPerAgility; } else { int32 minSpellPower = GetInt32Value(PLAYER_FIELD_MOD_HEALING_DONE_POS); for (int i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i) minSpellPower = std::min(minSpellPower, GetInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + i)); val2 = CalculatePct(float(minSpellPower), GetFloatValue(PLAYER_FIELD_OVERRIDE_AP_BY_SPELL_POWER_PERCENT)); } SetModifierValue(unitMod, BASE_VALUE, val2); 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; //add dynamic flat mods if (!ranged) { AuraEffectList const& mAPbyArmor = GetAuraEffectsByType(SPELL_AURA_MOD_ATTACK_POWER_OF_ARMOR); for (AuraEffectList::const_iterator iter = mAPbyArmor.begin(); iter != mAPbyArmor.end(); ++iter) // always: ((*i)->GetModifier()->m_miscvalue == 1 == SPELL_SCHOOL_MASK_NORMAL) attPowerMod += int32(GetArmor() / (*iter)->GetAmount()); } SetInt32Value(index, (uint32)base_attPower); //UNIT_FIELD_(RANGED)_ATTACK_POWER field SetInt32Value(index_mod, (uint32)attPowerMod); //UNIT_FIELD_(RANGED)_ATTACK_POWER_MOD_POS field SetFloatValue(index_mult, attPowerMultiplier); //UNIT_FIELD_(RANGED)_ATTACK_POWER_MULTIPLIER field Pet* pet = GetPet(); //update pet's AP Guardian* guardian = GetGuardianPet(); //automatically update weapon damage after attack power modification if (ranged) { UpdateDamagePhysical(RANGED_ATTACK); if (pet && pet->IsHunterPet()) // At ranged attack change for hunter pet pet->UpdateAttackPowerAndDamage(); } else { UpdateDamagePhysical(BASE_ATTACK); if (Item* offhand = GetWeaponForAttack(OFF_ATTACK, true)) if (CanDualWield() || offhand->GetTemplate()->GetFlags3() & ITEM_FLAG3_ALWAYS_ALLOW_DUAL_WIELD) UpdateDamagePhysical(OFF_ATTACK); if (HasAuraType(SPELL_AURA_MOD_SPELL_DAMAGE_OF_ATTACK_POWER) || HasAuraType(SPELL_AURA_MOD_SPELL_HEALING_OF_ATTACK_POWER) || HasAuraType(SPELL_AURA_OVERRIDE_SPELL_POWER_BY_AP_PCT)) UpdateSpellDamageAndHealingBonus(); if (pet && pet->IsPetGhoul()) // At melee attack power change for DK pet pet->UpdateAttackPowerAndDamage(); if (guardian && guardian->IsSpiritWolf()) // At melee attack power change for Shaman feral spirit guardian->UpdateAttackPowerAndDamage(); } }
void Player::UpdateAttackPowerAndDamage(bool ranged) { float val2 = 0.0f; float level = float(getLevel()); ChrClassesEntry const* entry = sChrClassesStore.LookupEntry(getClass()); UnitMods unitMod = ranged ? UNIT_MOD_ATTACK_POWER_RANGED : UNIT_MOD_ATTACK_POWER; uint16 index = UNIT_FIELD_ATTACK_POWER; uint16 index_mult = UNIT_FIELD_ATTACK_POWER_MULTIPLIER; if (ranged) { index = UNIT_FIELD_RANGED_ATTACK_POWER; index_mult = UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER; val2 = (level + std::max(GetStat(STAT_AGILITY) - 10.0f, 0.0f)) * entry->RAPPerAgility; } else { float strengthValue = std::max((GetStat(STAT_STRENGTH) - 10.0f) * entry->APPerStrenth, 0.0f); float agilityValue = std::max((GetStat(STAT_AGILITY) - 10.0f) * entry->APPerAgility, 0.0f); if (GetShapeshiftForm() == FORM_CAT || GetShapeshiftForm() == FORM_BEAR) agilityValue += std::max((GetStat(STAT_AGILITY) - 10.0f) * 2, 0.0f); val2 = strengthValue + agilityValue; } SetModifierValue(unitMod, BASE_VALUE, val2); float base_attPower = GetModifierValue(unitMod, BASE_VALUE) * GetModifierValue(unitMod, BASE_PCT); float attPowerMultiplier = GetModifierValue(unitMod, TOTAL_PCT) - 1.0f; float attPowerMod = GetModifierValue(unitMod, TOTAL_VALUE); //add dynamic flat mods if (!ranged) { AuraEffectList const& mAPbyArmor = GetAuraEffectsByType(SPELL_AURA_MOD_ATTACK_POWER_OF_ARMOR); for (AuraEffectList::const_iterator iter = mAPbyArmor.begin(); iter != mAPbyArmor.end(); ++iter) attPowerMod += int32(GetArmor() / (*iter)->GetAmount()); } SetInt32Value(index, uint32(base_attPower + attPowerMod)); // UNIT_FIELD_(RANGED)_ATTACK_POWER field SetFloatValue(index_mult, attPowerMultiplier); // UNIT_FIELD_(RANGED)_ATTACK_POWER_MULTIPLIER field Pet* pet = GetPet(); //update pet's AP //automatically update weapon damage after attack power modification if (ranged) { UpdateDamagePhysical(RANGED_ATTACK); if (pet && pet->isHunterPet()) // At ranged attack change for hunter pet pet->UpdateAttackPowerAndDamage(); } else { UpdateDamagePhysical(BASE_ATTACK); if (CanDualWield() && haveOffhandWeapon()) //allow update offhand damage only if player knows DualWield Spec and has equipped offhand weapon UpdateDamagePhysical(OFF_ATTACK); if (getClass() == CLASS_SHAMAN || getClass() == CLASS_PALADIN) // mental quickness UpdateSpellDamageAndHealingBonus(); if (pet && pet->IsPetGhoul()) // At ranged attack change for hunter pet pet->UpdateAttackPowerAndDamage(); } }
void Player::UpdateAttackPowerAndDamage(bool ranged) { ChrClassesEntry const * chrEntry = sChrClassesStore.LookupEntry(getClass()); MANGOS_ASSERT(chrEntry); float val2 = 0.0f; float level = float(getLevel()); UnitMods unitMod = ranged ? UNIT_MOD_ATTACK_POWER_RANGED : UNIT_MOD_ATTACK_POWER; uint16 index = UNIT_FIELD_ATTACK_POWER; uint16 index_mod = UNIT_FIELD_ATTACK_POWER_MOD_POS; uint16 index_mult = UNIT_FIELD_ATTACK_POWER_MULTIPLIER; if (ranged) { index = UNIT_FIELD_RANGED_ATTACK_POWER; index_mod = UNIT_FIELD_RANGED_ATTACK_POWER_MOD_POS; index_mult = UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER; float rapPerAgi = std::max(GetStat(STAT_AGILITY) - 10.0f, 0.0f) * chrEntry->rapPerAgi; switch (getClass()) { case CLASS_HUNTER: val2 = level * 2.0f + rapPerAgi; break; case CLASS_ROGUE: val2 = level + rapPerAgi; break; case CLASS_WARRIOR: val2 = level + rapPerAgi; break; default: break; } } else { float apPerAgi = std::max(GetStat(STAT_AGILITY) - 10.0f, 0.0f) * chrEntry->apPerAgi; float apPerStr = std::max(GetStat(STAT_STRENGTH) - 10.0f, 0.0f) * chrEntry->apPerStr; float levelmod; switch (getClass()) { case CLASS_WARRIOR: case CLASS_PALADIN: case CLASS_DEATH_KNIGHT: case CLASS_DRUID: levelmod = 3.0f; break; default: levelmod = 2.0f; break; } val2 = level * levelmod + apPerAgi + apPerStr; // extracted from client if (getClass() == CLASS_DRUID && GetShapeshiftForm()) { if (SpellShapeshiftFormEntry const * entry = sSpellShapeshiftFormStore.LookupEntry(uint32(GetShapeshiftForm()))) if (entry->flags1 & 0x20) val2 += std::max(GetStat(STAT_AGILITY) - 10.0f, 0.0f) * chrEntry->apPerStr; } } SetModifierValue(unitMod, BASE_VALUE, val2); float base_attPower = GetModifierValue(unitMod, BASE_VALUE) * GetModifierValue(unitMod, BASE_PCT); float attPowerMod = GetModifierValue(unitMod, TOTAL_VALUE); // add dynamic flat mods if (!ranged) { AuraList const& mAPbyArmor = GetAurasByType(SPELL_AURA_MOD_ATTACK_POWER_OF_ARMOR); for (AuraList::const_iterator iter = mAPbyArmor.begin(); iter != mAPbyArmor.end(); ++iter) // always: ((*i)->GetModifier()->m_miscvalue == 1 == SPELL_SCHOOL_MASK_NORMAL) attPowerMod += int32(GetArmor() / (*iter)->GetModifier()->m_amount); } float attPowerMultiplier = GetModifierValue(unitMod, TOTAL_PCT) - 1.0f; SetInt32Value(index, (uint32)base_attPower); // UNIT_FIELD_(RANGED)_ATTACK_POWER field SetInt32Value(index_mod, (uint32)attPowerMod); // UNIT_FIELD_(RANGED)_ATTACK_POWER_MODS field SetFloatValue(index_mult, attPowerMultiplier); // UNIT_FIELD_(RANGED)_ATTACK_POWER_MULTIPLIER field // automatically update weapon damage after attack power modification if (ranged) { UpdateDamagePhysical(RANGED_ATTACK); Pet* pet = GetPet(); // update pet's AP if (pet) pet->UpdateAttackPowerAndDamage(); } else { UpdateDamagePhysical(BASE_ATTACK); if (CanDualWield() && haveOffhandWeapon()) // allow update offhand damage only if player knows DualWield Spec and has equipped offhand weapon UpdateDamagePhysical(OFF_ATTACK); } }
bool Item::LoadFromDB(uint32 guid, uint64 owner_guid, Field* fields, uint32 entry) { // 0 1 2 3 4 5 6 7 8 9 10 //result = CharacterDatabase.PQuery("SELECT creatorGuid, giftCreatorGuid, count, duration, charges, flags, enchantments, randomPropertyId, durability, playedTime, text FROM item_instance WHERE guid = '%u'", guid); // create item before any checks for store correct guid // and allow use "FSetState(ITEM_REMOVED); SaveToDB();" for deleting item from DB Object::_Create(guid, 0, HIGHGUID_ITEM); // Set entry, MUST be before proto check SetEntry(entry); SetFloatValue(OBJECT_FIELD_SCALE_X, 1.0f); ItemPrototype const* proto = GetProto(); if (!proto) return false; // set owner (not if item is only loaded for gbank/auction/mail if (owner_guid != 0) SetOwnerGUID(owner_guid); bool need_save = false; // need explicit save data at load fixes SetUInt64Value(ITEM_FIELD_CREATOR, MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER)); SetUInt64Value(ITEM_FIELD_GIFTCREATOR, MAKE_NEW_GUID(fields[1].GetUInt32(), 0, HIGHGUID_PLAYER)); SetCount(fields[2].GetUInt32()); uint32 duration = fields[3].GetUInt32(); SetUInt32Value(ITEM_FIELD_DURATION, duration); // update duration if need, and remove if not need if ((proto->Duration == 0) != (duration == 0)) { SetUInt32Value(ITEM_FIELD_DURATION, abs(proto->Duration)); need_save = true; } Tokens tokens(fields[4].GetString(), ' ', MAX_ITEM_PROTO_SPELLS); if (tokens.size() == MAX_ITEM_PROTO_SPELLS) for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i) SetSpellCharges(i, atoi(tokens[i])); SetUInt32Value(ITEM_FIELD_FLAGS, fields[5].GetUInt32()); // Remove bind flag for items vs NO_BIND set if (IsSoulBound() && proto->Bonding == NO_BIND) { ApplyModFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_SOULBOUND, false); need_save = true; } std::string enchants = fields[6].GetString(); //_LoadIntoDataField(enchants.c_str(), ITEM_FIELD_ENCHANTMENT_1_1, MAX_ENCHANTMENT_SLOT * MAX_ENCHANTMENT_OFFSET); { // NOTE: // in the recent update of reforge system, definition of EnchantmentSlot has been changed, // and MAX_ENCHANTMENT_SLOT has been changed from 13 to 14, // which makes enchantments column of item_instance table incompatible with previous version. // in this case we will load only first 9 enchantment slots (0-8, for permanent, temporary, sockets, bonus, prismatic and reforge) // and ignore the remaining ones (9-13, for random properties). // which means item random properties will be lost after this update. // after player logging in and saving the inventory, enchantments column will be properly updated. uint32 count = MAX_ENCHANTMENT_SLOT * MAX_ENCHANTMENT_OFFSET; Tokens tokens(enchants, ' ', count); if (tokens.size() < MAX_ENCHANTMENT_SLOT * MAX_ENCHANTMENT_OFFSET) count = REFORGE_ENCHANTMENT_SLOT * MAX_ENCHANTMENT_OFFSET; for (uint32 index = 0; index < count; ++index) m_uint32Values[ITEM_FIELD_ENCHANTMENT_1_1 + index] = index < tokens.size() ? atol(tokens[index]) : 0; } SetInt32Value(ITEM_FIELD_RANDOM_PROPERTIES_ID, fields[7].GetInt16()); // recalculate suffix factor if (GetItemRandomPropertyId() < 0) UpdateItemSuffixFactor(); uint32 durability = fields[8].GetUInt16(); SetUInt32Value(ITEM_FIELD_DURABILITY, durability); // update max durability (and durability) if need SetUInt32Value(ITEM_FIELD_MAXDURABILITY, proto->MaxDurability); if (durability > proto->MaxDurability) { SetUInt32Value(ITEM_FIELD_DURABILITY, proto->MaxDurability); need_save = true; } SetUInt32Value(ITEM_FIELD_CREATE_PLAYED_TIME, fields[9].GetUInt32()); SetText(fields[10].GetString()); if (need_save) // normal item changed state set not work at loading { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPDATE_ITEM_INSTANCE_ON_LOAD); stmt->setUInt32(0, GetUInt32Value(ITEM_FIELD_DURATION)); stmt->setUInt32(1, GetUInt32Value(ITEM_FIELD_FLAGS)); stmt->setUInt32(2, GetUInt32Value(ITEM_FIELD_DURABILITY)); stmt->setUInt32(3, guid); CharacterDatabase.Execute(stmt); } return true; }
void Guardian::UpdateAttackPowerAndDamage(bool ranged) { if (ranged) return; float val = 0.0f; float bonusAP = 0.0f; UnitMods unitMod_pos = UNIT_MOD_ATTACK_POWER_POS; UnitMods unitMod_neg = UNIT_MOD_ATTACK_POWER_NEG; 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 { SpellEntry const* sProto = sSpellStore.LookupEntry(itr->first); // Then get the SpellProto and add the dummy effect value mod += (SpellMgr::CalculateSpellEffectAmount(sProto, 1) / 100.0f); } } bonusAP = owner->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.22f * mod; SetBonusDamage(int32(owner->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.425f * mod)); } else if (IsPetGhoul()) //ghouls benefit from deathknight's attack power (may be summon pet or not) { bonusAP = owner->GetTotalAttackPowerValue(BASE_ATTACK) * 0.22f; SetBonusDamage(int32(owner->GetTotalAttackPowerValue(BASE_ATTACK) * 0.1287f)); } //demons benefit from warlocks shadow or fire damage else if (isPet()) { 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)); } } if(bonusAP > 0) { SetModifierValue(UNIT_MOD_ATTACK_POWER_POS, BASE_VALUE, val + bonusAP); } else { SetModifierValue(UNIT_MOD_ATTACK_POWER_POS, BASE_VALUE, val); SetModifierValue(UNIT_MOD_ATTACK_POWER_NEG, BASE_VALUE, -bonusAP); } //in BASE_VALUE of UNIT_MOD_ATTACK_POWER for creatures we store data of meleeattackpower field in DB float base_attPower = (GetModifierValue(unitMod_pos, BASE_VALUE) - GetModifierValue(unitMod_neg, BASE_VALUE)) * (GetModifierValue(unitMod_pos, BASE_PCT) + (1 - GetModifierValue(unitMod_neg, BASE_PCT))); float attPowerMod_pos = GetModifierValue(unitMod_pos, TOTAL_VALUE); float attPowerMod_neg = GetModifierValue(unitMod_neg, TOTAL_VALUE); float attPowerMultiplier = (GetModifierValue(unitMod_pos, TOTAL_PCT) + (1 - GetModifierValue(unitMod_neg, 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_MOD_POS, (int32)attPowerMod_pos); SetInt32Value(UNIT_FIELD_ATTACK_POWER_MOD_NEG, (int32)attPowerMod_neg); //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 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 Player::UpdateAttackPowerAndDamage(bool ranged) { float val2 = 0.0f; float level = float(getLevel()); UnitMods unitMod = ranged ? UNIT_MOD_ATTACK_POWER_RANGED : UNIT_MOD_ATTACK_POWER; uint16 index = UNIT_FIELD_ATTACK_POWER; uint16 index_mod = UNIT_FIELD_ATTACK_POWER_MODS; uint16 index_mult = UNIT_FIELD_ATTACK_POWER_MULTIPLIER; if (ranged) { index = UNIT_FIELD_RANGED_ATTACK_POWER; index_mod = UNIT_FIELD_RANGED_ATTACK_POWER_MODS; index_mult = UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER; switch (getClass()) { case CLASS_HUNTER: val2 = level * 2.0f + GetStat(STAT_AGILITY) * 2.0f - 10.0f; break; case CLASS_ROGUE: val2 = level + GetStat(STAT_AGILITY) - 10.0f; break; case CLASS_WARRIOR: val2 = level + GetStat(STAT_AGILITY) - 10.0f; break; case CLASS_DRUID: switch (GetShapeshiftForm()) { case FORM_CAT: case FORM_BEAR: case FORM_DIREBEAR: val2 = 0.0f; break; default: val2 = GetStat(STAT_AGILITY) - 10.0f; break; } break; default: val2 = GetStat(STAT_AGILITY) - 10.0f; break; } } else { switch (getClass()) { case CLASS_WARRIOR: val2 = level * 3.0f + GetStat(STAT_STRENGTH) * 2.0f - 20.0f; break; case CLASS_PALADIN: val2 = level * 3.0f + GetStat(STAT_STRENGTH) * 2.0f - 20.0f; break; case CLASS_ROGUE: val2 = level * 2.0f + GetStat(STAT_STRENGTH) + GetStat(STAT_AGILITY) - 20.0f; break; case CLASS_HUNTER: val2 = level * 2.0f + GetStat(STAT_STRENGTH) + GetStat(STAT_AGILITY) - 20.0f; break; case CLASS_SHAMAN: val2 = level * 2.0f + GetStat(STAT_STRENGTH) * 2.0f - 20.0f; break; case CLASS_DRUID: { ShapeshiftForm form = GetShapeshiftForm(); // Check if Predatory Strikes is skilled float mLevelMult = 0.0; switch (form) { case FORM_CAT: case FORM_BEAR: case FORM_DIREBEAR: case FORM_MOONKIN: { Unit::AuraList const& mDummy = GetAurasByType(SPELL_AURA_DUMMY); for (Unit::AuraList::const_iterator itr = mDummy.begin(); itr != mDummy.end(); ++itr) { // Predatory Strikes if ((*itr)->GetSpellProto()->SpellIconID == 1563) { mLevelMult = (*itr)->GetModifier()->m_amount / 100.0f; break; } } break; } default: break; } switch (form) { case FORM_CAT: val2 = getLevel() * mLevelMult + GetStat(STAT_STRENGTH) * 2.0f + GetStat(STAT_AGILITY) - 20.0f; break; case FORM_BEAR: case FORM_DIREBEAR: val2 = getLevel() * mLevelMult + GetStat(STAT_STRENGTH) * 2.0f - 20.0f; break; case FORM_MOONKIN: val2 = getLevel() * (mLevelMult + 1.5f) + GetStat(STAT_STRENGTH) * 2.0f - 20.0f; break; default: val2 = GetStat(STAT_STRENGTH) * 2.0f - 20.0f; break; } break; } case CLASS_MAGE: val2 = GetStat(STAT_STRENGTH) - 10.0f; break; case CLASS_PRIEST: val2 = GetStat(STAT_STRENGTH) - 10.0f; break; case CLASS_WARLOCK: val2 = GetStat(STAT_STRENGTH) - 10.0f; break; } } SetModifierValue(unitMod, BASE_VALUE, val2); 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; SetInt32Value(index, (uint32)base_attPower); // UNIT_FIELD_(RANGED)_ATTACK_POWER field SetInt32Value(index_mod, (uint32)attPowerMod); // UNIT_FIELD_(RANGED)_ATTACK_POWER_MODS field SetFloatValue(index_mult, attPowerMultiplier); // UNIT_FIELD_(RANGED)_ATTACK_POWER_MULTIPLIER field // automatically update weapon damage after attack power modification if (ranged) { UpdateDamagePhysical(RANGED_ATTACK); } else { UpdateDamagePhysical(BASE_ATTACK); if (CanDualWield() && haveOffhandWeapon()) // allow update offhand damage only if player knows DualWield Spec and has equipped offhand weapon { UpdateDamagePhysical(OFF_ATTACK); } } }
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 bonusAP = owner->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.22f * mod; SetBonusDamage(int32(owner->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.1287f * mod)); } else if (IsPetGhoul()) //ghouls benefit from deathknight's attack power (may be summon pet or not) { bonusAP = owner->GetTotalAttackPowerValue(BASE_ATTACK) * 0.22f; SetBonusDamage(int32(owner->GetTotalAttackPowerValue(BASE_ATTACK) * 0.1287f)); } else if (IsSpiritWolf()) //wolf benefit from shaman's attack power { float dmg_multiplier = 0.31f; if (m_owner->GetAuraEffect(63271, 0)) // Glyph of Feral Spirit dmg_multiplier = 0.61f; bonusAP = owner->GetTotalAttackPowerValue(BASE_ATTACK) * dmg_multiplier; SetBonusDamage(int32(owner->GetTotalAttackPowerValue(BASE_ATTACK) * dmg_multiplier)); } //demons benefit from warlocks shadow or fire damage else if (IsPet()) { 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 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_MULTIPLIER field SetFloatValue(UNIT_FIELD_ATTACK_POWER_MULTIPLIER, attPowerMultiplier); //automatically update weapon damage after attack power modification UpdateDamagePhysical(BASE_ATTACK); }
void Player::UpdateAttackPowerAndDamage(bool ranged) { float val2 = 0.0f; float level = float(getLevel()); UnitMods unitMod = ranged ? UNIT_MOD_ATTACK_POWER_RANGED : UNIT_MOD_ATTACK_POWER; uint16 index = UNIT_FIELD_ATTACK_POWER; if (ranged) { index = UNIT_FIELD_RANGED_ATTACK_POWER; switch (getClass()) { case CLASS_HUNTER: val2 = level * 2.0f + GetStat(STAT_AGILITY) - 10.0f; break; case CLASS_ROGUE: val2 = level + GetStat(STAT_AGILITY) - 10.0f; break; case CLASS_WARRIOR: val2 = level + GetStat(STAT_AGILITY) - 10.0f; break; case CLASS_DRUID: switch (GetShapeshiftForm()) { case FORM_CAT: case FORM_BEAR: case FORM_DIREBEAR: val2 = 0.0f; break; default: val2 = GetStat(STAT_AGILITY) - 10.0f; break; } break; default: val2 = GetStat(STAT_AGILITY) - 10.0f; break; } } else { switch (getClass()) { case CLASS_WARRIOR: val2 = level * 3.0f + GetStat(STAT_STRENGTH) * 2.0f - 20.0f; break; case CLASS_PALADIN: val2 = level * 3.0f + GetStat(STAT_STRENGTH) * 2.0f - 20.0f; break; case CLASS_DEATH_KNIGHT: val2 = level * 3.0f + GetStat(STAT_STRENGTH) * 2.0f - 20.0f; break; case CLASS_ROGUE: val2 = level * 2.0f + GetStat(STAT_STRENGTH) + GetStat(STAT_AGILITY) - 20.0f; break; case CLASS_HUNTER: val2 = level * 2.0f + GetStat(STAT_STRENGTH) + GetStat(STAT_AGILITY) - 20.0f; break; case CLASS_SHAMAN: val2 = level * 2.0f + GetStat(STAT_STRENGTH) + GetStat(STAT_AGILITY) - 20.0f; break; case CLASS_DRUID: { switch (GetShapeshiftForm()) { case FORM_CAT: val2 = GetStat(STAT_STRENGTH) * 2.0f + GetStat(STAT_AGILITY) - 20.0f + m_baseFeralAP; break; case FORM_BEAR: case FORM_DIREBEAR: case FORM_MOONKIN: val2 = GetStat(STAT_STRENGTH) * 2.0f - 20.0f + m_baseFeralAP; break; default: val2 = GetStat(STAT_STRENGTH) * 2.0f - 20.0f; break; } break; } case CLASS_MAGE: val2 = GetStat(STAT_STRENGTH) - 10.0f; break; case CLASS_PRIEST: val2 = GetStat(STAT_STRENGTH) - 10.0f; break; case CLASS_WARLOCK: val2 = GetStat(STAT_STRENGTH) - 10.0f; break; } } SetModifierValue(unitMod, BASE_VALUE, val2); float base_attPower = GetModifierValue(unitMod, BASE_VALUE) * GetModifierValue(unitMod, BASE_PCT); float attPowerMod = GetModifierValue(unitMod, TOTAL_VALUE); //add dynamic flat mods if (ranged) { if ((getClassMask() & CLASSMASK_WAND_USERS) == 0) { AuraEffectList const& mRAPbyStat = GetAuraEffectsByType(SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT); for (AuraEffectList::const_iterator i = mRAPbyStat.begin(); i != mRAPbyStat.end(); ++i) attPowerMod += CalculatePctN(GetStat(Stats((*i)->GetMiscValue())), (*i)->GetAmount()); } } else { AuraEffectList const& mAPbyStat = GetAuraEffectsByType(SPELL_AURA_MOD_ATTACK_POWER_OF_STAT_PERCENT); for (AuraEffectList::const_iterator i = mAPbyStat.begin(); i != mAPbyStat.end(); ++i) attPowerMod += CalculatePctN(GetStat(Stats((*i)->GetMiscValue())), (*i)->GetAmount()); AuraEffectList const& mAPbyArmor = GetAuraEffectsByType(SPELL_AURA_MOD_ATTACK_POWER_OF_ARMOR); for (AuraEffectList::const_iterator iter = mAPbyArmor.begin(); iter != mAPbyArmor.end(); ++iter) // always: ((*i)->GetModifier()->m_miscvalue == 1 == SPELL_SCHOOL_MASK_NORMAL) attPowerMod += int32(GetArmor() / (*iter)->GetAmount()); } SetInt32Value(index, (uint32)base_attPower); //UNIT_FIELD_(RANGED)_ATTACK_POWER field Pet* pet = GetPet(); //update pet's AP //automatically update weapon damage after attack power modification if (ranged) { UpdateDamagePhysical(RANGED_ATTACK); if (pet && pet->isHunterPet()) // At ranged attack change for hunter pet pet->UpdateAttackPowerAndDamage(); } else { UpdateDamagePhysical(BASE_ATTACK); if (CanDualWield() && haveOffhandWeapon()) //allow update offhand damage only if player knows DualWield Spec and has equipped offhand weapon UpdateDamagePhysical(OFF_ATTACK); if (getClass() == CLASS_SHAMAN || getClass() == CLASS_PALADIN) // mental quickness UpdateSpellDamageAndHealingBonus(); if (pet && pet->IsPetGhoul()) // At ranged attack change for hunter pet pet->UpdateAttackPowerAndDamage(); } }
bool Item::LoadFromDB(uint32 guid, uint64 owner_guid, Field* fields, uint32 entry) { // 0 1 2 3 4 5 6 7 8 9 10 //result = CharacterDatabase.PQuery("SELECT creatorGuid, giftCreatorGuid, count, duration, charges, flags, enchantments, randomPropertyId, durability, playedTime, text FROM item_instance WHERE guid = '%u'", guid); // create item before any checks for store correct guid // and allow use "FSetState(ITEM_REMOVED); SaveToDB();" for deleting item from DB Object::_Create(guid, 0, HIGHGUID_ITEM); // Set entry, MUST be before proto check SetEntry(entry); SetObjectScale(1.0f); ItemTemplate const* proto = GetTemplate(); if (!proto) return false; // set owner (not if item is only loaded for gbank/auction/mail if (owner_guid != 0) SetOwnerGUID(owner_guid); bool need_save = false; // need explicit save data at load fixes SetUInt64Value(ITEM_FIELD_CREATOR, MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER)); SetUInt64Value(ITEM_FIELD_GIFTCREATOR, MAKE_NEW_GUID(fields[1].GetUInt32(), 0, HIGHGUID_PLAYER)); SetCount(fields[2].GetUInt32()); uint32 duration = fields[3].GetUInt32(); SetUInt32Value(ITEM_FIELD_DURATION, duration); // update duration if need, and remove if not need if ((proto->Duration == 0) != (duration == 0)) { SetUInt32Value(ITEM_FIELD_DURATION, proto->Duration); need_save = true; } Tokenizer tokens(fields[4].GetString(), ' ', MAX_ITEM_PROTO_SPELLS); if (tokens.size() == MAX_ITEM_PROTO_SPELLS) for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i) SetSpellCharges(i, atoi(tokens[i])); SetUInt32Value(ITEM_FIELD_FLAGS, fields[5].GetUInt32()); // Remove bind flag for items vs NO_BIND set if (IsSoulBound() && proto->Bonding == NO_BIND) { ApplyModFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_SOULBOUND, false); need_save = true; } std::string enchants = fields[6].GetString(); _LoadIntoDataField(enchants.c_str(), ITEM_FIELD_ENCHANTMENT_1_1, MAX_ENCHANTMENT_SLOT * MAX_ENCHANTMENT_OFFSET); SetInt32Value(ITEM_FIELD_RANDOM_PROPERTIES_ID, fields[7].GetInt16()); // recalculate suffix factor if (GetItemRandomPropertyId() < 0) UpdateItemSuffixFactor(); uint32 durability = fields[8].GetUInt16(); SetUInt32Value(ITEM_FIELD_DURABILITY, durability); // update max durability (and durability) if need SetUInt32Value(ITEM_FIELD_MAXDURABILITY, proto->MaxDurability); if (durability > proto->MaxDurability) { SetUInt32Value(ITEM_FIELD_DURABILITY, proto->MaxDurability); need_save = true; } SetUInt32Value(ITEM_FIELD_CREATE_PLAYED_TIME, fields[9].GetUInt32()); SetText(fields[10].GetString()); if (need_save) // normal item changed state set not work at loading { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ITEM_INSTANCE_ON_LOAD); stmt->setUInt32(0, GetUInt32Value(ITEM_FIELD_DURATION)); stmt->setUInt32(1, GetUInt32Value(ITEM_FIELD_FLAGS)); stmt->setUInt32(2, GetUInt32Value(ITEM_FIELD_DURABILITY)); stmt->setUInt32(3, guid); CharacterDatabase.Execute(stmt); } 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); }