Skip to content

Commit

Permalink
fix(Scripts/BlackwingLair): Razorgore improvements (azerothcore#10971)
Browse files Browse the repository at this point in the history
- Rewrite reset events
- Use proper healing spell on phase transition
- Now uses abilities during phase 1
- Phase transition scripted - mobs now run away
  • Loading branch information
Nyeriah committed Mar 23, 2022
1 parent 6a6d0e5 commit 7377c96
Show file tree
Hide file tree
Showing 12 changed files with 212 additions and 32 deletions.
9 changes: 9 additions & 0 deletions data/sql/updates/pending_db_world/rev_1647530609689243500.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
INSERT INTO `version_db_world` (`sql_rev`) VALUES ('1647530609689243500');

DELETE FROM `creature` WHERE `guid` = 84205 AND `id1` = 14459;
INSERT INTO `creature` (`guid`, `id1`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`,`equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `wander_distance`, `currentwaypoint`, `curhealth`, `curmana`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `ScriptName`, `VerifiedBuild`) VALUES
(84205,14459,469,0,0,1,1,0,-7644.53,-1081.53,408.574,5.2709,10,0,0,42,0,0,0,0,0,'',0);

DELETE FROM `creature_text` WHERE `CreatureID` = 14459;
INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration` ,`Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES
(14459, 0, 0, '%s flee as the controlling power of the orb is drained.', 16, 0, 100, 0, 0, 0, 9592, 3, '');
3 changes: 3 additions & 0 deletions src/server/game/AI/CoreAI/UnitAI.h
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,9 @@ class UnitAI
static AISpellInfoType* AISpellInfo;
static void FillAISpellInfo();

// Called when a summon reaches a waypoint or point movement finished.
virtual void SummonMovementInform(Creature* /*creature*/, uint32 /*motionType*/, uint32 /*point*/) { }

virtual void sGossipHello(Player* /*player*/) {}
virtual void sGossipSelect(Player* /*player*/, uint32 /*sender*/, uint32 /*action*/) {}
virtual void sGossipSelectCode(Player* /*player*/, uint32 /*sender*/, uint32 /*action*/, char const* /*code*/) {}
Expand Down
5 changes: 5 additions & 0 deletions src/server/game/Entities/Creature/Creature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3524,3 +3524,8 @@ void Creature::SetRespawnTime(uint32 respawn)
{
m_respawnTime = respawn ? GameTime::GetGameTime().count() + respawn : 0;
}

void Creature::SetCorpseRemoveTime(uint32 delay)
{
m_corpseRemoveTime = GameTime::GetGameTime().count() + delay;
}
3 changes: 2 additions & 1 deletion src/server/game/Entities/Creature/Creature.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ class Creature : public Unit, public GridObject<Creature>, public MovableMapObje
void GetRespawnPosition(float& x, float& y, float& z, float* ori = nullptr, float* dist = nullptr) const;

void SetCorpseDelay(uint32 delay) { m_corpseDelay = delay; }
void SetCorpseRemoveTime(uint32 delay);
[[nodiscard]] uint32 GetCorpseDelay() const { return m_corpseDelay; }
[[nodiscard]] bool IsRacialLeader() const { return GetCreatureTemplate()->RacialLeader; }
[[nodiscard]] bool IsCivilian() const { return GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_CIVILIAN; }
Expand Down Expand Up @@ -395,7 +396,7 @@ class Creature : public Unit, public GridObject<Creature>, public MovableMapObje
ObjectGuid::LowType m_lootRecipientGroup;

/// Timers
time_t m_corpseRemoveTime; // (msecs)timer for death or corpse disappearance
time_t m_corpseRemoveTime; // (secs) timer for death or corpse disappearance
time_t m_respawnTime; // (secs) time of next respawn
time_t m_respawnedTime; // (secs) time when creature respawned
uint32 m_respawnDelay; // (secs) delay between corpse disappearance and respawning
Expand Down
16 changes: 16 additions & 0 deletions src/server/game/Instances/InstanceScript.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,22 @@ void InstanceScript::DoRespawnGameObject(ObjectGuid uiGuid, uint32 uiTimeToDespa
}
}

void InstanceScript::DoRespawnCreature(ObjectGuid guid, bool force)
{
if (Creature* creature = instance->GetCreature(guid))
{
creature->Respawn(force);
}
}

