diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/server/game/AI/CreatureAI.cpp | 17 | ||||
| -rw-r--r-- | src/server/game/Combat/ThreatManager.cpp | 11 | ||||
| -rw-r--r-- | src/server/game/Entities/Creature/Creature.cpp | 2 | ||||
| -rw-r--r-- | src/server/game/Maps/Map.cpp | 5 | ||||
| -rw-r--r-- | src/server/scripts/Commands/cs_debug.cpp | 10 | ||||
| -rw-r--r-- | src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp | 74 |
6 files changed, 56 insertions, 63 deletions
diff --git a/src/server/game/AI/CreatureAI.cpp b/src/server/game/AI/CreatureAI.cpp index d8fcb6c95c5..8f53e885416 100644 --- a/src/server/game/AI/CreatureAI.cpp +++ b/src/server/game/AI/CreatureAI.cpp @@ -80,11 +80,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); + } } } } @@ -105,7 +106,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 @@ -233,12 +234,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; diff --git a/src/server/game/Combat/ThreatManager.cpp b/src/server/game/Combat/ThreatManager.cpp index ee1fe5683e7..3356dba4d13 100644 --- a/src/server/game/Combat/ThreatManager.cpp +++ b/src/server/game/Combat/ThreatManager.cpp @@ -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; diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index c6d824ed723..64a25262532 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -623,7 +623,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(); diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 8c1cf06a4f5..5dac23ddb07 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -3240,7 +3240,7 @@ void Map::ApplyDynamicModeRespawnScaling(WorldObject const* obj, ObjectGuid::Low SpawnGroupTemplateData const* Map::GetSpawnGroupData(uint32 groupId) const { SpawnGroupTemplateData const* data = sObjectMgr->GetSpawnGroupData(groupId); - if (data && data->mapId == GetId()) + if (data && (data->flags & SPAWNGROUP_FLAG_SYSTEM || data->mapId == GetId())) return data; return nullptr; } @@ -3371,11 +3371,12 @@ bool Map::IsSpawnGroupActive(uint32 groupId) const SpawnGroupTemplateData const* const data = GetSpawnGroupData(groupId); if (!data) { - TC_LOG_WARN("maps", "Tried to query state of non-existing spawn group %u on map %u.", groupId, GetId()); + TC_LOG_ERROR("maps", "Tried to query state of non-existing spawn group %u on map %u.", groupId, GetId()); return false; } if (data->flags & SPAWNGROUP_FLAG_SYSTEM) return true; + // either manual spawn group and toggled, or not manual spawn group and not toggled... return (_toggledSpawnGroupIds.find(groupId) != _toggledSpawnGroupIds.end()) != !(data->flags & SPAWNGROUP_FLAG_MANUAL_SPAWN); } diff --git a/src/server/scripts/Commands/cs_debug.cpp b/src/server/scripts/Commands/cs_debug.cpp index 54f80e6abb4..427a5f923ed 100644 --- a/src/server/scripts/Commands/cs_debug.cpp +++ b/src/server/scripts/Commands/cs_debug.cpp @@ -852,8 +852,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(); @@ -871,11 +869,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(); @@ -908,7 +906,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; } diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp index f940d67f8c7..be9ff037f12 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp @@ -231,44 +231,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: @@ -366,7 +332,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 @@ -629,8 +595,9 @@ class npc_the_lich_king_controller : public CreatureScript { // must not be in dream phase summon->SetPhaseMask((summon->GetPhaseMask() & ~0x10), 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); } @@ -712,7 +679,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) @@ -725,10 +692,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(); + } } } @@ -884,7 +857,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 |
