mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-02-07 21:01:37 +00:00
Merge branch 'azerothcore:master' into Playerbot
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "azerothcore-wotlk",
|
"name": "azerothcore-wotlk",
|
||||||
"version": "6.0.0-dev.2",
|
"version": "6.0.0-dev.3",
|
||||||
"license": "AGPL3"
|
"license": "AGPL3"
|
||||||
}
|
}
|
||||||
|
|||||||
35
data/sql/updates/db_world/2022_03_23_03.sql
Normal file
35
data/sql/updates/db_world/2022_03_23_03.sql
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
-- DB update 2022_03_23_02 -> 2022_03_23_03
|
||||||
|
DROP PROCEDURE IF EXISTS `updateDb`;
|
||||||
|
DELIMITER //
|
||||||
|
CREATE PROCEDURE updateDb ()
|
||||||
|
proc:BEGIN DECLARE OK VARCHAR(100) DEFAULT 'FALSE';
|
||||||
|
SELECT COUNT(*) INTO @COLEXISTS
|
||||||
|
FROM information_schema.COLUMNS
|
||||||
|
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'version_db_world' AND COLUMN_NAME = '2022_03_23_02';
|
||||||
|
IF @COLEXISTS = 0 THEN LEAVE proc; END IF;
|
||||||
|
START TRANSACTION;
|
||||||
|
ALTER TABLE version_db_world CHANGE COLUMN 2022_03_23_02 2022_03_23_03 bit;
|
||||||
|
SELECT sql_rev INTO OK FROM version_db_world WHERE sql_rev = '1647530609689243500'; IF OK <> 'FALSE' THEN LEAVE proc; END IF;
|
||||||
|
--
|
||||||
|
-- START UPDATING QUERIES
|
||||||
|
--
|
||||||
|
|
||||||
|
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, '');
|
||||||
|
|
||||||
|
--
|
||||||
|
-- END UPDATING QUERIES
|
||||||
|
--
|
||||||
|
UPDATE version_db_world SET date = '2022_03_23_03' WHERE sql_rev = '1647530609689243500';
|
||||||
|
COMMIT;
|
||||||
|
END //
|
||||||
|
DELIMITER ;
|
||||||
|
CALL updateDb();
|
||||||
|
DROP PROCEDURE IF EXISTS `updateDb`;
|
||||||
@@ -1,3 +1,15 @@
|
|||||||
|
## 6.0.0-dev.3 | Commit: [44b7a0666c78dc99ab0bbc94045abb6685b3ad86
|
||||||
|
](https://github.com/azerothcore/azerothcore-wotlk/commit/44b7a0666c78dc99ab0bbc94045abb6685b3ad86
|
||||||
|
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- New hook for OnQuestComputeXP(). The intended use is to change the XP values for certain quests programmatically. The hook is triggered after XP calculation and before rewarding XP or gold to the player.
|
||||||
|
|
||||||
|
### How to upgrade
|
||||||
|
|
||||||
|
- No special changes needed. The new hook is available for use and should not interfere with any existing hooks or logic.
|
||||||
|
|
||||||
## 6.0.0-dev.2 | Commit: [680e60c68b1864596bf23d427e9f4742c6437b86
|
## 6.0.0-dev.2 | Commit: [680e60c68b1864596bf23d427e9f4742c6437b86
|
||||||
](https://github.com/azerothcore/azerothcore-wotlk/commit/680e60c68b1864596bf23d427e9f4742c6437b86
|
](https://github.com/azerothcore/azerothcore-wotlk/commit/680e60c68b1864596bf23d427e9f4742c6437b86
|
||||||
|
|
||||||
|
|||||||
@@ -334,6 +334,9 @@ public:
|
|||||||
static AISpellInfoType* AISpellInfo;
|
static AISpellInfoType* AISpellInfo;
|
||||||
static void FillAISpellInfo();
|
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 sGossipHello(Player* /*player*/) {}
|
||||||
virtual void sGossipSelect(Player* /*player*/, uint32 /*sender*/, uint32 /*action*/) {}
|
virtual void sGossipSelect(Player* /*player*/, uint32 /*sender*/, uint32 /*action*/) {}
|
||||||
virtual void sGossipSelectCode(Player* /*player*/, uint32 /*sender*/, uint32 /*action*/, char const* /*code*/) {}
|
virtual void sGossipSelectCode(Player* /*player*/, uint32 /*sender*/, uint32 /*action*/, char const* /*code*/) {}
|
||||||
|
|||||||
@@ -3529,3 +3529,8 @@ void Creature::SetRespawnTime(uint32 respawn)
|
|||||||
{
|
{
|
||||||
m_respawnTime = respawn ? GameTime::GetGameTime().count() + respawn : 0;
|
m_respawnTime = respawn ? GameTime::GetGameTime().count() + respawn : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Creature::SetCorpseRemoveTime(uint32 delay)
|
||||||
|
{
|
||||||
|
m_corpseRemoveTime = GameTime::GetGameTime().count() + delay;
|
||||||
|
}
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ public:
|
|||||||
void GetRespawnPosition(float& x, float& y, float& z, float* ori = nullptr, float* dist = nullptr) const;
|
void GetRespawnPosition(float& x, float& y, float& z, float* ori = nullptr, float* dist = nullptr) const;
|
||||||
|
|
||||||
void SetCorpseDelay(uint32 delay) { m_corpseDelay = delay; }
|
void SetCorpseDelay(uint32 delay) { m_corpseDelay = delay; }
|
||||||
|
void SetCorpseRemoveTime(uint32 delay);
|
||||||
[[nodiscard]] uint32 GetCorpseDelay() const { return m_corpseDelay; }
|
[[nodiscard]] uint32 GetCorpseDelay() const { return m_corpseDelay; }
|
||||||
[[nodiscard]] bool IsRacialLeader() const { return GetCreatureTemplate()->RacialLeader; }
|
[[nodiscard]] bool IsRacialLeader() const { return GetCreatureTemplate()->RacialLeader; }
|
||||||
[[nodiscard]] bool IsCivilian() const { return GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_CIVILIAN; }
|
[[nodiscard]] bool IsCivilian() const { return GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_CIVILIAN; }
|
||||||
@@ -394,7 +395,7 @@ protected:
|
|||||||
ObjectGuid::LowType m_lootRecipientGroup;
|
ObjectGuid::LowType m_lootRecipientGroup;
|
||||||
|
|
||||||
/// Timers
|
/// 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_respawnTime; // (secs) time of next respawn
|
||||||
time_t m_respawnedTime; // (secs) time when creature respawned
|
time_t m_respawnedTime; // (secs) time when creature respawned
|
||||||
uint32 m_respawnDelay; // (secs) delay between corpse disappearance and respawning
|
uint32 m_respawnDelay; // (secs) delay between corpse disappearance and respawning
|
||||||
|
|||||||
@@ -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)
|
void InstanceScript::DoUpdateWorldState(uint32 uiStateId, uint32 uiStateData)
|
||||||
{
|
{
|
||||||
Map::PlayerList const& lPlayers = instance->GetPlayers();
|
Map::PlayerList const& lPlayers = instance->GetPlayers();
|
||||||
|
|||||||
@@ -194,6 +194,12 @@ public:
|
|||||||
//Respawns a GO having negative spawntimesecs in gameobject-table
|
//Respawns a GO having negative spawntimesecs in gameobject-table
|
||||||
void DoRespawnGameObject(ObjectGuid guid, uint32 timeToDespawn = MINUTE);
|
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
|
//sends world state update to all players in instance
|
||||||
void DoUpdateWorldState(uint32 worldstateId, uint32 worldstateValue);
|
void DoUpdateWorldState(uint32 worldstateId, uint32 worldstateValue);
|
||||||
|
|
||||||
|
|||||||
@@ -197,6 +197,14 @@ template <> void PointMovementGenerator<Creature>::MovementInform(Creature* unit
|
|||||||
{
|
{
|
||||||
if (unit->AI())
|
if (unit->AI())
|
||||||
unit->AI()->MovementInform(POINT_MOTION_TYPE, id);
|
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*);
|
template void PointMovementGenerator<Player>::DoInitialize(Player*);
|
||||||
|
|||||||
@@ -256,6 +256,14 @@ void WaypointMovementGenerator<Creature>::MovementInform(Creature* creature)
|
|||||||
{
|
{
|
||||||
if (creature->AI())
|
if (creature->AI())
|
||||||
creature->AI()->MovementInform(WAYPOINT_MOTION_TYPE, i_currentNode);
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------//
|
//----------------------------------------------------//
|
||||||
|
|||||||
@@ -4243,6 +4243,12 @@ void SpellMgr::LoadSpellInfoCorrections()
|
|||||||
spellInfo->Effects[EFFECT_0].DieSides = 1250;
|
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)
|
for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
|
||||||
{
|
{
|
||||||
SpellInfo* spellInfo = mSpellInfoMap[i];
|
SpellInfo* spellInfo = mSpellInfoMap[i];
|
||||||
|
|||||||
@@ -39,13 +39,18 @@ enum BWLEncounter
|
|||||||
|
|
||||||
// Additional Data
|
// Additional Data
|
||||||
DATA_LORD_VICTOR_NEFARIUS = 8,
|
DATA_LORD_VICTOR_NEFARIUS = 8,
|
||||||
|
DATA_GRETHOK = 9,
|
||||||
|
DATA_NEFARIAN_TROOPS = 10,
|
||||||
|
|
||||||
// Doors
|
// Doors
|
||||||
DATA_GO_CHROMAGGUS_DOOR = 9
|
DATA_GO_CHROMAGGUS_DOOR = 11
|
||||||
};
|
};
|
||||||
|
|
||||||
enum BWLCreatureIds
|
enum BWLCreatureIds
|
||||||
{
|
{
|
||||||
|
NPC_GRETHOK = 12557,
|
||||||
|
NPC_BLACKWING_GUARDSMAN = 14456,
|
||||||
|
NPC_NEFARIAN_TROOPS = 14459,
|
||||||
NPC_RAZORGORE = 12435,
|
NPC_RAZORGORE = 12435,
|
||||||
NPC_BLACKWING_DRAGON = 12422,
|
NPC_BLACKWING_DRAGON = 12422,
|
||||||
NPC_BLACKWING_TASKMASTER = 12458,
|
NPC_BLACKWING_TASKMASTER = 12458,
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ enum Say
|
|||||||
SAY_EGGS_BROKEN2 = 1,
|
SAY_EGGS_BROKEN2 = 1,
|
||||||
SAY_EGGS_BROKEN3 = 2,
|
SAY_EGGS_BROKEN3 = 2,
|
||||||
SAY_DEATH = 3,
|
SAY_DEATH = 3,
|
||||||
|
|
||||||
|
EMOTE_TROOPS_RETREAT = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Spells
|
enum Spells
|
||||||
@@ -38,7 +40,12 @@ enum Spells
|
|||||||
SPELL_CLEAVE = 19632,
|
SPELL_CLEAVE = 19632,
|
||||||
SPELL_WARSTOMP = 24375,
|
SPELL_WARSTOMP = 24375,
|
||||||
SPELL_FIREBALLVOLLEY = 22425,
|
SPELL_FIREBALLVOLLEY = 22425,
|
||||||
SPELL_CONFLAGRATION = 23023
|
SPELL_CONFLAGRATION = 23023,
|
||||||
|
|
||||||
|
SPELL_EXPLODE_ORB = 20037,
|
||||||
|
SPELL_EXPLOSION = 20038, // Instakill everything.
|
||||||
|
|
||||||
|
SPELL_WARMING_FLAMES = 23040,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Summons
|
enum Summons
|
||||||
@@ -72,16 +79,19 @@ public:
|
|||||||
void Reset() override
|
void Reset() override
|
||||||
{
|
{
|
||||||
_Reset();
|
_Reset();
|
||||||
|
_died = false;
|
||||||
_charmerGUID.Clear();
|
_charmerGUID.Clear();
|
||||||
secondPhase = false;
|
secondPhase = false;
|
||||||
|
summons.DespawnAll();
|
||||||
instance->SetData(DATA_EGG_EVENT, NOT_STARTED);
|
instance->SetData(DATA_EGG_EVENT, NOT_STARTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JustDied(Unit* /*killer*/) override
|
void JustDied(Unit* /*killer*/) override
|
||||||
{
|
{
|
||||||
_JustDied();
|
if (secondPhase)
|
||||||
Talk(SAY_DEATH);
|
{
|
||||||
|
_JustDied();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CanAIAttack(Unit const* target) const override
|
bool CanAIAttack(Unit const* target) const override
|
||||||
@@ -93,6 +103,11 @@ public:
|
|||||||
{
|
{
|
||||||
_EnterCombat();
|
_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);
|
instance->SetData(DATA_EGG_EVENT, IN_PROGRESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,12 +116,26 @@ public:
|
|||||||
secondPhase = true;
|
secondPhase = true;
|
||||||
_charmerGUID.Clear();
|
_charmerGUID.Clear();
|
||||||
me->RemoveAllAuras();
|
me->RemoveAllAuras();
|
||||||
me->SetHealth(me->GetMaxHealth());
|
|
||||||
|
|
||||||
events.ScheduleEvent(EVENT_CLEAVE, 15000);
|
DoCastSelf(SPELL_WARMING_FLAMES, true);
|
||||||
events.ScheduleEvent(EVENT_STOMP, 35000);
|
|
||||||
events.ScheduleEvent(EVENT_FIREBALL, 7000);
|
if (Creature* troops = instance->GetCreature(DATA_NEFARIAN_TROOPS))
|
||||||
events.ScheduleEvent(EVENT_CONFLAGRATION, 12000);
|
{
|
||||||
|
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
|
void SetGUID(ObjectGuid const guid, int32 /*id*/) override
|
||||||
@@ -123,6 +152,13 @@ public:
|
|||||||
charmer->CastSpell(charmer, SPELL_MIND_EXHAUSTION, true);
|
charmer->CastSpell(charmer, SPELL_MIND_EXHAUSTION, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (Unit* charmer = ObjectAccessor::GetUnit(*me, _charmerGUID))
|
||||||
|
{
|
||||||
|
me->TauntApply(charmer);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DoAction(int32 action) override
|
void DoAction(int32 action) override
|
||||||
@@ -138,12 +174,41 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override
|
||||||
{
|
{
|
||||||
if (!secondPhase && damage >= me->GetHealth())
|
if (!secondPhase && damage >= me->GetHealth() && !_died)
|
||||||
{
|
{
|
||||||
damage = me->GetHealth() - 1;
|
// This is required because he kills himself with the explosion spell, causing a loop.
|
||||||
EnterEvadeMode();
|
_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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,7 +217,10 @@ public:
|
|||||||
if (!UpdateVictim())
|
if (!UpdateVictim())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
events.Update(diff);
|
if (!me->IsCharmed())
|
||||||
|
{
|
||||||
|
events.Update(diff);
|
||||||
|
}
|
||||||
|
|
||||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||||
return;
|
return;
|
||||||
@@ -176,18 +244,21 @@ public:
|
|||||||
case EVENT_CONFLAGRATION:
|
case EVENT_CONFLAGRATION:
|
||||||
DoCastVictim(SPELL_CONFLAGRATION);
|
DoCastVictim(SPELL_CONFLAGRATION);
|
||||||
if (me->GetVictim() && me->GetVictim()->HasAura(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);
|
me->TauntApply(target);
|
||||||
events.ScheduleEvent(EVENT_CONFLAGRATION, 30000);
|
events.ScheduleEvent(EVENT_CONFLAGRATION, 30000);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DoMeleeAttackIfReady();
|
DoMeleeAttackIfReady();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool secondPhase;
|
bool secondPhase;
|
||||||
|
bool _died;
|
||||||
ObjectGuid _charmerGUID;
|
ObjectGuid _charmerGUID;
|
||||||
|
GuidVector _summonGUIDS;
|
||||||
};
|
};
|
||||||
|
|
||||||
CreatureAI* GetAI(Creature* creature) const override
|
CreatureAI* GetAI(Creature* creature) const override
|
||||||
|
|||||||
@@ -41,6 +41,12 @@ DoorData const doorData[] =
|
|||||||
{ 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE} // END
|
{ 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE} // END
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ObjectData const creatureData[] =
|
||||||
|
{
|
||||||
|
{ NPC_GRETHOK, DATA_GRETHOK },
|
||||||
|
{ NPC_NEFARIAN_TROOPS, DATA_NEFARIAN_TROOPS }
|
||||||
|
};
|
||||||
|
|
||||||
Position const SummonPosition[8] =
|
Position const SummonPosition[8] =
|
||||||
{
|
{
|
||||||
{-7661.207520f, -1043.268188f, 407.199554f, 6.280452f},
|
{-7661.207520f, -1043.268188f, 407.199554f, 6.280452f},
|
||||||
@@ -67,7 +73,7 @@ public:
|
|||||||
//SetHeaders(DataHeader);
|
//SetHeaders(DataHeader);
|
||||||
SetBossNumber(EncounterCount);
|
SetBossNumber(EncounterCount);
|
||||||
LoadDoorData(doorData);
|
LoadDoorData(doorData);
|
||||||
//LoadObjectData(creatureData, gameObjectData);
|
LoadObjectData(creatureData, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Initialize() override
|
void Initialize() override
|
||||||
@@ -98,6 +104,9 @@ public:
|
|||||||
if (CreatureAI* razorAI = razor->AI())
|
if (CreatureAI* razorAI = razor->AI())
|
||||||
razorAI->JustSummoned(creature);
|
razorAI->JustSummoned(creature);
|
||||||
break;
|
break;
|
||||||
|
case NPC_BLACKWING_GUARDSMAN:
|
||||||
|
guardList.push_back(creature->GetGUID());
|
||||||
|
break;
|
||||||
case NPC_NEFARIAN:
|
case NPC_NEFARIAN:
|
||||||
nefarianGUID = creature->GetGUID();
|
nefarianGUID = creature->GetGUID();
|
||||||
break;
|
break;
|
||||||
@@ -135,11 +144,14 @@ public:
|
|||||||
{
|
{
|
||||||
case GO_BLACK_DRAGON_EGG:
|
case GO_BLACK_DRAGON_EGG:
|
||||||
if (GetBossState(DATA_FIREMAW) == DONE)
|
if (GetBossState(DATA_FIREMAW) == DONE)
|
||||||
|
{
|
||||||
go->SetPhaseMask(2, true);
|
go->SetPhaseMask(2, true);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
EggList.push_back(go->GetGUID());
|
EggList.push_back(go->GetGUID());
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GO_PORTCULLIS_RAZORGORE:
|
case GO_PORTCULLIS_RAZORGORE:
|
||||||
case GO_PORTCULLIS_VAELASTRASZ:
|
case GO_PORTCULLIS_VAELASTRASZ:
|
||||||
case GO_PORTCULLIS_BROODLORD:
|
case GO_PORTCULLIS_BROODLORD:
|
||||||
@@ -233,10 +245,15 @@ public:
|
|||||||
if (state == DONE)
|
if (state == DONE)
|
||||||
{
|
{
|
||||||
for (ObjectGuid const& guid : EggList)
|
for (ObjectGuid const& guid : EggList)
|
||||||
|
{
|
||||||
|
// Eggs should be destroyed instead
|
||||||
|
// @todo: after dynamic spawns
|
||||||
if (GameObject* egg = instance->GetGameObject(guid))
|
if (GameObject* egg = instance->GetGameObject(guid))
|
||||||
|
{
|
||||||
egg->SetPhaseMask(2, true);
|
egg->SetPhaseMask(2, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
SetData(DATA_EGG_EVENT, NOT_STARTED);
|
|
||||||
break;
|
break;
|
||||||
case DATA_CHROMAGGUS:
|
case DATA_CHROMAGGUS:
|
||||||
if (state == DONE)
|
if (state == DONE)
|
||||||
@@ -270,7 +287,7 @@ public:
|
|||||||
switch (data)
|
switch (data)
|
||||||
{
|
{
|
||||||
case IN_PROGRESS:
|
case IN_PROGRESS:
|
||||||
_events.ScheduleEvent(EVENT_RAZOR_SPAWN, 45000);
|
_events.ScheduleEvent(EVENT_RAZOR_SPAWN, 45 * IN_MILLISECONDS);
|
||||||
EggEvent = data;
|
EggEvent = data;
|
||||||
EggCount = 0;
|
EggCount = 0;
|
||||||
break;
|
break;
|
||||||
@@ -278,13 +295,19 @@ public:
|
|||||||
_events.CancelEvent(EVENT_RAZOR_SPAWN);
|
_events.CancelEvent(EVENT_RAZOR_SPAWN);
|
||||||
EggEvent = data;
|
EggEvent = data;
|
||||||
EggCount = 0;
|
EggCount = 0;
|
||||||
|
|
||||||
for (ObjectGuid const& guid : EggList)
|
for (ObjectGuid const& guid : EggList)
|
||||||
{
|
{
|
||||||
if (GameObject* egg = instance->GetGameObject(guid))
|
DoRespawnGameObject(guid, 0);
|
||||||
{
|
|
||||||
egg->Respawn();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DoRespawnCreature(DATA_GRETHOK);
|
||||||
|
|
||||||
|
for (ObjectGuid const& guid : guardList)
|
||||||
|
{
|
||||||
|
DoRespawnCreature(guid);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case SPECIAL:
|
case SPECIAL:
|
||||||
if (++EggCount >= EggList.size())
|
if (++EggCount >= EggList.size())
|
||||||
@@ -336,12 +359,22 @@ public:
|
|||||||
|
|
||||||
void OnUnitDeath(Unit* unit) override
|
void OnUnitDeath(Unit* unit) override
|
||||||
{
|
{
|
||||||
//! HACK, needed because of buggy CreatureAI after charm
|
|
||||||
if (unit->GetEntry() == NPC_RAZORGORE && GetBossState(DATA_RAZORGORE_THE_UNTAMED) != DONE)
|
|
||||||
SetBossState(DATA_RAZORGORE_THE_UNTAMED, DONE);
|
|
||||||
|
|
||||||
switch (unit->GetEntry())
|
switch (unit->GetEntry())
|
||||||
{
|
{
|
||||||
|
case NPC_RAZORGORE:
|
||||||
|
//! HACK, needed because of buggy CreatureAI after charm
|
||||||
|
if (EggEvent == DONE)
|
||||||
|
{
|
||||||
|
if (unit->GetEntry() == NPC_RAZORGORE && GetBossState(DATA_RAZORGORE_THE_UNTAMED) != DONE)
|
||||||
|
{
|
||||||
|
SetBossState(DATA_RAZORGORE_THE_UNTAMED, DONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_events.CancelEvent(EVENT_RAZOR_SPAWN);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case NPC_BLACK_DRAKONID:
|
case NPC_BLACK_DRAKONID:
|
||||||
case NPC_BLUE_DRAKONID:
|
case NPC_BLUE_DRAKONID:
|
||||||
case NPC_BRONZE_DRAKONID:
|
case NPC_BRONZE_DRAKONID:
|
||||||
@@ -379,10 +412,18 @@ public:
|
|||||||
switch (eventId)
|
switch (eventId)
|
||||||
{
|
{
|
||||||
case EVENT_RAZOR_SPAWN:
|
case EVENT_RAZOR_SPAWN:
|
||||||
for (uint8 i = urand(2, 5); i > 0; --i)
|
if (EggEvent == IN_PROGRESS)
|
||||||
if (Creature* summon = instance->SummonCreature(Entry[urand(0, 2)], SummonPosition[urand(0, 7)]))
|
{
|
||||||
summon->AI()->DoZoneInCombat();
|
for (uint8 i = urand(2, 5); i > 0; --i)
|
||||||
_events.ScheduleEvent(EVENT_RAZOR_SPAWN, 12000, 17000);
|
{
|
||||||
|
if (Creature* summon = instance->SummonCreature(Entry[urand(0, 2)], SummonPosition[urand(0, 7)]))
|
||||||
|
{
|
||||||
|
summon->AI()->DoZoneInCombat();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_events.ScheduleEvent(EVENT_RAZOR_SPAWN, 12000, 17000);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case EVENT_RAZOR_PHASE_TWO:
|
case EVENT_RAZOR_PHASE_TWO:
|
||||||
_events.CancelEvent(EVENT_RAZOR_SPAWN);
|
_events.CancelEvent(EVENT_RAZOR_SPAWN);
|
||||||
@@ -462,6 +503,7 @@ public:
|
|||||||
uint8 EggCount;
|
uint8 EggCount;
|
||||||
uint32 EggEvent;
|
uint32 EggEvent;
|
||||||
GuidList EggList;
|
GuidList EggList;
|
||||||
|
GuidList guardList;
|
||||||
|
|
||||||
// Nefarian
|
// Nefarian
|
||||||
uint32 NefarianLeftTunnel;
|
uint32 NefarianLeftTunnel;
|
||||||
|
|||||||
Reference in New Issue
Block a user