void InstanceScript::DoRespawnCreature(uint32 type, bool force)
{
if (Creature* creature = instance->GetCreature(GetObjectGuid(type)))
{
creature->Respawn(force);
}
}

void InstanceScript::DoUpdateWorldState(uint32 uiStateId, uint32 uiStateData)
{
Map::PlayerList const& lPlayers = instance->GetPlayers();
Expand Down
6 changes: 6 additions & 0 deletions src/server/game/Instances/InstanceScript.h
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,12 @@ class InstanceScript : public ZoneScript
//Respawns a GO having negative spawntimesecs in gameobject-table
void DoRespawnGameObject(ObjectGuid guid, uint32 timeToDespawn = MINUTE);

// Respawns a creature.
void DoRespawnCreature(ObjectGuid guid, bool force = false);

// Respawns a creature from the creature object storage.
void DoRespawnCreature(uint32 type, bool force = false);

//sends world state update to all players in instance
void DoUpdateWorldState(uint32 worldstateId, uint32 worldstateValue);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,14 @@ template <> void PointMovementGenerator<Creature>::MovementInform(Creature* unit
{
if (unit->AI())
unit->AI()->MovementInform(POINT_MOTION_TYPE, id);

if (Unit* summoner = unit->GetCharmerOrOwner())
{
if (UnitAI* AI = summoner->GetAI())
{
AI->SummonMovementInform(unit, POINT_MOTION_TYPE, id);
}
}
}

template void PointMovementGenerator<Player>::DoInitialize(Player*);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,14 @@ void WaypointMovementGenerator<Creature>::MovementInform(Creature* creature)
{
if (creature->AI())
creature->AI()->MovementInform(WAYPOINT_MOTION_TYPE, i_currentNode);

if (Unit* owner = creature->GetCharmerOrOwner())
{
if (UnitAI* AI = owner->GetAI())
{
AI->SummonMovementInform(creature, WAYPOINT_MOTION_TYPE, i_currentNode);
}
}
}

//----------------------------------------------------//
Expand Down
6 changes: 6 additions & 0 deletions src/server/game/Spells/SpellInfoCorrections.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4243,6 +4243,12 @@ void SpellMgr::LoadSpellInfoCorrections()
spellInfo->Effects[EFFECT_0].DieSides = 1250;
});

// Explosion - Razorgore
ApplySpellFix({ 20038 }, [](SpellInfo* spellInfo)
{
spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS);
});

for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
{
SpellInfo* spellInfo = mSpellInfoMap[i];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,18 @@ enum BWLEncounter

// Additional Data
DATA_LORD_VICTOR_NEFARIUS = 8,
DATA_GRETHOK = 9,
DATA_NEFARIAN_TROOPS = 10,

// Doors
DATA_GO_CHROMAGGUS_DOOR = 9
DATA_GO_CHROMAGGUS_DOOR = 11
};

enum BWLCreatureIds
{
NPC_GRETHOK = 12557,
NPC_BLACKWING_GUARDSMAN = 14456,
NPC_NEFARIAN_TROOPS = 14459,
NPC_RAZORGORE = 12435,
NPC_BLACKWING_DRAGON = 12422,
NPC_BLACKWING_TASKMASTER = 12458,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ enum Say
SAY_EGGS_BROKEN2 = 1,
SAY_EGGS_BROKEN3 = 2,
SAY_DEATH = 3,

EMOTE_TROOPS_RETREAT = 0
};

enum Spells
Expand All @@ -38,7 +40,12 @@ enum Spells
SPELL_CLEAVE = 19632,
SPELL_WARSTOMP = 24375,
SPELL_FIREBALLVOLLEY = 22425,
SPELL_CONFLAGRATION = 23023
SPELL_CONFLAGRATION = 23023,

SPELL_EXPLODE_ORB = 20037,
SPELL_EXPLOSION = 20038, // Instakill everything.

SPELL_WARMING_FLAMES = 23040,
};

enum Summons
Expand Down Expand Up @@ -72,16 +79,19 @@ class boss_razorgore : public CreatureScript
void Reset() override
{
_Reset();

_died = false;
_charmerGUID.Clear();
secondPhase = false;
summons.DespawnAll();
instance->SetData(DATA_EGG_EVENT, NOT_STARTED);
}

void JustDied(Unit* /*killer*/) override
{
_JustDied();
Talk(SAY_DEATH);
if (secondPhase)
{
_JustDied();
}
}

