Merge branch 'master' into Playerbot
This commit is contained in:
@@ -0,0 +1,3 @@
|
|||||||
|
-- DB update 2023_05_29_02 -> 2023_06_01_00
|
||||||
|
--
|
||||||
|
UPDATE `creature_template` SET `mechanic_immune_mask` = `mechanic_immune_mask`|33554432 WHERE `entry` IN (18341, 20267);
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
-- DB update 2023_06_01_00 -> 2023_06_01_01
|
||||||
|
--
|
||||||
|
UPDATE `creature_template` SET `mechanic_immune_mask` = 663699067 WHERE `entry` IN (17839, 20744, 21140, 22172, 21104, 21148, 22170, 22171);
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
-- DB update 2023_06_01_01 -> 2023_06_01_02
|
||||||
|
--
|
||||||
|
UPDATE `smart_scripts` SET `action_param1` = 768 WHERE `entryorguid` IN (-151090, -151091, -151092, -151093) AND `source_type` = 0;
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
-- DB update 2023_06_01_02 -> 2023_06_01_03
|
||||||
|
-- 5097: Lupine Delusion (Shadowfang Keep)
|
||||||
|
-- 6493: Illusionary Phantasm (Scarlet Monastery Graveyard)
|
||||||
|
UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` IN (5097, 6493);
|
||||||
|
|
||||||
|
DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` IN (5097, 6493));
|
||||||
|
INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
|
||||||
|
(5097, 0, 0, 0, 2, 0, 100, 0, 0, 99, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Lupine Delusion - Between 0-99% Health - Despawn Instant'),
|
||||||
|
(5097, 0, 1, 0, 6, 0, 100, 0, 0, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Lupine Delusion - On Just Died - Despawn Instant'),
|
||||||
|
(6493, 0, 0, 0, 2, 0, 100, 0, 0, 99, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Illusionary Phantasm - Between 0-99% Health - Despawn Instant'),
|
||||||
|
(6493, 0, 1, 0, 6, 0, 100, 0, 0, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Illusionary Phantasm - On Just Died - Despawn Instant');
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
-- DB update 2023_06_01_03 -> 2023_06_01_04
|
||||||
|
-- Sul'lithuz Abomination and Sandfury Guardian creature formations
|
||||||
|
DELETE FROM `creature_formations` WHERE `memberGUID` IN (81527, 81565, 37998, 37999, 38000, 38001);
|
||||||
|
INSERT INTO `creature_formations` (`leaderGUID`, `memberGUID`, `dist`, `angle`, `groupAI`, `point_1`, `point_2`) VALUES
|
||||||
|
(81527, 81527, 0, 0, 3, 0, 0),
|
||||||
|
(81527, 81565, 0, 0, 3, 0, 0),
|
||||||
|
(37998, 37998, 0, 0, 3, 0, 0),
|
||||||
|
(37998, 37999, 0, 0, 3, 0, 0),
|
||||||
|
(37998, 38000, 0, 0, 3, 0, 0),
|
||||||
|
(37998, 38001, 0, 0, 3, 0, 0);
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
-- DB update 2023_06_01_04 -> 2023_06_01_05
|
||||||
|
--
|
||||||
|
DELETE FROM `smart_scripts` WHERE `entryorguid` = 19716 AND `source_type` = 0 AND `id` IN (5, 6);
|
||||||
|
INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
|
||||||
|
(19716, 0, 5, 6, 34, 2, 100, 1, 8, 0, 0, 0, 0, 11, 35058, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Mechanar Tinkerer - On Reached Point 0 - Cast \'Nether Explosion\' (Phase 2) (No Repeat)'),
|
||||||
|
(19716, 0, 6, 0, 61, 2, 100, 1, 0, 0, 0, 0, 0, 37, 1001, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Mechanar Tinkerer - On Reached Point 0 - Kill Self (Phase 2) (No Repeat)');
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
-- DB update 2023_06_01_05 -> 2023_06_01_06
|
||||||
|
--
|
||||||
|
DELETE FROM `spell_script_names` WHERE `spell_id` IN (34246, 60779) AND `ScriptName` = 'spell_dru_idol_lifebloom';
|
||||||
|
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
|
||||||
|
(34246, 'spell_dru_idol_lifebloom'),
|
||||||
|
(60779, 'spell_dru_idol_lifebloom');
|
||||||
@@ -1139,7 +1139,22 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
|
|||||||
}
|
}
|
||||||
case SMART_ACTION_DIE:
|
case SMART_ACTION_DIE:
|
||||||
{
|
{
|
||||||
if (me && !me->isDead())
|
if (e.action.die.milliseconds)
|
||||||
|
{
|
||||||
|
if (me && !me->isDead())
|
||||||
|
{
|
||||||
|
me->m_Events.AddEventAtOffset([&]
|
||||||
|
{
|
||||||
|
// We need to check again to see if we didn't die in the process.
|
||||||
|
if (me && !me->isDead())
|
||||||
|
{
|
||||||
|
me->KillSelf();
|
||||||
|
LOG_DEBUG("sql.sql", "SmartScript::ProcessAction: SMART_ACTION_DIE: Creature {}", me->GetGUID().ToString());
|
||||||
|
}
|
||||||
|
}, Milliseconds(e.action.die.milliseconds));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (me && !me->isDead())
|
||||||
{
|
{
|
||||||
me->KillSelf();
|
me->KillSelf();
|
||||||
LOG_DEBUG("sql.sql", "SmartScript::ProcessAction: SMART_ACTION_DIE: Creature {}", me->GetGUID().ToString());
|
LOG_DEBUG("sql.sql", "SmartScript::ProcessAction: SMART_ACTION_DIE: Creature {}", me->GetGUID().ToString());
|
||||||
|
|||||||
@@ -641,7 +641,7 @@ bool SmartAIMgr::CheckUnusedActionParams(SmartScriptHolder const& e)
|
|||||||
case SMART_ACTION_SET_INST_DATA: return sizeof(SmartAction::setInstanceData);
|
case SMART_ACTION_SET_INST_DATA: return sizeof(SmartAction::setInstanceData);
|
||||||
case SMART_ACTION_SET_INST_DATA64: return sizeof(SmartAction::setInstanceData64);
|
case SMART_ACTION_SET_INST_DATA64: return sizeof(SmartAction::setInstanceData64);
|
||||||
case SMART_ACTION_UPDATE_TEMPLATE: return sizeof(SmartAction::updateTemplate);
|
case SMART_ACTION_UPDATE_TEMPLATE: return sizeof(SmartAction::updateTemplate);
|
||||||
case SMART_ACTION_DIE: return NO_PARAMS;
|
case SMART_ACTION_DIE: return sizeof(SmartAction::die);
|
||||||
case SMART_ACTION_SET_IN_COMBAT_WITH_ZONE: return NO_PARAMS;
|
case SMART_ACTION_SET_IN_COMBAT_WITH_ZONE: return NO_PARAMS;
|
||||||
case SMART_ACTION_CALL_FOR_HELP: return sizeof(SmartAction::callHelp);
|
case SMART_ACTION_CALL_FOR_HELP: return sizeof(SmartAction::callHelp);
|
||||||
case SMART_ACTION_SET_SHEATH: return sizeof(SmartAction::setSheath);
|
case SMART_ACTION_SET_SHEATH: return sizeof(SmartAction::setSheath);
|
||||||
|
|||||||
@@ -559,7 +559,7 @@ enum SMART_ACTION
|
|||||||
SMART_ACTION_SET_INST_DATA = 34, // Field, Data
|
SMART_ACTION_SET_INST_DATA = 34, // Field, Data
|
||||||
SMART_ACTION_SET_INST_DATA64 = 35, // Field,
|
SMART_ACTION_SET_INST_DATA64 = 35, // Field,
|
||||||
SMART_ACTION_UPDATE_TEMPLATE = 36, // Entry, UpdateLevel
|
SMART_ACTION_UPDATE_TEMPLATE = 36, // Entry, UpdateLevel
|
||||||
SMART_ACTION_DIE = 37, // No Params
|
SMART_ACTION_DIE = 37, // Milliseconds
|
||||||
SMART_ACTION_SET_IN_COMBAT_WITH_ZONE = 38, // Range (if outside of dungeon)
|
SMART_ACTION_SET_IN_COMBAT_WITH_ZONE = 38, // Range (if outside of dungeon)
|
||||||
SMART_ACTION_CALL_FOR_HELP = 39, // Radius, With Emote
|
SMART_ACTION_CALL_FOR_HELP = 39, // Radius, With Emote
|
||||||
SMART_ACTION_SET_SHEATH = 40, // Sheath (0-unarmed, 1-melee, 2-ranged)
|
SMART_ACTION_SET_SHEATH = 40, // Sheath (0-unarmed, 1-melee, 2-ranged)
|
||||||
@@ -925,6 +925,11 @@ struct SmartAction
|
|||||||
SAIBool updateLevel;
|
SAIBool updateLevel;
|
||||||
} updateTemplate;
|
} updateTemplate;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32 milliseconds;
|
||||||
|
} die;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
uint32 range;
|
uint32 range;
|
||||||
|
|||||||
@@ -12482,32 +12482,6 @@ uint32 Unit::SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, ui
|
|||||||
|
|
||||||
switch (spellProto->SpellFamilyName)
|
switch (spellProto->SpellFamilyName)
|
||||||
{
|
{
|
||||||
case SPELLFAMILY_DRUID:
|
|
||||||
{
|
|
||||||
// Nourish vs Idol of the Flourishing Life
|
|
||||||
if (spellProto->SpellFamilyFlags[1] & 0x02000000)
|
|
||||||
{
|
|
||||||
if (AuraEffect const* relicAurEff = GetAuraEffect(64949, EFFECT_0))
|
|
||||||
{
|
|
||||||
DoneAdvertisedBenefit += relicAurEff->GetAmount();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Lifebloom vs Idol of Lush Moss/Increased Lifebloom Periodic
|
|
||||||
if (spellProto->SpellFamilyFlags[1] & 00000010)
|
|
||||||
{
|
|
||||||
if (AuraEffect const* relicAurEff = GetAuraEffect(60779, EFFECT_0))
|
|
||||||
{
|
|
||||||
DoneAdvertisedBenefit += relicAurEff->GetAmount();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (AuraEffect const* relicAurEff = GetAuraEffect(34246, EFFECT_0))
|
|
||||||
{
|
|
||||||
DoneAdvertisedBenefit += relicAurEff->GetAmount();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SPELLFAMILY_DEATHKNIGHT:
|
case SPELLFAMILY_DEATHKNIGHT:
|
||||||
{
|
{
|
||||||
// Impurity
|
// Impurity
|
||||||
|
|||||||
@@ -439,6 +439,13 @@ void SpellMgr::LoadSpellInfoCorrections()
|
|||||||
spellInfo->Effects[EFFECT_0].SpellClassMask = flag96(0x00000040, 0x00000000, 0x00000000);
|
spellInfo->Effects[EFFECT_0].SpellClassMask = flag96(0x00000040, 0x00000000, 0x00000000);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Idol of the Flourishing Life
|
||||||
|
ApplySpellFix({ 64949 }, [](SpellInfo* spellInfo)
|
||||||
|
{
|
||||||
|
spellInfo->Effects[EFFECT_0].SpellClassMask = flag96(0x00000000, 0x02000000, 0x00000000);
|
||||||
|
spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_ADD_FLAT_MODIFIER;
|
||||||
|
});
|
||||||
|
|
||||||
ApplySpellFix({
|
ApplySpellFix({
|
||||||
34231, // Libram of the Lightbringer
|
34231, // Libram of the Lightbringer
|
||||||
60792, // Libram of Tolerance
|
60792, // Libram of Tolerance
|
||||||
|
|||||||
+25
-36
@@ -63,9 +63,9 @@ enum Events
|
|||||||
EVENT_PYROBLAST = 6,
|
EVENT_PYROBLAST = 6,
|
||||||
// Hack due to trigger spell not in dbc
|
// Hack due to trigger spell not in dbc
|
||||||
EVENT_FIRE_SHIELD = 7,
|
EVENT_FIRE_SHIELD = 7,
|
||||||
// Make sure all players have aura from altar
|
EVENT_PRE_ENTER_COMBAT_1 = 8,
|
||||||
EVENT_PLAYER_CHECK = 8,
|
EVENT_PRE_ENTER_COMBAT_2 = 9,
|
||||||
EVENT_ENTER_COMBAT = 9
|
EVENT_ENTER_COMBAT = 10
|
||||||
};
|
};
|
||||||
|
|
||||||
class boss_pyroguard_emberseer : public CreatureScript
|
class boss_pyroguard_emberseer : public CreatureScript
|
||||||
@@ -101,7 +101,8 @@ public:
|
|||||||
switch (data)
|
switch (data)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
events.ScheduleEvent(EVENT_PLAYER_CHECK, 5s);
|
events.ScheduleEvent(EVENT_PRE_FIGHT_1, 2s);
|
||||||
|
instance->SetBossState(DATA_PYROGAURD_EMBERSEER, IN_PROGRESS);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
// Close these two doors on Blackhand Incarcerators aggro
|
// Close these two doors on Blackhand Incarcerators aggro
|
||||||
@@ -153,14 +154,12 @@ public:
|
|||||||
|
|
||||||
if (me->GetAuraCount(SPELL_EMBERSEER_GROWING_TRIGGER) == 20)
|
if (me->GetAuraCount(SPELL_EMBERSEER_GROWING_TRIGGER) == 20)
|
||||||
{
|
{
|
||||||
me->RemoveAura(SPELL_ENCAGED_EMBERSEER);
|
events.CancelEvent(EVENT_FIRE_SHIELD); // temporarily cancel fire shield to keep it from interrupting combat start
|
||||||
me->RemoveAura(SPELL_FREEZE_ANIM);
|
|
||||||
me->CastSpell(me, SPELL_EMBERSEER_FULL_STRENGTH);
|
// Schedule out the pre-combat scene
|
||||||
Talk(EMOTE_FREE_OF_BONDS);
|
events.ScheduleEvent(EVENT_PRE_ENTER_COMBAT_1, 0s);
|
||||||
Talk(YELL_FREE_OF_BONDS);
|
events.ScheduleEvent(EVENT_PRE_ENTER_COMBAT_2, 2s);
|
||||||
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
events.ScheduleEvent(EVENT_ENTER_COMBAT, 5s);
|
||||||
me->SetImmuneToPC(false);
|
|
||||||
events.ScheduleEvent(EVENT_ENTER_COMBAT, 2s);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -235,7 +234,7 @@ public:
|
|||||||
if (Creature* creature = *itr)
|
if (Creature* creature = *itr)
|
||||||
creature->AI()->SetData(1, 1);
|
creature->AI()->SetData(1, 1);
|
||||||
}
|
}
|
||||||
events.ScheduleEvent(EVENT_PRE_FIGHT_2, 32s);
|
events.ScheduleEvent(EVENT_PRE_FIGHT_2, 2s);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EVENT_PRE_FIGHT_2:
|
case EVENT_PRE_FIGHT_2:
|
||||||
@@ -248,25 +247,21 @@ public:
|
|||||||
DoCast(me, SPELL_FIRE_SHIELD);
|
DoCast(me, SPELL_FIRE_SHIELD);
|
||||||
events.ScheduleEvent(EVENT_FIRE_SHIELD, 3s);
|
events.ScheduleEvent(EVENT_FIRE_SHIELD, 3s);
|
||||||
break;
|
break;
|
||||||
case EVENT_PLAYER_CHECK:
|
case EVENT_PRE_ENTER_COMBAT_1:
|
||||||
{
|
me->RemoveAura(SPELL_ENCAGED_EMBERSEER);
|
||||||
// Check to see if all players in instance have aura SPELL_EMBERSEER_START before starting event
|
me->RemoveAura(SPELL_FREEZE_ANIM);
|
||||||
bool _hasAura = false;
|
me->CastSpell(me, SPELL_EMBERSEER_FULL_STRENGTH);
|
||||||
Map::PlayerList const& players = me->GetMap()->GetPlayers();
|
Talk(EMOTE_FREE_OF_BONDS);
|
||||||
for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
|
break;
|
||||||
if (Player* player = itr->GetSource()->ToPlayer())
|
case EVENT_PRE_ENTER_COMBAT_2:
|
||||||
if (player->HasAura(SPELL_EMBERSEER_OBJECT_VISUAL))
|
Talk(YELL_FREE_OF_BONDS);
|
||||||
_hasAura = true;
|
break;
|
||||||
|
|
||||||
if (_hasAura)
|
|
||||||
{
|
|
||||||
events.ScheduleEvent(EVENT_PRE_FIGHT_1, 1s);
|
|
||||||
instance->SetBossState(DATA_PYROGAURD_EMBERSEER, IN_PROGRESS);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case EVENT_ENTER_COMBAT:
|
case EVENT_ENTER_COMBAT:
|
||||||
|
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||||
|
me->SetImmuneToPC(false);
|
||||||
DoZoneInCombat();
|
DoZoneInCombat();
|
||||||
|
// re-enable fire shield
|
||||||
|
events.ScheduleEvent(EVENT_FIRE_SHIELD, 0s);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -347,11 +342,6 @@ public:
|
|||||||
_fleedForAssistance = false;
|
_fleedForAssistance = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void JustDied(Unit* /*killer*/) override
|
|
||||||
{
|
|
||||||
me->DespawnOrUnsummon(10000);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*type*/, SpellSchoolMask /*school*/) override
|
void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*type*/, SpellSchoolMask /*school*/) override
|
||||||
{
|
{
|
||||||
if (!_fleedForAssistance && me->HealthBelowPctDamaged(30, damage))
|
if (!_fleedForAssistance && me->HealthBelowPctDamaged(30, damage))
|
||||||
@@ -392,7 +382,6 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
_events.ScheduleEvent(EVENT_STRIKE, 8s, 16s);
|
_events.ScheduleEvent(EVENT_STRIKE, 8s, 16s);
|
||||||
_events.ScheduleEvent(EVENT_ENCAGE, 10s, 20s);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateAI(uint32 diff) override
|
void UpdateAI(uint32 diff) override
|
||||||
|
|||||||
@@ -34,107 +34,70 @@ enum Spells
|
|||||||
SPELL_DARK_SHELL = 32358
|
SPELL_DARK_SHELL = 32358
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Events
|
enum Groups
|
||||||
{
|
{
|
||||||
EVENT_VOID_BLAST = 1,
|
GROUP_VOID_BLAST = 1
|
||||||
EVENT_DARK_SHELL
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class boss_pandemonius : public CreatureScript
|
constexpr uint8 MAX_VOID_BLAST = 5;
|
||||||
{
|
|
||||||
public:
|
|
||||||
boss_pandemonius() : CreatureScript("boss_pandemonius") { }
|
|
||||||
|
|
||||||
CreatureAI* GetAI(Creature* creature) const override
|
struct boss_pandemonius : public BossAI
|
||||||
|
{
|
||||||
|
boss_pandemonius(Creature* creature) : BossAI(creature, DATA_PANDEMONIUS)
|
||||||
{
|
{
|
||||||
return GetManaTombsAI<boss_pandemoniusAI>(creature);
|
scheduler.SetValidator([this]
|
||||||
|
{
|
||||||
|
return !me->HasUnitState(UNIT_STATE_CASTING);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
struct boss_pandemoniusAI : public ScriptedAI
|
void JustEngagedWith(Unit* who) override
|
||||||
{
|
{
|
||||||
boss_pandemoniusAI(Creature* creature) : ScriptedAI(creature) { }
|
Talk(SAY_AGGRO);
|
||||||
|
|
||||||
EventMap events;
|
scheduler.
|
||||||
|
Schedule(20s, GROUP_VOID_BLAST, [this](TaskContext context)
|
||||||
void Reset() override
|
|
||||||
{
|
|
||||||
events.Reset();
|
|
||||||
VoidBlastCounter = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void JustEngagedWith(Unit*) override
|
|
||||||
{
|
|
||||||
me->SetInCombatWithZone();
|
|
||||||
|
|
||||||
Talk(SAY_AGGRO);
|
|
||||||
|
|
||||||
events.ScheduleEvent(EVENT_DARK_SHELL, 20000);
|
|
||||||
events.ScheduleEvent(EVENT_VOID_BLAST, urand(8000, 23000));
|
|
||||||
}
|
|
||||||
|
|
||||||
void KilledUnit(Unit* victim) override
|
|
||||||
{
|
|
||||||
if (victim->GetTypeId() == TYPEID_PLAYER)
|
|
||||||
Talk(SAY_KILL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void JustDied(Unit* /*killer*/) override
|
|
||||||
{
|
|
||||||
Talk(SAY_DEATH);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UpdateAI(uint32 diff) override
|
|
||||||
{
|
|
||||||
if (!UpdateVictim())
|
|
||||||
return;
|
|
||||||
|
|
||||||
events.Update(diff);
|
|
||||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
|
||||||
return;
|
|
||||||
|
|
||||||
switch (events.ExecuteEvent())
|
|
||||||
{
|
{
|
||||||
case EVENT_VOID_BLAST:
|
if (me->IsNonMeleeSpellCast(false))
|
||||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true))
|
{
|
||||||
{
|
me->InterruptNonMeleeSpells(true);
|
||||||
DoCast(target, SPELL_VOID_BLAST);
|
}
|
||||||
++VoidBlastCounter;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (VoidBlastCounter == 5)
|
Talk(EMOTE_DARK_SHELL);
|
||||||
|
DoCastSelf(SPELL_DARK_SHELL);
|
||||||
|
context.Repeat();
|
||||||
|
})
|
||||||
|
.Schedule(8s, 23s, [this](TaskContext context)
|
||||||
|
{
|
||||||
|
if (!(context.GetRepeatCounter() % (MAX_VOID_BLAST + 1)))
|
||||||
{
|
{
|
||||||
VoidBlastCounter = 0;
|
context.Repeat(15s, 25s);
|
||||||
events.RescheduleEvent(EVENT_VOID_BLAST, urand(15000, 25000));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
events.RescheduleEvent(EVENT_VOID_BLAST, 500);
|
DoCastRandomTarget(SPELL_VOID_BLAST);
|
||||||
events.DelayEvents(EVENT_DARK_SHELL, 500);
|
context.Repeat(500ms);
|
||||||
}
|
context.DelayGroup(GROUP_VOID_BLAST, 500ms);
|
||||||
break;
|
|
||||||
case EVENT_DARK_SHELL:
|
|
||||||
if (me->IsNonMeleeSpellCast(false))
|
|
||||||
{
|
|
||||||
me->InterruptNonMeleeSpells(true);
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
Talk(EMOTE_DARK_SHELL);
|
BossAI::JustEngagedWith(who);
|
||||||
DoCast(me, SPELL_DARK_SHELL);
|
}
|
||||||
events.RescheduleEvent(EVENT_DARK_SHELL, 20000);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
DoMeleeAttackIfReady();
|
void KilledUnit(Unit* victim) override
|
||||||
}
|
{
|
||||||
|
if (victim->GetTypeId() == TYPEID_PLAYER)
|
||||||
|
Talk(SAY_KILL);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
void JustDied(Unit* killer) override
|
||||||
uint32 VoidBlastCounter;
|
{
|
||||||
};
|
Talk(SAY_DEATH);
|
||||||
|
BossAI::JustDied(killer);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void AddSC_boss_pandemonius()
|
void AddSC_boss_pandemonius()
|
||||||
{
|
{
|
||||||
new boss_pandemonius();
|
RegisterManaTombsCreatureAI(boss_pandemonius);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -104,7 +104,14 @@ struct boss_talon_king_ikiss : public BossAI
|
|||||||
context.Repeat(7s, 12s);
|
context.Repeat(7s, 12s);
|
||||||
}).Schedule(8s, [this](TaskContext context)
|
}).Schedule(8s, [this](TaskContext context)
|
||||||
{
|
{
|
||||||
DoCastRandomTarget(SPELL_POLYMORPH);
|
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(SPELL_POLYMORPH);
|
||||||
|
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, [&](Unit* target) -> bool
|
||||||
|
{
|
||||||
|
return target && !target->IsImmunedToSpell(spellInfo);
|
||||||
|
}))
|
||||||
|
{
|
||||||
|
DoCast(target, SPELL_POLYMORPH);
|
||||||
|
}
|
||||||
context.Repeat(15s, 17500ms);
|
context.Repeat(15s, 17500ms);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ struct boss_grand_warlock_nethekurse : public BossAI
|
|||||||
|
|
||||||
if (!_canAggro)
|
if (!_canAggro)
|
||||||
{
|
{
|
||||||
me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
|
me->SetImmuneToAll(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -235,11 +235,13 @@ struct boss_grand_warlock_nethekurse : public BossAI
|
|||||||
me->SetInCombatWithZone();
|
me->SetInCombatWithZone();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (action == ACTION_START_INTRO)
|
else if (action == ACTION_START_INTRO && !_introStarted)
|
||||||
{
|
{
|
||||||
// Hack: Prevent from pulling from behind door
|
// Hack: Prevent from pulling from behind door
|
||||||
me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
|
me->SetImmuneToAll(false);
|
||||||
_canAggro = true;
|
_canAggro = true;
|
||||||
|
// Bit of a hack to make sure it can't be started with the areatrigger AND the door opening
|
||||||
|
_introStarted = true;
|
||||||
|
|
||||||
std::list<Creature*> creatureList;
|
std::list<Creature*> creatureList;
|
||||||
GetCreatureListWithEntryInGrid(creatureList, me, NPC_PEON, 60.0f);
|
GetCreatureListWithEntryInGrid(creatureList, me, NPC_PEON, 60.0f);
|
||||||
@@ -247,7 +249,7 @@ struct boss_grand_warlock_nethekurse : public BossAI
|
|||||||
{
|
{
|
||||||
if (creature)
|
if (creature)
|
||||||
{
|
{
|
||||||
creature->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
|
creature->SetImmuneToAll(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
IntroRP();
|
IntroRP();
|
||||||
@@ -258,6 +260,21 @@ struct boss_grand_warlock_nethekurse : public BossAI
|
|||||||
{
|
{
|
||||||
scheduler.Update(diff);
|
scheduler.Update(diff);
|
||||||
|
|
||||||
|
// this should never be called if the action to start intro has been called
|
||||||
|
if (!_introStarted)
|
||||||
|
{
|
||||||
|
// find the door that is nearest to the entrance
|
||||||
|
if (GameObject* nethekursedoor = GetClosestGameObjectWithEntry(me, GO_GRAND_WARLOCK_CHAMBER_DOOR_1, 100.0f))
|
||||||
|
{
|
||||||
|
// check if door is openened
|
||||||
|
//this should only happen before the intro, if the door is picked by someone
|
||||||
|
if(nethekursedoor->GetGoState() == 0)
|
||||||
|
{
|
||||||
|
DoAction(ACTION_START_INTRO);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!UpdateVictim())
|
if (!UpdateVictim())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -272,6 +289,7 @@ private:
|
|||||||
uint8 PeonEngagedCount = 0;
|
uint8 PeonEngagedCount = 0;
|
||||||
uint8 PeonKilledCount = 0;
|
uint8 PeonKilledCount = 0;
|
||||||
bool _canAggro = false;
|
bool _canAggro = false;
|
||||||
|
bool _introStarted = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
class spell_tsh_shadow_bolt : public SpellScript
|
class spell_tsh_shadow_bolt : public SpellScript
|
||||||
|
|||||||
@@ -54,6 +54,24 @@ struct boss_nethermancer_sepethrea : public BossAI
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CanAIAttack(Unit const* target) const override
|
||||||
|
{
|
||||||
|
if (me->GetThreatMgr().GetThreatListSize() > 1)
|
||||||
|
{
|
||||||
|
ThreatContainer::StorageType::const_iterator lastRef = me->GetThreatMgr().GetOnlineContainer().GetThreatList().end();
|
||||||
|
--lastRef;
|
||||||
|
if (Unit* lastTarget = (*lastRef)->getTarget())
|
||||||
|
{
|
||||||
|
if (lastTarget != target)
|
||||||
|
{
|
||||||
|
return !target->HasAura(SPELL_DRAGONS_BREATH);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void JustEngagedWith(Unit* /*who*/) override
|
void JustEngagedWith(Unit* /*who*/) override
|
||||||
{
|
{
|
||||||
_JustEngagedWith();
|
_JustEngagedWith();
|
||||||
|
|||||||
@@ -500,6 +500,31 @@ class spell_dru_glyph_of_starfire : public SpellScript
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 34246 - Idol of the Emerald Queen
|
||||||
|
// 60779 - Idol of Lush Moss
|
||||||
|
class spell_dru_idol_lifebloom : public AuraScript
|
||||||
|
{
|
||||||
|
PrepareAuraScript(spell_dru_idol_lifebloom);
|
||||||
|
|
||||||
|
void HandleEffectCalcSpellMod(AuraEffect const* aurEff, SpellModifier*& spellMod)
|
||||||
|
{
|
||||||
|
if (!spellMod)
|
||||||
|
{
|
||||||
|
spellMod = new SpellModifier(GetAura());
|
||||||
|
spellMod->op = SPELLMOD_DOT;
|
||||||
|
spellMod->type = SPELLMOD_FLAT;
|
||||||
|
spellMod->spellId = GetId();
|
||||||
|
spellMod->mask = aurEff->GetSpellInfo()->Effects[aurEff->GetEffIndex()].SpellClassMask;
|
||||||
|
}
|
||||||
|
spellMod->value = aurEff->GetAmount() / 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Register() override
|
||||||
|
{
|
||||||
|
DoEffectCalcSpellMod += AuraEffectCalcSpellModFn(spell_dru_idol_lifebloom::HandleEffectCalcSpellMod, EFFECT_0, SPELL_AURA_DUMMY);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// 29166 - Innervate
|
// 29166 - Innervate
|
||||||
class spell_dru_innervate : public AuraScript
|
class spell_dru_innervate : public AuraScript
|
||||||
{
|
{
|
||||||
@@ -1158,6 +1183,7 @@ void AddSC_druid_spell_scripts()
|
|||||||
RegisterSpellScript(spell_dru_dash);
|
RegisterSpellScript(spell_dru_dash);
|
||||||
RegisterSpellScript(spell_dru_enrage);
|
RegisterSpellScript(spell_dru_enrage);
|
||||||
RegisterSpellScript(spell_dru_glyph_of_starfire);
|
RegisterSpellScript(spell_dru_glyph_of_starfire);
|
||||||
|
RegisterSpellScript(spell_dru_idol_lifebloom);
|
||||||
RegisterSpellScript(spell_dru_innervate);
|
RegisterSpellScript(spell_dru_innervate);
|
||||||
RegisterSpellScript(spell_dru_lifebloom);
|
RegisterSpellScript(spell_dru_lifebloom);
|
||||||
RegisterSpellScript(spell_dru_living_seed);
|
RegisterSpellScript(spell_dru_living_seed);
|
||||||
|
|||||||
@@ -990,7 +990,7 @@ public:
|
|||||||
Reset();
|
Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PatientSaved(Creature* /*soldier*/, Player* player, Location* point)
|
void PatientSaved(Creature* savedPatient, Player* player, Location* point)
|
||||||
{
|
{
|
||||||
if (player && PlayerGUID == player->GetGUID())
|
if (player && PlayerGUID == player->GetGUID())
|
||||||
{
|
{
|
||||||
@@ -1004,8 +1004,9 @@ public:
|
|||||||
{
|
{
|
||||||
for (ObjectGuid const& guid : Patients)
|
for (ObjectGuid const& guid : Patients)
|
||||||
{
|
{
|
||||||
if (Creature* patient = ObjectAccessor::GetCreature(*me, guid))
|
if (guid != savedPatient->GetGUID()) // Don't kill the last guy we just saved
|
||||||
patient->setDeathState(JUST_DIED);
|
if (Creature* patient = ObjectAccessor::GetCreature(*me, guid))
|
||||||
|
patient->setDeathState(JUST_DIED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1069,6 +1070,9 @@ public:
|
|||||||
//no regen health
|
//no regen health
|
||||||
me->SetUnitFlag(UNIT_FLAG_IN_COMBAT);
|
me->SetUnitFlag(UNIT_FLAG_IN_COMBAT);
|
||||||
|
|
||||||
|
//prevent using normal bandages
|
||||||
|
me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_BANDAGE, true);
|
||||||
|
|
||||||
//to make them lay with face down
|
//to make them lay with face down
|
||||||
me->SetUInt32Value(UNIT_FIELD_BYTES_1, UNIT_STAND_STATE_DEAD);
|
me->SetUInt32Value(UNIT_FIELD_BYTES_1, UNIT_STAND_STATE_DEAD);
|
||||||
|
|
||||||
@@ -1078,18 +1082,26 @@ public:
|
|||||||
{
|
{
|
||||||
//lower max health
|
//lower max health
|
||||||
case 12923:
|
case 12923:
|
||||||
case 12938: //Injured Soldier
|
case 12938: //Injured Soldier, 65 seconds to die
|
||||||
me->SetHealth(me->CountPctFromMaxHealth(75));
|
me->SetHealth(me->CountPctFromMaxHealth(65));
|
||||||
break;
|
break;
|
||||||
case 12924:
|
case 12924:
|
||||||
case 12936: //Badly injured Soldier
|
case 12936: //Badly injured Soldier, 35 seconds to die
|
||||||
me->SetHealth(me->CountPctFromMaxHealth(50));
|
me->SetHealth(me->CountPctFromMaxHealth(35));
|
||||||
break;
|
break;
|
||||||
case 12925:
|
case 12925:
|
||||||
case 12937: //Critically injured Soldier
|
case 12937: //Critically injured Soldier, 25 seconds to die
|
||||||
me->SetHealth(me->CountPctFromMaxHealth(25));
|
me->SetHealth(me->CountPctFromMaxHealth(25));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Schedule health reduction every 1 second
|
||||||
|
_scheduler.Schedule(1s, [this](TaskContext context)
|
||||||
|
{
|
||||||
|
// Reduction of 1% per second, matching WotLK Classic timing
|
||||||
|
me->ModifyHealth(me->CountPctFromMaxHealth(1) * -1);
|
||||||
|
context.Repeat(1s);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void JustEngagedWith(Unit* /*who*/) override { }
|
void JustEngagedWith(Unit* /*who*/) override { }
|
||||||
@@ -1134,13 +1146,12 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateAI(uint32 /*diff*/) override
|
void UpdateAI(uint32 diff) override
|
||||||
{
|
{
|
||||||
//lower HP on every world tick makes it a useful counter, not officlone though
|
|
||||||
if (me->IsAlive() && me->GetHealth() > 6)
|
|
||||||
me->ModifyHealth(-5);
|
|
||||||
|
|
||||||
if (me->IsAlive() && me->GetHealth() <= 6)
|
_scheduler.Update(diff);
|
||||||
|
|
||||||
|
if (me->IsAlive() && me->GetHealth() < me->CountPctFromMaxHealth(1))
|
||||||
{
|
{
|
||||||
me->RemoveUnitFlag(UNIT_FLAG_IN_COMBAT);
|
me->RemoveUnitFlag(UNIT_FLAG_IN_COMBAT);
|
||||||
me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||||
@@ -1152,6 +1163,10 @@ public:
|
|||||||
CAST_AI(npc_doctor::npc_doctorAI, doctor->AI())->PatientDied(Coord);
|
CAST_AI(npc_doctor::npc_doctorAI, doctor->AI())->PatientDied(Coord);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
TaskScheduler _scheduler;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
CreatureAI* GetAI(Creature* creature) const override
|
CreatureAI* GetAI(Creature* creature) const override
|
||||||
@@ -1162,7 +1177,7 @@ public:
|
|||||||
|
|
||||||
void npc_doctor::npc_doctorAI::UpdateAI(uint32 diff)
|
void npc_doctor::npc_doctorAI::UpdateAI(uint32 diff)
|
||||||
{
|
{
|
||||||
if (Event && SummonPatientCount >= 20)
|
if (Event && SummonPatientCount >= 24) // Need to keep the event going long enough to save the last few patients
|
||||||
{
|
{
|
||||||
Reset();
|
Reset();
|
||||||
return;
|
return;
|
||||||
@@ -1170,7 +1185,7 @@ void npc_doctor::npc_doctorAI::UpdateAI(uint32 diff)
|
|||||||
|
|
||||||
if (Event)
|
if (Event)
|
||||||
{
|
{
|
||||||
if (SummonPatientTimer <= diff)
|
if (SummonPatientTimer <= diff || SummonPatientCount < 6) // Starts with 6 beds filled for both factions
|
||||||
{
|
{
|
||||||
if (Coordinates.empty())
|
if (Coordinates.empty())
|
||||||
return;
|
return;
|
||||||
|
|||||||
Reference in New Issue
Block a user