Skip to content

Commit 272da9f

Browse files
Nyeriahjoschiwaldclaude
authored
refactor(Scripts/VioletHold): Modernize Violet Hold dungeon scripts (azerothcore#25187)
Co-authored-by: joschiwald <joschiwald@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 25b928b commit 272da9f

12 files changed

Lines changed: 1661 additions & 2138 deletions

File tree

src/server/game/Maps/Map.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1810,12 +1810,13 @@ void Map::RemoveAllObjectsInRemoveList()
18101810
}
18111811
}
18121812

1813-
uint32 Map::GetPlayersCountExceptGMs() const
1813+
uint32 Map::GetPlayersCountExceptGMs(bool aliveOnly /*= false*/) const
18141814
{
18151815
uint32 count = 0;
1816-
for (MapRefMgr::const_iterator itr = m_mapRefMgr.begin(); itr != m_mapRefMgr.end(); ++itr)
1817-
if (!itr->GetSource()->IsGameMaster())
1818-
++count;
1816+
for (auto const& ref : m_mapRefMgr)
1817+
if (Player* player = ref.GetSource())
1818+
if (!player->IsGameMaster() && (!aliveOnly || (player->IsAlive() && !player->HasSpiritOfRedemptionAura())))
1819+
++count;
18191820
return count;
18201821
}
18211822

src/server/game/Maps/Map.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,8 @@ class Map : public GridRefMgr<MapGridType>
318318
void markCell(uint32 pCellId) { marked_cells.set(pCellId); }
319319

320320
[[nodiscard]] bool HavePlayers() const { return !m_mapRefMgr.IsEmpty(); }
321-
[[nodiscard]] uint32 GetPlayersCountExceptGMs() const;
321+
// When aliveOnly is true, counts only players that are alive and not in Spirit of Redemption form.
322+
[[nodiscard]] uint32 GetPlayersCountExceptGMs(bool aliveOnly = false) const;
322323

323324
void SendToPlayers(WorldPacket const* data) const;
324325

src/server/scripts/Northrend/VioletHold/boss_cyanigosa.cpp

Lines changed: 72 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -50,141 +50,95 @@ enum eEvents
5050
EVENT_UNROOT,
5151
};
5252

53-
class boss_cyanigosa : public CreatureScript
53+
struct boss_cyanigosa : public BossAI
5454
{
55-
public:
56-
boss_cyanigosa() : CreatureScript("boss_cyanigosa") { }
55+
boss_cyanigosa(Creature* c) : BossAI(c, DATA_CYANIGOSA) { }
5756

58-
CreatureAI* GetAI(Creature* pCreature) const override
57+
void JustEngagedWith(Unit* who) override
5958
{
60-
return GetVioletHoldAI<boss_cyanigosaAI>(pCreature);
59+
BossAI::JustEngagedWith(who);
60+
Talk(SAY_AGGRO);
61+
events.RescheduleEvent(EVENT_SPELL_ARCANE_VACUUM, 30s);
62+
events.RescheduleEvent(EVENT_SPELL_BLIZZARD, 5s, 10s);
63+
events.RescheduleEvent(EVENT_SPELL_TAIL_SWEEP, 15s, 20s);
64+
events.RescheduleEvent(EVENT_SPELL_UNCONTROLLABLE_ENERGY, 5s, 8s);
65+
if (IsHeroic())
66+
events.RescheduleEvent(EVENT_SPELL_MANA_DESTRUCTION, 20s);
6167
}
6268

63-
struct boss_cyanigosaAI : public ScriptedAI
69+
void SpellHitTarget(Unit* target, SpellInfo const* spell) override
6470
{
65-
boss_cyanigosaAI(Creature* c) : ScriptedAI(c)
66-
{
67-
pInstance = c->GetInstanceScript();
68-
}
69-
70-
InstanceScript* pInstance;
71-
EventMap events;
72-
73-
void Reset() override
74-
{
75-
events.Reset();
76-
}
77-
78-
void JustEngagedWith(Unit* /*who*/) override
79-
{
80-
DoZoneInCombat();
81-
Talk(SAY_AGGRO);
82-
events.Reset();
83-
events.RescheduleEvent(EVENT_SPELL_ARCANE_VACUUM, 30s);
84-
events.RescheduleEvent(EVENT_SPELL_BLIZZARD, 5s, 10s);
85-
events.RescheduleEvent(EVENT_SPELL_TAIL_SWEEP, 15s, 20s);
86-
events.RescheduleEvent(EVENT_SPELL_UNCONTROLLABLE_ENERGY, 5s, 8s);
87-
if (IsHeroic())
88-
events.RescheduleEvent(EVENT_SPELL_MANA_DESTRUCTION, 20s);
89-
}
90-
91-
void SpellHitTarget(Unit* target, SpellInfo const* spell) override
92-
{
93-
if (!target || !spell)
94-
return;
95-
switch (spell->Id)
96-
{
97-
case SPELL_ARCANE_VACUUM:
98-
target->NearTeleportTo(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() + 10.0f, target->GetOrientation());
99-
break;
100-
}
101-
}
71+
if (!target || !spell)
72+
return;
73+
if (spell->Id == SPELL_ARCANE_VACUUM)
74+
target->NearTeleportTo(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() + 10.0f, target->GetOrientation());
75+
}
10276

103-
void UpdateAI(uint32 diff) override
77+
void ExecuteEvent(uint32 eventId) override
78+
{
79+
switch (eventId)
10480
{
105-
if (!UpdateVictim())
106-
return;
107-
108-
events.Update(diff);
109-
110-
if (me->HasUnitState(UNIT_STATE_CASTING))
111-
return;
112-
113-
switch (events.ExecuteEvent())
114-
{
115-
case 0:
116-
break;
117-
case EVENT_SPELL_ARCANE_VACUUM:
118-
me->CastSpell((Unit*)nullptr, SPELL_ARCANE_VACUUM, false);
119-
DoResetThreatList();
120-
me->SetControlled(true, UNIT_STATE_ROOT);
121-
me->setAttackTimer(BASE_ATTACK, 3000);
122-
events.Repeat(30s);
123-
events.ScheduleEvent(EVENT_UNROOT, 3s);
124-
break;
125-
case EVENT_UNROOT:
126-
me->SetControlled(false, UNIT_STATE_ROOT);
127-
128-
break;
129-
case EVENT_SPELL_BLIZZARD:
130-
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 45.0f, true))
131-
me->CastSpell(target, SPELL_BLIZZARD, false);
132-
events.Repeat(15s);
133-
break;
134-
case EVENT_SPELL_MANA_DESTRUCTION:
135-
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 50.0f, true))
136-
me->CastSpell(target, SPELL_MANA_DESTRUCTION, false);
137-
events.Repeat(20s);
138-
break;
139-
case EVENT_SPELL_TAIL_SWEEP:
140-
me->CastSpell(me->GetVictim(), SPELL_TAIL_SWEEP, false);
141-
events.Repeat(15s, 20s);
142-
break;
143-
case EVENT_SPELL_UNCONTROLLABLE_ENERGY:
144-
me->CastSpell(me->GetVictim(), SPELL_UNCONTROLLABLE_ENERGY, false);
145-
events.Repeat(20s, 25s);
146-
break;
147-
}
148-
149-
DoMeleeAttackIfReady();
81+
case EVENT_SPELL_ARCANE_VACUUM:
82+
DoCastAOE(SPELL_ARCANE_VACUUM);
83+
DoResetThreatList();
84+
me->SetControlled(true, UNIT_STATE_ROOT);
85+
me->setAttackTimer(BASE_ATTACK, 3000);
86+
events.Repeat(30s);
87+
events.ScheduleEvent(EVENT_UNROOT, 3s);
88+
break;
89+
case EVENT_UNROOT:
90+
me->SetControlled(false, UNIT_STATE_ROOT);
91+
break;
92+
case EVENT_SPELL_BLIZZARD:
93+
DoCastRandomTarget(SPELL_BLIZZARD, 0, 45.0f);
94+
events.Repeat(15s);
95+
break;
96+
case EVENT_SPELL_MANA_DESTRUCTION:
97+
DoCastRandomTarget(SPELL_MANA_DESTRUCTION, 0, 50.0f);
98+
events.Repeat(20s);
99+
break;
100+
case EVENT_SPELL_TAIL_SWEEP:
101+
DoCastVictim(SPELL_TAIL_SWEEP);
102+
events.Repeat(15s, 20s);
103+
break;
104+
case EVENT_SPELL_UNCONTROLLABLE_ENERGY:
105+
DoCastVictim(SPELL_UNCONTROLLABLE_ENERGY);
106+
events.Repeat(20s, 25s);
107+
break;
150108
}
109+
}
151110

