fix(Scripts/DB): UBRS Solakar / father flame (#8236)

This commit is contained in:
patou01
2021-11-07 10:10:19 +01:00
committed by GitHub
parent c0728f6e2d
commit cb07d1fc8a
5 changed files with 398 additions and 9 deletions

View File

@@ -0,0 +1,27 @@
INSERT INTO `version_db_world` (`sql_rev`) VALUES ('1633268017505597200');
-- rookery guardians
UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 10258;
DELETE FROM `smart_scripts` WHERE `entryorguid` = 10258 AND `source_type` = 0 AND (`id` IN (0, 1, 2, 3));
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
(10258, 0, 0, 0, 63, 0, 100, 0, 0, 0, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 25, 500, 1, 0, 0, 0, 0, 0, 0, 'Rookery Guardian - On Just Created - Start Attacking'),
(10258, 0, 1, 0, 0, 0, 100, 2, 10000, 12000, 10000, 15000, 0, 11, 15572, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Rookery Guardian - In Combat - Cast \'Sunder Armor\' (Normal Dungeon)'),
(10258, 0, 2, 0, 0, 0, 100, 2, 5000, 7000, 4000, 6000, 0, 11, 15580, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Rookery Guardian - In Combat - Cast \'Strike\' (Normal Dungeon)');
-- rookery hatcher
UPDATE `creature_template` SET `ScriptName` = 'npc_rookery_hatcher' WHERE `entry` = 10683;
DELETE FROM `creature_text` WHERE `CreatureID` = 10683;
INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `Comment`) VALUES
(10683, 0, 0, 'Intruders are destroying our eggs! Stop!!', 14, 0, 0, 0, 5538, 0, 'UBRS - Solakar event');
-- solakar
UPDATE `creature_template` SET `ScriptName` = 'boss_solakar_flamewreath' WHERE `entry` = 10264;
-- father flame
UPDATE `gameobject_template` SET `ScriptName` = 'go_father_flame' WHERE `entry` = 175245;
DELETE FROM `smart_scripts` WHERE `entryorguid` = 175245 AND `source_type` = 1 AND `id` = 0;
-- partial cleanup for the eggs
DELETE FROM `gameobject_template` WHERE `entry` = 175622;
DELETE FROM `gameobject_template_addon` WHERE `entry` = 175622;
DELETE FROM `smart_scripts` WHERE `entryorguid` = 175622;

View File

