diff options
Diffstat (limited to 'src/game/Player.cpp')
-rw-r--r-- | src/game/Player.cpp | 322 |
1 files changed, 213 insertions, 109 deletions
diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 494334466f4..a68002445bc 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -230,7 +230,7 @@ bool PlayerTaxi::LoadTaxiDestinationsFromString( const std::string& values, uint } // can't load taxi path without mount set (quest taxi path?) - if(!objmgr.GetTaxiMount(GetTaxiSource(),team)) + if(!objmgr.GetTaxiMount(GetTaxiSource(),team,true)) return false; return true; @@ -897,6 +897,8 @@ void Player::EnvironmentalDamage(EnviromentalDamage type, uint32 damage) damage-=absorb+resist; + DealDamageMods(this,damage,&absorb); + WorldPacket data(SMSG_ENVIRONMENTALDAMAGELOG, (21)); data << uint64(GetGUID()); data << uint8(type!=DAMAGE_FALL_TO_VOID ? type : DAMAGE_FALL); @@ -1490,7 +1492,12 @@ void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data ) char_flags |= CHARACTER_FLAG_GHOST; if(HasAtLoginFlag(AT_LOGIN_RENAME)) char_flags |= CHARACTER_FLAG_RENAME; - if(sWorld.getConfig(CONFIG_DECLINED_NAMES_USED) && (fields[14].GetCppString() != "")) + if(sWorld.getConfig(CONFIG_DECLINED_NAMES_USED)) + { + if(!fields[14].GetCppString().empty()) + char_flags |= CHARACTER_FLAG_DECLINED; + } + else char_flags |= CHARACTER_FLAG_DECLINED; *p_data << uint32(char_flags); // character flags @@ -1505,7 +1512,7 @@ void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data ) uint32 petFamily = 0; // show pet at selection character in character list only for non-ghost character - if(result && isAlive() && (pClass == CLASS_WARLOCK || pClass == CLASS_HUNTER)) + if (result && isAlive() && (pClass == CLASS_WARLOCK || pClass == CLASS_HUNTER || pClass == CLASS_DEATH_KNIGHT)) { uint32 entry = fields[10].GetUInt32(); CreatureInfo const* cInfo = sCreatureStorage.LookupEntry<CreatureInfo>(entry); @@ -1666,7 +1673,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati if (!(options & TELE_TO_NOT_UNSUMMON_PET)) { //same map, only remove pet if out of range for new position - if(pet && pet->GetDistance(x,y,z) >= OWNER_MAX_DISTANCE) + if(pet && !pet->IsWithinDist3d(x,y,z, OWNER_MAX_DISTANCE)) UnsummonPetTemporaryIfAny(); } @@ -1798,7 +1805,7 @@ void Player::AddToWorld() ///- The player should only be added when logging in Unit::AddToWorld(); - for(int i = PLAYER_SLOT_START; i < PLAYER_SLOT_END; i++) + for(int i = PLAYER_SLOT_START; i < PLAYER_SLOT_END; ++i) { if(m_items[i]) m_items[i]->AddToWorld(); @@ -1815,7 +1822,7 @@ void Player::RemoveFromWorld() StopCastingBindSight(); } - for(int i = PLAYER_SLOT_START; i < PLAYER_SLOT_END; i++) + for(int i = PLAYER_SLOT_START; i < PLAYER_SLOT_END; ++i) { if(m_items[i]) m_items[i]->RemoveFromWorld(); @@ -3287,6 +3294,20 @@ void Player::removeSpell(uint32 spell_id, bool disabled, bool update_action_bar_ } } + +void Player::RemoveSpellCooldown( uint32 spell_id, bool update /* = false */ ) +{ + m_spellCooldowns.erase(spell_id); + + if(update) + { + WorldPacket data(SMSG_CLEAR_COOLDOWN, (4+8)); + data << uint32(spell_id); + data << uint64(GetGUID()); + SendDirectMessage(&data); + } +} + void Player::RemoveArenaSpellCooldowns() { // remove cooldowns on spells that has < 15 min CD @@ -5729,23 +5750,26 @@ ReputationRank Player::GetReputationRank(uint32 faction) const } //Calculate total reputation percent player gain with quest/creature level -int32 Player::CalculateReputationGain(uint32 creatureOrQuestLevel, int32 rep, bool for_quest) +int32 Player::CalculateReputationGain(uint32 creatureOrQuestLevel, int32 rep, int32 faction, bool for_quest) { float percent = 100.0f; float rate = for_quest ? sWorld.getRate(RATE_REPUTATION_LOWLEVEL_QUEST) : sWorld.getRate(RATE_REPUTATION_LOWLEVEL_KILL); - if(rate != 1.0f && creatureOrQuestLevel <= MaNGOS::XP::GetGrayLevel(getLevel())) + if (rate != 1.0f && creatureOrQuestLevel <= MaNGOS::XP::GetGrayLevel(getLevel())) percent *= rate; - int32 repMod = GetTotalAuraModifier(SPELL_AURA_MOD_REPUTATION_GAIN); + float repMod = GetTotalAuraModifier(SPELL_AURA_MOD_REPUTATION_GAIN); + + if (!for_quest) + repMod += GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_FACTION_REPUTATION_GAIN, faction); percent += rep > 0 ? repMod : -repMod; - if(percent <= 0.0f) + if (percent <= 0.0f) return 0; - return int32(sWorld.getRate(RATE_REPUTATION_GAIN)*rep*percent/100); + return int32(sWorld.getRate(RATE_REPUTATION_GAIN)*rep*percent/100.0f); } //Calculates how many reputation points player gains in victim's enemy factions @@ -5764,7 +5788,7 @@ void Player::RewardReputation(Unit *pVictim, float rate) if(Rep->repfaction1 && (!Rep->team_dependent || GetTeam()==ALLIANCE)) { - int32 donerep1 = CalculateReputationGain(pVictim->getLevel(),Rep->repvalue1,false); + int32 donerep1 = CalculateReputationGain(pVictim->getLevel(), Rep->repvalue1, Rep->repfaction1, false); donerep1 = int32(donerep1*rate); FactionEntry const *factionEntry1 = sFactionStore.LookupEntry(Rep->repfaction1); uint32 current_reputation_rank1 = GetReputationMgr().GetRank(factionEntry1); @@ -5782,7 +5806,7 @@ void Player::RewardReputation(Unit *pVictim, float rate) if(Rep->repfaction2 && (!Rep->team_dependent || GetTeam()==HORDE)) { - int32 donerep2 = CalculateReputationGain(pVictim->getLevel(),Rep->repvalue2,false); + int32 donerep2 = CalculateReputationGain(pVictim->getLevel(), Rep->repvalue2, Rep->repfaction2, false); donerep2 = int32(donerep2*rate); FactionEntry const *factionEntry2 = sFactionStore.LookupEntry(Rep->repfaction2); uint32 current_reputation_rank2 = GetReputationMgr().GetRank(factionEntry2); @@ -5807,7 +5831,7 @@ void Player::RewardReputation(Quest const *pQuest) { if(pQuest->RewRepFaction[i] && pQuest->RewRepValue[i] ) { - int32 rep = CalculateReputationGain(GetQuestLevel(pQuest),pQuest->RewRepValue[i],true); + int32 rep = CalculateReputationGain(GetQuestLevel(pQuest), pQuest->RewRepValue[i], pQuest->RewRepFaction[i], true); FactionEntry const* factionEntry = sFactionStore.LookupEntry(pQuest->RewRepFaction[i]); if(factionEntry) GetReputationMgr().ModifyReputation(factionEntry, rep); @@ -6425,8 +6449,8 @@ void Player::_ApplyItemMods(Item *item, uint8 slot,bool apply) if(slot >= INVENTORY_SLOT_BAG_END || !item) return; - // not apply/remove mods for broken item - if(item->IsBroken()) + // not apply mods for broken item + if(item->IsBroken() && apply) return; ItemPrototype const *proto = item->GetProto(); @@ -6464,30 +6488,25 @@ void Player::_ApplyItemBonuses(ItemPrototype const *proto, uint8 slot, bool appl if(slot >= INVENTORY_SLOT_BAG_END || !proto) return; + ScalingStatDistributionEntry const *ssd = proto->ScalingStatDistribution ? sScalingStatDistributionStore.LookupEntry(proto->ScalingStatDistribution) : 0; + ScalingStatValuesEntry const *ssv = proto->ScalingStatValue ? sScalingStatValuesStore.LookupEntry(getLevel()) : 0; + for (int i = 0; i < MAX_ITEM_PROTO_STATS; ++i) { uint32 statType = 0; - int32 val = 0; - - if(proto->ScalingStatDistribution) + int32 val = 0; + // If set ScalingStatDistribution need get stats and values from it + if (ssd && ssv) { - if(ScalingStatDistributionEntry const *ssd = sScalingStatDistributionStore.LookupEntry(proto->ScalingStatDistribution)) - { - statType = ssd->StatMod[i]; - - if(uint32 modifier = ssd->Modifier[i]) - { - uint32 level = ((getLevel() > ssd->MaxLevel) ? ssd->MaxLevel : getLevel()); - if(ScalingStatValuesEntry const *ssv = sScalingStatValuesStore.LookupEntry(level)) - { - uint32 multiplier = ssv->Multiplier[proto->GetScalingStatValuesColumn()]; - val = (multiplier * modifier) / 10000; - } - } - } + if (ssd->StatMod[i] < 0) + continue; + statType = ssd->StatMod[i]; + val = (ssv->getssdMultiplier(proto->ScalingStatValue) * ssd->Modifier[i]) / 10000; } else { + if (i >= proto->StatsCount) + continue; statType = proto->ItemStat[i].ItemStatType; val = proto->ItemStat[i].ItemStatValue; } @@ -6642,8 +6661,18 @@ void Player::_ApplyItemBonuses(ItemPrototype const *proto, uint8 slot, bool appl } } - if (proto->Armor) - HandleStatModifier(UNIT_MOD_ARMOR, BASE_VALUE, float(proto->Armor), apply); + // If set ScalingStatValue armor get it or use item armor + uint32 armor = proto->Armor; + if (ssv) + { + if (uint32 ssvarmor = ssv->getArmorMod(proto->ScalingStatValue)) + armor = ssvarmor; + } + // Add armor bonus from ArmorDamageModifier if > 0 + if (proto->ArmorDamageModifier > 0) + armor+=proto->ArmorDamageModifier; + if (armor) + HandleStatModifier(UNIT_MOD_ARMOR, BASE_VALUE, float(armor), apply); if (proto->Block) HandleBaseModValue(SHIELD_BLOCK_VALUE, FLAT_MOD, float(proto->Block), apply); @@ -6680,23 +6709,42 @@ void Player::_ApplyItemBonuses(ItemPrototype const *proto, uint8 slot, bool appl attType = OFF_ATTACK; } - if (proto->Damage[0].DamageMin > 0 ) + float minDamage = proto->Damage[0].DamageMin; + float maxDamage = proto->Damage[0].DamageMax; + int32 extraDPS = 0; + // If set dpsMod in ScalingStatValue use it for min (70% from average), max (130% from average) damage + if (ssv) + { + if (extraDPS = ssv->getDPSMod(proto->ScalingStatValue)) + { + float average = extraDPS * proto->Delay / 1000.0f; + minDamage = 0.7f * average; + maxDamage = 1.3f * average; + } + } + if (minDamage > 0 ) { - damage = apply ? proto->Damage[0].DamageMin : BASE_MINDAMAGE; + damage = apply ? minDamage : BASE_MINDAMAGE; SetBaseWeaponDamage(attType, MINDAMAGE, damage); //sLog.outError("applying mindam: assigning %f to weapon mindamage, now is: %f", damage, GetWeaponDamageRange(attType, MINDAMAGE)); } - if (proto->Damage[0].DamageMax > 0 ) + if (maxDamage > 0 ) { - damage = apply ? proto->Damage[0].DamageMax : BASE_MAXDAMAGE; + damage = apply ? maxDamage : BASE_MAXDAMAGE; SetBaseWeaponDamage(attType, MAXDAMAGE, damage); } - // Druids get feral AP bonus from weapon dps + // Apply feral bonus from ScalingStatValue if set + if (ssv) + { + if (int32 feral_bonus = ssv->getFeralBonus(proto->ScalingStatValue)) + ApplyFeralAPBonus(feral_bonus, apply); + } + // Druids get feral AP bonus from weapon dps (lso use DPS from ScalingStatValue) if(getClass() == CLASS_DRUID) { - int32 feral_bonus = proto->getFeralBonus(); + int32 feral_bonus = proto->getFeralBonus(extraDPS); if (feral_bonus > 0) ApplyFeralAPBonus(feral_bonus, apply); } @@ -9825,18 +9873,22 @@ uint8 Player::CanEquipItem( uint8 slot, uint16 &dest, Item *pItem, bool swap, bo return EQUIP_ERR_CANT_DO_RIGHT_NOW; } + ScalingStatDistributionEntry const *ssd = pProto->ScalingStatDistribution ? sScalingStatDistributionStore.LookupEntry(pProto->ScalingStatDistribution) : 0; + if (ssd && ssd->MaxLevel < getLevel()) + return EQUIP_ERR_ITEM_CANT_BE_EQUIPPED; + uint8 eslot = FindEquipSlot( pProto, slot, swap ); - if( eslot == NULL_SLOT ) + if (eslot == NULL_SLOT) return EQUIP_ERR_ITEM_CANT_BE_EQUIPPED; - uint8 msg = CanUseItem( pItem , not_loading ); - if( msg != EQUIP_ERR_OK ) + uint8 msg = CanUseItem(pItem , not_loading); + if (msg != EQUIP_ERR_OK) return msg; - if( !swap && GetItemByPos( INVENTORY_SLOT_BAG_0, eslot ) ) + if (!swap && GetItemByPos(INVENTORY_SLOT_BAG_0, eslot)) return EQUIP_ERR_NO_EQUIPMENT_SLOT_AVAILABLE; // if swap ignore item (equipped also) - if(uint8 res2 = CanEquipUniqueItem(pItem, swap ? eslot : NULL_SLOT)) + if (uint8 res2 = CanEquipUniqueItem(pItem, swap ? eslot : NULL_SLOT)) return res2; // check unique-equipped special item classes @@ -9844,16 +9896,16 @@ uint8 Player::CanEquipItem( uint8 slot, uint16 &dest, Item *pItem, bool swap, bo { for(int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; ++i) { - if( Item* pBag = GetItemByPos( INVENTORY_SLOT_BAG_0, i ) ) + if (Item* pBag = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) { - if( ItemPrototype const* pBagProto = pBag->GetProto() ) + if (pBag != pItem) { - if( pBagProto->Class==pProto->Class && (!swap || pBag->GetSlot() != eslot ) ) + if (ItemPrototype const* pBagProto = pBag->GetProto()) { - if(pBagProto->SubClass == ITEM_SUBCLASS_AMMO_POUCH) - return EQUIP_ERR_CAN_EQUIP_ONLY1_AMMOPOUCH; - else - return EQUIP_ERR_CAN_EQUIP_ONLY1_QUIVER; + if (pBagProto->Class==pProto->Class && (!swap || pBag->GetSlot() != eslot)) + return (pBagProto->SubClass == ITEM_SUBCLASS_AMMO_POUCH) + ? EQUIP_ERR_CAN_EQUIP_ONLY1_AMMOPOUCH + : EQUIP_ERR_CAN_EQUIP_ONLY1_QUIVER; } } } @@ -9862,25 +9914,25 @@ uint8 Player::CanEquipItem( uint8 slot, uint16 &dest, Item *pItem, bool swap, bo uint32 type = pProto->InventoryType; - if(eslot == EQUIPMENT_SLOT_OFFHAND) + if (eslot == EQUIPMENT_SLOT_OFFHAND) { if (type == INVTYPE_WEAPON || type == INVTYPE_WEAPONOFFHAND) { - if(!CanDualWield()) + if (!CanDualWield()) return EQUIP_ERR_CANT_DUAL_WIELD; } else if (type == INVTYPE_2HWEAPON) { - if(!CanDualWield() || !CanTitanGrip()) + if (!CanDualWield() || !CanTitanGrip()) return EQUIP_ERR_CANT_DUAL_WIELD; } - if(IsTwoHandUsed()) + if (IsTwoHandUsed()) return EQUIP_ERR_CANT_EQUIP_WITH_TWOHANDED; } // equip two-hand weapon case (with possible unequip 2 items) - if( type == INVTYPE_2HWEAPON ) + if (type == INVTYPE_2HWEAPON) { if (eslot == EQUIPMENT_SLOT_OFFHAND) { @@ -9895,9 +9947,9 @@ uint8 Player::CanEquipItem( uint8 slot, uint16 &dest, Item *pItem, bool swap, bo // offhand item must can be stored in inventory for offhand item and it also must be unequipped Item *offItem = GetItemByPos( INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND ); ItemPosCountVec off_dest; - if( offItem && (!not_loading || + if (offItem && (!not_loading || CanUnequipItem(uint16(INVENTORY_SLOT_BAG_0) << 8 | EQUIPMENT_SLOT_OFFHAND,false) != EQUIP_ERR_OK || - CanStoreItem( NULL_BAG, NULL_SLOT, off_dest, offItem, false ) != EQUIP_ERR_OK ) ) + CanStoreItem( NULL_BAG, NULL_SLOT, off_dest, offItem, false ) != EQUIP_ERR_OK )) return swap ? EQUIP_ERR_ITEMS_CANT_BE_SWAPPED : EQUIP_ERR_INVENTORY_FULL; } } @@ -9905,10 +9957,8 @@ uint8 Player::CanEquipItem( uint8 slot, uint16 &dest, Item *pItem, bool swap, bo return EQUIP_ERR_OK; } } - if( !swap ) - return EQUIP_ERR_ITEM_NOT_FOUND; - else - return EQUIP_ERR_ITEMS_CANT_BE_SWAPPED; + + return !swap ? EQUIP_ERR_ITEM_NOT_FOUND : EQUIP_ERR_ITEMS_CANT_BE_SWAPPED; } uint8 Player::CanUnequipItem( uint16 pos, bool swap ) const @@ -10127,38 +10177,49 @@ uint8 Player::CanBankItem( uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *p uint8 Player::CanUseItem( Item *pItem, bool not_loading ) const { - if( pItem ) + if (pItem) { sLog.outDebug( "STORAGE: CanUseItem item = %u", pItem->GetEntry()); - if( !isAlive() && not_loading ) + + if (!isAlive() && not_loading) return EQUIP_ERR_YOU_ARE_DEAD; - //if( isStunned() ) + + //if (isStunned()) // return EQUIP_ERR_YOU_ARE_STUNNED; + ItemPrototype const *pProto = pItem->GetProto(); - if( pProto ) + if (pProto) { - if( pItem->IsBindedNotWith(GetGUID()) ) + if (pItem->IsBindedNotWith(GetGUID())) return EQUIP_ERR_DONT_OWN_THAT_ITEM; - if( (pProto->AllowableClass & getClassMask()) == 0 || (pProto->AllowableRace & getRaceMask()) == 0 ) + + if ((pProto->AllowableClass & getClassMask()) == 0 || (pProto->AllowableRace & getRaceMask()) == 0) return EQUIP_ERR_YOU_CAN_NEVER_USE_THAT_ITEM; - if( pItem->GetSkill() != 0 ) + + if (pItem->GetSkill() != 0) { - if( GetSkillValue( pItem->GetSkill() ) == 0 ) + if (GetSkillValue( pItem->GetSkill() ) == 0) return EQUIP_ERR_NO_REQUIRED_PROFICIENCY; } - if( pProto->RequiredSkill != 0 ) + + if (pProto->RequiredSkill != 0) { - if( GetSkillValue( pProto->RequiredSkill ) == 0 ) + if (GetSkillValue( pProto->RequiredSkill ) == 0) return EQUIP_ERR_NO_REQUIRED_PROFICIENCY; - else if( GetSkillValue( pProto->RequiredSkill ) < pProto->RequiredSkillRank ) + + if (GetSkillValue( pProto->RequiredSkill ) < pProto->RequiredSkillRank) return EQUIP_ERR_ERR_CANT_EQUIP_SKILL; } - if( pProto->RequiredSpell != 0 && !HasSpell( pProto->RequiredSpell ) ) + + if (pProto->RequiredSpell != 0 && !HasSpell(pProto->RequiredSpell)) return EQUIP_ERR_NO_REQUIRED_PROFICIENCY; - if( pProto->RequiredReputationFaction && uint32(GetReputationRank(pProto->RequiredReputationFaction)) < pProto->RequiredReputationRank ) + + if (pProto->RequiredReputationFaction && uint32(GetReputationRank(pProto->RequiredReputationFaction)) < pProto->RequiredReputationRank) return EQUIP_ERR_CANT_EQUIP_REPUTATION; - if( getLevel() < pProto->RequiredLevel ) + + if (getLevel() < pProto->RequiredLevel) return EQUIP_ERR_CANT_EQUIP_LEVEL_I; + return EQUIP_ERR_OK; } } @@ -16712,7 +16773,7 @@ void Player::PetSpellInitialize() uint8 addlist = 0; data << uint8(addlist); // placeholder - if(pet->isControlled() && ((pet->getPetType() == HUNTER_PET) || ((pet->GetCreatureInfo()->type == CREATURE_TYPE_DEMON) && (getClass() == CLASS_WARLOCK)))) + if (pet->IsPermanentPetFor(this)) { // spells loop for (PetSpellMap::iterator itr = pet->m_spells.begin(); itr != pet->m_spells.end(); ++itr) @@ -17114,43 +17175,68 @@ void Player::HandleStealthedUnitsDetection() } } -bool Player::ActivateTaxiPathTo(std::vector<uint32> const& nodes, uint32 mount_id, Creature* npc) +bool Player::ActivateTaxiPathTo(std::vector<uint32> const& nodes, Creature* npc /*= NULL*/, uint32 spellid /*= 0*/) { if(nodes.size() < 2) return false; - // not let cheating with start flight mounted - if(IsMounted()) + // not let cheating with start flight in time of logout process || if casting not finished || while in combat || if not use Spell's with EffectSendTaxi + if(GetSession()->isLogingOut() || isInCombat()) { WorldPacket data(SMSG_ACTIVATETAXIREPLY, 4); - data << uint32(ERR_TAXIPLAYERALREADYMOUNTED); + data << uint32(ERR_TAXIPLAYERBUSY); GetSession()->SendPacket(&data); return false; } - if( m_ShapeShiftFormSpellId && m_form != FORM_BATTLESTANCE && m_form != FORM_BERSERKERSTANCE && m_form != FORM_DEFENSIVESTANCE && m_form != FORM_SHADOW ) - { - WorldPacket data(SMSG_ACTIVATETAXIREPLY, 4); - data << uint32(ERR_TAXIPLAYERSHAPESHIFTED); - GetSession()->SendPacket(&data); + if(HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE)) return false; - } - // not let cheating with start flight in time of logout process || if casting not finished || while in combat || if not use Spell's with EffectSendTaxi - if(GetSession()->isLogingOut() || - (!m_currentSpells[CURRENT_GENERIC_SPELL] || - m_currentSpells[CURRENT_GENERIC_SPELL]->m_spellInfo->Effect[0] != SPELL_EFFECT_SEND_TAXI)&& - IsNonMeleeSpellCasted(false) || - isInCombat()) + // taximaster case + if(npc) { - WorldPacket data(SMSG_ACTIVATETAXIREPLY, 4); - data << uint32(ERR_TAXIPLAYERBUSY); - GetSession()->SendPacket(&data); - return false; + // not let cheating with start flight mounted + if(IsMounted()) + { + WorldPacket data(SMSG_ACTIVATETAXIREPLY, 4); + data << uint32(ERR_TAXIPLAYERALREADYMOUNTED); + GetSession()->SendPacket(&data); + return false; + } + + if( m_ShapeShiftFormSpellId && m_form != FORM_BATTLESTANCE && m_form != FORM_BERSERKERSTANCE && m_form != FORM_DEFENSIVESTANCE && m_form != FORM_SHADOW ) + { + WorldPacket data(SMSG_ACTIVATETAXIREPLY, 4); + data << uint32(ERR_TAXIPLAYERSHAPESHIFTED); + GetSession()->SendPacket(&data); + return false; + } + + // not let cheating with start flight in time of logout process || if casting not finished || while in combat || if not use Spell's with EffectSendTaxi + if(IsNonMeleeSpellCasted(false)) + { + WorldPacket data(SMSG_ACTIVATETAXIREPLY, 4); + data << uint32(ERR_TAXIPLAYERBUSY); + GetSession()->SendPacket(&data); + return false; + } } + // cast case or scripted call case + else + { + RemoveAurasByType(SPELL_AURA_MOUNTED); - if(HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE)) - return false; + if( m_ShapeShiftFormSpellId && m_form != FORM_BATTLESTANCE && m_form != FORM_BERSERKERSTANCE && m_form != FORM_DEFENSIVESTANCE && m_form != FORM_SHADOW ) + RemoveAurasDueToSpell(m_ShapeShiftFormSpellId); + + if(m_currentSpells[CURRENT_GENERIC_SPELL] && m_currentSpells[CURRENT_GENERIC_SPELL]->m_spellInfo->Id != spellid) + InterruptSpell(CURRENT_GENERIC_SPELL,false); + + InterruptSpell(CURRENT_AUTOREPEAT_SPELL,false); + + if(m_currentSpells[CURRENT_CHANNELED_SPELL] && m_currentSpells[CURRENT_CHANNELED_SPELL]->m_spellInfo->Id != spellid) + InterruptSpell(CURRENT_CHANNELED_SPELL,true); + } uint32 sourcenode = nodes[0]; @@ -17179,8 +17265,8 @@ bool Player::ActivateTaxiPathTo(std::vector<uint32> const& nodes, uint32 mount_i return false; } } - // node must have pos if not spell case (npc!=0) - else if(npc) + // node must have pos if taxi master case (npc != NULL) + else if (npc) { WorldPacket data(SMSG_ACTIVATETAXIREPLY, 4); data << uint32(ERR_TAXIUNSPECIFIEDSERVERERROR); @@ -17232,10 +17318,11 @@ bool Player::ActivateTaxiPathTo(std::vector<uint32> const& nodes, uint32 mount_i prevnode = lastnode; } - if(!mount_id) // if not provide then attempt use default. - mount_id = objmgr.GetTaxiMount(sourcenode, GetTeam()); + // get mount model (in case non taximaster (npc==NULL) allow more wide lookup) + uint16 mount_id = objmgr.GetTaxiMount(sourcenode, GetTeam(), npc == NULL); - if (mount_id == 0 || sourcepath == 0) + // in spell case allow 0 model + if (mount_id == 0 && spellid == 0 || sourcepath == 0) { WorldPacket data(SMSG_ACTIVATETAXIREPLY, 4); data << uint32(ERR_TAXIUNSPECIFIEDSERVERERROR); @@ -17277,6 +17364,21 @@ bool Player::ActivateTaxiPathTo(std::vector<uint32> const& nodes, uint32 mount_i return true; } +bool Player::ActivateTaxiPathTo( uint32 taxi_path_id, uint32 spellid /*= 0*/ ) +{ + TaxiPathEntry const* entry = sTaxiPathStore.LookupEntry(taxi_path_id); + if(!entry) + return false; + + std::vector<uint32> nodes; + + nodes.resize(2); + nodes[0] = entry->from; + nodes[1] = entry->to; + + return ActivateTaxiPathTo(nodes,NULL,spellid); +} + void Player::ProhibitSpellScholl(SpellSchoolMask idSchoolMask, uint32 unTimeMs ) { // last check 2.0.10 @@ -20509,12 +20611,14 @@ void Player::ResummonPetTemporaryUnSummonedIfAny() bool Player::canSeeSpellClickOn(Creature const *c) const { - SpellClickInfoMap const& map = objmgr.mSpellClickInfoMap; - if(map.empty()) + SpellClickInfoMap::const_iterator lower = objmgr.mSpellClickInfoMap.lower_bound(c->GetEntry()); + SpellClickInfoMap::const_iterator upper = objmgr.mSpellClickInfoMap.upper_bound(c->GetEntry()); + if(lower == upper) return true; - for(SpellClickInfoMap::const_iterator itr = map.lower_bound(c->GetEntry()); itr != map.upper_bound(c->GetEntry()); ++itr) + for(SpellClickInfoMap::const_iterator itr = lower; itr != upper; ++itr) { + sLog.outError("%u %u %u %u", (uint32)itr->second.castFlags, itr->second.questId, itr->second.spellId); if(itr->second.questId == 0 || GetQuestStatus(itr->second.questId) == QUEST_STATUS_INCOMPLETE) return true; } |