152-
void JustDied(Unit* /*killer*/) override
111+
void JustDied(Unit* killer) override
112+
{
113+
Talk(SAY_DEATH);
114+
BossAI::JustDied(killer);
115+
float h = me->GetMapHeight(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ());
116+
if (h != INVALID_HEIGHT && me->GetPositionZ() - h > 3.0f)
153117
{
154-
Talk(SAY_DEATH);
155-
if (pInstance)
156-
pInstance->SetData(DATA_BOSS_DIED, 0);
157-
float h = me->GetMapHeight(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ());
158-
if (h != INVALID_HEIGHT && me->GetPositionZ() - h > 3.0f)
159-
{
160-
me->UpdatePosition(me->GetPositionX(), me->GetPositionY(), h, me->GetOrientation(), true); // move to ground
161-
me->StopMovingOnCurrentPos();
162-
me->DestroyForVisiblePlayers();
163-
}
118+
me->UpdatePosition(me->GetPositionX(), me->GetPositionY(), h, me->GetOrientation(), true);
119+
me->StopMovingOnCurrentPos();
120+
me->DestroyForVisiblePlayers();
164121
}
122+
}
165123

166-
void KilledUnit(Unit* victim) override
167-
{
168-
if (victim && victim->GetGUID() == me->GetGUID())
169-
return;
170-
Talk(SAY_SLAY);
171-
}
124+
void KilledUnit(Unit* victim) override
125+
{
126+
if (victim && victim->GetGUID() == me->GetGUID())
127+
return;
128+
Talk(SAY_SLAY);
129+
}
172130

173-
void MoveInLineOfSight(Unit* /*who*/) override {}
131+
void MoveInLineOfSight(Unit* /*who*/) override {}
174132

175-
void EnterEvadeMode(EvadeReason why) override
176-
{
177-
me->SetControlled(false, UNIT_STATE_ROOT);
178-
ScriptedAI::EnterEvadeMode(why);
179-
events.Reset();
180-
me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
181-
if (pInstance)
182-
pInstance->SetData(DATA_FAILED, 1);
183-
}
184-
};
133+
void EnterEvadeMode(EvadeReason why) override
134+
{
135+
me->SetControlled(false, UNIT_STATE_ROOT);
136+
me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
137+
_EnterEvadeMode(why);
138+
}
185139
};
186140

187141
void AddSC_boss_cyanigosa()
188142
{
189-
new boss_cyanigosa();
143+
RegisterVioletHoldCreatureAI(boss_cyanigosa);
190144
}

0 commit comments

Comments
 (0)