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.cpp546
1 files changed, 261 insertions, 285 deletions
diff --git a/src/game/Player.cpp b/src/game/Player.cpp
index 2ddd89d7b2f..3bb7c959ca0 100644
--- a/src/game/Player.cpp
+++ b/src/game/Player.cpp
@@ -372,7 +372,7 @@ Player::Player (WorldSession *session): Unit(), m_achievementMgr(this)
m_bgBattleGroundID = 0;
for (int j=0; j < PLAYER_MAX_BATTLEGROUND_QUEUES; j++)
{
- m_bgBattleGroundQueueID[j].bgQueueType = 0;
+ m_bgBattleGroundQueueID[j].bgQueueTypeId = BATTLEGROUND_QUEUE_NONE;
m_bgBattleGroundQueueID[j].invitedToInstance = 0;
}
m_bgTeam = 0;
@@ -506,9 +506,6 @@ Player::~Player ()
for(BoundInstancesMap::iterator itr = m_boundInstances[i].begin(); itr != m_boundInstances[i].end(); ++itr)
itr->second.save->RemovePlayer(this);
- if (m_uint32Values && isPossessing())
- RemovePossess(false);
-
delete m_declinedname;
delete m_runes;
}
@@ -1378,12 +1375,6 @@ void Player::setDeathState(DeathState s)
RemoveMiniPet();
RemoveGuardians();
- // remove possession
- if(isPossessing())
- RemovePossess(false);
- else
- RemoveFarsightTarget();
-
// save value before aura remove in Unit::setDeathState
ressSpellId = GetUInt32Value(PLAYER_SELF_RES_SPELL);
@@ -1578,15 +1569,15 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
if(!InBattleGround() && mEntry->IsBattleGroundOrArena())
return false;
- // 449 - Champions' Hall (Alliance) // 450 - Hall of Legends (Horde)
- if(mapid == 449 && GetTeam()==HORDE)
+ // 449 - Champions' Hall (Alliance) // 450 - Hall of Legends (Horde)
+ if(mapid == 449 && GetTeam()==HORDE)
{
GetSession()->SendNotification(LANG_NO_ENTER_CHAMPIONS_HALL);
return false;
}
- if(mapid == 450 && GetTeam() == ALLIANCE)
- {
+ if(mapid == 450 && GetTeam() == ALLIANCE)
+ {
GetSession()->SendNotification(LANG_NO_ENTER_HALL_OF_LEGENDS);
return false;
}
@@ -1605,7 +1596,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
}
else
{
- sLog.outDebug("Player %s will teleported to map %u", GetName(), mapid);
+ sLog.outDebug("Player %s is being teleported to map %u", GetName(), mapid);
}
// if we were on a transport, leave
@@ -1622,18 +1613,6 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
SetSemaphoreTeleport(true);
- // Remove any possession on the player before teleporting
- if (isPossessedByPlayer())
- ((Player*)GetCharmer())->RemovePossess();
-
- // Remove player's possession before teleporting
- if (isPossessing())
- RemovePossess(false);
-
- // Empty vision list and clear farsight (if it hasn't already been cleared by RemovePossess) before teleporting
- RemoveAllFromVision();
- RemoveFarsightTarget();
-
// The player was ported to another map and looses the duel immediatly.
// We have to perform this check before the teleport, otherwise the
// ObjectAccessor won't find the flag.
@@ -1860,12 +1839,13 @@ void Player::RemoveFromWorld()
if(IsInWorld())
{
///- Release charmed creatures, unsummon totems and remove pets/guardians
- RemovePossess(false);
- Uncharm();
+ StopCastingCharm();
+ StopCastingBindSight();
+ RemoveCharmAuras();
+ RemoveBindSightAuras();
UnsummonAllTotems();
RemoveMiniPet();
RemoveGuardians();
- RemoveFarsightTarget();
}
for(int i = PLAYER_SLOT_START; i < PLAYER_SLOT_END; i++)
@@ -5520,17 +5500,17 @@ void Player::SaveRecallPosition()
void Player::SendMessageToSet(WorldPacket *data, bool self, bool to_possessor)
{
- MapManager::Instance().GetMap(GetMapId(), this)->MessageBroadcast(this, data, self, to_possessor);
+ GetMap()->MessageBroadcast(this, data, self, to_possessor);
}
void Player::SendMessageToSetInRange(WorldPacket *data, float dist, bool self, bool to_possessor)
{
- MapManager::Instance().GetMap(GetMapId(), this)->MessageDistBroadcast(this, data, dist, self, to_possessor);
+ GetMap()->MessageDistBroadcast(this, data, dist, self, to_possessor);
}
void Player::SendMessageToSetInRange(WorldPacket *data, float dist, bool self, bool to_possessor, bool own_team_only)
{
- MapManager::Instance().GetMap(GetMapId(), this)->MessageDistBroadcast(this, data, dist, self, to_possessor, own_team_only);
+ GetMap()->MessageDistBroadcast(this, data, dist, self, to_possessor, own_team_only);
}
void Player::SendDirectMessage(WorldPacket *data)
@@ -5972,7 +5952,7 @@ bool Player::ModifyOneFactionReputation(FactionEntry const* factionEntry, int32
SetFactionVisible(&itr->second);
- for( int i = 0; i < MAX_QUEST_LOG_SIZE; i++ )
+ for( int i = 0; i < MAX_QUEST_LOG_SIZE; ++i )
{
if(uint32 questid = GetQuestSlotQuestId(i))
{
@@ -6298,7 +6278,7 @@ bool Player::RewardHonor(Unit *uVictim, uint32 groupsize, float honor, bool pvpt
honor /= groupsize;
// apply honor multiplier from aura (not stacking-get highest)
- honor *= (float(GetMaxPositiveAuraModifier(SPELL_AURA_MOD_HONOR_GAIN_PCT))+100.0f)/100.0f;
+ honor = int32(float(honor) * (float(GetMaxPositiveAuraModifier(SPELL_AURA_MOD_HONOR_GAIN_PCT))+100.0f)/100.0f);
honor *= (((float)urand(8,12))/10); // approx honor: 80% - 120% of real honor
}
@@ -9099,31 +9079,76 @@ bool Player::HasItemCount( uint32 item, uint32 count, bool inBankAlso ) const
return false;
}
-Item* Player::GetItemOrItemWithGemEquipped( uint32 item ) const
+bool Player::HasItemOrGemWithIdEquipped( uint32 item, uint32 count, uint8 except_slot ) const
{
- Item *pItem;
- for(int i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; i++)
+ uint32 tempcount = 0;
+ for(int i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; ++i)
{
- pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i );
- if( pItem && pItem->GetEntry() == item )
- return pItem;
+ if(i==int(except_slot))
+ continue;
+
+ Item *pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i );
+ if( pItem && pItem->GetEntry() == item)
+ {
+ tempcount += pItem->GetCount();
+ if( tempcount >= count )
+ return true;
+ }
}
ItemPrototype const *pProto = objmgr.GetItemPrototype(item);
if (pProto && pProto->GemProperties)
{
- for(int i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; i++)
+ for(int i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; ++i)
{
- pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i );
- if( pItem && pItem->GetProto()->Socket[0].Color )
+ if(i==int(except_slot))
+ continue;
+
+ Item *pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i );
+ if( pItem && pItem->GetProto()->Socket[0].Color)
{
- if (pItem->GetGemCountWithID(item) > 0 )
- return pItem;
+ tempcount += pItem->GetGemCountWithID(item);
+ if( tempcount >= count )
+ return true;
}
}
}
- return NULL;
+ return false;
+}
+
+bool Player::HasItemOrGemWithLimitCategoryEquipped( uint32 limitCategory, uint32 count, uint8 except_slot ) const
+{
+ uint32 tempcount = 0;
+ for(int i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; ++i)
+ {
+ if(i==int(except_slot))
+ continue;
+
+ Item *pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i );
+ if (!pItem)
+ continue;
+
+ ItemPrototype const *pProto = pItem->GetProto();
+ if (!pProto)
+ continue;
+
+ if (pProto->ItemLimitCategory == limitCategory)
+ {
+ tempcount += pItem->GetCount();
+ if( tempcount >= count )
+ return true;
+ }
+
+ if( pProto->Socket[0].Color)
+ {
+ tempcount += pItem->GetGemCountWithLimitCategory(limitCategory);
+ if( tempcount >= count )
+ return true;
+ }
+ }
+
+ return false;
}
uint8 Player::_CanTakeMoreSimilarItems(uint32 entry, uint32 count, Item* pItem, uint32* no_space_count ) const
@@ -10168,11 +10193,6 @@ uint8 Player::CanEquipItem( uint8 slot, uint16 &dest, Item *pItem, bool swap, bo
ItemPrototype const *pProto = pItem->GetProto();
if( pProto )
{
- // May be here should be more stronger checks; STUNNED checked
- // ROOT, CONFUSED, DISTRACTED, FLEEING this needs to be checked.
- if (not_loading && hasUnitState(UNIT_STAT_STUNNED))
- return EQUIP_ERR_YOU_ARE_STUNNED;
-
if(pItem->IsBindedNotWith(GetGUID()))
return EQUIP_ERR_DONT_OWN_THAT_ITEM;
@@ -10181,24 +10201,33 @@ uint8 Player::CanEquipItem( uint8 slot, uint16 &dest, Item *pItem, bool swap, bo
if(res != EQUIP_ERR_OK)
return res;
- // do not allow equipping gear except weapons, offhands, projectiles, relics in
- // - combat
- // - in-progress arenas
- if( !pProto->CanChangeEquipStateInCombat() )
+ // check this only in game
+ if(not_loading)
{
- if( isInCombat() )
- return EQUIP_ERR_NOT_IN_COMBAT;
+ // May be here should be more stronger checks; STUNNED checked
+ // ROOT, CONFUSED, DISTRACTED, FLEEING this needs to be checked.
+ if (hasUnitState(UNIT_STAT_STUNNED))
+ return EQUIP_ERR_YOU_ARE_STUNNED;
- if(BattleGround* bg = GetBattleGround())
- if( bg->isArena() && bg->GetStatus() == STATUS_IN_PROGRESS )
- return EQUIP_ERR_NOT_DURING_ARENA_MATCH;
- }
+ // do not allow equipping gear except weapons, offhands, projectiles, relics in
+ // - combat
+ // - in-progress arenas
+ if( !pProto->CanChangeEquipStateInCombat() )
+ {
+ if( isInCombat() )
+ return EQUIP_ERR_NOT_IN_COMBAT;
- if(isInCombat()&& pProto->Class == ITEM_CLASS_WEAPON && m_weaponChangeTimer != 0)
- return EQUIP_ERR_CANT_DO_RIGHT_NOW; // maybe exist better err
+ if(BattleGround* bg = GetBattleGround())
+ if( bg->isArena() && bg->GetStatus() == STATUS_IN_PROGRESS )
+ return EQUIP_ERR_NOT_DURING_ARENA_MATCH;
+ }
- if(IsNonMeleeSpellCasted(false))
- return EQUIP_ERR_CANT_DO_RIGHT_NOW;
+ if(isInCombat()&& pProto->Class == ITEM_CLASS_WEAPON && m_weaponChangeTimer != 0)
+ return EQUIP_ERR_CANT_DO_RIGHT_NOW; // maybe exist better err
+
+ if(IsNonMeleeSpellCasted(false))
+ return EQUIP_ERR_CANT_DO_RIGHT_NOW;
+ }
uint8 eslot = FindEquipSlot( pProto, slot, swap );
if( eslot == NULL_SLOT )
@@ -10210,33 +10239,9 @@ uint8 Player::CanEquipItem( uint8 slot, uint16 &dest, Item *pItem, bool swap, bo
if( !swap && GetItemByPos( INVENTORY_SLOT_BAG_0, eslot ) )
return EQUIP_ERR_NO_EQUIPMENT_SLOT_AVAILABLE;
- // check unique-equipped on item
- if (pProto->Flags & ITEM_FLAGS_UNIQUE_EQUIPPED)
- {
- // there is an equip limit on this item
- Item* tItem = GetItemOrItemWithGemEquipped(pProto->ItemId);
- if (tItem && (!swap || tItem->GetSlot() != eslot ) )
- return EQUIP_ERR_ITEM_UNIQUE_EQUIPABLE;
- }
-
- // check unique-equipped on gems
- for(uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+3; ++enchant_slot)
- {
- uint32 enchant_id = pItem->GetEnchantmentId(EnchantmentSlot(enchant_slot));
- if(!enchant_id)
- continue;
- SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
- if(!enchantEntry)
- continue;
-
- ItemPrototype const* pGem = objmgr.GetItemPrototype(enchantEntry->GemID);
- if(pGem && (pGem->Flags & ITEM_FLAGS_UNIQUE_EQUIPPED))
- {
- Item* tItem = GetItemOrItemWithGemEquipped(enchantEntry->GemID);
- if(tItem && (!swap || tItem->GetSlot() != eslot ))
- return EQUIP_ERR_ITEM_UNIQUE_EQUIPABLE;
- }
- }
+ // if swap ignore item (equipped also)
+ if(uint8 res = CanEquipUniqueItem(pItem, swap ? eslot : NULL_SLOT))
+ return res;
// check unique-equipped special item classes
if (pProto->Class == ITEM_CLASS_QUIVER)
@@ -12618,7 +12623,7 @@ void Player::SendPreparedQuest( uint64 guid )
if( pCreature )
{
uint32 textid = pCreature->GetNpcTextId();
- GossipText * gossiptext = objmgr.GetGossipText(textid);
+ GossipText const* gossiptext = objmgr.GetGossipText(textid);
if( !gossiptext )
{
qe._Delay = 0; //TEXTEMOTE_MESSAGE; //zyg: player emote
@@ -13700,7 +13705,7 @@ void Player::AdjustQuestReqItemCount( Quest const* pQuest, QuestStatusData& ques
uint16 Player::FindQuestSlot( uint32 quest_id ) const
{
- for ( uint16 i = 0; i < MAX_QUEST_LOG_SIZE; i++ )
+ for ( uint16 i = 0; i < MAX_QUEST_LOG_SIZE; ++i )
if ( GetQuestSlotQuestId(i) == quest_id )
return i;
@@ -13748,7 +13753,7 @@ void Player::GroupEventHappens( uint32 questId, WorldObject const* pEventObject
void Player::ItemAddedQuestCheck( uint32 entry, uint32 count )
{
- for( int i = 0; i < MAX_QUEST_LOG_SIZE; i++ )
+ for( int i = 0; i < MAX_QUEST_LOG_SIZE; ++i )
{
uint32 questid = GetQuestSlotQuestId(i);
if ( questid == 0 )
@@ -13790,7 +13795,7 @@ void Player::ItemAddedQuestCheck( uint32 entry, uint32 count )
void Player::ItemRemovedQuestCheck( uint32 entry, uint32 count )
{
- for( int i = 0; i < MAX_QUEST_LOG_SIZE; i++ )
+ for( int i = 0; i < MAX_QUEST_LOG_SIZE; ++i )
{
uint32 questid = GetQuestSlotQuestId(i);
if(!questid)
@@ -13833,7 +13838,7 @@ void Player::KilledMonster( uint32 entry, uint64 guid )
{
uint32 addkillcount = 1;
GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE, entry, addkillcount);
- for( int i = 0; i < MAX_QUEST_LOG_SIZE; i++ )
+ for( int i = 0; i < MAX_QUEST_LOG_SIZE; ++i )
{
uint32 questid = GetQuestSlotQuestId(i);
if(!questid)
@@ -13888,7 +13893,7 @@ void Player::CastedCreatureOrGO( uint32 entry, uint64 guid, uint32 spell_id )
bool isCreature = IS_CREATURE_GUID(guid);
uint32 addCastCount = 1;
- for( int i = 0; i < MAX_QUEST_LOG_SIZE; i++ )
+ for( int i = 0; i < MAX_QUEST_LOG_SIZE; ++i)
{
uint32 questid = GetQuestSlotQuestId(i);
if(!questid)
@@ -13955,7 +13960,7 @@ void Player::CastedCreatureOrGO( uint32 entry, uint64 guid, uint32 spell_id )
void Player::TalkedToCreature( uint32 entry, uint64 guid )
{
uint32 addTalkCount = 1;
- for( int i = 0; i < MAX_QUEST_LOG_SIZE; i++ )
+ for( int i = 0; i < MAX_QUEST_LOG_SIZE; ++i )
{
uint32 questid = GetQuestSlotQuestId(i);
if(!questid)
@@ -14010,7 +14015,7 @@ void Player::TalkedToCreature( uint32 entry, uint64 guid )
void Player::MoneyChanged( uint32 count )
{
- for( int i = 0; i < MAX_QUEST_LOG_SIZE; i++ )
+ for( int i = 0; i < MAX_QUEST_LOG_SIZE; ++i )
{
uint32 questid = GetQuestSlotQuestId(i);
if (!questid)
@@ -14040,13 +14045,21 @@ void Player::MoneyChanged( uint32 count )
bool Player::HasQuestForItem( uint32 itemid ) const
{
- for( QuestStatusMap::const_iterator i = mQuestStatus.begin( ); i != mQuestStatus.end( ); ++i )
+ for( int i = 0; i < MAX_QUEST_LOG_SIZE; ++i )
{
- QuestStatusData const& q_status = i->second;
+ uint32 questid = GetQuestSlotQuestId(i);
+ if ( questid == 0 )
+ continue;
+
+ QuestStatusMap::const_iterator qs_itr = mQuestStatus.find(questid);
+ if(qs_itr == mQuestStatus.end())
+ continue;
+
+ QuestStatusData const& q_status = qs_itr->second;
if (q_status.m_status == QUEST_STATUS_INCOMPLETE)
{
- Quest const* qinfo = objmgr.GetQuestTemplate(i->first);
+ Quest const* qinfo = objmgr.GetQuestTemplate(questid);
if(!qinfo)
continue;
@@ -14542,42 +14555,6 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
m_movementInfo.t_o = 0.0f;
}
- /*// load the player's map here if it's not already loaded
- Map *map = GetMap();
- if (!map)
- {
- AreaTrigger const* at = objmgr.GetGoBackTrigger(GetMapId());
- if(at)
- {
- SetMapId(at->target_mapId);
- Relocate(at->target_X, at->target_Y, at->target_Z, GetOrientation());
- sLog.outError("Player (guidlow %d) is teleported to gobacktrigger (Map: %u X: %f Y: %f Z: %f O: %f).",guid,GetMapId(),GetPositionX(),GetPositionY(),GetPositionZ(),GetOrientation());
- }
- else
- {
- SetMapId(m_homebindMapId);
- Relocate(m_homebindX, m_homebindY, m_homebindZ, GetOrientation());
- sLog.outError("Player (guidlow %d) is teleported to home (Map: %u X: %f Y: %f Z: %f O: %f).",guid,GetMapId(),GetPositionX(),GetPositionY(),GetPositionZ(),GetOrientation());
- }
-
- map = GetMap();
- if(!map)
- {
- sLog.outError("ERROR: Player (guidlow %d) have invalid coordinates (X: %f Y: %f Z: %f O: %f). Teleport to default race/class locations.",guid,GetPositionX(),GetPositionY(),GetPositionZ(),GetOrientation());
-
- SetMapId(info->mapId);
- Relocate(info->positionX,info->positionY,info->positionZ,0.0f);
-
- map = GetMap();
- if(!map)
- {
- sLog.outError("ERROR: Player (guidlow %d) have invalid coordinates (X: %f Y: %f Z: %f O: %f). Teleport to default race/class locations.",guid,GetPositionX(),GetPositionY(),GetPositionZ(),GetOrientation());
- sLog.outError("CRASH.");
- assert(false);
- }
- }
- }*/
-
uint32 bgid = fields[34].GetUInt32();
uint32 bgteam = fields[35].GetUInt32();
@@ -14594,12 +14571,16 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
if(currentBg && currentBg->IsPlayerInBattleGround(GetGUID()))
{
- uint32 bgQueueTypeId = sBattleGroundMgr.BGQueueTypeId(currentBg->GetTypeID(), currentBg->GetArenaType());
+ BattleGroundQueueTypeId bgQueueTypeId = sBattleGroundMgr.BGQueueTypeId(currentBg->GetTypeID(), currentBg->GetArenaType());
uint32 queueSlot = AddBattleGroundQueueId(bgQueueTypeId);
SetBattleGroundId(currentBg->GetInstanceID());
SetBGTeam(bgteam);
+ //join player to battleground group
+ currentBg->PlayerRelogin(this);
+ currentBg->AddOrSetPlayerToCorrectBgGroup(this, GetGUID(), bgteam);
+
SetInviteForBattleGroundQueueType(bgQueueTypeId,currentBg->GetInstanceID());
}
else
@@ -14687,6 +14668,41 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
// load the player's map here if it's not already loaded
Map *map = GetMap();
+ if (!map)
+ {
+ AreaTrigger const* at = objmgr.GetGoBackTrigger(GetMapId());
+ if(at)
+ {
+ SetMapId(at->target_mapId);
+ Relocate(at->target_X, at->target_Y, at->target_Z, GetOrientation());
+ sLog.outError("Player (guidlow %d) is teleported to gobacktrigger (Map: %u X: %f Y: %f Z: %f O: %f).",guid,GetMapId(),GetPositionX(),GetPositionY(),GetPositionZ(),GetOrientation());
+ }
+ else
+ {
+ RelocateToHomebind();
+ sLog.outError("Player (guidlow %d) is teleported to home (Map: %u X: %f Y: %f Z: %f O: %f).",guid,GetMapId(),GetPositionX(),GetPositionY(),GetPositionZ(),GetOrientation());
+ }
+
+ map = GetMap();
+ if(!map)
+ {
+ sLog.outError("ERROR: Player (guidlow %d) have invalid coordinates (X: %f Y: %f Z: %f O: %f). Teleport to default race/class locations.",guid,GetPositionX(),GetPositionY(),GetPositionZ(),GetOrientation());
+ delete result;
+ return false;
+
+ /*SetMapId(info->mapId);
+ Relocate(info->positionX,info->positionY,info->positionZ,0.0f);
+
+ map = GetMap();
+ if(!map)
+ {
+ sLog.outError("ERROR: Player (guidlow %d) have invalid coordinates (X: %f Y: %f Z: %f O: %f). Teleport to default race/class locations.",guid,GetPositionX(),GetPositionY(),GetPositionZ(),GetOrientation());
+ sLog.outError("CRASH.");
+ assert(false);
+ }*/
+ }
+ }
+
// since the player may not be bound to the map yet, make sure subsequent
// getmap calls won't create new maps
SetInstanceId(map->GetInstanceId());
@@ -16079,8 +16095,8 @@ void Player::SaveToDB()
ss << ", '";
ss << m_taxi.SaveTaxiDestinationsToString();
- ss << "', '0', ";
- ss << GetSession()->GetLatency();
+ ss << "', '0', ";
+ ss << GetSession()->GetLatency();
ss << ", ";
ss << GetBattleGroundId();
ss << ", ";
@@ -16120,23 +16136,6 @@ void Player::SaveToDB()
// save pet (hunter pet level and experience and all type pets health/mana).
if(Pet* pet = GetPet())
pet->SavePetToDB(PET_SAVE_AS_CURRENT);
-
- //to prevent access to DB we should cache some data, which is used very often
- /*CachePlayerInfoMap::iterator _iter = objmgr.m_mPlayerInfoMap.find(GetGUIDLow());
- if(_iter != objmgr.m_mPlayerInfoMap.end())//skip new players
- {
- _iter->second->unLevel = getLevel();
-
- _iter->second->unArenaInfoSlot0 = GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 0 * 6 + 5);
- _iter->second->unArenaInfoSlot1 = GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 1 * 6 + 5);
- _iter->second->unArenaInfoSlot2 = GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 2 * 6 + 5);
-
- _iter->second->unfield = GetUInt32Value(UNIT_FIELD_BYTES_0);
-
- _iter->second->unArenaInfoId0 = GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (0 * 6));
- _iter->second->unArenaInfoId1 = GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (1 * 6));
- _iter->second->unArenaInfoId2 = GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (2 * 6));
- }*/
m_achievementMgr.SaveToDB();
}
@@ -16959,6 +16958,8 @@ void Player::Uncharm()
return;
charm->RemoveSpellsCausingAura(SPELL_AURA_MOD_CHARM);
+ charm->RemoveSpellsCausingAura(SPELL_AURA_MOD_POSSESS_PET);
+ charm->RemoveSpellsCausingAura(SPELL_AURA_MOD_POSSESS);
}
void Player::BuildPlayerChat(WorldPacket *data, uint8 msgtype, const std::string& text, uint32 language) const
@@ -18685,40 +18686,6 @@ void Player::SendInitialPacketsAfterAddToMap()
SendMessageToSet(&data,true);
}
- // setup BG group membership if need
- if(BattleGround* currentBg = GetBattleGround())
- {
- // call for invited (join) or listed (relogin) and avoid other cases (GM teleport)
- if (IsInvitedForBattleGroundInstance(GetBattleGroundId()) ||
- currentBg->IsPlayerInBattleGround(GetGUID()))
- {
- currentBg->PlayerRelogin(this);
- if(currentBg->GetMapId() == GetMapId()) // we teleported/login to/in bg
- {
- uint32 team = currentBg->GetPlayerTeam(GetGUID());
- if(!team)
- team = GetTeam();
- Group* group = currentBg->GetBgRaid(team);
- if(!group) // first player joined
- {
- group = new Group;
- currentBg->SetBgRaid(team, group);
- group->Create(GetGUIDLow(), GetName());
- }
- else // raid already exist
- {
- if(group->IsMember(GetGUID()))
- {
- uint8 subgroup = group->GetMemberGroup(GetGUID());
- SetGroup(group, subgroup);
- }
- else
- currentBg->GetBgRaid(team)->AddMember(GetGUID(), GetName());
- }
- }
- }
- }
-
SendAurasForTarget(this);
SendEnchantmentDurations(); // must be after add to map
SendItemDurations(); // must be after add to map
@@ -19053,40 +19020,34 @@ bool Player::GetBGAccessByLevel(BattleGroundTypeId bgTypeId) const
return true;
}
-uint32 Player::GetMinLevelForBattleGroundQueueId(uint32 queue_id)
+uint32 Player::GetMinLevelForBattleGroundQueueId(uint32 queue_id, BattleGroundTypeId bgTypeId)
{
- if(queue_id < 1)
- return 0;
-
- if(queue_id >=7)
- queue_id = 7;
-
- return 10*(queue_id+1);
+ BattleGround *bg = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId);
+ assert(bg);
+ return (queue_id*10)+bg->GetMinLevel();
}
-uint32 Player::GetMaxLevelForBattleGroundQueueId(uint32 queue_id)
+uint32 Player::GetMaxLevelForBattleGroundQueueId(uint32 queue_id, BattleGroundTypeId bgTypeId)
{
- if(queue_id >=7)
- return 255; // hardcoded max level
-
- return 10*(queue_id+2)-1;
+ return GetMinLevelForBattleGroundQueueId(queue_id, bgTypeId)+10;
}
-//TODO make this more generic - current implementation is wrong
-uint32 Player::GetBattleGroundQueueIdFromLevel() const
+uint32 Player::GetBattleGroundQueueIdFromLevel(BattleGroundTypeId bgTypeId) const
{
- uint32 level = getLevel();
- if(level <= 19)
- return 0;
- else if (level > 79)
- return 7;
- else
- return level/10 - 1; // 20..29 -> 1, 30-39 -> 2, ...
- /*
- assert(bgTypeId < MAX_BATTLEGROUND_TYPES);
BattleGround *bg = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId);
assert(bg);
- return (getLevel() - bg->GetMinLevel()) / 10;*/
+ if(getLevel()<bg->GetMinLevel())
+ {
+ sLog.outError("getting queue_id for player who doesn't meet the requirements - this shouldn't happen");
+ return 0;
+ }
+ uint32 queue_id = (getLevel() - bg->GetMinLevel()) / 10;
+ if(queue_id>MAX_BATTLEGROUND_QUEUES)
+ {
+ sLog.outError("to high queue_id %u this shouldn't happen",queue_id);
+ return 0;
+ }
+ return queue_id;
}
float Player::GetReputationPriceDiscount( Creature const* pCreature ) const
@@ -19128,14 +19089,23 @@ bool Player::IsSpellFitByClassAndRace( uint32 spell_id ) const
return false;
}
-bool Player::HasQuestForGO(int32 GOId)
+bool Player::HasQuestForGO(int32 GOId) const
{
- for( QuestStatusMap::iterator i = mQuestStatus.begin( ); i != mQuestStatus.end( ); ++i )
+ for( int i = 0; i < MAX_QUEST_LOG_SIZE; ++i )
{
- QuestStatusData qs=i->second;
+ uint32 questid = GetQuestSlotQuestId(i);
+ if ( questid == 0 )
+ continue;
+
+ QuestStatusMap::const_iterator qs_itr = mQuestStatus.find(questid);
+ if(qs_itr == mQuestStatus.end())
+ continue;
+
+ QuestStatusData const& qs = qs_itr->second;
+
if (qs.m_status == QUEST_STATUS_INCOMPLETE)
{
- Quest const* qinfo = objmgr.GetQuestTemplate(i->first);
+ Quest const* qinfo = objmgr.GetQuestTemplate(questid);
if(!qinfo)
continue;
@@ -19895,41 +19865,6 @@ void Player::HandleFallUnderMap()
}
}
-void Player::RemovePossess(bool attack)
-{
- if(Unit *u = GetCharm())
- u->RemoveCharmedOrPossessedBy(this);
-
- /*else if (target->isAlive())
- {
- // If we're still hostile to our target, continue attacking otherwise reset threat and go home
- if (Unit* victim = target->getVictim())
- {
- FactionTemplateEntry const* t_faction = target->getFactionTemplateEntry();
- FactionTemplateEntry const* v_faction = victim->getFactionTemplateEntry();
- // Unit::IsHostileTo will always return true since the unit is always hostile to its victim
- if (t_faction && v_faction && !t_faction->IsHostileTo(*v_faction))
- {
- // Stop combat and remove the target from the threat lists of all its victims
- target->CombatStop();
- target->getHostilRefManager().deleteReferences();
- target->DeleteThreatList();
- target->GetMotionMaster()->Clear();
- target->GetMotionMaster()->MoveTargetedHome();
- }
- }
- else
- {
- target->GetMotionMaster()->Clear();
- target->GetMotionMaster()->MoveTargetedHome();
- }
-
- // Add high amount of threat on the player
- if(attack)
- target->AddThreat(this, 1000000.0f);
- }*/
-}
-
/*void Player::SetViewport(uint64 guid, bool moveable)
{
WorldPacket data(SMSG_CLIENT_CONTROL_UPDATE, 8+1);
@@ -19950,24 +19885,23 @@ void Player::SetBindSight(Unit *target)
WorldObject* Player::GetFarsightTarget() const
{
// Players can have in farsight field another player's guid, a creature's guid, or a dynamic object's guid
- if(uint64 guid = GetFarSight())
+ if(uint64 guid = GetFarSightGUID())
return (WorldObject*)ObjectAccessor::GetObjectByTypeMask(*this, guid, TYPEMASK_FARSIGHTOBJ);
return NULL;
}
-void Player::RemoveFarsightTarget()
+void Player::StopCastingBindSight()
{
if (WorldObject* target = GetFarsightTarget())
{
if (target->isType(TYPEMASK_PLAYER | TYPEMASK_UNIT))
- ((Unit*)target)->RemovePlayerFromVision(this);
+ ((Unit*)target)->RemoveSpellsCausingAura(SPELL_AURA_BIND_SIGHT);
}
- ClearFarsight();
}
void Player::ClearFarsight()
{
- if(GetFarSight())
+ if(GetFarSightGUID())
{
SetFarSightGUID(0);
WorldPacket data(SMSG_CLEAR_FAR_SIGHT_IMMEDIATE, 0);
@@ -19981,7 +19915,7 @@ void Player::SetFarsightTarget(WorldObject* obj)
return;
// Remove the current target if there is one
- RemoveFarsightTarget();
+ StopCastingBindSight();
SetFarSightGUID(obj->GetGUID());
}
@@ -20323,27 +20257,8 @@ bool Player::IsAllowUseFlyMountsHere() const
if (isGameMaster())
return true;
- switch(GetVirtualMapForMapAndZone(GetMapId(), GetZoneId()))
- {
- case 0:
- case 1:
- //if (!sWorld.getConfig(CONFIG_FLYING_MOUNTS_AZEROTH))
- return false;
- break;
- case 530:
- //if (!sWorld.getConfig(CONFIG_FLYING_MOUNTS_OUTLAND))
- return false;
- break;
- case 571:
- if(!HasSpell(54197))
- return false;
- break;
- default:
- //if (!sWorld.getConfig(CONFIG_FLYING_MOUNTS_OTHERS))
- return false;
- break;
- }
- return true;
+ uint32 v_map = GetVirtualMapForMapAndZone(GetMapId(), GetZoneId());
+ return v_map == 530 || v_map == 571 && HasSpell(54197);
}
void Player::learnSpellHighRank(uint32 spellid)
@@ -20428,3 +20343,64 @@ uint32 Player::GetPhaseMaskForSpawn() const
return PHASEMASK_NORMAL;
}
+
+uint8 Player::CanEquipUniqueItem(Item* pItem, uint8 eslot, uint32 limit_count) const
+{
+ ItemPrototype const* pProto = pItem->GetProto();
+
+ // proto based limitations
+ if(uint8 res = CanEquipUniqueItem(pProto,eslot,limit_count))
+ return res;
+
+ // check unique-equipped on gems
+ for(uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+3; ++enchant_slot)
+ {
+ uint32 enchant_id = pItem->GetEnchantmentId(EnchantmentSlot(enchant_slot));
+ if(!enchant_id)
+ continue;
+ SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
+ if(!enchantEntry)
+ continue;
+
+ ItemPrototype const* pGem = objmgr.GetItemPrototype(enchantEntry->GemID);
+ if(!pGem)
+ continue;
+
+ // include for check equip another gems with same limit category for not equipped item (and then not counted)
+ uint32 gem_limit_count = !pItem->IsEquipped() && pGem->ItemLimitCategory
+ ? pItem->GetGemCountWithLimitCategory(pGem->ItemLimitCategory) : 1;
+
+ if(uint8 res = CanEquipUniqueItem(pGem, eslot,gem_limit_count))
+ return res;
+ }
+
+ return EQUIP_ERR_OK;
+}
+
+uint8 Player::CanEquipUniqueItem( ItemPrototype const* itemProto, uint8 except_slot, uint32 limit_count) const
+{
+ // check unique-equipped on item
+ if (itemProto->Flags & ITEM_FLAGS_UNIQUE_EQUIPPED)
+ {
+ // there is an equip limit on this item
+ if(HasItemOrGemWithIdEquipped(itemProto->ItemId,1,except_slot))
+ return EQUIP_ERR_ITEM_UNIQUE_EQUIPABLE;
+ }
+
+ // check unique-equipped limit
+ if (itemProto->ItemLimitCategory)
+ {
+ ItemLimitCategoryEntry const* limitEntry = sItemLimitCategoryStore.LookupEntry(itemProto->ItemLimitCategory);
+ if(!limitEntry)
+ return EQUIP_ERR_ITEM_UNIQUE_EQUIPABLE;
+
+ if(limit_count > limitEntry->maxCount)
+ return EQUIP_ERR_ITEM_UNIQUE_EQUIPABLE; // attempt add too many limit category items (gems)
+
+ // 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_OK;
+}