Core/Misc: Various crash fixes
This commit is contained in:
1 parent
02e174d7e9
commit
b88200cd58
22 files changed
+79
-60
No files matched your search
@@ -461,7 +461,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
|
||||
if (IsUnit(*itr))
|
||||
if (Vehicle* vehicle = (*itr)->ToUnit()->GetVehicleKit())
|
||||
for (SeatMap::iterator it = vehicle->Seats.begin(); it != vehicle->Seats.end(); ++it)
|
||||
if (Player* player = ObjectAccessor::FindPlayer(it->second.Passenger.Guid))
|
||||
if (Player* player = ObjectAccessor::GetPlayer(*(*itr), it->second.Passenger.Guid))
|
||||
player->AreaExploredOrEventHappens(e.action.quest.quest);
|
||||
|
||||
if (IsPlayer(*itr))
|
||||
@@ -547,7 +547,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
|
||||
}
|
||||
case SMART_ACTION_INVOKER_CAST:
|
||||
{
|
||||
Unit* tempLastInvoker = GetLastInvoker();
|
||||
Unit* tempLastInvoker = GetLastInvoker(unit);
|
||||
if (!tempLastInvoker)
|
||||
break;
|
||||
|
||||
@@ -805,7 +805,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
|
||||
// Special handling for vehicles
|
||||
if (Vehicle* vehicle = unit->GetVehicleKit())
|
||||
for (SeatMap::iterator it = vehicle->Seats.begin(); it != vehicle->Seats.end(); ++it)
|
||||
if (Player* player = ObjectAccessor::FindPlayer(it->second.Passenger.Guid))
|
||||
if (Player* player = ObjectAccessor::GetPlayer(*unit, it->second.Passenger.Guid))
|
||||
player->GroupEventHappens(e.action.quest.quest, GetBaseObject());
|
||||
break;
|
||||
}
|
||||
@@ -950,7 +950,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
|
||||
else if (IsUnit(*itr)) // Special handling for vehicles
|
||||
if (Vehicle* vehicle = (*itr)->ToUnit()->GetVehicleKit())
|
||||
for (SeatMap::iterator seatItr = vehicle->Seats.begin(); seatItr != vehicle->Seats.end(); ++seatItr)
|
||||
if (Player* player = ObjectAccessor::FindPlayer(seatItr->second.Passenger.Guid))
|
||||
if (Player* player = ObjectAccessor::GetPlayer(*(*itr), seatItr->second.Passenger.Guid))
|
||||
player->KilledMonsterCredit(e.action.killedMonster.creature);
|
||||
}
|
||||
|
||||
@@ -4082,14 +4082,14 @@ void SmartScript::SetScript9(SmartScriptHolder& e, uint32 entry)
|
||||
}
|
||||
}
|
||||
|
||||
Unit* SmartScript::GetLastInvoker()
|
||||
Unit* SmartScript::GetLastInvoker(Unit* invoker)
|
||||
{
|
||||
WorldObject* lookupRoot = me;
|
||||
if (!lookupRoot)
|
||||
lookupRoot = go;
|
||||
// Look for invoker only on map of base object... Prevents multithreaded crashes
|
||||
if (WorldObject* baseObject = GetBaseObject())
|
||||
return ObjectAccessor::GetUnit(*baseObject, mLastInvoker);
|
||||
// used for area triggers invoker cast
|
||||
else if (invoker)
|
||||
return ObjectAccessor::GetUnit(*invoker, mLastInvoker);
|
||||
|
||||
if (lookupRoot)
|
||||
return ObjectAccessor::GetUnit(*lookupRoot, mLastInvoker);
|
||||
|
||||
return ObjectAccessor::FindPlayer(mLastInvoker);
|
||||
return nullptr;
|
||||
}
|
||||
@@ -235,7 +235,7 @@ class TC_GAME_API SmartScript
|
||||
|
||||
//TIMED_ACTIONLIST (script type 9 aka script9)
|
||||
void SetScript9(SmartScriptHolder& e, uint32 entry);
|
||||
Unit* GetLastInvoker();
|
||||
Unit* GetLastInvoker(Unit* invoker = nullptr);
|
||||
ObjectGuid mLastInvoker;
|
||||
typedef std::unordered_map<uint32, uint32> CounterMap;
|
||||
CounterMap mCounterList;
|
||||
|
||||
@@ -422,7 +422,8 @@ void ThreatManager::doAddThreat(Unit* victim, float threat)
|
||||
{
|
||||
float redirectThreat = CalculatePct(threat, redirectThreadPct);
|
||||
threat -= redirectThreat;
|
||||
_addThreat(redirectTarget, redirectThreat);
|
||||
if (ThreatCalcHelper::isValidProcess(redirectTarget, GetOwner()))
|
||||
_addThreat(redirectTarget, redirectThreat);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1346,7 +1346,7 @@ void LFGMgr::TeleportPlayer(Player* player, bool out, bool fromOpcode /*= false*
|
||||
@param[in] guid Group guid
|
||||
@param[in] dungeonId Dungeonid
|
||||
*/
|
||||
void LFGMgr::FinishDungeon(ObjectGuid gguid, const uint32 dungeonId)
|
||||
void LFGMgr::FinishDungeon(ObjectGuid gguid, const uint32 dungeonId, Map const* currMap)
|
||||
{
|
||||
uint32 gDungeonId = GetDungeon(gguid);
|
||||
if (gDungeonId != dungeonId)
|
||||
@@ -1390,7 +1390,7 @@ void LFGMgr::FinishDungeon(ObjectGuid gguid, const uint32 dungeonId)
|
||||
}
|
||||
|
||||
Player* player = ObjectAccessor::FindPlayer(guid);
|
||||
if (!player)
|
||||
if (!player || player->FindMap() != currMap)
|
||||
{
|
||||
TC_LOG_DEBUG("lfg.dungeon.finish", "Group: %s, Player: %s not found in world", gguid.ToString().c_str(), guid.ToString().c_str());
|
||||
continue;
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
class Group;
|
||||
class Player;
|
||||
class Quest;
|
||||
class Map;
|
||||
|
||||
namespace lfg
|
||||
{
|
||||
@@ -309,7 +310,7 @@ class TC_GAME_API LFGMgr
|
||||
|
||||
// World.cpp
|
||||
/// Finish the dungeon for the given group. All check are performed using internal lfg data
|
||||
void FinishDungeon(ObjectGuid gguid, uint32 dungeonId);
|
||||
void FinishDungeon(ObjectGuid gguid, uint32 dungeonId, Map const* currMap);
|
||||
/// Loads rewards for random dungeons
|
||||
void LoadRewards();
|
||||
/// Loads dungeons from dbc and adds teleport coords
|
||||
|
||||
@@ -2012,7 +2012,7 @@ void WorldObject::AddObjectToRemoveList()
|
||||
map->AddObjectToRemoveList(this);
|
||||
}
|
||||
|
||||
TempSummon* Map::SummonCreature(uint32 entry, Position const& pos, SummonPropertiesEntry const* properties /*= NULL*/, uint32 duration /*= 0*/, Unit* summoner /*= NULL*/, uint32 spellId /*= 0*/, uint32 vehId /*= 0*/)
|
||||
TempSummon* Map::SummonCreature(uint32 entry, Position const& pos, SummonPropertiesEntry const* properties /*= nullptr*/, uint32 duration /*= 0*/, Unit* summoner /*= nullptr*/, uint32 spellId /*= 0*/, uint32 vehId /*= 0*/)
|
||||
{
|
||||
uint32 mask = UNIT_MASK_SUMMON;
|
||||
if (properties)
|
||||
|
||||
@@ -2174,6 +2174,9 @@ void Player::RemoveFromWorld()
|
||||
UnsummonPetTemporaryIfAny();
|
||||
ClearComboPoints();
|
||||
ClearComboPointHolders();
|
||||
ObjectGuid lootGuid = GetLootGUID();
|
||||
if (!lootGuid.IsEmpty())
|
||||
m_session->DoLootRelease(lootGuid);
|
||||
sOutdoorPvPMgr->HandlePlayerLeaveZone(this, m_zoneUpdateId);
|
||||
sBattlefieldMgr->HandlePlayerLeaveZone(this, m_zoneUpdateId);
|
||||
}
|
||||
@@ -24315,7 +24318,7 @@ bool Player::IsAtGroupRewardDistance(WorldObject const* pRewardSource) const
|
||||
if (!player || IsAlive())
|
||||
player = this;
|
||||
|
||||
if (player->GetMap()->IsDungeon())
|
||||
if (pRewardSource->GetMap()->IsDungeon())
|
||||
return true;
|
||||
|
||||
return pRewardSource->GetDistance(player) <= sWorld->getFloatConfig(CONFIG_GROUP_XP_DISTANCE);
|
||||
|
||||
@@ -10833,7 +10833,7 @@ void Unit::ClearComboPointHolders()
|
||||
{
|
||||
ObjectGuid guid = *m_ComboPointHolders.begin();
|
||||
|
||||
Player* player = ObjectAccessor::FindPlayer(guid);
|
||||
Player* player = ObjectAccessor::GetPlayer(*this, guid);
|
||||
if (player && player->GetComboTarget() == GetGUID()) // recheck for safe
|
||||
player->ClearComboPoints(); // remove also guid from m_ComboPointHolders;
|
||||
else
|
||||
|
||||
@@ -1028,21 +1028,18 @@ void Group::GroupLoot(Loot* loot, WorldObject* pLootedObject)
|
||||
Player* member = itr->GetSource();
|
||||
if (!member || !member->GetSession())
|
||||
continue;
|
||||
if (i->AllowedForPlayer(member))
|
||||
if (member->IsAtGroupRewardDistance(pLootedObject) && i->AllowedForPlayer(member))
|
||||
{
|
||||
if (member->IsAtGroupRewardDistance(pLootedObject))
|
||||
{
|
||||
r->totalPlayersRolling++;
|
||||
r->totalPlayersRolling++;
|
||||
|
||||
if (member->GetPassOnGroupLoot())
|
||||
{
|
||||
r->playerVote[member->GetGUID()] = PASS;
|
||||
r->totalPass++;
|
||||
// can't broadcast the pass now. need to wait until all rolling players are known.
|
||||
}
|
||||
else
|
||||
r->playerVote[member->GetGUID()] = NOT_EMITED_YET;
|
||||
if (member->GetPassOnGroupLoot())
|
||||
{
|
||||
r->playerVote[member->GetGUID()] = PASS;
|
||||
r->totalPass++;
|
||||
// can't broadcast the pass now. need to wait until all rolling players are known.
|
||||
}
|
||||
else
|
||||
r->playerVote[member->GetGUID()] = NOT_EMITED_YET;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1114,13 +1111,10 @@ void Group::GroupLoot(Loot* loot, WorldObject* pLootedObject)
|
||||
if (!member || !member->GetSession())
|
||||
continue;
|
||||
|
||||
if (i->AllowedForPlayer(member))
|
||||
if (member->IsAtGroupRewardDistance(pLootedObject) && i->AllowedForPlayer(member))
|
||||
{
|
||||
if (member->IsAtGroupRewardDistance(pLootedObject))
|
||||
{
|
||||
r->totalPlayersRolling++;
|
||||
r->playerVote[member->GetGUID()] = NOT_EMITED_YET;
|
||||
}
|
||||
r->totalPlayersRolling++;
|
||||
r->playerVote[member->GetGUID()] = NOT_EMITED_YET;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1175,8 +1169,7 @@ void Group::NeedBeforeGreed(Loot* loot, WorldObject* lootedObject)
|
||||
if (!playerToRoll || !playerToRoll->GetSession())
|
||||
continue;
|
||||
|
||||
bool allowedForPlayer = i->AllowedForPlayer(playerToRoll);
|
||||
if (allowedForPlayer && playerToRoll->IsAtGroupRewardDistance(lootedObject))
|
||||
if (playerToRoll->IsAtGroupRewardDistance(lootedObject) && i->AllowedForPlayer(playerToRoll))
|
||||
{
|
||||
r->totalPlayersRolling++;
|
||||
if (playerToRoll->GetPassOnGroupLoot())
|
||||
@@ -1251,8 +1244,7 @@ void Group::NeedBeforeGreed(Loot* loot, WorldObject* lootedObject)
|
||||
if (!playerToRoll || !playerToRoll->GetSession())
|
||||
continue;
|
||||
|
||||
bool allowedForPlayer = i->AllowedForPlayer(playerToRoll);
|
||||
if (allowedForPlayer && playerToRoll->IsAtGroupRewardDistance(lootedObject))
|
||||
if (playerToRoll->IsAtGroupRewardDistance(lootedObject) && i->AllowedForPlayer(playerToRoll))
|
||||
{
|
||||
r->totalPlayersRolling++;
|
||||
r->playerVote[playerToRoll->GetGUID()] = NOT_EMITED_YET;
|
||||
|
||||
@@ -445,7 +445,8 @@ void WorldSession::HandleLootMasterGiveOpcode(WorldPacket& recvData)
|
||||
return;
|
||||
}
|
||||
|
||||
Player* target = ObjectAccessor::FindPlayer(target_playerguid);
|
||||
// player on other map
|
||||
Player* target = ObjectAccessor::GetPlayer(*_player, target_playerguid);
|
||||
if (!target)
|
||||
{
|
||||
_player->SendLootError(lootguid, LOOT_ERROR_PLAYER_NOT_FOUND);
|
||||
|
||||
@@ -1065,7 +1065,7 @@ void WorldSession::HandleInspectOpcode(WorldPacket& recvData)
|
||||
|
||||
TC_LOG_DEBUG("network", "WORLD: Received CMSG_INSPECT");
|
||||
|
||||
Player* player = ObjectAccessor::FindPlayer(guid);
|
||||
Player* player = ObjectAccessor::GetPlayer(*_player, guid);
|
||||
if (!player)
|
||||
{
|
||||
TC_LOG_DEBUG("network", "CMSG_INSPECT: No player found from %s", guid.ToString().c_str());
|
||||
@@ -1122,7 +1122,7 @@ void WorldSession::HandleInspectHonorStatsOpcode(WorldPacket& recvData)
|
||||
recvData.ReadByteSeq(guid[6]);
|
||||
recvData.ReadByteSeq(guid[2]);
|
||||
recvData.ReadByteSeq(guid[3]);
|
||||
Player* player = ObjectAccessor::FindPlayer(guid);
|
||||
Player* player = ObjectAccessor::GetPlayer(*_player, guid);
|
||||
if (!player)
|
||||
{
|
||||
TC_LOG_DEBUG("network", "CMSG_INSPECT_HONOR_STATS: No player found from %s", guid.ToString().c_str());
|
||||
@@ -1567,7 +1567,7 @@ void WorldSession::HandleQueryInspectAchievements(WorldPacket& recvData)
|
||||
recvData >> guid.ReadAsPacked();
|
||||
|
||||
TC_LOG_DEBUG("network", "CMSG_QUERY_INSPECT_ACHIEVEMENTS [%s] Inspected Player [%s]", _player->GetGUID().ToString().c_str(), guid.ToString().c_str());
|
||||
Player* player = ObjectAccessor::FindPlayer(guid);
|
||||
Player* player = ObjectAccessor::GetPlayer(*_player, guid);
|
||||
if (!player)
|
||||
return;
|
||||
|
||||
|
||||
@@ -711,7 +711,7 @@ void WorldSession::HandlePetSpellAutocastOpcode(WorldPacket& recvPacket)
|
||||
if (!_player->GetGuardianPet() && !_player->GetCharm())
|
||||
return;
|
||||
|
||||
if (ObjectAccessor::FindPlayer(guid))
|
||||
if (guid.IsPlayer())
|
||||
return;
|
||||
|
||||
Creature* pet=ObjectAccessor::GetCreatureOrPetOrVehicle(*_player, guid);
|
||||
|
||||
@@ -142,7 +142,7 @@ void WorldSession::HandleEnterPlayerVehicle(WorldPacket& data)
|
||||
ObjectGuid guid;
|
||||
data >> guid;
|
||||
|
||||
if (Player* player = ObjectAccessor::FindPlayer(guid))
|
||||
if (Player* player = ObjectAccessor::GetPlayer(*_player, guid))
|
||||
{
|
||||
if (!player->GetVehicleKit())
|
||||
return;
|
||||
@@ -150,6 +150,9 @@ void WorldSession::HandleEnterPlayerVehicle(WorldPacket& data)
|
||||
return;
|
||||
if (!player->IsWithinDistInMap(_player, INTERACTION_DISTANCE))
|
||||
return;
|
||||
// Dont' allow players to enter player vehicle on arena
|
||||
if (!_player->FindMap() || _player->FindMap()->IsBattleArena())
|
||||
return;
|
||||
|
||||
_player->EnterVehicle(player);
|
||||
}
|
||||
|
||||
@@ -679,7 +679,7 @@ void InstanceScript::UpdateEncounterState(EncounterCreditType type, uint32 credi
|
||||
if (Group* grp = player->GetGroup())
|
||||
if (grp->isLFGGroup())
|
||||
{
|
||||
sLFGMgr->FinishDungeon(grp->GetGUID(), dungeonId);
|
||||
sLFGMgr->FinishDungeon(grp->GetGUID(), dungeonId, instance);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3447,6 +3447,11 @@ void BattlegroundMap::RemoveAllPlayers()
|
||||
player->TeleportTo(player->GetBattlegroundEntryPoint());
|
||||
}
|
||||
|
||||
Player* Map::GetPlayer(ObjectGuid const& guid)
|
||||
{
|
||||
return ObjectAccessor::GetPlayer(this, guid);
|
||||
}
|
||||
|
||||
AreaTrigger* Map::GetAreaTrigger(ObjectGuid const& guid)
|
||||
{
|
||||
return _objectsStore.Find<AreaTrigger>(guid);
|
||||
|
||||
@@ -446,8 +446,9 @@ class TC_GAME_API Map : public GridRefManager<NGridType>
|
||||
|
||||
void UpdateIteratorBack(Player* player);
|
||||
|
||||
TempSummon* SummonCreature(uint32 entry, Position const& pos, SummonPropertiesEntry const* properties = NULL, uint32 duration = 0, Unit* summoner = NULL, uint32 spellId = 0, uint32 vehId = 0);
|
||||
void SummonCreatureGroup(uint8 group, std::list<TempSummon*>* list = NULL);
|
||||
TempSummon* SummonCreature(uint32 entry, Position const& pos, SummonPropertiesEntry const* properties = nullptr, uint32 duration = 0, Unit* summoner = nullptr, uint32 spellId = 0, uint32 vehId = 0);
|
||||
void SummonCreatureGroup(uint8 group, std::list<TempSummon*>* list = nullptr);
|
||||
Player* GetPlayer(ObjectGuid const& guid);
|
||||
AreaTrigger* GetAreaTrigger(ObjectGuid const& guid);
|
||||
Corpse* GetCorpse(ObjectGuid const& guid);
|
||||
Creature* GetCreature(ObjectGuid const& guid);
|
||||
|
||||
@@ -296,7 +296,7 @@ void Map::ScriptsProcess()
|
||||
switch (step.sourceGUID.GetHigh())
|
||||
{
|
||||
case HighGuid::Item: // as well as HighGuid::Container
|
||||
if (Player* player = HashMapHolder<Player>::Find(step.ownerGUID))
|
||||
if (Player* player = GetPlayer(step.ownerGUID))
|
||||
source = player->GetItemByGuid(step.sourceGUID);
|
||||
break;
|
||||
case HighGuid::Unit:
|
||||
@@ -307,7 +307,7 @@ void Map::ScriptsProcess()
|
||||
source = GetPet(step.sourceGUID);
|
||||
break;
|
||||
case HighGuid::Player:
|
||||
source = HashMapHolder<Player>::Find(step.sourceGUID);
|
||||
source = GetPlayer(step.sourceGUID);
|
||||
break;
|
||||
case HighGuid::Transport:
|
||||
case HighGuid::GameObject:
|
||||
@@ -339,7 +339,7 @@ void Map::ScriptsProcess()
|
||||
target = GetPet(step.targetGUID);
|
||||
break;
|
||||
case HighGuid::Player: // empty GUID case also
|
||||
target = HashMapHolder<Player>::Find(step.targetGUID);
|
||||
target = GetPlayer(step.targetGUID);
|
||||
break;
|
||||
case HighGuid::Transport:
|
||||
case HighGuid::GameObject:
|
||||
|
||||
@@ -971,8 +971,9 @@ bool Aura::CanBeSaved() const
|
||||
if (IsPassive())
|
||||
return false;
|
||||
|
||||
// Check if aura is single target, not only spell info
|
||||
if (GetCasterGUID() != GetOwner()->GetGUID())
|
||||
if (GetSpellInfo()->IsSingleTarget())
|
||||
if (GetSpellInfo()->IsSingleTarget() || IsSingleTarget())
|
||||
return false;
|
||||
|
||||
// Can't be saved - aura handler relies on calculated amount and changes it
|
||||
@@ -987,6 +988,18 @@ bool Aura::CanBeSaved() const
|
||||
if (HasEffectType(SPELL_AURA_CONTROL_VEHICLE))
|
||||
return false;
|
||||
|
||||
// do not save bind sight auras
|
||||
if (HasEffectType(SPELL_AURA_BIND_SIGHT))
|
||||
return false;
|
||||
|
||||
// no charming auras (taking direct control)
|
||||
if (HasEffectType(SPELL_AURA_MOD_POSSESS) || HasEffectType(SPELL_AURA_MOD_POSSESS_PET))
|
||||
return false;
|
||||
|
||||
// no charming auras can be saved
|
||||
if (HasEffectType(SPELL_AURA_MOD_CHARM) || HasEffectType(SPELL_AURA_AOE_CHARM))
|
||||
return false;
|
||||
|
||||
// Incanter's Absorbtion - considering the minimal duration and problems with aura stacking
|
||||
// we skip saving this aura
|
||||
// Also for some reason other auras put as MultiSlot crash core on keeping them after restart,
|
||||
|
||||
@@ -416,8 +416,7 @@ bool SpellEffectInfo::IsFarUnitTargetEffect() const
|
||||
return (Effect == SPELL_EFFECT_SUMMON_PLAYER)
|
||||
|| (Effect == SPELL_EFFECT_SUMMON_RAF_FRIEND)
|
||||
|| (Effect == SPELL_EFFECT_RESURRECT)
|
||||
|| (Effect == SPELL_EFFECT_RESURRECT_NEW)
|
||||
|| (Effect == SPELL_EFFECT_SKIN_PLAYER_CORPSE);
|
||||
|| (Effect == SPELL_EFFECT_RESURRECT_NEW);
|
||||
}
|
||||
|
||||
bool SpellEffectInfo::IsFarDestTargetEffect() const
|
||||
|
||||
+1
-1
@@ -204,7 +204,7 @@ public:
|
||||
{
|
||||
if (Group* group = players.begin()->GetSource()->GetGroup())
|
||||
if (group->isLFGGroup())
|
||||
sLFGMgr->FinishDungeon(group->GetGUID(), 287);
|
||||
sLFGMgr->FinishDungeon(group->GetGUID(), 287, me->GetMap());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -576,7 +576,7 @@ public:
|
||||
{
|
||||
if (Group* group = players.begin()->GetSource()->GetGroup())
|
||||
if (group->isLFGGroup())
|
||||
sLFGMgr->FinishDungeon(group->GetGUID(), 285);
|
||||
sLFGMgr->FinishDungeon(group->GetGUID(), 285, me->GetMap());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -201,7 +201,7 @@ public:
|
||||
{
|
||||
if (Group* group = players.begin()->GetSource()->GetGroup())
|
||||
if (group->isLFGGroup())
|
||||
sLFGMgr->FinishDungeon(group->GetGUID(), 286);
|
||||
sLFGMgr->FinishDungeon(group->GetGUID(), 286, me->GetMap());
|
||||
}
|
||||
|
||||
_JustDied();
|
||||
|
||||
Reference in new issue
Block a user