diff --git a/src/Ai/Base/Actions/TravelAction.cpp b/src/Ai/Base/Actions/TravelAction.cpp index f99f8b29..a2906057 100644 --- a/src/Ai/Base/Actions/TravelAction.cpp +++ b/src/Ai/Base/Actions/TravelAction.cpp @@ -28,7 +28,7 @@ bool TravelAction::Execute(Event event) for (Unit* unit : targets) { newTarget = unit; - if (!newTarget) + if (!newTarget || !newTarget->IsInWorld() || newTarget->IsDuringRemoveFromWorld()) continue; if (newTarget->GetMapId() != bot->GetMapId()) diff --git a/src/Ai/Base/Actions/UseItemAction.cpp b/src/Ai/Base/Actions/UseItemAction.cpp index 690d2d4b..bfb86ef0 100644 --- a/src/Ai/Base/Actions/UseItemAction.cpp +++ b/src/Ai/Base/Actions/UseItemAction.cpp @@ -245,8 +245,10 @@ bool UseItemAction::UseItem(Item* item, ObjectGuid goGuid, Item* itemTarget, Uni { packet << unitTarget->GetGUID(); targetSelected = true; - // If the target is bot or is an enemy, say "on self" - if (unitTarget == bot || (unitTarget->IsHostileTo(bot))) + + if (unitTarget == bot || !unitTarget->IsInWorld() || unitTarget->IsDuringRemoveFromWorld()) + out << " on self"; + else if (unitTarget->IsHostileTo(bot)) out << " on self"; else out << " on " << unitTarget->GetName(); diff --git a/src/Ai/Base/Value/AttackersValue.cpp b/src/Ai/Base/Value/AttackersValue.cpp index 3c968589..f6da0aa7 100644 --- a/src/Ai/Base/Value/AttackersValue.cpp +++ b/src/Ai/Base/Value/AttackersValue.cpp @@ -258,6 +258,9 @@ bool PossibleAddsValue::Calculate() if (Unit* add = botAI->GetUnit(guid)) { + if (!add->IsInWorld() || add->IsDuringRemoveFromWorld()) + continue; + if (!add->GetTarget() && !add->GetThreatMgr().getCurrentVictim() && add->IsHostileTo(bot)) { for (ObjectGuid const attackerGUID : attackers) diff --git a/src/Ai/Base/Value/GrindTargetValue.cpp b/src/Ai/Base/Value/GrindTargetValue.cpp index d1d7f912..7e6168c7 100644 --- a/src/Ai/Base/Value/GrindTargetValue.cpp +++ b/src/Ai/Base/Value/GrindTargetValue.cpp @@ -59,26 +59,22 @@ Unit* GrindTargetValue::FindTargetForGrinding(uint32 assistCount) for (ObjectGuid const guid : targets) { Unit* unit = botAI->GetUnit(guid); - if (!unit) continue; + if (!unit->IsInWorld() || unit->IsDuringRemoveFromWorld()) + continue; + auto& rep = bot->ToPlayer()->GetReputationMgr(); if (unit->ToCreature() && !unit->ToCreature()->GetCreatureTemplate()->lootid && bot->GetReactionTo(unit) >= REP_NEUTRAL) - { continue; - } if (!bot->IsHostileTo(unit) && unit->GetNpcFlags() != UNIT_NPC_FLAG_NONE) - { continue; - } if (!bot->isHonorOrXPTarget(unit)) - { continue; - } if (abs(bot->GetPositionZ() - unit->GetPositionZ()) > INTERACTION_DISTANCE) continue; diff --git a/src/Ai/Base/Value/NearestNpcsValue.cpp b/src/Ai/Base/Value/NearestNpcsValue.cpp index 1c188d29..a32c007f 100644 --- a/src/Ai/Base/Value/NearestNpcsValue.cpp +++ b/src/Ai/Base/Value/NearestNpcsValue.cpp @@ -27,7 +27,16 @@ void NearestHostileNpcsValue::FindUnits(std::list& targets) Cell::VisitObjects(bot, searcher, range); } -bool NearestHostileNpcsValue::AcceptUnit(Unit* unit) { return unit->IsHostileTo(bot) && !unit->IsPlayer(); } +bool NearestHostileNpcsValue::AcceptUnit(Unit* unit) +{ + if (!unit || !unit->IsInWorld() || unit->IsDuringRemoveFromWorld()) + return false; + + if (unit->IsPlayer()) + return false; + + return unit->IsHostileTo(bot); +} void NearestVehiclesValue::FindUnits(std::list& targets) { diff --git a/src/Ai/Base/Value/PossibleRpgTargetsValue.cpp b/src/Ai/Base/Value/PossibleRpgTargetsValue.cpp index 6e78f37f..e9b79deb 100644 --- a/src/Ai/Base/Value/PossibleRpgTargetsValue.cpp +++ b/src/Ai/Base/Value/PossibleRpgTargetsValue.cpp @@ -54,6 +54,9 @@ void PossibleRpgTargetsValue::FindUnits(std::list& targets) bool PossibleRpgTargetsValue::AcceptUnit(Unit* unit) { + if (!unit || !unit->IsInWorld() || unit->IsDuringRemoveFromWorld()) + return false; + if (unit->IsHostileTo(bot) || unit->IsPlayer()) return false; @@ -70,7 +73,8 @@ bool PossibleRpgTargetsValue::AcceptUnit(Unit* unit) } TravelTarget* travelTarget = context->GetValue("travel target")->Get(); - if (travelTarget->getDestination() && travelTarget->getDestination()->getEntry() == unit->GetEntry()) + if (travelTarget && travelTarget->getDestination() && + travelTarget->getDestination()->getEntry() == unit->GetEntry()) return true; if (urand(1, 100) < 25 && unit->IsFriendlyTo(bot)) @@ -145,6 +149,9 @@ void PossibleNewRpgTargetsValue::FindUnits(std::list& targets) bool PossibleNewRpgTargetsValue::AcceptUnit(Unit* unit) { + if (!unit || !unit->IsInWorld() || unit->IsDuringRemoveFromWorld()) + return false; + if (unit->IsHostileTo(bot) || unit->IsPlayer()) return false; diff --git a/src/Ai/Raid/Icecrown/Trigger/RaidIccTriggers.cpp b/src/Ai/Raid/Icecrown/Trigger/RaidIccTriggers.cpp index 55cfe9fc..b9ebb8ca 100644 --- a/src/Ai/Raid/Icecrown/Trigger/RaidIccTriggers.cpp +++ b/src/Ai/Raid/Icecrown/Trigger/RaidIccTriggers.cpp @@ -99,7 +99,10 @@ bool IccGunshipCannonNearTrigger::IsActive() bool IccGunshipTeleportAllyTrigger::IsActive() { Unit* boss = bot->FindNearestCreature(NPC_HIGH_OVERLORD_SAURFANG, 100.0f); - if (!boss) + if (!boss || !boss->IsInWorld() || boss->IsDuringRemoveFromWorld()) + return false; + + if (!boss->IsAlive()) return false; if (!boss->IsHostileTo(bot)) @@ -111,7 +114,10 @@ bool IccGunshipTeleportAllyTrigger::IsActive() bool IccGunshipTeleportHordeTrigger::IsActive() { Unit* boss = bot->FindNearestCreature(NPC_MURADIN_BRONZEBEARD, 100.0f); - if (!boss) + if (!boss || !boss->IsInWorld() || boss->IsDuringRemoveFromWorld()) + return false; + + if (!boss->IsAlive()) return false; if (!boss->IsHostileTo(bot)) diff --git a/src/Ai/Raid/Ulduar/Trigger/RaidUlduarTriggers.cpp b/src/Ai/Raid/Ulduar/Trigger/RaidUlduarTriggers.cpp index 89ad7ac5..f883917e 100644 --- a/src/Ai/Raid/Ulduar/Trigger/RaidUlduarTriggers.cpp +++ b/src/Ai/Raid/Ulduar/Trigger/RaidUlduarTriggers.cpp @@ -765,9 +765,13 @@ bool FreyaMoveToHealingSporeTrigger::IsActive() bool ThorimUnbalancingStrikeTrigger::IsActive() { Unit* boss = AI_VALUE2(Unit*, "find target", "thorim"); + if (!boss || !boss->IsInWorld() || boss->IsDuringRemoveFromWorld()) + return false; - // Check boss and it is alive - if (!boss || !boss->IsAlive() || !boss->IsHostileTo(bot)) + if (!boss->IsAlive()) + return false; + + if (!boss->IsHostileTo(bot)) return false; return bot->HasAura(SPELL_UNBALANCING_STRIKE); @@ -804,8 +808,13 @@ bool ThorimMarkDpsTargetTrigger::IsActive() Unit* boss = AI_VALUE2(Unit*, "find target", "thorim"); - // Check boss and it is alive - if (!boss || !boss->IsAlive() || !boss->IsHostileTo(bot)) + if (!boss || !boss->IsInWorld() || boss->IsDuringRemoveFromWorld()) + return false; + + if (!boss->IsAlive()) + return false; + + if (!boss->IsHostileTo(bot)) return false; if (boss->GetPositionZ() < ULDUAR_THORIM_AXIS_Z_FLOOR_THRESHOLD && (!currentSkullUnit || !currentSkullUnit->IsAlive())) @@ -982,9 +991,13 @@ bool ThorimGauntletPositioningTrigger::IsActive() bool ThorimArenaPositioningTrigger::IsActive() { Unit* boss = AI_VALUE2(Unit*, "find target", "thorim"); + if (!boss || !boss->IsInWorld() || boss->IsDuringRemoveFromWorld()) + return false; - // Check boss and it is alive - if (!boss || !boss->IsAlive() || !boss->IsHostileTo(bot)) + if (!boss->IsAlive()) + return false; + + if (!boss->IsHostileTo(bot)) return false; if (boss->GetPositionZ() < ULDUAR_THORIM_AXIS_Z_FLOOR_THRESHOLD) @@ -1080,9 +1093,13 @@ bool ThorimPhase2PositioningTrigger::IsActive() return false; Unit* boss = AI_VALUE2(Unit*, "find target", "thorim"); + if (!boss || !boss->IsInWorld() || boss->IsDuringRemoveFromWorld()) + return false; - // Check boss and it is alive - if (!boss || !boss->IsAlive() || !boss->IsHostileTo(bot)) + if (!boss->IsAlive()) + return false; + + if (!boss->IsHostileTo(bot)) return false; if (boss->GetPositionZ() > ULDUAR_THORIM_AXIS_Z_FLOOR_THRESHOLD)