Core/Misc: A variety of clean-up changes, mostly following up on 532ab1c to fix legacy bugs exposed by it:
- Triggers can no longer have a threat list (this may expose some ugliness in old legacy scripts) - Threat entries are forced to OFFLINE if the AI refuses to attack the target - Clean up passive creature evade behavior to be more consistent - Fix a months old issue in spawn group management that would cause "Inactive" to incorrectly show in .list respawns for system groups outside of map 0 - Valithria script cleanups, remove old hacks and make it work with the new system. Closes #21174. - Some strings cleanup # Conflicts: # sql/old/4.3.4/world/23_2017_11_15/2018_01_04_00_world.sql # src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp
This commit is contained in:
1 parent
20a9a8d934
commit
4fd7d9aa00
5 files changed
+53
-61
No files matched your search
@@ -84,11 +84,12 @@ void CreatureAI::DoZoneInCombat(Creature* creature /*= nullptr*/, float maxRange
|
||||
{
|
||||
if (Unit* summoner = creature->ToTempSummon()->GetSummoner())
|
||||
{
|
||||
Unit* target = summoner->getAttackerForHelper();
|
||||
if (!target && !summoner->GetThreatManager().IsThreatListEmpty())
|
||||
target = summoner->GetThreatManager().GetAnyTarget();
|
||||
if (target && (creature->IsFriendlyTo(summoner) || creature->IsHostileTo(target)))
|
||||
creature->AI()->AttackStart(target);
|
||||
if (creature->IsFriendlyTo(summoner))
|
||||
{
|
||||
Unit* target = summoner->getAttackerForHelper();
|
||||
if (target && creature->IsHostileTo(target))
|
||||
creature->AI()->AttackStart(target);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -109,7 +110,7 @@ void CreatureAI::DoZoneInCombat(Creature* creature /*= nullptr*/, float maxRange
|
||||
for (Map::PlayerList::const_iterator itr = playerList.begin(); itr != playerList.end(); ++itr)
|
||||
if (Player* player = itr->GetSource())
|
||||
if (player->IsAlive())
|
||||
creature->SetInCombatWith(player);
|
||||
creature->EngageWithTarget(player);
|
||||
}
|
||||
|
||||
// scripts does not take care about MoveInLineOfSight loops
|
||||
@@ -286,12 +287,12 @@ bool CreatureAI::UpdateVictim()
|
||||
|
||||
return me->GetVictim() != nullptr;
|
||||
}
|
||||
else if (me->GetThreatManager().IsThreatListEmpty(true))
|
||||
else if (!me->IsInCombat())
|
||||
{
|
||||
EnterEvadeMode(EVADE_REASON_NO_HOSTILES);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
else if (me->GetVictim())
|
||||
me->AttackStop();
|
||||
|
||||
return true;
|
||||
|
||||
@@ -95,6 +95,8 @@ ThreatReference::OnlineState ThreatReference::SelectOnlineState()
|
||||
return ONLINE_STATE_OFFLINE;
|
||||
if (!FlagsAllowFighting(_owner, _victim) || !FlagsAllowFighting(_victim, _owner))
|
||||
return ONLINE_STATE_OFFLINE;
|
||||
if (_owner->IsAIEnabled && !_owner->GetAI()->CanAIAttack(_victim))
|
||||
return ONLINE_STATE_OFFLINE;
|
||||
// next, check suppression (immunity to chosen melee attack school)
|
||||
if (_victim->IsImmunedToDamage(_owner->GetMeleeDamageSchoolMask()))
|
||||
return ONLINE_STATE_SUPPRESSED;
|
||||
@@ -136,16 +138,17 @@ void ThreatReference::ClearThreat(bool sendRemove)
|
||||
|
||||
/*static*/ bool ThreatManager::CanHaveThreatList(Unit const* who)
|
||||
{
|
||||
Creature const* cWho = who->ToCreature();
|
||||
// only creatures can have threat list
|
||||
if (who->GetTypeId() != TYPEID_UNIT)
|
||||
if (!cWho)
|
||||
return false;
|
||||
|
||||
// pets and totems cannot have threat list
|
||||
if (who->IsPet() || who->IsTotem())
|
||||
// pets, totems and triggers cannot have threat list
|
||||
if (cWho->IsPet() || cWho->IsTotem() || cWho->IsTrigger())
|
||||
return false;
|
||||
|
||||
// summons cannot have a threat list, unless they are controlled by a creature
|
||||
if (who->HasUnitTypeMask(UNIT_MASK_MINION | UNIT_MASK_GUARDIAN) && !who->GetOwnerGUID().IsCreature())
|
||||
if (cWho->HasUnitTypeMask(UNIT_MASK_MINION | UNIT_MASK_GUARDIAN) && !cWho->GetOwnerGUID().IsCreature())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
||||
@@ -593,7 +593,7 @@ bool Creature::UpdateEntry(uint32 entry, CreatureData const* data /*= nullptr*/,
|
||||
|
||||
void Creature::Update(uint32 diff)
|
||||
{
|
||||
if (IsAIEnabled && m_triggerJustAppeared && m_deathState == ALIVE)
|
||||
if (IsAIEnabled && m_triggerJustAppeared && m_deathState != DEAD)
|
||||
{
|
||||
if (m_respawnCompatibilityMode && m_vehicleKit)
|
||||
m_vehicleKit->Reset();
|
||||
|
||||
@@ -858,8 +858,6 @@ public:
|
||||
handler->PSendSysMessage("%s (guid %u) is not alive.", target->GetName().c_str(), target->GetGUID().GetCounter());
|
||||
return true;
|
||||
}
|
||||
if (!target->CanHaveThreatList())
|
||||
handler->PSendSysMessage("%s (guid %u) cannot have a threat list.", target->GetName().c_str(), target->GetGUID().GetCounter());
|
||||
|
||||
uint32 count = 0;
|
||||
auto const& threatenedByMe = target->GetThreatManager().GetThreatenedByMeList();
|
||||
@@ -877,11 +875,11 @@ public:
|
||||
}
|
||||
|
||||
if (!mgr.CanHaveThreatList())
|
||||
return true;
|
||||
if (mgr.IsEngaged())
|
||||
handler->PSendSysMessage("%s (guid %u) cannot have a threat list.", target->GetName().c_str(), target->GetGUID().GetCounter());
|
||||
else if (mgr.IsEngaged())
|
||||
{
|
||||
count = 0;
|
||||
handler->PSendSysMessage("Threat list of %s (guid %u, DB GUID %u)", target->GetName().c_str(), target->GetGUID().GetCounter(), target->GetTypeId() == TYPEID_UNIT ? target->ToCreature()->GetSpawnId() : 0);
|
||||
handler->PSendSysMessage("Threat list of %s (guid %u, spawnID %u)", target->GetName().c_str(), target->GetGUID().GetCounter(), target->GetTypeId() == TYPEID_UNIT ? target->ToCreature()->GetSpawnId() : 0);
|
||||
for (ThreatReference const* ref : mgr.GetSortedThreatList())
|
||||
{
|
||||
Unit* unit = ref->GetVictim();
|
||||
@@ -914,7 +912,7 @@ public:
|
||||
handler->SendSysMessage("End of threat list.");
|
||||
}
|
||||
else
|
||||
handler->PSendSysMessage("%s (guid %u, DB GUID %u) is not currently engaged.", target->GetName().c_str(), target->GetGUID().GetCounter(), target->GetTypeId() == TYPEID_UNIT ? target->ToCreature()->GetSpawnId() : 0);
|
||||
handler->PSendSysMessage("%s (guid %u, spawnID %u) is not currently engaged.", target->GetName().c_str(), target->GetGUID().GetCounter(), target->GetTypeId() == TYPEID_UNIT ? target->ToCreature()->GetSpawnId() : 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -226,44 +226,10 @@ class ValithriaDespawner : public BasicEvent
|
||||
|
||||
void operator()(Creature* creature) const
|
||||
{
|
||||
switch (creature->GetEntry())
|
||||
{
|
||||
case NPC_VALITHRIA_DREAMWALKER:
|
||||
if (InstanceScript* instance = creature->GetInstanceScript())
|
||||
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, creature);
|
||||
break;
|
||||
case NPC_BLAZING_SKELETON:
|
||||
case NPC_SUPPRESSER:
|
||||
case NPC_BLISTERING_ZOMBIE:
|
||||
case NPC_GLUTTONOUS_ABOMINATION:
|
||||
case NPC_MANA_VOID:
|
||||
case NPC_COLUMN_OF_FROST:
|
||||
case NPC_ROT_WORM:
|
||||
creature->DespawnOrUnsummon();
|
||||
return;
|
||||
case NPC_RISEN_ARCHMAGE:
|
||||
if (!creature->GetSpawnId())
|
||||
{
|
||||
creature->DespawnOrUnsummon();
|
||||
return;
|
||||
}
|
||||
creature->Respawn(true);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 corpseDelay = creature->GetCorpseDelay();
|
||||
uint32 respawnDelay = creature->GetRespawnDelay();
|
||||
creature->SetCorpseDelay(1);
|
||||
creature->SetRespawnDelay(10);
|
||||
|
||||
if (CreatureData const* data = creature->GetCreatureData())
|
||||
creature->UpdatePosition(data->spawnPoint);
|
||||
creature->DespawnOrUnsummon();
|
||||
|
||||
creature->SetCorpseDelay(corpseDelay);
|
||||
creature->SetRespawnDelay(respawnDelay);
|
||||
if (creature->GetEntry() == NPC_VALITHRIA_DREAMWALKER)
|
||||
if (InstanceScript* instance = creature->GetInstanceScript())
|
||||
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, creature);
|
||||
creature->DespawnOrUnsummon(0, 10s);
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -361,7 +327,7 @@ class boss_valithria_dreamwalker : public CreatureScript
|
||||
}
|
||||
else if (_instance->GetBossState(DATA_VALITHRIA_DREAMWALKER) == NOT_STARTED)
|
||||
if (Creature* archmage = me->FindNearestCreature(NPC_RISEN_ARCHMAGE, 30.0f))
|
||||
archmage->AI()->DoZoneInCombat(); // call JustEngagedWith on one of them, that will make it all start
|
||||
archmage->EngageWithTarget(healer); // call JustEngagedWith on one of them, that will make it all start
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* /*attacker*/, uint32& damage) override
|
||||
@@ -624,8 +590,9 @@ class npc_the_lich_king_controller : public CreatureScript
|
||||
{
|
||||
// must not be in dream phase
|
||||
PhasingHandler::RemovePhase(summon, 173, true);
|
||||
summon->AI()->DoZoneInCombat();
|
||||
if (summon->GetEntry() != NPC_SUPPRESSER)
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
|
||||
if (Unit* target = me->GetCombatManager().GetAnyTarget())
|
||||
summon->AI()->AttackStart(target);
|
||||
}
|
||||
|
||||
@@ -707,7 +674,7 @@ class npc_risen_archmage : public CreatureScript
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* /*target*/) override
|
||||
void JustEngagedWith(Unit* target) override
|
||||
{
|
||||
me->FinishSpell(CURRENT_CHANNELED_SPELL, false);
|
||||
if (me->GetSpawnId() && _canCallJustEngagedWith)
|
||||
@@ -720,10 +687,16 @@ class npc_risen_archmage : public CreatureScript
|
||||
(*itr)->AI()->DoAction(ACTION_ENTER_COMBAT);
|
||||
|
||||
if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_VALITHRIA_LICH_KING)))
|
||||
{
|
||||
lichKing->EngageWithTarget(target);
|
||||
lichKing->AI()->DoZoneInCombat();
|
||||
}
|
||||
|
||||
if (Creature* trigger = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_VALITHRIA_TRIGGER)))
|
||||
{
|
||||
trigger->EngageWithTarget(target);
|
||||
trigger->AI()->DoZoneInCombat();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -879,7 +852,24 @@ class npc_suppresser : public CreatureScript
|
||||
void IsSummonedBy(Unit* /*summoner*/) override
|
||||
{
|
||||
if (Creature* valithria = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_VALITHRIA_DREAMWALKER)))
|
||||
AttackStart(valithria);
|
||||
{
|
||||
float x, y, z;
|
||||
valithria->GetContactPoint(me, x,y,z);
|
||||
me->GetMotionMaster()->MovePoint(42, x, y, z);
|
||||
}
|
||||
}
|
||||
|
||||
void MovementInform(uint32 /*type*/, uint32 id)
|
||||
{
|
||||
if (id == 42)
|
||||
{
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
if (Creature* valithria = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_VALITHRIA_DREAMWALKER)))
|
||||
{
|
||||
AttackStart(valithria);
|
||||
DoCastAOE(SPELL_SUPPRESSION);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
|
||||
Reference in new issue
Block a user