@@ -49,7 +49,8 @@ enum DataTypes
DATA_HALL_RUNE_4 = 19,
DATA_HALL_RUNE_5 = 20,
DATA_HALL_RUNE_6 = 21,
DATA_HALL_RUNE_7 = 22
DATA_HALL_RUNE_7 = 22,
DATA_SOLAKAR_FLAMEWREATH = 23
};
enum CreaturesIds
@@ -73,6 +74,12 @@ enum CreaturesIds
NPC_BLACKHAND_VETERAN = 9819,
NPC_BLACKHAND_INCARCERATOR = 10316,
NPC_LORD_VICTOR_NEFARIUS = 10162,
NPC_SOLAKAR = 10264,
NPC_ROOKERY_GUARDIAN = 10258,
NPC_ROOKERY_HATCHER = 10683,
NPC_ROOKERY_WHELP = 10161,
NPC_UROK_MAGUS = 10602,
NPC_UROK_ENFORCER = 10601,
NPC_FINKLE_EINHORN = 10776
@@ -91,7 +98,7 @@ enum AdditionalData
enum GameObjectsIds
{
GO_WHELP_SPAWNER = 175622, // trap spawned by go id 175124
GO_ROOKERY_EGG = 175124,
// Doors
GO_EMBERSEER_IN = 175244, // First door to Pyroguard Emberseer
GO_DOORS = 175705, // Second door to Pyroguard Emberseer

View File

@@ -0,0 +1,248 @@
/*
* This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by the
* Free Software Foundation; either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "blackrock_spire.h"
enum Spells
{
SPELL_WAR_STOMP = 16727,
SPELL_HATCH_EGG = 15746
};
enum Timer
{
TIMER_WAR_STOMP = 20000
};
constexpr float RANGE_SPELL_HATCH_EGG = 3.0f; // needed because the eggs seem to hatch if the mobs goes too close
constexpr float RANGE_WHELP_CALL_HELP = 15.0f; // range for the hatchers to call nearby whelps after having summoned them.
enum Says
{
SAY_SUMMON = 0,
};
class npc_rookery_hatcher : public CreatureScript
{
public:
npc_rookery_hatcher() : CreatureScript("npc_rookery_hatcher") {}
CreatureAI* GetAI(Creature* creature) const override
{
return GetBlackrockSpireAI<npc_rookery_hatcherAI>(creature);
}
struct npc_rookery_hatcherAI : public CreatureAI
{
npc_rookery_hatcherAI(Creature* creature) : CreatureAI(creature) {}
EventMap events;
std::list<GameObject*> nearbyEggs;
GameObject* targetEgg;
Position targetPosition;
void InitializeAI() override
{
CreatureAI::InitializeAI();
DoZoneInCombat(nullptr, 100.0f);
nearbyEggs.clear();
targetEgg = nullptr;
}
void EnterCombat(Unit* /*who*/) override
{
events.ScheduleEvent(SPELL_HATCH_EGG, 1000);
}
void UpdateAI(uint32 diff) override
{
std::list<GameObject*> nearbyEggs;
float tempDist = 20;
float minDist = 25;
std::list<Creature*> nearbyWhelps;
if (!UpdateVictim())
{
return;
}
GetCreatureListWithEntryInGrid(nearbyWhelps, me, NPC_ROOKERY_WHELP, RANGE_WHELP_CALL_HELP);
for (const auto& whelp : nearbyWhelps)
{
if (!whelp->IsInCombat())
{
whelp->SetInCombatWith(me->GetVictim());
whelp->AI()->AttackStart(me->GetVictim());
}
}
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
events.Update(diff);
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
case SPELL_HATCH_EGG:
if (!targetEgg) // no target, try to find one
{
minDist = 50;
tempDist = 50;
me->GetGameObjectListWithEntryInGrid(nearbyEggs, GO_ROOKERY_EGG, 40);
for (const auto& egg : nearbyEggs)
{
if (egg->isSpawned() && egg->getLootState() == GO_READY)
{
tempDist = me->GetDistance2d(egg);
if (tempDist < minDist)
{
minDist = tempDist;
targetEgg = egg;
}
}
}
}
if (targetEgg) //have a target, go to it and cast it
{
me->GetMotionMaster()->MovePoint(0, targetEgg->GetPosition());
}
break;
default:
break;
}
}
// cast takes 1.5second, during which we don't have a target
if (targetEgg && targetEgg->getLootState() == GO_READY && me->GetDistance2d(targetEgg) < RANGE_SPELL_HATCH_EGG)
{
me->StopMovingOnCurrentPos();
me->SetFacingToObject(targetEgg);
targetPosition = me->GetPosition();
DoCast(SPELL_HATCH_EGG);
targetEgg = nullptr;
events.ScheduleEvent(SPELL_HATCH_EGG, urand(6000, 8000));
}
else if (!me->HasUnitState(UNIT_STATE_CASTING) && !targetEgg)
{
if (Unit* victim = me->GetVictim())
{
AttackStart(victim);
}
if (me->GetDistance2d(me->GetVictim()) > me->GetMeleeReach())
{
me->GetMotionMaster()->MovePoint(0, me->GetVictim()->GetPosition()); // a bit hacky, but needed to start moving once we've summoned an egg
}
}
DoMeleeAttackIfReady();
}
};
};
class boss_solakar_flamewreath : public CreatureScript
{
public:
boss_solakar_flamewreath() : CreatureScript("boss_solakar_flamewreath") { }
struct boss_solakar_flamewreathAI : public BossAI
{
boss_solakar_flamewreathAI(Creature* creature) : BossAI(creature, DATA_SOLAKAR_FLAMEWREATH) {}
uint32 resetTimer;
void Reset() override
{
_Reset();
resetTimer = 10000;
}
void InitializeAI() override
{
BossAI::InitializeAI();
Talk(SAY_SUMMON);
DoZoneInCombat(nullptr, 100.0f);
}
void EnterCombat(Unit* /*who*/) override
{
_EnterCombat();
events.ScheduleEvent(SPELL_WAR_STOMP, urand(17000, 20000));
resetTimer = 0;
}
void JustDied(Unit* /*killer*/) override
{
_JustDied();
instance->SetData(DATA_SOLAKAR_FLAMEWREATH, DONE);
}
void ExecuteEvent(uint32 eventId) override
{
switch (eventId)
{
case SPELL_WAR_STOMP:
DoCastVictim(SPELL_WAR_STOMP);
events.ScheduleEvent(SPELL_WAR_STOMP, urand(17000, 20000));
break;
default:
break;
}
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
{
resetTimer -= diff;
if (resetTimer < diff)
{
instance->SetData(DATA_SOLAKAR_FLAMEWREATH, FAIL);
}
return;
}
resetTimer = 10000;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
{
return;
}
while (uint32 eventId = events.ExecuteEvent())
{
ExecuteEvent(eventId);
}
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI(Creature* creature) const override
{
return GetBlackrockSpireAI<boss_solakar_flamewreathAI>(creature);
}
};
void AddSC_boss_solakar_flamewreath()
{
new boss_solakar_flamewreath();
new npc_rookery_hatcher();
}

View File

@@ -26,19 +26,34 @@
#include "ScriptedCreature.h"
#include "ScriptMgr.h"
//uint32 const DragonspireRunes[7] = { GO_HALL_RUNE_1, GO_HALL_RUNE_2, GO_HALL_RUNE_3, GO_HALL_RUNE_4, GO_HALL_RUNE_5, GO_HALL_RUNE_6, GO_HALL_RUNE_7 };
uint32 const DragonspireMobs[3] = { NPC_BLACKHAND_DREADWEAVER, NPC_BLACKHAND_SUMMONER, NPC_BLACKHAND_VETERAN };
enum EventIds
{
EVENT_DARGONSPIRE_ROOM_STORE = 1,
EVENT_DARGONSPIRE_ROOM_CHECK = 2
EVENT_DARGONSPIRE_ROOM_CHECK = 2,
EVENT_SOLAKAR_WAVE = 3
};
enum Timers
{
TIMER_SOLAKAR_WAVE = 30000
};
enum SolakarWaves
{
MAX_WAVE_COUNT = 5
};
Position SolakarPosLeft = Position(78.0f, -280.0f, 93.0f, 3.0f * M_PI / 2.0);
Position SolakarPosRight = Position(84.0f, -280.0f, 93.0f, 3.0f * M_PI / 2.0);
Position SolakarPosBoss = Position(80.0f, -280.0f, 93.0f, 3.0f * M_PI / 2.0);
enum Texts
{
SAY_NEFARIUS_REND_WIPE = 11
SAY_NEFARIUS_REND_WIPE = 11,
SAY_SOLAKAR_FIRST_HATCHER = 0
};
class instance_blackrock_spire : public InstanceMapScript
@@ -48,9 +63,16 @@ public:
struct instance_blackrock_spireMapScript : public InstanceScript
{
uint32 CurrentSolakarWave = 0;
uint32 SolakarState = NOT_STARTED; // there should be a global instance encounter state, where is it?
std::vector<TempSummon*> SolakarSummons;
instance_blackrock_spireMapScript(InstanceMap* map) : InstanceScript(map)
{
SetBossNumber(EncounterCount);
CurrentSolakarWave = 0;
SolakarState = NOT_STARTED;
SolakarSummons.clear();
}
void CreatureLooted(Creature* creature, LootType loot) override
@@ -140,9 +162,6 @@ public:
{
switch (go->GetEntry())
{
case GO_WHELP_SPAWNER:
go->CastSpell(nullptr, SPELL_SUMMON_ROOKERY_WHELP);
break;
case GO_EMBERSEER_IN:
go_emberseerin = go->GetGUID();
HandleGameObject(ObjectGuid::Empty, GetBossState(DATA_DRAGONSPIRE_ROOM) == DONE, go);
@@ -331,6 +350,29 @@ public:
Events.ScheduleEvent(EVENT_DARGONSPIRE_ROOM_STORE, 1000);
}
break;
case DATA_SOLAKAR_FLAMEWREATH:
switch(data)
{
case IN_PROGRESS:
if (SolakarState == NOT_STARTED)
{
Events.ScheduleEvent(EVENT_SOLAKAR_WAVE, 500);
}
break;
case FAIL:
for (const auto& creature : SolakarSummons)
{
creature->RemoveFromWorld();
}
SolakarSummons.clear();
CurrentSolakarWave = 0;
SetData(DATA_SOLAKAR_FLAMEWREATH, NOT_STARTED);
break;
case DONE:
break;
}
SolakarState = data;
break;
case DATA_UROK_DOOMHOWL:
if (data == FAIL)
{
@@ -368,6 +410,38 @@ public:
}
}
uint32 GetData(uint32 type) const override
{
if (type == DATA_SOLAKAR_FLAMEWREATH)
{
return SolakarState;
}
else
{
return InstanceScript::GetData(type);
}
}
void SummonSolakarWave(uint8 number)
{
if (number < MAX_WAVE_COUNT)
{
SolakarSummons.push_back(instance->SummonCreature(NPC_ROOKERY_GUARDIAN, SolakarPosLeft));
SolakarSummons.push_back(instance->SummonCreature(NPC_ROOKERY_HATCHER, SolakarPosRight));
if (number == 0)
{
if (Creature* FirstHatcher = SolakarSummons.back()) // works because we spawned a hatcher second
{
FirstHatcher->AI()->Talk(SAY_SOLAKAR_FIRST_HATCHER);
}
}
}
else if (number == MAX_WAVE_COUNT)
{
SolakarSummons.push_back(instance->SummonCreature(NPC_SOLAKAR, SolakarPosBoss));
}
}
ObjectGuid GetGuidData(uint32 type) const override
{
switch (type)
@@ -462,6 +536,14 @@ public:
if ((GetBossState(DATA_DRAGONSPIRE_ROOM) != DONE))
Events.ScheduleEvent(EVENT_DARGONSPIRE_ROOM_CHECK, 3000);
break;
case EVENT_SOLAKAR_WAVE:
SummonSolakarWave(CurrentSolakarWave);
if (CurrentSolakarWave < MAX_WAVE_COUNT)
{
Events.ScheduleEvent(EVENT_SOLAKAR_WAVE, TIMER_SOLAKAR_WAVE);
CurrentSolakarWave++;
}
break;
default:
break;
}
@@ -704,9 +786,32 @@ public:
}
};
class go_father_flame : public GameObjectScript
{
public:
go_father_flame() : GameObjectScript("go_father_flame") {}
void OnLootStateChanged(GameObject* go, uint32 state, Unit* /*unit*/) override
{
if (InstanceScript* instance = go->GetInstanceScript())
{
if (state == GO_ACTIVATED)
{
if (instance->GetData(DATA_SOLAKAR_FLAMEWREATH) == IN_PROGRESS || instance->GetData(DATA_SOLAKAR_FLAMEWREATH) == DONE)
{
return;
}
instance->SetData(DATA_SOLAKAR_FLAMEWREATH, IN_PROGRESS);
}
}
}
};
void AddSC_instance_blackrock_spire()
{
new instance_blackrock_spire();
new at_dragonspire_hall();
new at_blackrock_stadium();
new go_father_flame();
}

View File

@@ -43,6 +43,7 @@ void AddSC_boss_pyroguard_emberseer();
void AddSC_boss_gyth();
void AddSC_boss_rend_blackhand();
void AddSC_boss_urok_doomhowl();
void AddSC_boss_solakar_flamewreath();
void AddSC_instance_blackrock_spire();
void AddSC_boss_razorgore(); //Blackwing lair
void AddSC_boss_vaelastrasz();
@@ -179,6 +180,7 @@ void AddEasternKingdomsScripts()
AddSC_boss_warmastervoone();
AddSC_boss_pyroguard_emberseer();
AddSC_boss_gyth();
AddSC_boss_solakar_flamewreath();
AddSC_boss_rend_blackhand();
AddSC_boss_urok_doomhowl();
AddSC_instance_blackrock_spire();