void CBaseObj::UpdataObjInfo(CBaseObj *obj) { netData::UpdataObjInfo sendMsg; if (obj) { // 将obj的信息发送给我 sendMsg.set_name(obj->GetName()); sendMsg.set_ntempid(obj->GetTempID()); sendMsg.set_x(obj->GetNowPosX()); sendMsg.set_y(obj->GetNowPosY()); sendMsg.set_z(obj->GetNowPosZ()); FuncUti::SendPBNoLoop(ToPlayer(), sendMsg, CLIENT_TYPE_MAIN, CLIENT_SUB_UPTATE_OBJINFO); } else { // 广播我的信息 sendMsg.set_name(GetName()); sendMsg.set_ntempid(GetTempID()); sendMsg.set_x(GetNowPosX()); sendMsg.set_y(GetNowPosY()); sendMsg.set_z(GetNowPosZ()); FuncUti::SendPBNoLoop(ToPlayer(), sendMsg, CLIENT_TYPE_MAIN, CLIENT_SUB_UPTATE_OBJINFO, true); } }
void CBaseObj::DelObjFromView(uint32 tempid) { netData::DelObjFromView sendMsg; sendMsg.set_ntempid(tempid); FuncUti::SendPBNoLoop(ToPlayer(), sendMsg, CLIENT_TYPE_MAIN, CLIENT_SUB_DELOBJ_FROM_VIEW); }
void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { auto caster = GetCaster(); auto target = GetTarget(); if (!caster || !target) return; if (target->GetTypeId() == TYPEID_UNIT && target->GetEntry() == 60925 && !target->HasAura(106246)) { if (auto player = caster->ToPlayer()) player->KilledMonsterCredit(target->GetEntry()); target->CastSpell(target, 106246, 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; 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(); } }
bool Player::UpdateAllStats() { for (int8 i = STAT_STRENGTH; i < MAX_STATS; ++i) { float value = GetTotalStatValue(Stats(i)); SetStat(Stats(i), int32(value)); } UpdateArmor(); // calls UpdateAttackPowerAndDamage() in UpdateArmor for SPELL_AURA_MOD_ATTACK_POWER_OF_ARMOR UpdateAttackPowerAndDamage(true); UpdateMaxHealth(); for (uint8 i = POWER_MANA; i < MAX_POWERS; ++i) UpdateMaxPower(Powers(i)); // Custom MoP script // Jab Override Driver if (GetTypeId() == TYPEID_PLAYER && getClass() == CLASS_MONK) { Item* mainItem = GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND); if (mainItem && mainItem->GetTemplate()->Class == ITEM_CLASS_WEAPON && !HasAura(125660)) { RemoveAura(108561); // 2H Staff Override RemoveAura(115697); // 2H Polearm Override RemoveAura(115689); // D/W Axes RemoveAura(115694); // D/W Maces RemoveAura(115696); // D/W Swords switch (mainItem->GetTemplate()->SubClass) { case ITEM_SUBCLASS_WEAPON_STAFF: CastSpell(this, 108561, true); break; case ITEM_SUBCLASS_WEAPON_POLEARM: CastSpell(this, 115697, true); break; case ITEM_SUBCLASS_WEAPON_AXE: CastSpell(this, 115689, true); break; case ITEM_SUBCLASS_WEAPON_MACE: CastSpell(this, 115694, true); break; case ITEM_SUBCLASS_WEAPON_SWORD: CastSpell(this, 115696, true); break; default: break; } } else if (HasAura(125660)) { RemoveAura(108561); // 2H Staff Override RemoveAura(115697); // 2H Polearm Override RemoveAura(115689); // D/W Axes RemoveAura(115694); // D/W Maces RemoveAura(115696); // D/W Swords } } // Way of the Monk - 120277 if (GetTypeId() == TYPEID_PLAYER) { if (getClass() == CLASS_MONK && HasAura(120277)) { RemoveAurasDueToSpell(120275); RemoveAurasDueToSpell(108977); uint32 trigger = 0; if (IsTwoHandUsed()) { trigger = 120275; } else { Item* mainItem = GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND); Item* offItem = GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND); if (mainItem && mainItem->GetTemplate()->Class == ITEM_CLASS_WEAPON && offItem && offItem->GetTemplate()->Class == ITEM_CLASS_WEAPON) trigger = 108977; } if (trigger) CastSpell(this, trigger, true); } } // Assassin's Resolve - 84601 if (GetTypeId() == TYPEID_PLAYER) { if (getClass() == CLASS_ROGUE && ToPlayer()->GetSpecializationId(ToPlayer()->GetActiveSpec()) == SPEC_ROGUE_ASSASSINATION) { Item* mainItem = GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND); Item* offItem = GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND); if (((mainItem && mainItem->GetTemplate()->SubClass == ITEM_SUBCLASS_WEAPON_DAGGER) || (offItem && offItem->GetTemplate()->SubClass == ITEM_SUBCLASS_WEAPON_DAGGER))) { if (HasAura(84601)) RemoveAura(84601); CastSpell(this, 84601, true); } else RemoveAura(84601); } } UpdateAllRatings(); UpdateAllCritPercentages(); UpdateAllSpellCritChances(); UpdateBlockPercentage(); UpdateParryPercentage(); UpdateDodgePercentage(); UpdateSpellDamageAndHealingBonus(); UpdateManaRegen(); UpdateExpertise(BASE_ATTACK); UpdateExpertise(OFF_ATTACK); UpdateExpertise(RANGED_ATTACK); for (int i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; ++i) UpdateResistances(i); return true; }
bool CPlayer::SellItemToMultiVendor(ObjectGuid itemGuid, uint8 _count) { DEBUG_LOG("WORLD: SellItemToMultiVendor"); // prevent possible overflow, as mangos uses uint32 for item count uint32 count = _count; uint32 entry; ObjectGuid guid; GetMultiVendor(entry, guid); if (!itemGuid) return false; Creature* pCreature = GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_NONE); if (!pCreature) { DEBUG_LOG("WORLD: SellItemToMultiVendor - %s not found or you can't interact with him.", guid.GetString().c_str()); SendSellError(SELL_ERR_CANT_FIND_VENDOR, NULL, itemGuid, 0); return false; } // remove fake death if (hasUnitState(UNIT_STAT_DIED)) RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); Item* pItem = GetItemByGuid(itemGuid); if (pItem) { // prevent sell not owner item if (GetObjectGuid() != pItem->GetOwnerGuid()) { SendSellError(SELL_ERR_CANT_SELL_ITEM, pCreature, itemGuid, 0); return false; } // prevent sell non empty bag by drag-and-drop at vendor's item list if (pItem->IsBag() && !((Bag*)pItem)->IsEmpty()) { SendSellError(SELL_ERR_CANT_SELL_ITEM, pCreature, itemGuid, 0); return false; } // prevent sell currently looted item if (GetLootGuid() == pItem->GetObjectGuid()) { SendSellError(SELL_ERR_CANT_SELL_ITEM, pCreature, itemGuid, 0); return false; } // special case at auto sell (sell all) if (count == 0) { count = pItem->GetCount(); } else { // prevent sell more items that exist in stack (possible only not from client) if (count > pItem->GetCount()) { SendSellError(SELL_ERR_CANT_SELL_ITEM, pCreature, itemGuid, 0); return false; } } ItemPrototype const* pProto = pItem->GetProto(); if (pProto) { if (pProto->SellPrice > 0) { if (count < pItem->GetCount()) // need split items { Item* pNewItem = pItem->CloneItem(count, ToPlayer()); if (!pNewItem) { sLog.outError("WORLD: SellItemToMultiVendor - could not create clone of item %u; count = %u", pItem->GetEntry(), count); SendSellError(SELL_ERR_CANT_SELL_ITEM, pCreature, itemGuid, 0); return false; } pItem->SetCount(pItem->GetCount() - count); ItemRemovedQuestCheck(pItem->GetEntry(), count); if (IsInWorld()) pItem->SendCreateUpdateToPlayer(ToPlayer()); pItem->SetState(ITEM_CHANGED, ToPlayer()); AddItemToBuyBackSlot(pNewItem); if (IsInWorld()) pNewItem->SendCreateUpdateToPlayer(ToPlayer()); } else { ItemRemovedQuestCheck(pItem->GetEntry(), pItem->GetCount()); RemoveItem(pItem->GetBagSlot(), pItem->GetSlot(), true); pItem->RemoveFromUpdateQueueOf(ToPlayer()); AddItemToBuyBackSlot(pItem); } uint32 money = pProto->SellPrice * count; ModifyMoney(money); } else SendSellError(SELL_ERR_CANT_SELL_ITEM, pCreature, itemGuid, 0); return true; } } SendSellError(SELL_ERR_CANT_FIND_ITEM, pCreature, itemGuid, 0); return false; }
// Return true is the bought item has a max count to force refresh of window by caller bool CPlayer::BuyItemFromMultiVendor(uint32 item, uint8 count, uint8 bag, uint8 slot) { DEBUG_LOG("WORLD: BuyItemFromMultiVendor"); // cheating attempt if (count < 1) count = 1; if (!isAlive()) return false; ItemPrototype const* pProto = ObjectMgr::GetItemPrototype(item); if (!pProto) { SendBuyError(BUY_ERR_CANT_FIND_ITEM, NULL, item, 0); return false; } uint32 entry; ObjectGuid guid; GetMultiVendor(entry, guid); CreatureInfo const *cinfo = sObjectMgr.GetCreatureTemplate(entry); if (!cinfo) { BoxChat << MSG_COLOR_WHITE << "This vendor seems to be removed from the database. Please report that creature " << entry << " is missing." << std::endl; return false; } Creature* pCreature = GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_NONE); if (!pCreature) { DEBUG_LOG("WORLD: BuyItemFromMultiVendor - %s not found or you can't interact with him.", guid.GetString().c_str()); SendBuyError(BUY_ERR_DISTANCE_TOO_FAR, NULL, item, 0); return false; } VendorItemData const* vItems = sObjectMgr.GetNpcVendorItemList(entry); VendorItemData const* tItems = cinfo->VendorTemplateId ? sObjectMgr.GetNpcVendorTemplateItemList(cinfo->VendorTemplateId) : NULL; if ((!vItems || vItems->Empty()) && (!tItems || tItems->Empty())) { SendBuyError(BUY_ERR_CANT_FIND_ITEM, pCreature, item, 0); return false; } uint32 vCount = vItems ? vItems->GetItemCount() : 0; uint32 tCount = tItems ? tItems->GetItemCount() : 0; size_t vendorslot = vItems ? vItems->FindItemSlot(item) : vCount; if (vendorslot >= vCount) vendorslot = vCount + (tItems ? tItems->FindItemSlot(item) : tCount); if (vendorslot >= vCount + tCount) { SendBuyError(BUY_ERR_CANT_FIND_ITEM, pCreature, item, 0); return false; } VendorItem const* crItem = vendorslot < vCount ? vItems->GetItem(vendorslot) : tItems->GetItem(vendorslot - vCount); if (!crItem || crItem->item != item) // store diff item (cheating) { SendBuyError(BUY_ERR_CANT_FIND_ITEM, pCreature, item, 0); return false; } uint32 totalCount = pProto->BuyCount * count; // check current item amount if it limited if (crItem->maxcount != 0) { if (pCreature->GetVendorItemCurrentCount(crItem) < totalCount) { SendBuyError(BUY_ERR_ITEM_ALREADY_SOLD, pCreature, item, 0); return false; } } if (uint32(GetReputationRank(pProto->RequiredReputationFaction)) < pProto->RequiredReputationRank) { SendBuyError(BUY_ERR_REPUTATION_REQUIRE, pCreature, item, 0); return false; } if (uint32 extendedCostId = crItem->ExtendedCost) { ItemExtendedCostEntry const* iece = sItemExtendedCostStore.LookupEntry(extendedCostId); if (!iece) { sLog.outError("Item %u have wrong ExtendedCost field value %u", pProto->ItemId, extendedCostId); return false; } // honor points price if (GetHonorPoints() < (iece->reqhonorpoints * count)) { SendEquipError(EQUIP_ERR_NOT_ENOUGH_HONOR_POINTS, NULL, NULL); return false; } // arena points price if (GetArenaPoints() < (iece->reqarenapoints * count)) { SendEquipError(EQUIP_ERR_NOT_ENOUGH_ARENA_POINTS, NULL, NULL); return false; } // item base price for (auto i = 0; i < MAX_EXTENDED_COST_ITEMS; ++i) { if (iece->reqitem[i] && !HasItemCount(iece->reqitem[i], iece->reqitemcount[i] * count)) { SendEquipError(EQUIP_ERR_VENDOR_MISSING_TURNINS, NULL, NULL); return false; } } // check for personal arena rating requirement if (GetMaxPersonalArenaRatingRequirement() < iece->reqpersonalarenarating) { // probably not the proper equip err SendEquipError(EQUIP_ERR_CANT_EQUIP_RANK, NULL, NULL); return false; } } if (crItem->conditionId && !isGameMaster() && !sObjectMgr.IsPlayerMeetToCondition(crItem->conditionId, ToPlayer(), pCreature->GetMap(), pCreature, CONDITION_FROM_VENDOR)) { SendBuyError(BUY_ERR_CANT_FIND_ITEM, pCreature, item, 0); return false; } uint32 price = pProto->BuyPrice * count; // reputation discount price = uint32(floor(price * GetReputationPriceDiscount(pCreature))); if (GetMoney() < price) { SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, pCreature, item, 0); return false; } // if (GetAverageItemLevel() < crItem->itemlevel && !isGameMaster()) // { // // probably not the proper equip err // SendEquipError(EQUIP_ERR_CANT_EQUIP_RANK, NULL, NULL); // SendChatMessage("You need at least %u averange itemlevel.", crItem->itemlevel); // SendChatMessage("You currently have a averange itemlevel %u.", uint32(floor(GetAverageItemLevel()))); // return false; // } Item* pItem = NULL; if ((bag == NULL_BAG && slot == NULL_SLOT) || IsInventoryPos(bag, slot)) { ItemPosCountVec dest; InventoryResult msg = CanStoreNewItem(bag, slot, dest, item, totalCount); if (msg != EQUIP_ERR_OK) { SendEquipError(msg, NULL, NULL, item); return false; } ModifyMoney(-int32(price)); if (crItem->ExtendedCost) TakeExtendedCost(crItem->ExtendedCost, count); pItem = StoreNewItem(dest, item, true); } else if (IsEquipmentPos(bag, slot)) { if (totalCount != 1) { SendEquipError(EQUIP_ERR_ITEM_CANT_BE_EQUIPPED, NULL, NULL); return false; } uint16 dest; InventoryResult msg = CanEquipNewItem(slot, dest, item, false); if (msg != EQUIP_ERR_OK) { SendEquipError(msg, NULL, NULL, item); return false; } ModifyMoney(-int32(price)); if (crItem->ExtendedCost) TakeExtendedCost(crItem->ExtendedCost, count); pItem = EquipNewItem(dest, item, true); if (pItem) AutoUnequipOffhandIfNeed(); } else { SendEquipError(EQUIP_ERR_ITEM_DOESNT_GO_TO_SLOT, NULL, NULL); return false; } if (!pItem) return false; uint32 new_count = pCreature->UpdateVendorItemCurrentCount(crItem, totalCount); WorldPacket data(SMSG_BUY_ITEM, 8 + 4 + 4 + 4); data << pCreature->GetObjectGuid(); data << uint32(vendorslot + 1); // numbered from 1 at client data << uint32(crItem->maxcount > 0 ? new_count : 0xFFFFFFFF); data << uint32(count); GetSession()->SendPacket(&data); SendNewItem(pItem, totalCount, true, false, false); return crItem->maxcount != 0; }