mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-21 01:37:37 +01:00
Scripts/Ulduar: Flame Leviathan used a very weird mixture of victim logic and REACT_PASSIVE, which broke during transition to the new system. Replaced with a working version.
Closes #21265.
This commit is contained in:
@@ -370,9 +370,15 @@ class boss_flame_leviathan : public CreatureScript
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
if (!me->IsEngaged())
|
||||
return;
|
||||
|
||||
if (!me->IsInCombat())
|
||||
{
|
||||
EnterEvadeMode(EVADE_REASON_NO_HOSTILES);
|
||||
return;
|
||||
}
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (Shutdown == RAID_MODE(TWO_SEATS, FOUR_SEATS))
|
||||
@@ -472,8 +478,21 @@ class boss_flame_leviathan : public CreatureScript
|
||||
|
||||
void SpellHitTarget(Unit* target, SpellInfo const* spell) override
|
||||
{
|
||||
if (spell->Id == SPELL_PURSUED)
|
||||
_pursueTarget = target->GetGUID();
|
||||
if (spell->Id != SPELL_PURSUED)
|
||||
return;
|
||||
|
||||
_pursueTarget = target->GetGUID();
|
||||
me->GetMotionMaster()->Clear();
|
||||
me->GetMotionMaster()->MoveChase(target);
|
||||
|
||||
for (SeatMap::const_iterator itr = target->GetVehicleKit()->Seats.begin(); itr != target->GetVehicleKit()->Seats.end(); ++itr)
|
||||
{
|
||||
if (Player* passenger = ObjectAccessor::GetPlayer(*me, itr->second.Passenger.Guid))
|
||||
{
|
||||
Talk(EMOTE_PURSUE, passenger);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DoAction(int32 action) override
|
||||
@@ -532,13 +551,10 @@ class boss_flame_leviathan : public CreatureScript
|
||||
me->SetLootMode(LOOT_MODE_DEFAULT | LOOT_MODE_HARD_MODE_1 | LOOT_MODE_HARD_MODE_2 | LOOT_MODE_HARD_MODE_3 | LOOT_MODE_HARD_MODE_4);
|
||||
break;
|
||||
case ACTION_MOVE_TO_CENTER_POSITION: // Triggered by 2 Collossus near door
|
||||
if (!me->isDead())
|
||||
if (!me->isDead() && me->HasReactState(REACT_PASSIVE))
|
||||
{
|
||||
me->SetHomePosition(Center);
|
||||
me->GetMotionMaster()->MoveCharge(Center.GetPositionX(), Center.GetPositionY(), Center.GetPositionZ()); // position center
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_STUNNED);
|
||||
return;
|
||||
me->GetMotionMaster()->MoveCharge(Center.GetPositionX(), Center.GetPositionY(), Center.GetPositionZ(), 42.0f, ACTION_MOVE_TO_CENTER_POSITION); // position center
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -546,6 +562,14 @@ class boss_flame_leviathan : public CreatureScript
|
||||
}
|
||||
}
|
||||
|
||||
void MovementInform(uint32 /*type*/, uint32 id) override
|
||||
{
|
||||
if (id != ACTION_MOVE_TO_CENTER_POSITION)
|
||||
return;
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_STUNNED);
|
||||
}
|
||||
|
||||
private:
|
||||
//! Copypasta from DoSpellAttackIfReady, only difference is the target - it cannot be selected trough GetVictim this way -
|
||||
//! I also removed the spellInfo check
|
||||
@@ -555,9 +579,11 @@ class boss_flame_leviathan : public CreatureScript
|
||||
{
|
||||
Unit* target = ObjectAccessor::GetUnit(*me, _pursueTarget);
|
||||
|
||||
// Pursue was unable to acquire a valid target, so get the current victim as target.
|
||||
if (!target && me->GetVictim())
|
||||
target = me->GetVictim();
|
||||
if (!target)
|
||||
{
|
||||
events.RescheduleEvent(EVENT_PURSUE, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (me->IsWithinCombatRange(target, 30.0f))
|
||||
{
|
||||
@@ -1639,28 +1665,27 @@ class FlameLeviathanPursuedTargetSelector
|
||||
//! No players, only vehicles. Pursue is never cast on players.
|
||||
Creature* creatureTarget = target->ToCreature();
|
||||
if (!creatureTarget)
|
||||
return true;
|
||||
return false;
|
||||
|
||||
//! NPC entries must match
|
||||
if (creatureTarget->GetEntry() != NPC_SALVAGED_DEMOLISHER && creatureTarget->GetEntry() != NPC_SALVAGED_SIEGE_ENGINE)
|
||||
return true;
|
||||
return false;
|
||||
|
||||
//! NPC must be a valid vehicle installation
|
||||
Vehicle* vehicle = creatureTarget->GetVehicleKit();
|
||||
if (!vehicle)
|
||||
return true;
|
||||
return false;
|
||||
|
||||
//! Entity needs to be in appropriate area
|
||||
if (target->GetAreaId() != AREA_FORMATION_GROUNDS)
|
||||
return true;
|
||||
return false;
|
||||
|
||||
//! Vehicle must be in use by player
|
||||
bool playerFound = false;
|
||||
for (SeatMap::const_iterator itr = vehicle->Seats.begin(); itr != vehicle->Seats.end() && !playerFound; ++itr)
|
||||
for (SeatMap::const_iterator itr = vehicle->Seats.begin(); itr != vehicle->Seats.end(); ++itr)
|
||||
if (itr->second.Passenger.Guid.IsPlayer())
|
||||
playerFound = true;
|
||||
return true;
|
||||
|
||||
return !playerFound;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1673,24 +1698,22 @@ class spell_pursue : public SpellScriptLoader
|
||||
{
|
||||
PrepareSpellScript(spell_pursue_SpellScript);
|
||||
|
||||
public:
|
||||
spell_pursue_SpellScript()
|
||||
{
|
||||
_target = nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
// EFFECT #0 - select target
|
||||
void FilterTargets(std::list<WorldObject*>& targets)
|
||||
{
|
||||
targets.remove_if(FlameLeviathanPursuedTargetSelector());
|
||||
if (!targets.empty())
|
||||
Trinity::Containers::RandomResize(targets, FlameLeviathanPursuedTargetSelector(), 1);
|
||||
if (targets.empty())
|
||||
{
|
||||
//! In the end, only one target should be selected
|
||||
_target = Trinity::Containers::SelectRandomContainerElement(targets);
|
||||
FilterTargetsSubsequently(targets);
|
||||
if (Unit* caster = GetCaster())
|
||||
if (Creature* cCaster = caster->ToCreature())
|
||||
cCaster->AI()->EnterEvadeMode(CreatureAI::EVADE_REASON_NO_HOSTILES);
|
||||
}
|
||||
else
|
||||
_target = targets.front();
|
||||
}
|
||||
|
||||
// EFFECT #1 - copy target from effect #0
|
||||
void FilterTargetsSubsequently(std::list<WorldObject*>& targets)
|
||||
{
|
||||
targets.clear();
|
||||
@@ -1698,32 +1721,13 @@ class spell_pursue : public SpellScriptLoader
|
||||
targets.push_back(_target);
|
||||
}
|
||||
|
||||
void HandleScript(SpellEffIndex /*eff*/)
|
||||
{
|
||||
Creature* caster = GetCaster()->ToCreature();
|
||||
if (!caster)
|
||||
return;
|
||||
|
||||
caster->AI()->AttackStart(GetHitUnit()); // Chase target
|
||||
|
||||
for (SeatMap::const_iterator itr = caster->GetVehicleKit()->Seats.begin(); itr != caster->GetVehicleKit()->Seats.end(); ++itr)
|
||||
{
|
||||
if (Player* passenger = ObjectAccessor::GetPlayer(*caster, itr->second.Passenger.Guid))
|
||||
{
|
||||
caster->AI()->Talk(EMOTE_PURSUE, passenger);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_pursue_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_pursue_SpellScript::FilterTargetsSubsequently, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);
|
||||
OnEffectHitTarget += SpellEffectFn(spell_pursue_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_APPLY_AURA);
|
||||
}
|
||||
|
||||
WorldObject* _target;
|
||||
WorldObject* _target = nullptr;
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
|
||||
@@ -764,7 +764,7 @@ class instance_ulduar : public InstanceMapScript
|
||||
{
|
||||
case DATA_COLOSSUS:
|
||||
ColossusData = data;
|
||||
if (data == 2 && GetBossState(BOSS_LEVIATHAN) == NOT_STARTED)
|
||||
if (data >= 2 && GetBossState(BOSS_LEVIATHAN) == NOT_STARTED)
|
||||
{
|
||||
_events.ScheduleEvent(EVENT_LEVIATHAN_BREAK_DOOR, 5 * IN_MILLISECONDS);
|
||||
SaveToDB();
|
||||
@@ -971,7 +971,7 @@ class instance_ulduar : public InstanceMapScript
|
||||
|
||||
void WriteSaveDataMore(std::ostringstream& data) override
|
||||
{
|
||||
data << GetData(DATA_COLOSSUS) << ' ' << _algalonTimer << ' ' << uint32(_algalonSummoned ? 1 : 0);
|
||||
data << ColossusData << ' ' << _algalonTimer << ' ' << uint32(_algalonSummoned ? 1 : 0);
|
||||
|
||||
for (uint8 i = 0; i < 4; ++i)
|
||||
data << ' ' << uint32(KeeperGUIDs[i] ? 1 : 0);
|
||||
@@ -983,8 +983,6 @@ class instance_ulduar : public InstanceMapScript
|
||||
{
|
||||
uint32 tempState;
|
||||
data >> tempState;
|
||||
if (tempState == IN_PROGRESS || tempState > SPECIAL)
|
||||
tempState = NOT_STARTED;
|
||||
SetData(DATA_COLOSSUS, tempState);
|
||||
|
||||
data >> _algalonTimer;
|
||||
|
||||
Reference in New Issue
Block a user