diff options
Diffstat (limited to 'src/game/Player.cpp')
-rw-r--r-- | src/game/Player.cpp | 546 |
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; +} |