aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/AI/CoreAI/PetAI.cpp2
-rw-r--r--src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp3
-rw-r--r--src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp7
-rw-r--r--src/server/game/AI/SmartScripts/SmartAI.cpp5
-rw-r--r--src/server/game/AI/SmartScripts/SmartScript.cpp6
-rw-r--r--src/server/game/Combat/ThreatManager.h1
-rw-r--r--src/server/game/Entities/Creature/Creature.cpp2
-rw-r--r--src/server/game/Entities/GameObject/GameObject.cpp4
-rw-r--r--src/server/game/Entities/Player/KillRewarder.cpp5
-rw-r--r--src/server/game/Entities/Player/Player.cpp32
-rw-r--r--src/server/game/Entities/Player/Player.h1
-rw-r--r--src/server/game/Entities/Totem/Totem.cpp2
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp16
-rw-r--r--src/server/game/Grids/ObjectGridLoader.cpp2
-rw-r--r--src/server/game/Groups/Group.cpp168
-rw-r--r--src/server/game/Groups/Group.h4
-rw-r--r--src/server/game/Loot/LootMgr.cpp3
-rw-r--r--src/server/scripts/EasternKingdoms/Stratholme/stratholme.cpp2
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp6
-rw-r--r--src/server/scripts/Outland/zone_terokkar_forest.cpp2
20 files changed, 161 insertions, 112 deletions
diff --git a/src/server/game/AI/CoreAI/PetAI.cpp b/src/server/game/AI/CoreAI/PetAI.cpp
index 6662c4d87e9..1e059190a04 100644
--- a/src/server/game/AI/CoreAI/PetAI.cpp
+++ b/src/server/game/AI/CoreAI/PetAI.cpp
@@ -280,7 +280,7 @@ void PetAI::UpdateAllies()
for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next())
{
Player* Target = itr->GetSource();
- if (!Target || !group->SameSubGroup(owner->ToPlayer(), Target))
+ if (!Target || !Target->IsInMap(owner) || !group->SameSubGroup(owner->ToPlayer(), Target))
continue;
if (Target->GetGUID() == owner->GetGUID())
diff --git a/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp b/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp
index 369c92d4153..93f31a0f57a 100644
--- a/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp
+++ b/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp
@@ -150,7 +150,8 @@ void npc_escortAI::JustDied(Unit* /*killer*/)
{
for (GroupReference* groupRef = group->GetFirstMember(); groupRef != NULL; groupRef = groupRef->next())
if (Player* member = groupRef->GetSource())
- member->FailQuest(m_pQuestForEscort->GetQuestId());
+ if (member->IsInMap(player))
+ member->FailQuest(m_pQuestForEscort->GetQuestId());
}
else
player->FailQuest(m_pQuestForEscort->GetQuestId());
diff --git a/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp b/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp
index a2677b3bdf2..cf6c693fb7a 100644
--- a/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp
+++ b/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp
@@ -148,7 +148,8 @@ void FollowerAI::JustDied(Unit* /*killer*/)
{
for (GroupReference* groupRef = group->GetFirstMember(); groupRef != NULL; groupRef = groupRef->next())
if (Player* member = groupRef->GetSource())
- member->FailQuest(m_pQuestForFollow->GetQuestId());
+ if (member->IsInMap(player))
+ member->FailQuest(m_pQuestForFollow->GetQuestId());
}
else
player->FailQuest(m_pQuestForFollow->GetQuestId());
@@ -226,7 +227,6 @@ void FollowerAI::UpdateAI(uint32 uiDiff)
for (GroupReference* groupRef = group->GetFirstMember(); groupRef != NULL; groupRef = groupRef->next())
{
Player* member = groupRef->GetSource();
-
if (member && me->IsWithinDistInMap(member, MAX_PLAYER_DISTANCE))
{
bIsMaxRangeExceeded = false;
@@ -333,8 +333,7 @@ Player* FollowerAI::GetLeaderForFollower()
for (GroupReference* groupRef = group->GetFirstMember(); groupRef != NULL; groupRef = groupRef->next())
{
Player* member = groupRef->GetSource();
-
- if (member && member->IsAlive() && me->IsWithinDistInMap(member, MAX_PLAYER_DISTANCE))
+ if (member && me->IsWithinDistInMap(member, MAX_PLAYER_DISTANCE) && member->IsAlive())
{
TC_LOG_DEBUG("scripts", "FollowerAI GetLeader changed and returned new leader.");
m_uiLeaderGUID = member->GetGUID();
diff --git a/src/server/game/AI/SmartScripts/SmartAI.cpp b/src/server/game/AI/SmartScripts/SmartAI.cpp
index 20efde08f1a..ed034cd3336 100644
--- a/src/server/game/AI/SmartScripts/SmartAI.cpp
+++ b/src/server/game/AI/SmartScripts/SmartAI.cpp
@@ -229,6 +229,8 @@ void SmartAI::EndPath(bool fail)
for (GroupReference* groupRef = group->GetFirstMember(); groupRef != nullptr; groupRef = groupRef->next())
{
Player* groupGuy = groupRef->GetSource();
+ if (!groupGuy->IsInMap(player))
+ continue;
if (!fail && groupGuy->IsAtGroupRewardDistance(me) && !groupGuy->HasCorpse())
groupGuy->AreaExploredOrEventHappens(mEscortQuestID);
@@ -384,8 +386,7 @@ bool SmartAI::IsEscortInvokerInRange()
for (GroupReference* groupRef = group->GetFirstMember(); groupRef != nullptr; groupRef = groupRef->next())
{
Player* groupGuy = groupRef->GetSource();
-
- if (me->GetDistance(groupGuy) <= SMART_ESCORT_MAX_PLAYER_DIST)
+ if (groupGuy->IsInMap(player) && me->GetDistance(groupGuy) <= SMART_ESCORT_MAX_PLAYER_DIST)
return true;
}
}
diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp
index 4d23ba14a5b..95a04a29cda 100644
--- a/src/server/game/AI/SmartScripts/SmartScript.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScript.cpp
@@ -2601,7 +2601,8 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
{
for (GroupReference* groupRef = group->GetFirstMember(); groupRef != nullptr; groupRef = groupRef->next())
if (Player* member = groupRef->GetSource())
- l->push_back(member);
+ if (member->IsInMap(player))
+ l->push_back(member);
}
// We still add the player to the list if there is no group. If we do
// this even if there is a group (thus the else-check), it will add the
@@ -2818,7 +2819,8 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
{
for (GroupReference* it = lootGroup->GetFirstMember(); it != nullptr; it = it->next())
if (Player* recipient = it->GetSource())
- l->push_back(recipient);
+ if (recipient->IsInMap(me))
+ l->push_back(recipient);
}
else
{
diff --git a/src/server/game/Combat/ThreatManager.h b/src/server/game/Combat/ThreatManager.h
index 4b739d192c1..e17a6926ffd 100644
--- a/src/server/game/Combat/ThreatManager.h
+++ b/src/server/game/Combat/ThreatManager.h
@@ -221,6 +221,7 @@ class TC_GAME_API ThreatManager
float getThreat(Unit* victim, bool alsoSearchOfflineList = false);
bool isThreatListEmpty() const { return iThreatContainer.empty(); }
+ bool areThreatListsEmpty() const { return iThreatContainer.empty() && iThreatOfflineContainer.empty(); }
void processThreatEvent(ThreatRefStatusChangeEvent* threatRefStatusChangeEvent);
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp
index 0d18b915144..3c6fae376fc 100644
--- a/src/server/game/Entities/Creature/Creature.cpp
+++ b/src/server/game/Entities/Creature/Creature.cpp
@@ -554,7 +554,7 @@ void Creature::Update(uint32 diff)
{
Group* group = sGroupMgr->GetGroupByGUID(lootingGroupLowGUID);
if (group)
- group->EndRoll(&loot);
+ group->EndRoll(&loot, GetMap());
m_groupLootTimer = 0;
lootingGroupLowGUID = 0;
}
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp
index 8b80d027c9f..b7f4433b63e 100644
--- a/src/server/game/Entities/GameObject/GameObject.cpp
+++ b/src/server/game/Entities/GameObject/GameObject.cpp
@@ -582,7 +582,7 @@ void GameObject::Update(uint32 diff)
{
Group* group = sGroupMgr->GetGroupByGUID(lootingGroupLowGUID);
if (group)
- group->EndRoll(&loot);
+ group->EndRoll(&loot, GetMap());
m_groupLootTimer = 0;
lootingGroupLowGUID = 0;
}
@@ -1290,7 +1290,7 @@ void GameObject::Use(Unit* user)
if (itr->second)
{
- if (Player* ChairUser = ObjectAccessor::FindPlayer(itr->second))
+ if (Player* ChairUser = ObjectAccessor::GetPlayer(*this, itr->second))
{
if (ChairUser->IsSitState() && ChairUser->GetStandState() != UNIT_STAND_STATE_SIT && ChairUser->GetExactDist2d(x_i, y_i) < 0.1f)
continue; // This seat is already occupied by ChairUser. NOTE: Not sure if the ChairUser->GetStandState() != UNIT_STAND_STATE_SIT check is required.
diff --git a/src/server/game/Entities/Player/KillRewarder.cpp b/src/server/game/Entities/Player/KillRewarder.cpp
index 0235866dbca..61a6277e6cd 100644
--- a/src/server/game/Entities/Player/KillRewarder.cpp
+++ b/src/server/game/Entities/Player/KillRewarder.cpp
@@ -90,7 +90,7 @@ inline void KillRewarder::_InitGroupData()
// 2. In case when player is in group, initialize variables necessary for group calculations:
for (GroupReference* itr = _group->GetFirstMember(); itr != nullptr; itr = itr->next())
if (Player* member = itr->GetSource())
- if (member->IsAlive() && member->IsAtGroupRewardDistance(_victim))
+ if (_killer == member || (member->IsAtGroupRewardDistance(_victim) && member->IsAlive()))
{
const uint8 lvl = member->getLevel();
// 2.1. _count - number of alive group members within reward distance;
@@ -235,7 +235,8 @@ void KillRewarder::_RewardGroup()
{
if (Player* member = itr->GetSource())
{
- if (member->IsAtGroupRewardDistance(_victim))
+ // Killer may not be at reward distance, check directly
+ if (_killer == member || member->IsAtGroupRewardDistance(_victim))
{
_RewardPlayer(member, isDungeon);
member->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL, 1, 0, _victim);
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 2edff5f9527..73a20ff0310 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -2145,6 +2145,8 @@ void Player::RemoveFromWorld()
StopCastingCharm();
StopCastingBindSight();
UnsummonPetTemporaryIfAny();
+ ClearComboPoints();
+ ClearComboPointHolders();
sOutdoorPvPMgr->HandlePlayerLeaveZone(this, m_zoneUpdateId);
sBattlefieldMgr->HandlePlayerLeaveZone(this, m_zoneUpdateId);
}
@@ -13467,6 +13469,17 @@ void Player::RemoveEnchantmentDurations(Item* item)
}
}
+void Player::RemoveEnchantmentDurationsReferences(Item* item)
+{
+ for (EnchantDurationList::iterator itr = m_enchantDuration.begin(); itr != m_enchantDuration.end();)
+ {
+ if (itr->item == item)
+ itr = m_enchantDuration.erase(itr);
+ else
+ ++itr;
+ }
+}
+
void Player::RemoveArenaEnchantments(EnchantmentSlot slot)
{
// remove enchantments from equipped items first to clean up the m_enchantDuration list
@@ -19605,6 +19618,10 @@ void Player::_SaveInventory(SQLTransaction& trans)
stmt->setUInt32(2, lowGuid);
trans->Append(stmt);
+ RemoveTradeableItem(item);
+ RemoveEnchantmentDurationsReferences(item);
+ RemoveItemDurations(item);
+
// also THIS item should be somewhere else, cheat attempt
item->FSetState(ITEM_REMOVED); // we are IN updateQueue right now, can't use SetState which modifies the queue
DeleteRefundReference(item->GetGUID());
@@ -23631,15 +23648,13 @@ void Player::RewardPlayerAndGroupAtEvent(uint32 creature_id, WorldObject* pRewar
bool Player::IsAtGroupRewardDistance(WorldObject const* pRewardSource) const
{
- if (!pRewardSource)
+ if (!pRewardSource || !IsInMap(pRewardSource))
return false;
+
const WorldObject* player = GetCorpse();
if (!player || IsAlive())
player = this;
- if (player->GetMapId() != pRewardSource->GetMapId() || player->GetInstanceId() != pRewardSource->GetInstanceId())
- return false;
-
if (player->GetMap()->IsDungeon())
return true;
@@ -23648,15 +23663,13 @@ bool Player::IsAtGroupRewardDistance(WorldObject const* pRewardSource) const
bool Player::IsAtRecruitAFriendDistance(WorldObject const* pOther) const
{
- if (!pOther)
+ if (!pOther || !IsInMap(pOther))
return false;
+
const WorldObject* player = GetCorpse();
if (!player || IsAlive())
player = this;
- if (player->GetMapId() != pOther->GetMapId() || player->GetInstanceId() != pOther->GetInstanceId())
- return false;
-
return pOther->GetDistance(player) <= sWorld->getFloatConfig(CONFIG_MAX_RECRUIT_A_FRIEND_DISTANCE);
}
@@ -23909,7 +23922,7 @@ PartyResult Player::CanUninviteFromGroup(ObjectGuid guidMember) const
/// @todo Should also be sent when anyone has recently left combat, with an aprox ~5 seconds timer.
for (GroupReference const* itr = grp->GetFirstMember(); itr != nullptr; itr = itr->next())
- if (itr->GetSource() && itr->GetSource()->IsInCombat())
+ if (itr->GetSource() && itr->GetSource()->IsInMap(this) && itr->GetSource()->IsInCombat())
return ERR_PARTY_LFG_BOOT_IN_COMBAT;
/* Missing support for these types
@@ -25753,7 +25766,6 @@ void Player::ActivateSpec(uint8 spec)
if (Pet* pet = GetPet())
RemovePet(pet, PET_SAVE_NOT_IN_SLOT);
- ClearComboPointHolders();
ClearAllReactives();
UnsummonAllTotems();
ExitVehicle();
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index 9e671a305b0..9fbac96b4e6 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -1291,6 +1291,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
void UpdateItemDuration(uint32 time, bool realtimeonly = false);
void AddEnchantmentDurations(Item* item);
void RemoveEnchantmentDurations(Item* item);
+ void RemoveEnchantmentDurationsReferences(Item* item);
void RemoveArenaEnchantments(EnchantmentSlot slot);
void AddEnchantmentDuration(Item* item, EnchantmentSlot slot, uint32 duration);
void ApplyEnchantment(Item* item, EnchantmentSlot slot, bool apply, bool apply_dur = true, bool ignore_condition = false);
diff --git a/src/server/game/Entities/Totem/Totem.cpp b/src/server/game/Entities/Totem/Totem.cpp
index 65d31fc45dd..74acba5c0a9 100644
--- a/src/server/game/Entities/Totem/Totem.cpp
+++ b/src/server/game/Entities/Totem/Totem.cpp
@@ -136,7 +136,7 @@ void Totem::UnSummon(uint32 msTime)
for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next())
{
Player* target = itr->GetSource();
- if (target && group->SameSubGroup(owner, target))
+ if (target && target->IsInMap(owner) && group->SameSubGroup(owner, target))
target->RemoveAurasDueToSpell(GetSpell(), GetGUID());
}
}
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 3407c63aa38..61cfa0322fd 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -6491,12 +6491,12 @@ Unit* Unit::GetNextRandomRaidMemberOrPet(float radius)
if (Player* Target = itr->GetSource())
{
// IsHostileTo check duel and controlled by enemy
- if (Target != this && Target->IsAlive() && IsWithinDistInMap(Target, radius) && !IsHostileTo(Target))
+ if (Target != this && IsWithinDistInMap(Target, radius) && Target->IsAlive() && !IsHostileTo(Target))
nearMembers.push_back(Target);
// Push player's pet to vector
if (Unit* pet = Target->GetGuardianPet())
- if (pet != this && pet->IsAlive() && IsWithinDistInMap(pet, radius) && !IsHostileTo(pet))
+ if (pet != this && IsWithinDistInMap(pet, radius) && pet->IsAlive() && !IsHostileTo(pet))
nearMembers.push_back(pet);
}
@@ -10371,7 +10371,7 @@ void Unit::CleanupBeforeRemoveFromMap(bool finalCleanup)
CombatStop();
ClearComboPointHolders();
DeleteThreatList();
- getHostileRefManager().setOnlineOfflineState(false);
+ getHostileRefManager().deleteReferences();
GetMotionMaster()->Clear(false); // remove different non-standard movement generators.
}
@@ -12555,23 +12555,23 @@ void Unit::GetPartyMembers(std::list<Unit*> &TagUnitMap)
Player* Target = itr->GetSource();
// IsHostileTo check duel and controlled by enemy
- if (Target && Target->GetSubGroup() == subgroup && !IsHostileTo(Target))
+ if (Target && Target->IsInMap(owner) && Target->GetSubGroup() == subgroup && !IsHostileTo(Target))
{
- if (Target->IsAlive() && IsInMap(Target))
+ if (Target->IsAlive())
TagUnitMap.push_back(Target);
if (Guardian* pet = Target->GetGuardianPet())
- if (pet->IsAlive() && IsInMap(Target))
+ if (pet->IsAlive())
TagUnitMap.push_back(pet);
}
}
}
else
{
- if (owner->IsAlive() && (owner == this || IsInMap(owner)))
+ if ((owner == this || IsInMap(owner)) && owner->IsAlive())
TagUnitMap.push_back(owner);
if (Guardian* pet = owner->GetGuardianPet())
- if (pet->IsAlive() && (pet == this || IsInMap(pet)))
+ if ((pet == this || IsInMap(pet)) && pet->IsAlive())
TagUnitMap.push_back(pet);
}
}
diff --git a/src/server/game/Grids/ObjectGridLoader.cpp b/src/server/game/Grids/ObjectGridLoader.cpp
index 48d4ef634fd..1cdedf34ec5 100644
--- a/src/server/game/Grids/ObjectGridLoader.cpp
+++ b/src/server/game/Grids/ObjectGridLoader.cpp
@@ -216,7 +216,7 @@ void ObjectGridStoper::Visit(CreatureMapType &m)
for (CreatureMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
{
iter->GetSource()->RemoveAllDynObjects();
- if (iter->GetSource()->IsInCombat())
+ if (iter->GetSource()->IsInCombat() || !iter->GetSource()->getThreatManager().areThreatListsEmpty())
{
iter->GetSource()->CombatStop();
iter->GetSource()->DeleteThreatList();
diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp
index 11d29ba8b62..30ecfb83f59 100644
--- a/src/server/game/Groups/Group.cpp
+++ b/src/server/game/Groups/Group.cpp
@@ -1343,16 +1343,16 @@ void Group::CountRollVote(ObjectGuid playerGUID, ObjectGuid Guid, uint8 Choice)
}
if (roll->totalPass + roll->totalNeed + roll->totalGreed >= roll->totalPlayersRolling)
- CountTheRoll(rollI);
+ CountTheRoll(rollI, nullptr);
}
//called when roll timer expires
-void Group::EndRoll(Loot* pLoot)
+void Group::EndRoll(Loot* pLoot, Map* allowedMap)
{
for (Rolls::iterator itr = RollId.begin(); itr != RollId.end();)
{
if ((*itr)->getLoot() == pLoot) {
- CountTheRoll(itr); //i don't have to edit player votes, who didn't vote ... he will pass
+ CountTheRoll(itr, allowedMap); //i don't have to edit player votes, who didn't vote ... he will pass
itr = RollId.begin();
}
else
@@ -1360,7 +1360,7 @@ void Group::EndRoll(Loot* pLoot)
}
}
-void Group::CountTheRoll(Rolls::iterator rollI)
+void Group::CountTheRoll(Rolls::iterator rollI, Map* allowedMap)
{
Roll* roll = *rollI;
if (!roll->isValid()) // is loot already deleted ?
@@ -1376,14 +1376,21 @@ void Group::CountTheRoll(Rolls::iterator rollI)
if (!roll->playerVote.empty())
{
uint8 maxresul = 0;
- ObjectGuid maxguid = (*roll->playerVote.begin()).first;
- Player* player;
+ ObjectGuid maxguid = ObjectGuid::Empty;
+ Player* player = nullptr;
for (Roll::PlayerVote::const_iterator itr=roll->playerVote.begin(); itr != roll->playerVote.end(); ++itr)
{
if (itr->second != NEED)
continue;
+ player = ObjectAccessor::FindPlayer(itr->first);
+ if (!player || (allowedMap != nullptr && player->FindMap() != allowedMap))
+ {
+ --roll->totalNeed;
+ continue;
+ }
+
uint8 randomN = urand(1, 100);
SendLootRoll(ObjectGuid::Empty, itr->first, randomN, ROLL_NEED, *roll);
if (maxresul < randomN)
@@ -1392,39 +1399,46 @@ void Group::CountTheRoll(Rolls::iterator rollI)
maxresul = randomN;
}
}
- SendLootRollWon(ObjectGuid::Empty, maxguid, maxresul, ROLL_NEED, *roll);
- player = ObjectAccessor::FindConnectedPlayer(maxguid);
- if (player && player->GetSession())
+ if (!maxguid.IsEmpty())
{
- player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED_ON_LOOT, roll->itemid, maxresul);
+ SendLootRollWon(ObjectGuid::Empty, maxguid, maxresul, ROLL_NEED, *roll);
+ player = ObjectAccessor::FindConnectedPlayer(maxguid);
- ItemPosCountVec dest;
- LootItem* item = &(roll->itemSlot >= roll->getLoot()->items.size() ? roll->getLoot()->quest_items[roll->itemSlot - roll->getLoot()->items.size()] : roll->getLoot()->items[roll->itemSlot]);
- InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, roll->itemid, item->count);
- if (msg == EQUIP_ERR_OK)
+ if (player && player->GetSession())
{
- item->is_looted = true;
- roll->getLoot()->NotifyItemRemoved(roll->itemSlot);
- roll->getLoot()->unlootedCount--;
- player->StoreNewItem(dest, roll->itemid, true, item->randomPropertyId, item->GetAllowedLooters());
- }
- else
- {
- item->is_blocked = false;
- item->rollWinnerGUID = player->GetGUID();
- player->SendEquipError(msg, nullptr, nullptr, roll->itemid);
+ player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED_ON_LOOT, roll->itemid, maxresul);
+
+ ItemPosCountVec dest;
+ LootItem* item = &(roll->itemSlot >= roll->getLoot()->items.size() ? roll->getLoot()->quest_items[roll->itemSlot - roll->getLoot()->items.size()] : roll->getLoot()->items[roll->itemSlot]);
+ InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, roll->itemid, item->count);
+ if (msg == EQUIP_ERR_OK)
+ {
+ item->is_looted = true;
+ roll->getLoot()->NotifyItemRemoved(roll->itemSlot);
+ roll->getLoot()->unlootedCount--;
+ player->StoreNewItem(dest, roll->itemid, true, item->randomPropertyId, item->GetAllowedLooters());
+ }
+ else
+ {
+ item->is_blocked = false;
+ item->rollWinnerGUID = player->GetGUID();
+ player->SendEquipError(msg, NULL, NULL, roll->itemid);
+ }
}
}
+ else
+ roll->totalNeed = 0;
}
}
- else if (roll->totalGreed > 0)
+
+ if (roll->totalNeed == 0 && roll->totalGreed > 0) // if (roll->totalNeed == 0 && ...), not else if, because numbers can be modified above if player is on a different map
{
if (!roll->playerVote.empty())
{
uint8 maxresul = 0;
- ObjectGuid maxguid = (*roll->playerVote.begin()).first;
- Player* player;
+ ObjectGuid maxguid = ObjectGuid::Empty;
+ Player* player = nullptr;
RollVote rollvote = NOT_VALID;
Roll::PlayerVote::iterator itr;
@@ -1433,6 +1447,13 @@ void Group::CountTheRoll(Rolls::iterator rollI)
if (itr->second != GREED && itr->second != DISENCHANT)
continue;
+ player = ObjectAccessor::FindPlayer(itr->first);
+ if (!player || (allowedMap != NULL && player->FindMap() != allowedMap))
+ {
+ --roll->totalGreed;
+ continue;
+ }
+
uint8 randomN = urand(1, 100);
SendLootRoll(ObjectGuid::Empty, itr->first, randomN, itr->second, *roll);
if (maxresul < randomN)
@@ -1442,63 +1463,70 @@ void Group::CountTheRoll(Rolls::iterator rollI)
rollvote = itr->second;
}
}
- SendLootRollWon(ObjectGuid::Empty, maxguid, maxresul, rollvote, *roll);
- player = ObjectAccessor::FindConnectedPlayer(maxguid);
- if (player && player->GetSession())
+ if (!maxguid.IsEmpty())
{
- player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED_ON_LOOT, roll->itemid, maxresul);
-
- LootItem* item = &(roll->itemSlot >= roll->getLoot()->items.size() ? roll->getLoot()->quest_items[roll->itemSlot - roll->getLoot()->items.size()] : roll->getLoot()->items[roll->itemSlot]);
+ SendLootRollWon(ObjectGuid::Empty, maxguid, maxresul, rollvote, *roll);
+ player = ObjectAccessor::FindConnectedPlayer(maxguid);
- if (rollvote == GREED)
+ if (player && player->GetSession())
{
- ItemPosCountVec dest;
- InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, roll->itemid, item->count);
- if (msg == EQUIP_ERR_OK)
+ player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED_ON_LOOT, roll->itemid, maxresul);
+
+ LootItem* item = &(roll->itemSlot >= roll->getLoot()->items.size() ? roll->getLoot()->quest_items[roll->itemSlot - roll->getLoot()->items.size()] : roll->getLoot()->items[roll->itemSlot]);
+
+ if (rollvote == GREED)
+ {
+ ItemPosCountVec dest;
+ InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, roll->itemid, item->count);
+ if (msg == EQUIP_ERR_OK)
+ {
+ item->is_looted = true;
+ roll->getLoot()->NotifyItemRemoved(roll->itemSlot);
+ roll->getLoot()->unlootedCount--;
+ player->StoreNewItem(dest, roll->itemid, true, item->randomPropertyId, item->GetAllowedLooters());
+ }
+ else
+ {
+ item->is_blocked = false;
+ item->rollWinnerGUID = player->GetGUID();
+ player->SendEquipError(msg, NULL, NULL, roll->itemid);
+ }
+ }
+ else if (rollvote == DISENCHANT)
{
item->is_looted = true;
roll->getLoot()->NotifyItemRemoved(roll->itemSlot);
roll->getLoot()->unlootedCount--;
- player->StoreNewItem(dest, roll->itemid, true, item->randomPropertyId, item->GetAllowedLooters());
- }
- else
- {
- item->is_blocked = false;
- item->rollWinnerGUID = player->GetGUID();
- player->SendEquipError(msg, nullptr, nullptr, roll->itemid);
- }
- }
- else if (rollvote == DISENCHANT)
- {
- item->is_looted = true;
- roll->getLoot()->NotifyItemRemoved(roll->itemSlot);
- roll->getLoot()->unlootedCount--;
- ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(roll->itemid);
- player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL, 13262); // Disenchant
-
- ItemPosCountVec dest;
- InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, roll->itemid, item->count);
- if (msg == EQUIP_ERR_OK)
- player->AutoStoreLoot(pProto->DisenchantID, LootTemplates_Disenchant, true);
- else // If the player's inventory is full, send the disenchant result in a mail.
- {
- Loot loot;
- loot.FillLoot(pProto->DisenchantID, LootTemplates_Disenchant, player, true);
-
- uint32 max_slot = loot.GetMaxSlotInLootFor(player);
- for (uint32 i = 0; i < max_slot; ++i)
+ ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(roll->itemid);
+ player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL, 13262); // Disenchant
+
+ ItemPosCountVec dest;
+ InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, roll->itemid, item->count);
+ if (msg == EQUIP_ERR_OK)
+ player->AutoStoreLoot(pProto->DisenchantID, LootTemplates_Disenchant, true);
+ else // If the player's inventory is full, send the disenchant result in a mail.
{
- LootItem* lootItem = loot.LootItemInSlot(i, player);
- player->SendEquipError(msg, nullptr, nullptr, lootItem->itemid);
- player->SendItemRetrievalMail(lootItem->itemid, lootItem->count);
+ Loot loot;
+ loot.FillLoot(pProto->DisenchantID, LootTemplates_Disenchant, player, true);
+
+ uint32 max_slot = loot.GetMaxSlotInLootFor(player);
+ for (uint32 i = 0; i < max_slot; ++i)
+ {
+ LootItem* lootItem = loot.LootItemInSlot(i, player);
+ player->SendEquipError(msg, NULL, NULL, lootItem->itemid);
+ player->SendItemRetrievalMail(lootItem->itemid, lootItem->count);
+ }
}
}
}
}
+ else
+ roll->totalGreed = 0;
}
}
- else
+
+ if (roll->totalNeed == 0 && roll->totalGreed == 0) // if, not else, because numbers can be modified above if player is on a different map
{
SendLootAllPassed(*roll);
@@ -1988,7 +2016,7 @@ bool Group::InCombatToInstance(uint32 instanceId)
for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next())
{
Player* player = itr->GetSource();
- if (player && !player->getAttackers().empty() && player->GetInstanceId() == instanceId && (player->GetMap()->IsRaidOrHeroicDungeon()))
+ if (player && player->GetInstanceId() == instanceId && !player->getAttackers().empty() && (player->GetMap()->IsRaidOrHeroicDungeon()))
for (std::set<Unit*>::const_iterator i = player->getAttackers().begin(); i != player->getAttackers().end(); ++i)
if ((*i) && (*i)->GetTypeId() == TYPEID_UNIT && (*i)->ToCreature()->GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_INSTANCE_BIND)
return true;
diff --git a/src/server/game/Groups/Group.h b/src/server/game/Groups/Group.h
index d2c4ec692ba..cd8c50a8efd 100644
--- a/src/server/game/Groups/Group.h
+++ b/src/server/game/Groups/Group.h
@@ -303,9 +303,9 @@ class TC_GAME_API Group
void NeedBeforeGreed(Loot* loot, WorldObject* pLootedObject);
void MasterLoot(Loot* loot, WorldObject* pLootedObject);
Rolls::iterator GetRoll(ObjectGuid Guid);
- void CountTheRoll(Rolls::iterator roll);
+ void CountTheRoll(Rolls::iterator roll, Map* allowedMap);
void CountRollVote(ObjectGuid playerGUID, ObjectGuid Guid, uint8 Choise);
- void EndRoll(Loot* loot);
+ void EndRoll(Loot* loot, Map* allowedMap);
// related to disenchant rolls
void ResetMaxEnchantingLevel();
diff --git a/src/server/game/Loot/LootMgr.cpp b/src/server/game/Loot/LootMgr.cpp
index d25eca4b036..9d56d8decb3 100644
--- a/src/server/game/Loot/LootMgr.cpp
+++ b/src/server/game/Loot/LootMgr.cpp
@@ -464,7 +464,8 @@ bool Loot::FillLoot(uint32 lootId, LootStore const& store, Player* lootOwner, bo
for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next())
if (Player* player = itr->GetSource()) // should actually be looted object instead of lootOwner but looter has to be really close so doesnt really matter
- FillNotNormalLootFor(player, player->IsAtGroupRewardDistance(lootOwner));
+ if (player->IsInMap(lootOwner))
+ FillNotNormalLootFor(player, player->IsAtGroupRewardDistance(lootOwner));
for (uint8 i = 0; i < items.size(); ++i)
{
diff --git a/src/server/scripts/EasternKingdoms/Stratholme/stratholme.cpp b/src/server/scripts/EasternKingdoms/Stratholme/stratholme.cpp
index 03dd3986a4a..3ccf0e3dd19 100644
--- a/src/server/scripts/EasternKingdoms/Stratholme/stratholme.cpp
+++ b/src/server/scripts/EasternKingdoms/Stratholme/stratholme.cpp
@@ -61,7 +61,7 @@ public:
for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next())
{
Player* pGroupie = itr->GetSource();
- if (!pGroupie)
+ if (!pGroupie || !pGroupie->IsInMap(player))
continue;
if (pGroupie->GetQuestStatus(QUEST_DEAD_MAN_PLEA) == QUEST_STATUS_INCOMPLETE &&
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp
index 3567acb001b..a751e9e172c 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp
@@ -367,7 +367,8 @@ class boss_lady_deathwhisper : public CreatureScript
{
for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
if (Player* member = itr->GetSource())
- member->KilledMonsterCredit(NPC_DARNAVAN_CREDIT);
+ if (member->IsInMap(owner))
+ member->KilledMonsterCredit(NPC_DARNAVAN_CREDIT);
}
else
owner->KilledMonsterCredit(NPC_DARNAVAN_CREDIT);
@@ -881,7 +882,8 @@ class npc_darnavan : public CreatureScript
{
for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
if (Player* member = itr->GetSource())
- member->FailQuest(QUEST_DEPROGRAMMING);
+ if (member->IsInMap(owner))
+ member->FailQuest(QUEST_DEPROGRAMMING);
}
else
owner->FailQuest(QUEST_DEPROGRAMMING);
diff --git a/src/server/scripts/Outland/zone_terokkar_forest.cpp b/src/server/scripts/Outland/zone_terokkar_forest.cpp
index 1927dae9d57..d2a7a29e01a 100644
--- a/src/server/scripts/Outland/zone_terokkar_forest.cpp
+++ b/src/server/scripts/Outland/zone_terokkar_forest.cpp
@@ -114,7 +114,7 @@ public:
for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next())
{
Player* groupie = itr->GetSource();
- if (groupie &&
+ if (groupie && groupie->IsInMap(player) &&
groupie->GetQuestStatus(QUEST_DONTKILLTHEFATONE) == QUEST_STATUS_INCOMPLETE &&
groupie->GetReqKillOrCastCurrentCount(QUEST_DONTKILLTHEFATONE, NPC_BOULDERFIST_INVADER) == REQUIRED_KILL_COUNT)
{