mirror of
https://github.com/mangosfour/server.git
synced 2025-12-15 01:37:00 +00:00
Merge remote branch 'origin/master' into 330
Conflicts: src/game/Unit.cpp
This commit is contained in:
commit
e73c5d3b79
177 changed files with 24212 additions and 2127 deletions
|
|
@ -42,7 +42,7 @@
|
|||
#include "CellImpl.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "ObjectDefines.h"
|
||||
#include "ObjectGuid.h"
|
||||
#include "CreatureAI.h"
|
||||
#include "Formulas.h"
|
||||
#include "Group.h"
|
||||
|
|
@ -515,9 +515,6 @@ Player::~Player ()
|
|||
}
|
||||
CleanupChannels();
|
||||
|
||||
for (PlayerSpellMap::const_iterator itr = m_spells.begin(); itr != m_spells.end(); ++itr)
|
||||
delete itr->second;
|
||||
|
||||
//all mailed items should be deleted, also all mail should be deallocated
|
||||
for (PlayerMails::const_iterator itr = m_mail.begin(); itr != m_mail.end();++itr)
|
||||
delete *itr;
|
||||
|
|
@ -2050,10 +2047,18 @@ void Player::Regenerate(Powers power, uint32 diff)
|
|||
if (getClass() != CLASS_DEATH_KNIGHT)
|
||||
break;
|
||||
|
||||
for(uint32 i = 0; i < MAX_RUNES; ++i)
|
||||
for(uint32 rune = 0; rune < MAX_RUNES; ++rune)
|
||||
{
|
||||
if(uint16 cd = GetRuneCooldown(i)) // if we have cooldown, reduce it...
|
||||
SetRuneCooldown(i, (cd < diff) ? 0 : cd - diff);
|
||||
if(uint16 cd = GetRuneCooldown(rune)) // if we have cooldown, reduce it...
|
||||
{
|
||||
uint32 cd_diff = diff;
|
||||
AuraList const& ModPowerRegenPCTAuras = GetAurasByType(SPELL_AURA_MOD_POWER_REGEN_PERCENT);
|
||||
for(AuraList::const_iterator i = ModPowerRegenPCTAuras.begin(); i != ModPowerRegenPCTAuras.end(); ++i)
|
||||
if ((*i)->GetModifier()->m_miscvalue == power && (*i)->GetMiscBValue()==GetCurrentRune(rune))
|
||||
cd_diff = cd_diff * ((*i)->GetModifier()->m_amount + 100) / 100.0f;
|
||||
|
||||
SetRuneCooldown(rune, (cd < cd_diff) ? 0 : cd - cd_diff);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case POWER_FOCUS:
|
||||
|
|
@ -2735,10 +2740,10 @@ void Player::SendInitialSpells()
|
|||
|
||||
for (PlayerSpellMap::const_iterator itr = m_spells.begin(); itr != m_spells.end(); ++itr)
|
||||
{
|
||||
if(itr->second->state == PLAYERSPELL_REMOVED)
|
||||
if(itr->second.state == PLAYERSPELL_REMOVED)
|
||||
continue;
|
||||
|
||||
if(!itr->second->active || itr->second->disabled)
|
||||
if(!itr->second.active || itr->second.disabled)
|
||||
continue;
|
||||
|
||||
data << uint32(itr->first);
|
||||
|
|
@ -2917,33 +2922,33 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
|
|||
}
|
||||
|
||||
// not do anything if already known in expected state
|
||||
if(itr->second->state != PLAYERSPELL_REMOVED && itr->second->active == active &&
|
||||
itr->second->dependent == dependent && itr->second->disabled == disabled)
|
||||
if(itr->second.state != PLAYERSPELL_REMOVED && itr->second.active == active &&
|
||||
itr->second.dependent == dependent && itr->second.disabled == disabled)
|
||||
{
|
||||
if(!IsInWorld() && !learning) // explicitly load from DB and then exist in it already and set correctly
|
||||
itr->second->state = PLAYERSPELL_UNCHANGED;
|
||||
itr->second.state = PLAYERSPELL_UNCHANGED;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// dependent spell known as not dependent, overwrite state
|
||||
if (itr->second->state != PLAYERSPELL_REMOVED && !itr->second->dependent && dependent)
|
||||
if (itr->second.state != PLAYERSPELL_REMOVED && !itr->second.dependent && dependent)
|
||||
{
|
||||
itr->second->dependent = dependent;
|
||||
if (itr->second->state != PLAYERSPELL_NEW)
|
||||
itr->second->state = PLAYERSPELL_CHANGED;
|
||||
itr->second.dependent = dependent;
|
||||
if (itr->second.state != PLAYERSPELL_NEW)
|
||||
itr->second.state = PLAYERSPELL_CHANGED;
|
||||
dependent_set = true;
|
||||
}
|
||||
|
||||
// update active state for known spell
|
||||
if(itr->second->active != active && itr->second->state != PLAYERSPELL_REMOVED && !itr->second->disabled)
|
||||
if(itr->second.active != active && itr->second.state != PLAYERSPELL_REMOVED && !itr->second.disabled)
|
||||
{
|
||||
itr->second->active = active;
|
||||
itr->second.active = active;
|
||||
|
||||
if(!IsInWorld() && !learning && !dependent_set) // explicitly load from DB and then exist in it already and set correctly
|
||||
itr->second->state = PLAYERSPELL_UNCHANGED;
|
||||
else if(itr->second->state != PLAYERSPELL_NEW)
|
||||
itr->second->state = PLAYERSPELL_CHANGED;
|
||||
itr->second.state = PLAYERSPELL_UNCHANGED;
|
||||
else if(itr->second.state != PLAYERSPELL_NEW)
|
||||
itr->second.state = PLAYERSPELL_CHANGED;
|
||||
|
||||
if(active)
|
||||
{
|
||||
|
|
@ -2971,24 +2976,23 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
|
|||
return active; // learn (show in spell book if active now)
|
||||
}
|
||||
|
||||
if(itr->second->disabled != disabled && itr->second->state != PLAYERSPELL_REMOVED)
|
||||
if(itr->second.disabled != disabled && itr->second.state != PLAYERSPELL_REMOVED)
|
||||
{
|
||||
if(itr->second->state != PLAYERSPELL_NEW)
|
||||
itr->second->state = PLAYERSPELL_CHANGED;
|
||||
itr->second->disabled = disabled;
|
||||
if(itr->second.state != PLAYERSPELL_NEW)
|
||||
itr->second.state = PLAYERSPELL_CHANGED;
|
||||
itr->second.disabled = disabled;
|
||||
|
||||
if(disabled)
|
||||
return false;
|
||||
|
||||
disabled_case = true;
|
||||
}
|
||||
else switch(itr->second->state)
|
||||
else switch(itr->second.state)
|
||||
{
|
||||
case PLAYERSPELL_UNCHANGED: // known saved spell
|
||||
return false;
|
||||
case PLAYERSPELL_REMOVED: // re-learning removed not saved spell
|
||||
{
|
||||
delete itr->second;
|
||||
m_spells.erase(itr);
|
||||
state = PLAYERSPELL_CHANGED;
|
||||
break; // need re-add
|
||||
|
|
@ -2997,7 +3001,7 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
|
|||
{
|
||||
// can be in case spell loading but learned at some previous spell loading
|
||||
if(!IsInWorld() && !learning && !dependent_set)
|
||||
itr->second->state = PLAYERSPELL_UNCHANGED;
|
||||
itr->second.state = PLAYERSPELL_UNCHANGED;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
@ -3031,24 +3035,24 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
|
|||
learnSpell(prev_spell,true);
|
||||
}
|
||||
|
||||
PlayerSpell *newspell = new PlayerSpell;
|
||||
newspell->state = state;
|
||||
newspell->active = active;
|
||||
newspell->dependent = dependent;
|
||||
newspell->disabled = disabled;
|
||||
PlayerSpell newspell;
|
||||
newspell.state = state;
|
||||
newspell.active = active;
|
||||
newspell.dependent = dependent;
|
||||
newspell.disabled = disabled;
|
||||
|
||||
// replace spells in action bars and spellbook to bigger rank if only one spell rank must be accessible
|
||||
if(newspell->active && !newspell->disabled && !SpellMgr::canStackSpellRanks(spellInfo) && sSpellMgr.GetSpellRank(spellInfo->Id) != 0)
|
||||
if(newspell.active && !newspell.disabled && !SpellMgr::canStackSpellRanks(spellInfo) && sSpellMgr.GetSpellRank(spellInfo->Id) != 0)
|
||||
{
|
||||
for( PlayerSpellMap::iterator itr2 = m_spells.begin(); itr2 != m_spells.end(); ++itr2 )
|
||||
{
|
||||
if(itr2->second->state == PLAYERSPELL_REMOVED) continue;
|
||||
if(itr2->second.state == PLAYERSPELL_REMOVED) continue;
|
||||
SpellEntry const *i_spellInfo = sSpellStore.LookupEntry(itr2->first);
|
||||
if(!i_spellInfo) continue;
|
||||
|
||||
if( sSpellMgr.IsRankSpellDueToSpell(spellInfo,itr2->first) )
|
||||
{
|
||||
if(itr2->second->active)
|
||||
if(itr2->second.active)
|
||||
{
|
||||
if(sSpellMgr.IsHighRankOfSpell(spell_id,itr2->first))
|
||||
{
|
||||
|
|
@ -3061,9 +3065,9 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
|
|||
}
|
||||
|
||||
// mark old spell as disable (SMSG_SUPERCEDED_SPELL replace it in client by new)
|
||||
itr2->second->active = false;
|
||||
if(itr2->second->state != PLAYERSPELL_NEW)
|
||||
itr2->second->state = PLAYERSPELL_CHANGED;
|
||||
itr2->second.active = false;
|
||||
if(itr2->second.state != PLAYERSPELL_NEW)
|
||||
itr2->second.state = PLAYERSPELL_CHANGED;
|
||||
superceded_old = true; // new spell replace old in action bars and spell book.
|
||||
}
|
||||
else if(sSpellMgr.IsHighRankOfSpell(itr2->first,spell_id))
|
||||
|
|
@ -3077,9 +3081,9 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
|
|||
}
|
||||
|
||||
// mark new spell as disable (not learned yet for client and will not learned)
|
||||
newspell->active = false;
|
||||
if(newspell->state != PLAYERSPELL_NEW)
|
||||
newspell->state = PLAYERSPELL_CHANGED;
|
||||
newspell.active = false;
|
||||
if(newspell.state != PLAYERSPELL_NEW)
|
||||
newspell.state = PLAYERSPELL_CHANGED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3089,7 +3093,7 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
|
|||
m_spells[spell_id] = newspell;
|
||||
|
||||
// return false if spell disabled
|
||||
if (newspell->disabled)
|
||||
if (newspell.disabled)
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -3224,8 +3228,8 @@ void Player::learnSpell(uint32 spell_id, bool dependent)
|
|||
{
|
||||
PlayerSpellMap::iterator itr = m_spells.find(spell_id);
|
||||
|
||||
bool disabled = (itr != m_spells.end()) ? itr->second->disabled : false;
|
||||
bool active = disabled ? itr->second->active : true;
|
||||
bool disabled = (itr != m_spells.end()) ? itr->second.disabled : false;
|
||||
bool active = disabled ? itr->second.active : true;
|
||||
|
||||
bool learning = addSpell(spell_id,active,true,dependent,false);
|
||||
|
||||
|
|
@ -3236,7 +3240,7 @@ void Player::learnSpell(uint32 spell_id, bool dependent)
|
|||
for(SpellChainMapNext::const_iterator i = nextMap.lower_bound(spell_id); i != nextMap.upper_bound(spell_id); ++i)
|
||||
{
|
||||
PlayerSpellMap::iterator iter = m_spells.find(i->second);
|
||||
if (iter != m_spells.end() && iter->second->disabled)
|
||||
if (iter != m_spells.end() && iter->second.disabled)
|
||||
learnSpell(i->second,false);
|
||||
}
|
||||
}
|
||||
|
|
@ -3256,7 +3260,7 @@ void Player::removeSpell(uint32 spell_id, bool disabled, bool learn_low_rank, bo
|
|||
if (itr == m_spells.end())
|
||||
return;
|
||||
|
||||
if (itr->second->state == PLAYERSPELL_REMOVED || (disabled && itr->second->disabled))
|
||||
if (itr->second.state == PLAYERSPELL_REMOVED || (disabled && itr->second.disabled))
|
||||
return;
|
||||
|
||||
// unlearn non talent higher ranks (recursive)
|
||||
|
|
@ -3270,24 +3274,21 @@ void Player::removeSpell(uint32 spell_id, bool disabled, bool learn_low_rank, bo
|
|||
if (itr == m_spells.end())
|
||||
return; // already unleared
|
||||
|
||||
bool cur_active = itr->second->active;
|
||||
bool cur_dependent = itr->second->dependent;
|
||||
bool cur_active = itr->second.active;
|
||||
bool cur_dependent = itr->second.dependent;
|
||||
|
||||
if (disabled)
|
||||
{
|
||||
itr->second->disabled = disabled;
|
||||
if(itr->second->state != PLAYERSPELL_NEW)
|
||||
itr->second->state = PLAYERSPELL_CHANGED;
|
||||
itr->second.disabled = disabled;
|
||||
if(itr->second.state != PLAYERSPELL_NEW)
|
||||
itr->second.state = PLAYERSPELL_CHANGED;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(itr->second->state == PLAYERSPELL_NEW)
|
||||
{
|
||||
delete itr->second;
|
||||
if(itr->second.state == PLAYERSPELL_NEW)
|
||||
m_spells.erase(itr);
|
||||
}
|
||||
else
|
||||
itr->second->state = PLAYERSPELL_REMOVED;
|
||||
itr->second.state = PLAYERSPELL_REMOVED;
|
||||
}
|
||||
|
||||
RemoveAurasDueToSpell(spell_id);
|
||||
|
|
@ -3404,17 +3405,17 @@ void Player::removeSpell(uint32 spell_id, bool disabled, bool learn_low_rank, bo
|
|||
PlayerSpellMap::iterator prev_itr = m_spells.find(prev_id);
|
||||
if (prev_itr != m_spells.end())
|
||||
{
|
||||
if (prev_itr->second->dependent != cur_dependent)
|
||||
if (prev_itr->second.dependent != cur_dependent)
|
||||
{
|
||||
prev_itr->second->dependent = cur_dependent;
|
||||
if (prev_itr->second->state != PLAYERSPELL_NEW)
|
||||
prev_itr->second->state = PLAYERSPELL_CHANGED;
|
||||
prev_itr->second.dependent = cur_dependent;
|
||||
if (prev_itr->second.state != PLAYERSPELL_NEW)
|
||||
prev_itr->second.state = PLAYERSPELL_CHANGED;
|
||||
}
|
||||
|
||||
// now re-learn if need re-activate
|
||||
if (cur_active && !prev_itr->second->active && learn_low_rank)
|
||||
if (cur_active && !prev_itr->second.active && learn_low_rank)
|
||||
{
|
||||
if (addSpell(prev_id,true,false,prev_itr->second->dependent,prev_itr->second->disabled))
|
||||
if (addSpell(prev_id,true,false,prev_itr->second.dependent,prev_itr->second.disabled))
|
||||
{
|
||||
// downgrade spell ranks in spellbook and action bar
|
||||
WorldPacket data(SMSG_SUPERCEDED_SPELL, 4 + 4);
|
||||
|
|
@ -3650,7 +3651,7 @@ bool Player::resetTalents(bool no_cost)
|
|||
{
|
||||
for(PlayerSpellMap::iterator itr = GetSpellMap().begin(); itr != GetSpellMap().end();)
|
||||
{
|
||||
if(itr->second->state == PLAYERSPELL_REMOVED || itr->second->disabled)
|
||||
if(itr->second.state == PLAYERSPELL_REMOVED || itr->second.disabled)
|
||||
{
|
||||
++itr;
|
||||
continue;
|
||||
|
|
@ -3906,15 +3907,15 @@ void Player::DestroyForPlayer( Player *target, bool anim ) const
|
|||
bool Player::HasSpell(uint32 spell) const
|
||||
{
|
||||
PlayerSpellMap::const_iterator itr = m_spells.find(spell);
|
||||
return (itr != m_spells.end() && itr->second->state != PLAYERSPELL_REMOVED &&
|
||||
!itr->second->disabled);
|
||||
return (itr != m_spells.end() && itr->second.state != PLAYERSPELL_REMOVED &&
|
||||
!itr->second.disabled);
|
||||
}
|
||||
|
||||
bool Player::HasActiveSpell(uint32 spell) const
|
||||
{
|
||||
PlayerSpellMap::const_iterator itr = m_spells.find(spell);
|
||||
return (itr != m_spells.end() && itr->second->state != PLAYERSPELL_REMOVED &&
|
||||
itr->second->active && !itr->second->disabled);
|
||||
return (itr != m_spells.end() && itr->second.state != PLAYERSPELL_REMOVED &&
|
||||
itr->second.active && !itr->second.disabled);
|
||||
}
|
||||
|
||||
TrainerSpellState Player::GetTrainerSpellState(TrainerSpell const* trainer_spell) const
|
||||
|
|
@ -4147,7 +4148,7 @@ void Player::SetMovement(PlayerMovementType pType)
|
|||
sLog.outError("Player::SetMovement: Unsupported move type (%d), data not sent to client.",pType);
|
||||
return;
|
||||
}
|
||||
data.append(GetPackGUID());
|
||||
data << GetPackGUID();
|
||||
data << uint32(0);
|
||||
GetSession()->SendPacket( &data );
|
||||
}
|
||||
|
|
@ -4159,7 +4160,7 @@ void Player::SetMovement(PlayerMovementType pType)
|
|||
void Player::BuildPlayerRepop()
|
||||
{
|
||||
WorldPacket data(SMSG_PRE_RESURRECT, GetPackGUID().size());
|
||||
data.append(GetPackGUID());
|
||||
data << GetPackGUID();
|
||||
GetSession()->SendPacket(&data);
|
||||
|
||||
if(getRace() == RACE_NIGHTELF)
|
||||
|
|
@ -7263,10 +7264,10 @@ void Player::CastItemUseSpell(Item *item,SpellCastTargets const& targets,uint8 c
|
|||
uint32 learning_spell_id = proto->Spells[1].SpellId;
|
||||
|
||||
SpellEntry const *spellInfo = sSpellStore.LookupEntry(learn_spell_id);
|
||||
if(!spellInfo)
|
||||
if (!spellInfo)
|
||||
{
|
||||
sLog.outError("Player::CastItemUseSpell: Item (Entry: %u) in have wrong spell id %u, ignoring ",proto->ItemId, learn_spell_id);
|
||||
SendEquipError(EQUIP_ERR_NONE,item,NULL);
|
||||
SendEquipError(EQUIP_ERR_NONE, item);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -8614,6 +8615,75 @@ uint32 Player::GetItemCount( uint32 item, bool inBankAlso, Item* skipItem ) cons
|
|||
return count;
|
||||
}
|
||||
|
||||
uint32 Player::GetItemCountWithLimitCategory( uint32 limitCategory ) const
|
||||
{
|
||||
uint32 count = 0;
|
||||
for(int i = EQUIPMENT_SLOT_START; i < INVENTORY_SLOT_ITEM_END; ++i)
|
||||
if (Item *pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i))
|
||||
if (pItem->GetProto()->ItemLimitCategory == limitCategory)
|
||||
count += pItem->GetCount();
|
||||
|
||||
for(int i = KEYRING_SLOT_START; i < CURRENCYTOKEN_SLOT_END; ++i)
|
||||
if (Item *pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i))
|
||||
if (pItem->GetProto()->ItemLimitCategory == limitCategory)
|
||||
count += pItem->GetCount();
|
||||
|
||||
for(int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; ++i)
|
||||
if (Bag* pBag = (Bag*)GetItemByPos(INVENTORY_SLOT_BAG_0, i))
|
||||
count += pBag->GetItemCountWithLimitCategory(limitCategory);
|
||||
|
||||
for(int i = BANK_SLOT_ITEM_START; i < BANK_SLOT_ITEM_END; ++i)
|
||||
if (Item *pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i))
|
||||
if (pItem->GetProto()->ItemLimitCategory == limitCategory)
|
||||
count += pItem->GetCount();
|
||||
|
||||
for(int i = BANK_SLOT_BAG_START; i < BANK_SLOT_BAG_END; ++i)
|
||||
if (Bag* pBag = (Bag*)GetItemByPos(INVENTORY_SLOT_BAG_0, i))
|
||||
count += pBag->GetItemCountWithLimitCategory(limitCategory);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
Item* Player::GetItemByEntry( uint32 item ) const
|
||||
{
|
||||
for(int i = EQUIPMENT_SLOT_START; i < INVENTORY_SLOT_ITEM_END; ++i)
|
||||
if (Item *pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i))
|
||||
if (pItem->GetEntry() == item)
|
||||
return pItem;
|
||||
|
||||
for(int i = KEYRING_SLOT_START; i < CURRENCYTOKEN_SLOT_END; ++i)
|
||||
if (Item *pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i))
|
||||
if (pItem->GetEntry() == item)
|
||||
return pItem;
|
||||
|
||||
for(int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; ++i)
|
||||
if (Bag* pBag = (Bag*)GetItemByPos( INVENTORY_SLOT_BAG_0, i))
|
||||
if (Item* itemPtr = pBag->GetItemByEntry(item))
|
||||
return itemPtr;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Item* Player::GetItemByLimitedCategory(uint32 limitedCategory) const
|
||||
{
|
||||
for(int i = EQUIPMENT_SLOT_START; i < INVENTORY_SLOT_ITEM_END; ++i)
|
||||
if (Item *pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i))
|
||||
if (pItem->GetProto()->ItemLimitCategory == limitedCategory)
|
||||
return pItem;
|
||||
|
||||
for(int i = KEYRING_SLOT_START; i < CURRENCYTOKEN_SLOT_END; ++i)
|
||||
if (Item *pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i))
|
||||
if (pItem->GetProto()->ItemLimitCategory == limitedCategory)
|
||||
return pItem;
|
||||
|
||||
for(int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; ++i)
|
||||
if (Bag* pBag = (Bag*)GetItemByPos( INVENTORY_SLOT_BAG_0, i))
|
||||
if (Item* itemPtr = pBag->GetItemByLimitedCategory(limitedCategory))
|
||||
return itemPtr;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Item* Player::GetItemByGuid( uint64 guid ) const
|
||||
{
|
||||
for(int i = EQUIPMENT_SLOT_START; i < INVENTORY_SLOT_ITEM_END; ++i)
|
||||
|
|
@ -8774,7 +8844,7 @@ bool Player::IsBagPos( uint16 pos )
|
|||
return false;
|
||||
}
|
||||
|
||||
bool Player::IsValidPos( uint8 bag, uint8 slot, bool explicit_pos )
|
||||
bool Player::IsValidPos( uint8 bag, uint8 slot, bool explicit_pos ) const
|
||||
{
|
||||
// post selected
|
||||
if(bag == NULL_BAG && !explicit_pos)
|
||||
|
|
@ -9002,16 +9072,40 @@ uint8 Player::_CanTakeMoreSimilarItems(uint32 entry, uint32 count, Item* pItem,
|
|||
}
|
||||
|
||||
// no maximum
|
||||
if(pProto->MaxCount <= 0)
|
||||
return EQUIP_ERR_OK;
|
||||
|
||||
uint32 curcount = GetItemCount(pProto->ItemId,true,pItem);
|
||||
|
||||
if (curcount + count > uint32(pProto->MaxCount))
|
||||
if(pProto->MaxCount > 0)
|
||||
{
|
||||
if(no_space_count)
|
||||
*no_space_count = count +curcount - pProto->MaxCount;
|
||||
return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS;
|
||||
uint32 curcount = GetItemCount(pProto->ItemId,true,pItem);
|
||||
|
||||
if (curcount + count > uint32(pProto->MaxCount))
|
||||
{
|
||||
if(no_space_count)
|
||||
*no_space_count = count +curcount - pProto->MaxCount;
|
||||
return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS;
|
||||
}
|
||||
}
|
||||
|
||||
// check unique-equipped limit
|
||||
if (pProto->ItemLimitCategory)
|
||||
{
|
||||
ItemLimitCategoryEntry const* limitEntry = sItemLimitCategoryStore.LookupEntry(pProto->ItemLimitCategory);
|
||||
if (!limitEntry)
|
||||
{
|
||||
if(no_space_count)
|
||||
*no_space_count = count;
|
||||
return EQUIP_ERR_ITEM_CANT_BE_EQUIPPED;
|
||||
}
|
||||
|
||||
if (limitEntry->mode == ITEM_LIMIT_CATEGORY_MODE_HAVE)
|
||||
{
|
||||
uint32 curcount = GetItemCountWithLimitCategory(pProto->ItemLimitCategory);
|
||||
|
||||
if (curcount + count > uint32(limitEntry->maxCount))
|
||||
{
|
||||
if(no_space_count)
|
||||
*no_space_count = count + curcount - limitEntry->maxCount;
|
||||
return EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_COUNT_EXCEEDED_IS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return EQUIP_ERR_OK;
|
||||
|
|
@ -10450,12 +10544,12 @@ void Player::SetAmmo( uint32 item )
|
|||
return;
|
||||
|
||||
// check ammo
|
||||
if(item)
|
||||
if (item)
|
||||
{
|
||||
uint8 msg = CanUseAmmo( item );
|
||||
if( msg != EQUIP_ERR_OK )
|
||||
if (msg != EQUIP_ERR_OK)
|
||||
{
|
||||
SendEquipError( msg, NULL, NULL );
|
||||
SendEquipError(msg, NULL, NULL, item);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -10471,7 +10565,7 @@ void Player::RemoveAmmo()
|
|||
|
||||
m_ammoDPS = 0.0f;
|
||||
|
||||
if(CanModifyStats())
|
||||
if (CanModifyStats())
|
||||
UpdateDamagePhysical(RANGED_ATTACK);
|
||||
}
|
||||
|
||||
|
|
@ -11695,7 +11789,7 @@ void Player::RemoveItemFromBuyBackSlot( uint32 slot, bool del )
|
|||
}
|
||||
}
|
||||
|
||||
void Player::SendEquipError( uint8 msg, Item* pItem, Item *pItem2 )
|
||||
void Player::SendEquipError( uint8 msg, Item* pItem, Item *pItem2, uint32 itemid /*= 0*/ )
|
||||
{
|
||||
sLog.outDebug( "WORLD: Sent SMSG_INVENTORY_CHANGE_FAILURE (%u)", msg);
|
||||
WorldPacket data(SMSG_INVENTORY_CHANGE_FAILURE, 1+8+8+1);
|
||||
|
|
@ -11711,25 +11805,28 @@ void Player::SendEquipError( uint8 msg, Item* pItem, Item *pItem2 )
|
|||
{
|
||||
case EQUIP_ERR_CANT_EQUIP_LEVEL_I:
|
||||
case EQUIP_ERR_PURCHASE_LEVEL_TOO_LOW:
|
||||
{
|
||||
ItemPrototype const* proto = pItem ? pItem->GetProto() : NULL;
|
||||
data << uint32(proto ? proto->RequiredLevel : 0);
|
||||
} break;
|
||||
{
|
||||
ItemPrototype const* proto = pItem ? pItem->GetProto() : sObjectMgr.GetItemPrototype(itemid);
|
||||
data << uint32(proto ? proto->RequiredLevel : 0);
|
||||
break;
|
||||
}
|
||||
case EQUIP_ERR_EVENT_AUTOEQUIP_BIND_CONFIRM: // no idea about this one...
|
||||
{
|
||||
data << uint64(0);
|
||||
data << uint32(0);
|
||||
data << uint64(0);
|
||||
} break;
|
||||
{
|
||||
data << uint64(0);
|
||||
data << uint32(0);
|
||||
data << uint64(0);
|
||||
break;
|
||||
}
|
||||
case EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_COUNT_EXCEEDED_IS:
|
||||
case EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_SOCKETED_EXCEEDED_IS:
|
||||
case EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_EQUIPPED_EXCEEDED_IS:
|
||||
{
|
||||
ItemPrototype const* proto = pItem ? pItem->GetProto() : NULL;
|
||||
data << uint32(proto ? proto->ItemLimitCategory : 0);
|
||||
} break;
|
||||
default:
|
||||
break;
|
||||
{
|
||||
ItemPrototype const* proto = pItem ? pItem->GetProto() : sObjectMgr.GetItemPrototype(itemid);
|
||||
data << uint32(proto ? proto->ItemLimitCategory : 0);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
GetSession()->SendPacket(&data);
|
||||
|
|
@ -12909,7 +13006,7 @@ bool Player::CanAddQuest( Quest const *pQuest, bool msg )
|
|||
return true;
|
||||
else if( msg2 != EQUIP_ERR_OK )
|
||||
{
|
||||
SendEquipError( msg2, NULL, NULL );
|
||||
SendEquipError(msg2, NULL, NULL, srcitem);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -13021,7 +13118,7 @@ bool Player::CanRewardQuest( Quest const *pQuest, bool msg )
|
|||
GetItemCount(pQuest->ReqItemId[i]) < pQuest->ReqItemCount[i] )
|
||||
{
|
||||
if(msg)
|
||||
SendEquipError( EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL );
|
||||
SendEquipError( EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL, pQuest->ReqItemId[i]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -13048,7 +13145,7 @@ bool Player::CanRewardQuest( Quest const *pQuest, uint32 reward, bool msg )
|
|||
uint8 res = CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, pQuest->RewChoiceItemId[reward], pQuest->RewChoiceItemCount[reward] );
|
||||
if( res != EQUIP_ERR_OK )
|
||||
{
|
||||
SendEquipError( res, NULL, NULL );
|
||||
SendEquipError( res, NULL, NULL, pQuest->RewChoiceItemId[reward] );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -13746,7 +13843,7 @@ bool Player::GiveQuestSourceItem( Quest const *pQuest )
|
|||
else if( msg == EQUIP_ERR_CANT_CARRY_MORE_OF_THIS )
|
||||
return true;
|
||||
else
|
||||
SendEquipError( msg, NULL, NULL );
|
||||
SendEquipError( msg, NULL, NULL, srcitem );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -13771,7 +13868,7 @@ bool Player::TakeQuestSourceItem( uint32 quest_id, bool msg )
|
|||
if(res != EQUIP_ERR_OK)
|
||||
{
|
||||
if(msg)
|
||||
SendEquipError( res, NULL, NULL );
|
||||
SendEquipError( res, NULL, NULL, srcitem );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -15468,7 +15565,7 @@ void Player::_LoadInventory(QueryResult *result, uint32 timediff)
|
|||
}
|
||||
|
||||
// "Conjured items disappear if you are logged out for more than 15 minutes"
|
||||
if ((timediff > 15*60) && (item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_CONJURED)))
|
||||
if (timediff > 15*MINUTE && item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_CONJURED))
|
||||
{
|
||||
CharacterDatabase.PExecute("DELETE FROM character_inventory WHERE item = '%u'", item_guid);
|
||||
item->FSetState(ITEM_REMOVED);
|
||||
|
|
@ -15536,7 +15633,13 @@ void Player::_LoadInventory(QueryResult *result, uint32 timediff)
|
|||
|
||||
// item's state may have changed after stored
|
||||
if (success)
|
||||
{
|
||||
item->SetState(ITEM_UNCHANGED, this);
|
||||
|
||||
// recharged mana gem
|
||||
if (timediff > 15*MINUTE && proto->ItemLimitCategory ==ITEM_LIMIT_CATEGORY_MANA_GEM)
|
||||
item->RestoreCharges();
|
||||
}
|
||||
else
|
||||
{
|
||||
sLog.outError("Player::_LoadInventory: Player %s has item (GUID: %u Entry: %u) can't be loaded to inventory (Bag GUID: %u Slot: %u) by some reason, will send by mail.", GetName(),item_guid, item_id, bag_guid, slot);
|
||||
|
|
@ -16116,7 +16219,7 @@ bool Player::_LoadHomeBind(QueryResult *result)
|
|||
{
|
||||
Field *fields = result->Fetch();
|
||||
m_homebindMapId = fields[0].GetUInt32();
|
||||
m_homebindZoneId = fields[1].GetUInt16();
|
||||
m_homebindAreaId = fields[1].GetUInt16();
|
||||
m_homebindX = fields[2].GetFloat();
|
||||
m_homebindY = fields[3].GetFloat();
|
||||
m_homebindZ = fields[4].GetFloat();
|
||||
|
|
@ -16137,16 +16240,16 @@ bool Player::_LoadHomeBind(QueryResult *result)
|
|||
if(!ok)
|
||||
{
|
||||
m_homebindMapId = info->mapId;
|
||||
m_homebindZoneId = info->zoneId;
|
||||
m_homebindAreaId = info->areaId;
|
||||
m_homebindX = info->positionX;
|
||||
m_homebindY = info->positionY;
|
||||
m_homebindZ = info->positionZ;
|
||||
|
||||
CharacterDatabase.PExecute("INSERT INTO character_homebind (guid,map,zone,position_x,position_y,position_z) VALUES ('%u', '%u', '%u', '%f', '%f', '%f')", GetGUIDLow(), m_homebindMapId, (uint32)m_homebindZoneId, m_homebindX, m_homebindY, m_homebindZ);
|
||||
CharacterDatabase.PExecute("INSERT INTO character_homebind (guid,map,zone,position_x,position_y,position_z) VALUES ('%u', '%u', '%u', '%f', '%f', '%f')", GetGUIDLow(), m_homebindMapId, (uint32)m_homebindAreaId, m_homebindX, m_homebindY, m_homebindZ);
|
||||
}
|
||||
|
||||
DEBUG_LOG("Setting player home position: mapid is: %u, zoneid is %u, X is %f, Y is %f, Z is %f",
|
||||
m_homebindMapId, m_homebindZoneId, m_homebindX, m_homebindY, m_homebindZ);
|
||||
m_homebindMapId, m_homebindAreaId, m_homebindX, m_homebindY, m_homebindZ);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -16668,21 +16771,18 @@ void Player::_SaveSpells()
|
|||
{
|
||||
for (PlayerSpellMap::iterator itr = m_spells.begin(), next = m_spells.begin(); itr != m_spells.end();)
|
||||
{
|
||||
if (itr->second->state == PLAYERSPELL_REMOVED || itr->second->state == PLAYERSPELL_CHANGED)
|
||||
if (itr->second.state == PLAYERSPELL_REMOVED || itr->second.state == PLAYERSPELL_CHANGED)
|
||||
CharacterDatabase.PExecute("DELETE FROM character_spell WHERE guid = '%u' and spell = '%u'", GetGUIDLow(), itr->first);
|
||||
|
||||
// add only changed/new not dependent spells
|
||||
if (!itr->second->dependent && (itr->second->state == PLAYERSPELL_NEW || itr->second->state == PLAYERSPELL_CHANGED))
|
||||
CharacterDatabase.PExecute("INSERT INTO character_spell (guid,spell,active,disabled) VALUES ('%u', '%u', '%u', '%u')", GetGUIDLow(), itr->first, itr->second->active ? 1 : 0,itr->second->disabled ? 1 : 0);
|
||||
if (!itr->second.dependent && (itr->second.state == PLAYERSPELL_NEW || itr->second.state == PLAYERSPELL_CHANGED))
|
||||
CharacterDatabase.PExecute("INSERT INTO character_spell (guid,spell,active,disabled) VALUES ('%u', '%u', '%u', '%u')", GetGUIDLow(), itr->first, itr->second.active ? 1 : 0,itr->second.disabled ? 1 : 0);
|
||||
|
||||
if (itr->second->state == PLAYERSPELL_REMOVED)
|
||||
{
|
||||
delete itr->second;
|
||||
if (itr->second.state == PLAYERSPELL_REMOVED)
|
||||
m_spells.erase(itr++);
|
||||
}
|
||||
else
|
||||
{
|
||||
itr->second->state = PLAYERSPELL_UNCHANGED;
|
||||
itr->second.state = PLAYERSPELL_UNCHANGED;
|
||||
++itr;
|
||||
}
|
||||
|
||||
|
|
@ -16875,7 +16975,7 @@ void Player::SendAttackSwingBadFacingAttack()
|
|||
void Player::SendAutoRepeatCancel(Unit *target)
|
||||
{
|
||||
WorldPacket data(SMSG_CANCEL_AUTO_REPEAT, target->GetPackGUID().size());
|
||||
data.append(target->GetPackGUID()); // may be it's target guid
|
||||
data << target->GetPackGUID(); // may be it's target guid
|
||||
GetSession()->SendPacket( &data );
|
||||
}
|
||||
|
||||
|
|
@ -17871,7 +17971,7 @@ void Player::ProhibitSpellSchool(SpellSchoolMask idSchoolMask, uint32 unTimeMs )
|
|||
time_t curTime = time(NULL);
|
||||
for(PlayerSpellMap::const_iterator itr = m_spells.begin(); itr != m_spells.end(); ++itr)
|
||||
{
|
||||
if (itr->second->state == PLAYERSPELL_REMOVED)
|
||||
if (itr->second.state == PLAYERSPELL_REMOVED)
|
||||
continue;
|
||||
uint32 unSpellId = itr->first;
|
||||
SpellEntry const *spellInfo = sSpellStore.LookupEntry(unSpellId);
|
||||
|
|
@ -18080,7 +18180,7 @@ bool Player::BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint
|
|||
uint8 msg = CanStoreNewItem( bag, slot, dest, item, pProto->BuyCount * count );
|
||||
if (msg != EQUIP_ERR_OK)
|
||||
{
|
||||
SendEquipError( msg, NULL, NULL );
|
||||
SendEquipError( msg, NULL, NULL, item );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -18125,7 +18225,7 @@ bool Player::BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint
|
|||
uint8 msg = CanEquipNewItem( slot, dest, item, false );
|
||||
if (msg != EQUIP_ERR_OK)
|
||||
{
|
||||
SendEquipError( msg, NULL, NULL );
|
||||
SendEquipError( msg, NULL, NULL, item );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -18850,7 +18950,7 @@ void Player::SendComboPoints()
|
|||
if (combotarget)
|
||||
{
|
||||
WorldPacket data(SMSG_UPDATE_COMBO_POINTS, combotarget->GetPackGUID().size()+1);
|
||||
data.append(combotarget->GetPackGUID());
|
||||
data << combotarget->GetPackGUID();
|
||||
data << uint8(m_comboPoints);
|
||||
GetSession()->SendPacket(&data);
|
||||
}
|
||||
|
|
@ -18925,7 +19025,7 @@ void Player::SendInitialPacketsBeforeAddToMap()
|
|||
WorldPacket data(SMSG_BINDPOINTUPDATE, 5*4);
|
||||
data << m_homebindX << m_homebindY << m_homebindZ;
|
||||
data << (uint32) m_homebindMapId;
|
||||
data << (uint32) m_homebindZoneId;
|
||||
data << (uint32) m_homebindAreaId;
|
||||
GetSession()->SendPacket(&data);
|
||||
|
||||
// SMSG_SET_PROFICIENCY
|
||||
|
|
@ -19009,7 +19109,7 @@ void Player::SendInitialPacketsAfterAddToMap()
|
|||
if(HasAuraType(SPELL_AURA_MOD_ROOT))
|
||||
{
|
||||
WorldPacket data2(SMSG_FORCE_MOVE_ROOT, 10);
|
||||
data2.append(GetPackGUID());
|
||||
data2 << GetPackGUID();
|
||||
data2 << (uint32)2;
|
||||
SendMessageToSet(&data2,true);
|
||||
}
|
||||
|
|
@ -19175,7 +19275,7 @@ void Player::learnQuestRewardedSpells(Quest const* quest)
|
|||
// search other specialization for same prof
|
||||
for(PlayerSpellMap::const_iterator itr = m_spells.begin(); itr != m_spells.end(); ++itr)
|
||||
{
|
||||
if(itr->second->state == PLAYERSPELL_REMOVED || itr->first==learned_0)
|
||||
if(itr->second.state == PLAYERSPELL_REMOVED || itr->first==learned_0)
|
||||
continue;
|
||||
|
||||
SpellEntry const *itrInfo = sSpellStore.LookupEntry(itr->first);
|
||||
|
|
@ -19253,7 +19353,7 @@ void Player::SendAurasForTarget(Unit *target)
|
|||
return;
|
||||
|
||||
WorldPacket data(SMSG_AURA_UPDATE_ALL);
|
||||
data.append(target->GetPackGUID());
|
||||
data << target->GetPackGUID();
|
||||
|
||||
Unit::VisibleAuraMap const *visibleAuras = target->GetVisibleAuras();
|
||||
for(Unit::VisibleAuraMap::const_iterator itr = visibleAuras->begin(); itr != visibleAuras->end(); ++itr)
|
||||
|
|
@ -19692,7 +19792,7 @@ uint32 Player::GetResurrectionSpellId()
|
|||
}
|
||||
|
||||
// Used in triggers for check "Only to targets that grant experience or honor" req
|
||||
bool Player::isHonorOrXPTarget(Unit* pVictim)
|
||||
bool Player::isHonorOrXPTarget(Unit* pVictim) const
|
||||
{
|
||||
uint32 v_level = pVictim->getLevel();
|
||||
uint32 k_grey = MaNGOS::XP::GetGrayLevel(getLevel());
|
||||
|
|
@ -19896,7 +19996,7 @@ void Player::ResurectUsingRequestData()
|
|||
void Player::SetClientControl(Unit* target, uint8 allowMove)
|
||||
{
|
||||
WorldPacket data(SMSG_CLIENT_CONTROL_UPDATE, target->GetPackGUID().size()+1);
|
||||
data.append(target->GetPackGUID());
|
||||
data << target->GetPackGUID();
|
||||
data << uint8(allowMove);
|
||||
GetSession()->SendPacket(&data);
|
||||
}
|
||||
|
|
@ -20292,7 +20392,7 @@ void Player::EnterVehicle(Vehicle *vehicle)
|
|||
GetSession()->SendPacket(&data);
|
||||
|
||||
data.Initialize(MSG_MOVE_TELEPORT_ACK, 30);
|
||||
data.append(GetPackGUID());
|
||||
data << GetPackGUID();
|
||||
data << uint32(0); // counter?
|
||||
data << uint32(MOVEFLAG_ONTRANSPORT); // transport
|
||||
data << uint16(0); // special flags
|
||||
|
|
@ -20341,7 +20441,7 @@ void Player::ExitVehicle(Vehicle *vehicle)
|
|||
SetMover(NULL);
|
||||
|
||||
WorldPacket data(MSG_MOVE_TELEPORT_ACK, 30);
|
||||
data.append(GetPackGUID());
|
||||
data << GetPackGUID();
|
||||
data << uint32(0); // counter?
|
||||
data << uint32(MOVEFLAG_ROOT); // fly unk
|
||||
data << uint16(MOVEFLAG2_UNK4); // special flags
|
||||
|
|
@ -20495,7 +20595,7 @@ void Player::AutoStoreLoot(uint8 bag, uint8 slot, uint32 loot_id, LootStore cons
|
|||
msg = CanStoreNewItem( NULL_BAG, NULL_SLOT,dest,lootItem->itemid,lootItem->count);
|
||||
if(msg != EQUIP_ERR_OK)
|
||||
{
|
||||
SendEquipError( msg, NULL, NULL );
|
||||
SendEquipError( msg, NULL, NULL, lootItem->itemid );
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -20712,14 +20812,16 @@ uint8 Player::CanEquipUniqueItem( ItemPrototype const* itemProto, uint8 except_s
|
|||
{
|
||||
ItemLimitCategoryEntry const* limitEntry = sItemLimitCategoryStore.LookupEntry(itemProto->ItemLimitCategory);
|
||||
if(!limitEntry)
|
||||
return EQUIP_ERR_ITEM_UNIQUE_EQUIPABLE;
|
||||
return EQUIP_ERR_ITEM_CANT_BE_EQUIPPED;
|
||||
|
||||
// NOTE: limitEntry->mode not checked because if item have have-limit then it applied and to equip case
|
||||
|
||||
if(limit_count > limitEntry->maxCount)
|
||||
return EQUIP_ERR_ITEM_UNIQUE_EQUIPABLE; // attempt add too many limit category items (gems)
|
||||
return EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_EQUIPPED_EXCEEDED_IS;
|
||||
|
||||
// there is an equip limit on this item
|
||||
if(HasItemOrGemWithLimitCategoryEquipped(itemProto->ItemLimitCategory,limitEntry->maxCount-limit_count+1,except_slot))
|
||||
return EQUIP_ERR_ITEM_UNIQUE_EQUIPABLE;
|
||||
return EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_EQUIPPED_EXCEEDED_IS;
|
||||
}
|
||||
|
||||
return EQUIP_ERR_OK;
|
||||
|
|
@ -21497,7 +21599,7 @@ void Player::SendClearCooldown( uint32 spell_id, Unit* target )
|
|||
void Player::BuildTeleportAckMsg( WorldPacket *data, float x, float y, float z, float ang ) const
|
||||
{
|
||||
data->Initialize(MSG_MOVE_TELEPORT_ACK, 41);
|
||||
data->append(GetPackGUID());
|
||||
*data << GetPackGUID();
|
||||
*data << uint32(0); // this value increments every time
|
||||
*data << uint32(m_movementInfo.GetMovementFlags()); // movement flags
|
||||
*data << uint16(0); // 2.3.0
|
||||
|
|
@ -21591,16 +21693,17 @@ bool Player::IsImmunedToSpellEffect(SpellEntry const* spellInfo, SpellEffectInde
|
|||
return Unit::IsImmunedToSpellEffect(spellInfo, index);
|
||||
}
|
||||
|
||||
void Player::SetHomebindToCurrentPos()
|
||||
void Player::SetHomebindToLocation(WorldLocation const& loc, uint32 area_id)
|
||||
{
|
||||
m_homebindMapId = GetMapId();
|
||||
m_homebindZoneId = GetZoneId();
|
||||
m_homebindX = GetPositionX();
|
||||
m_homebindY = GetPositionY();
|
||||
m_homebindZ = GetPositionZ();
|
||||
m_homebindMapId = loc.mapid;
|
||||
m_homebindAreaId = area_id;
|
||||
m_homebindX = loc.coord_x;
|
||||
m_homebindY = loc.coord_y;
|
||||
m_homebindZ = loc.coord_z;
|
||||
|
||||
// update sql homebind
|
||||
CharacterDatabase.PExecute("UPDATE character_homebind SET map = '%u', zone = '%u', position_x = '%f', position_y = '%f', position_z = '%f' WHERE guid = '%u'",
|
||||
m_homebindMapId, m_homebindZoneId, m_homebindX, m_homebindY, m_homebindZ, GetGUIDLow());
|
||||
m_homebindMapId, m_homebindAreaId, m_homebindX, m_homebindY, m_homebindZ, GetGUIDLow());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue