aboutsummaryrefslogtreecommitdiff
path: root/src/game/Player.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/game/Player.cpp')
-rw-r--r--src/game/Player.cpp322
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;
}