bool CanAIAttack(Unit const* target) const override
Expand All @@ -93,6 +103,11 @@ class boss_razorgore : public CreatureScript
{
_EnterCombat();

events.ScheduleEvent(EVENT_CLEAVE, 15000);
events.ScheduleEvent(EVENT_STOMP, 35000);
events.ScheduleEvent(EVENT_FIREBALL, 7000);
events.ScheduleEvent(EVENT_CONFLAGRATION, 12000);

instance->SetData(DATA_EGG_EVENT, IN_PROGRESS);
}

Expand All @@ -101,12 +116,26 @@ class boss_razorgore : public CreatureScript
secondPhase = true;
_charmerGUID.Clear();
me->RemoveAllAuras();
me->SetHealth(me->GetMaxHealth());

events.ScheduleEvent(EVENT_CLEAVE, 15000);
events.ScheduleEvent(EVENT_STOMP, 35000);
events.ScheduleEvent(EVENT_FIREBALL, 7000);
events.ScheduleEvent(EVENT_CONFLAGRATION, 12000);
DoCastSelf(SPELL_WARMING_FLAMES, true);

if (Creature* troops = instance->GetCreature(DATA_NEFARIAN_TROOPS))
{
troops->AI()->Talk(EMOTE_TROOPS_RETREAT);
}

for (ObjectGuid const& guid : _summonGUIDS)
{
if (Creature* creature = ObjectAccessor::GetCreature(*me, guid))
{
if (creature->IsAlive())
{
creature->CombatStop(true);
creature->SetReactState(REACT_PASSIVE);
creature->GetMotionMaster()->MovePoint(0, Position(-7560.568848f, -1028.553345f, 408.491211f, 0.523858f));
}
}
}
}

void SetGUID(ObjectGuid const guid, int32 /*id*/) override
Expand All @@ -123,6 +152,13 @@ class boss_razorgore : public CreatureScript
charmer->CastSpell(charmer, SPELL_MIND_EXHAUSTION, true);
}
}
else
{
if (Unit* charmer = ObjectAccessor::GetUnit(*me, _charmerGUID))
{
me->TauntApply(charmer);
}
}
}

void DoAction(int32 action) override
Expand All @@ -138,12 +174,41 @@ class boss_razorgore : public CreatureScript
}
}

void JustSummoned(Creature* summon) override
{
_summonGUIDS.push_back(summon->GetGUID());
summon->SetOwnerGUID(me->GetGUID());
summons.Summon(summon);
}

void SummonMovementInform(Creature* summon, uint32 movementType, uint32 /*pathId*/) override
{
if (movementType == POINT_MOTION_TYPE)
{
summon->DespawnOrUnsummon();
}
}

void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override
{
if (!secondPhase && damage >= me->GetHealth())
if (!secondPhase && damage >= me->GetHealth() && !_died)
{
damage = me->GetHealth() - 1;
EnterEvadeMode();
// This is required because he kills himself with the explosion spell, causing a loop.
_died = true;

Talk(SAY_DEATH);
DoCastAOE(SPELL_EXPLODE_ORB);
DoCastAOE(SPELL_EXPLOSION);

// Respawn shorty in case of failure during phase 1.
me->SetCorpseRemoveTime(25);
me->SetRespawnTime(30);
me->SaveRespawnTime();

// Might not be required, safe measure.
me->SetLootRecipient(nullptr);

instance->SetData(DATA_EGG_EVENT, FAIL);
}
}

Expand All @@ -152,7 +217,10 @@ class boss_razorgore : public CreatureScript
if (!UpdateVictim())
return;

events.Update(diff);
if (!me->IsCharmed())
{
events.Update(diff);
}

if (me->HasUnitState(UNIT_STATE_CASTING))
return;
Expand All @@ -176,18 +244,21 @@ class boss_razorgore : public CreatureScript
case EVENT_CONFLAGRATION:
DoCastVictim(SPELL_CONFLAGRATION);
if (me->GetVictim() && me->GetVictim()->HasAura(SPELL_CONFLAGRATION))
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 100, true))
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1))
me->TauntApply(target);
events.ScheduleEvent(EVENT_CONFLAGRATION, 30000);
break;
}
}

DoMeleeAttackIfReady();
}

private:
bool secondPhase;
bool _died;
ObjectGuid _charmerGUID;
GuidVector _summonGUIDS;
};

CreatureAI* GetAI(Creature* creature) const override
Expand Down
Loading

0 comments on commit 7377c96

Please sign in to comment.