mirror of
https://github.com/liyunfan1223/azerothcore-wotlk.git
synced 2026-08-07 15:28:02 +00:00
fix(Scripts/Quest): Implement Sorlof's Booty Quest Event (#26810)
This commit is contained in:
135
data/sql/updates/pending_db_world/rev_1785013957591502300.sql
Normal file
135
data/sql/updates/pending_db_world/rev_1785013957591502300.sql
Normal file
@@ -0,0 +1,135 @@
|
||||
--
|
||||
-- Quest 11529 "Sorlof's Booty": restore the sniffed cannon chain.
|
||||
--
|
||||
-- Clicking The Big Gun used to cast the damage spell itself, instantly, with the
|
||||
-- clicker as original caster - so Sorlof could be shelled from anywhere on the map by
|
||||
-- spamming the gun, and the player tagged him and looted his corpse. Sniffs show the
|
||||
-- click casts the primer, which starts the player's timed Big Gun Assault, which in
|
||||
-- turn has the gun fire Cannon Assault at Sorlof.
|
||||
DELETE FROM `npc_spellclick_spells` WHERE `npc_entry` = 24992;
|
||||
INSERT INTO `npc_spellclick_spells` (`npc_entry`, `spell_id`, `cast_flags`, `user_type`) VALUES
|
||||
(24992, 45045, 3, 0); -- The Big Gun - Big Cannon Assault Primer
|
||||
|
||||
-- Resolve the nearby-entry target of Big Gun Assault to the gun the player is manning.
|
||||
DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` = 13 AND `SourceEntry` = 45013;
|
||||
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
|
||||
(13, 1, 45013, 0, 0, 31, 0, 3, 24992, 0, 0, 0, 0, '', 'Spell Big Gun Assault targets The Big Gun');
|
||||
|
||||
DELETE FROM `spell_script_names` WHERE `spell_id` IN (45013, 45045);
|
||||
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
|
||||
(45045, 'spell_sorlofs_booty_cannon_primer'),
|
||||
(45013, 'spell_sorlofs_booty_big_gun_assault');
|
||||
|
||||
--
|
||||
-- Sorlof shadows the Sister Mercy along the shore instead of walking his own loop.
|
||||
--
|
||||
-- The ship's stops carry departure events in TaxiPathNode.dbc (path 778), which
|
||||
-- MotionTransport::DoEventIfAny hands to her GameObjectAI; the script forwards each one
|
||||
-- to Sorlof as the path he takes to the matching shore position.
|
||||
UPDATE `gameobject_template` SET `ScriptName` = 'go_sister_mercy' WHERE `entry` = 187038; -- Sister Mercy
|
||||
|
||||
-- His movement, boulder assault and death are all script-driven now.
|
||||
UPDATE `creature_template` SET `AIName` = '', `ScriptName` = 'npc_sorlof' WHERE `entry` = 24914; -- Sorlof
|
||||
DELETE FROM `smart_scripts` WHERE `entryorguid` = 24914 AND `source_type` = 0;
|
||||
|
||||
-- Sniffed spawn position; the AI walks him from here on the ship's first departure.
|
||||
UPDATE `creature` SET `position_x` = 97.17545, `position_y` = -4024.8862, `position_z` = 1.5117704, `orientation` = 2.606328010559082031, `MovementType` = 0 WHERE `guid` = 103278; -- Sorlof
|
||||
|
||||
-- The boulders land on these: crew triggers dotted over the Sister Mercy's decks and
|
||||
-- rigging. 44965 has no target cap, so the script picks one of them per throw.
|
||||
SET @CGUID := 73617;
|
||||
|
||||
-- Crew Triggers for Boulder Targets
|
||||
DELETE FROM `creature` WHERE `id` = 24973 AND `guid` BETWEEN @CGUID+0 AND @CGUID+26;
|
||||
INSERT INTO `creature` (`guid`, `id`, `map`, `zoneId`, `areaId`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `CreateObject`, `VerifiedBuild`) VALUES
|
||||
(@CGUID+0 , 24973, 594, 495, 4077, -20.6305503845214843, 0.87925499677658081, 23.15439796447753906, 2.234021425247192382, 120, 1, 68887),
|
||||
(@CGUID+1 , 24973, 594, 495, 4077, -26.7290573120117187, 8.964938163757324218, 16.09914779663085937, 1.326450228691101074, 120, 1, 68887),
|
||||
(@CGUID+2 , 24973, 594, 495, 4077, -28.3763332366943359, 2.132025003433227539, 19.53076934814453125, 2.897246599197387695, 120, 1, 68887),
|
||||
(@CGUID+3 , 24973, 594, 495, 4077, -16.0938186645507812, 0.273838013410568237, 43.55142974853515625, 4.485496044158935546, 120, 1, 68887),
|
||||
(@CGUID+4 , 24973, 594, 495, 4077, -18.2567806243896484, 12.23450279235839843, 13.1617746353149414, 4.15388345718383789, 120, 1, 68887),
|
||||
(@CGUID+5 , 24973, 594, 495, 4077, -21.46112060546875, -0.04458500072360038, 26.67117500305175781, 1.064650893211364746, 120, 1, 68887),
|
||||
(@CGUID+6 , 24973, 594, 495, 4077, 1.346712946891784667, 13.24960041046142578, 20.16955184936523437, 1.326450228691101074, 120, 1, 68887),
|
||||
(@CGUID+7 , 24973, 594, 495, 4077, -10.768381118774414, 10.98365497589111328, 11.52657890319824218, 4.590215682983398437, 120, 1, 68887),
|
||||
(@CGUID+8 , 24973, 594, 495, 4077, 0.120067000389099121, 2.717941045761108398, 9.014368057250976562, 2.827433347702026367, 120, 1, 68887),
|
||||
(@CGUID+9 , 24973, 594, 495, 4077, -14.4963808059692382, 5.586709022521972656, 19.56297492980957031, 2.652900457382202148, 120, 1, 68887),
|
||||
(@CGUID+10, 24973, 594, 495, 4077, 2.856342077255249023, 0.252011001110076904, 39.62346649169921875, 2.216568231582641601, 120, 1, 68887),
|
||||
(@CGUID+11, 24973, 594, 495, 4077, 7.384247779846191406, 4.385578155517578125, 14.35732841491699218, 2.478367567062377929, 120, 1, 68887),
|
||||
(@CGUID+12, 24973, 594, 495, 4077, -4.44231891632080078, 1.441480040550231933, 30.1070098876953125, 0.104719758033752441, 120, 1, 68887),
|
||||
(@CGUID+13, 24973, 594, 495, 4077, -0.38327699899673461, 9.437303543090820312, 8.811459541320800781, 4.24114990234375, 120, 1, 68887),
|
||||
(@CGUID+14, 24973, 594, 495, 4077, -0.61927801370620727, 0.729270994663238525, 15.69870185852050781, 4.712388992309570312, 120, 1, 68887),
|
||||
(@CGUID+15, 24973, 594, 495, 4077, 2.437870979309082031, 10.67437362670898437, 3.100884199142456054, 5.602506637573242187, 120, 1, 68887),
|
||||
(@CGUID+16, 24973, 594, 495, 4077, 0.543250977993011474, 0.511954009532928466, 22.23152732849121093, 0.436332315206527709, 120, 1, 68887),
|
||||
(@CGUID+17, 24973, 594, 495, 4077, 5.890214920043945312, 0.641448020935058593, 56.5892181396484375, 3.228859186172485351, 120, 1, 68887),
|
||||
(@CGUID+18, 24973, 594, 495, 4077, 2.481215953826904296, -7.58693122863769531, 14.11674880981445312, 2.635447263717651367, 120, 1, 68887),
|
||||
(@CGUID+19, 24973, 594, 495, 4077, 28.58755874633789062, 7.992822170257568359, 20.73052597045898437, 5.009094715118408203, 120, 1, 68887),
|
||||
(@CGUID+20, 24973, 594, 495, 4077, 11.99658966064453125, 13.07939910888671875, 10.18214607238769531, 6.230825424194335937, 120, 1, 68887),
|
||||
(@CGUID+21, 24973, 594, 495, 4077, 21.87375259399414062, 12.49561214447021484, 9.61978912353515625, 3.246312379837036132, 120, 1, 68887),
|
||||
(@CGUID+22, 24973, 594, 495, 4077, 22.16750526428222656, 1.304870963096618652, 25.48061752319335937, 5.480333805084228515, 120, 1, 68887),
|
||||
(@CGUID+23, 24973, 594, 495, 4077, 25.33149147033691406, 0.86961299180984497, 46.09729766845703125, 6.213372230529785156, 120, 1, 68887),
|
||||
(@CGUID+24, 24973, 594, 495, 4077, 32.807464599609375, 3.295629024505615234, 20.36577415466308593, 5.585053443908691406, 120, 1, 68887),
|
||||
(@CGUID+25, 24973, 594, 495, 4077, 8.728032112121582031, 11.15651130676269531, 3.116890192031860351, 2.39110112190246582, 120, 1, 68887),
|
||||
(@CGUID+26, 24973, 594, 495, 4077, 20.87360382080078125, 10.74199485778808593, 3.112012147903442382, 4.607669353485107421, 120, 1, 68887);
|
||||
|
||||
-- Boulder Assault: 44965 picks a crew trigger inside its 200 yard reach, lands 44966 on
|
||||
-- it, and 44967 leaves Creeping Flames burning where it struck.
|
||||
DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` = 13 AND `SourceEntry` = 44965;
|
||||
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
|
||||
(13, 1, 44965, 0, 0, 31, 0, 3, 24973, 0, 0, 0, 0, '', 'Spell Boulder Assault targets Ellis Crew Trigger');
|
||||
|
||||
DELETE FROM `spell_script_names` WHERE `spell_id` IN (44965, 44966);
|
||||
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
|
||||
(44965, 'spell_sorlofs_booty_boulder_assault'),
|
||||
(44966, 'spell_sorlofs_booty_boulder_assault_hit');
|
||||
|
||||
-- Serverside Boulder Assault: triggers 44965 at the Ellis Crew Trigger every 3s.
|
||||
DELETE FROM `creature_addon` WHERE `guid` = 103278;
|
||||
INSERT INTO `creature_addon` (`guid`, `path_id`, `mount`, `bytes1`, `bytes2`, `emote`, `visibilityDistanceType`, `auras`) VALUES
|
||||
(103278, 0, 0, 0, 1, 0, 3, '44964'); -- Sorlof
|
||||
|
||||
DELETE FROM `waypoint_data` WHERE `id` IN (1032780, 1032781, 1032782, 1032783, 1032784, 1032785);
|
||||
INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `orientation`) VALUES
|
||||
-- Pos 1 (spawn)
|
||||
(1032780, 1, 97.17545, -4024.8862, 1.5117704, NULL),
|
||||
-- Pos 2
|
||||
(1032781, 1, 101.15443, -3924.839, 2.2858443, NULL),
|
||||
(1032781, 2, 92.51937, -3893.2766, 1.7101376, NULL),
|
||||
(1032781, 3, 113.66331, -3885.0088, 3.9941988, NULL),
|
||||
-- Pos 3
|
||||
(1032782, 1, 170.00453, -3834.312, 1.0282993, NULL),
|
||||
-- Pos 4
|
||||
(1032783, 1, 234.34787, -3839.6567, 6.5361958, NULL),
|
||||
(1032783, 2, 260.00797, -3825.02, 4.976329, NULL),
|
||||
(1032783, 3, 279.02988, -3805.746, 4.17469, NULL),
|
||||
(1032783, 4, 266.36356, -3775.4158, 3.9740202, NULL),
|
||||
-- Pos 5
|
||||
(1032784, 1, 307.11368, -3802.3945, 2.1991935, NULL),
|
||||
(1032784, 2, 327.66074, -3807.0261, 2.548757, NULL),
|
||||
(1032784, 3, 356.2998, -3801.8398, 1.4324319, NULL),
|
||||
(1032784, 4, 390.81516, -3765.8672, 0.9260107, NULL),
|
||||
-- Return path (inferred - he died at the last position)
|
||||
(1032785, 1, 356.2998, -3801.8398, 1.4324319, NULL),
|
||||
(1032785, 2, 327.66074, -3807.0261, 2.548757, NULL),
|
||||
(1032785, 3, 307.11368, -3802.3945, 2.1991935, NULL),
|
||||
(1032785, 4, 266.36356, -3775.4158, 3.9740202, NULL),
|
||||
(1032785, 5, 279.02988, -3805.746, 4.17469, NULL),
|
||||
(1032785, 6, 260.00797, -3825.02, 4.976329, NULL),
|
||||
(1032785, 7, 234.34787, -3839.6567, 6.5361958, NULL),
|
||||
(1032785, 8, 170.00453, -3834.312, 1.0282993, NULL),
|
||||
(1032785, 9, 113.66331, -3885.0088, 3.9941988, NULL),
|
||||
(1032785, 10, 92.51937, -3893.2766, 1.7101376, NULL),
|
||||
(1032785, 11, 101.15443, -3924.839, 2.2858443, NULL),
|
||||
(1032785, 12, 97.17545, -4024.8862, 1.5117704, NULL);
|
||||
|
||||
DELETE FROM `creature_template_movement` WHERE (`CreatureId` = 24992);
|
||||
INSERT INTO `creature_template_movement` (`CreatureId`, `Ground`, `Swim`, `Flight`, `Rooted`, `Chase`, `Random`, `InteractionPauseTimer`) VALUES
|
||||
(24992, 0, 0, 1, 1, 0, 0, 0);
|
||||
|
||||
UPDATE `creature_template` SET `flags_extra` = `flags_extra`|128 WHERE (`entry` = 23826);
|
||||
DELETE FROM `creature_template_addon` WHERE (`entry` = 23826);
|
||||
INSERT INTO `creature_template_addon` (`entry`, `path_id`, `mount`, `bytes1`, `bytes2`, `emote`, `visibilityDistanceType`, `auras`) VALUES
|
||||
(23826, 0, 0, 0, 0, 0, 0, '42460');
|
||||
|
||||
DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 24911);
|
||||
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`, `event_param6`, `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
|
||||
(24911, 0, 0, 1, 60, 0, 100, 0, 3400, 6200, 3400, 6200, 0, 0, 11, 44961, 64, 0, 0, 0, 0, 10, 103278, 24914, 0, 0, 0, 0, 0, 0, 'Cursed Sea Dog - On Update - Cast \'Shoot\' at Sorlof'),
|
||||
(24911, 0, 1, 0, 61, 0, 4, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Cursed Sea Dog - On Cast \'Shoot\' - Say Line');
|
||||
@@ -5242,6 +5242,18 @@ void SpellMgr::LoadSpellInfoCorrections()
|
||||
spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
|
||||
});
|
||||
|
||||
// Boulder Assault (Sorlof's Booty)
|
||||
ApplySpellFix({ 44966 }, [](SpellInfo* spellInfo)
|
||||
{
|
||||
spellInfo->AttributesEx |= SPELL_ATTR1_NO_THREAT;
|
||||
});
|
||||
|
||||
// Cannon Assault (Sorlof's Booty)
|
||||
ApplySpellFix({ 45008 }, [](SpellInfo* spellInfo)
|
||||
{
|
||||
spellInfo->AttributesEx3 |= SPELL_ATTR3_ALWAYS_HIT;
|
||||
});
|
||||
|
||||
for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
|
||||
{
|
||||
SpellInfo* spellInfo = mSpellInfoMap[i];
|
||||
|
||||
@@ -15,13 +15,19 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "Containers.h"
|
||||
#include "CreatureScript.h"
|
||||
#include "GameObjectAI.h"
|
||||
#include "GameObjectScript.h"
|
||||
#include "Map.h"
|
||||
#include "MotionMaster.h"
|
||||
#include "PassiveAI.h"
|
||||
#include "Player.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ScriptedEscortAI.h"
|
||||
#include "SpellInfo.h"
|
||||
#include "SpellScript.h"
|
||||
#include "WaypointMgr.h"
|
||||
|
||||
class npc_attracted_reef_bull : public CreatureScript
|
||||
{
|
||||
@@ -417,6 +423,263 @@ class spell_the_cleansing_on_death_cast_on_master : public SpellScript
|
||||
}
|
||||
};
|
||||
|
||||
/*######
|
||||
## Quest 11529: Sorlof's Booty
|
||||
######*/
|
||||
|
||||
enum SorlofsBooty
|
||||
{
|
||||
NPC_SORLOF = 24914,
|
||||
NPC_THE_BIG_GUN = 24992,
|
||||
|
||||
SPELL_CANNON_ASSAULT = 45008,
|
||||
SPELL_SORLOFS_BOOTY = 45070,
|
||||
|
||||
// SPELL_BOULDER_ASSAULT_AURA = 44964, // Serverside, triggers 44965 every 3s
|
||||
SPELL_BOULDER_ASSAULT_HIT = 44966,
|
||||
SPELL_BOULDER_ASSAULT_FIRE = 44967,
|
||||
|
||||
// About the maximum range for broadside
|
||||
CANNON_RANGE = 200,
|
||||
|
||||
// The ship needs to ping Sorlof from wherever she is on her lap
|
||||
SORLOF_SEARCH_RANGE = 1000,
|
||||
|
||||
SORLOF_WANDER_DISTANCE = 10,
|
||||
|
||||
DATA_SORLOF_TAKE_PATH = 1,
|
||||
POINT_SORLOF_PATH = 1000,
|
||||
|
||||
// He only knits himself back together once he has broken off and headed home
|
||||
PATH_SORLOF_RETURN = 1032785,
|
||||
|
||||
// The gun's own SmartAI announces the booty on this data set.
|
||||
DATA_SORLOF_SLAIN = 1
|
||||
};
|
||||
|
||||
// 44965 - Boulder Assault
|
||||
class spell_sorlofs_booty_boulder_assault : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_sorlofs_booty_boulder_assault);
|
||||
|
||||
bool Validate(SpellInfo const* /*spellInfo*/) override
|
||||
{
|
||||
return ValidateSpellInfo({ SPELL_BOULDER_ASSAULT_HIT });
|
||||
}
|
||||
|
||||
void FilterTargets(std::list<WorldObject*>& targets)
|
||||
{
|
||||
if (targets.empty())
|
||||
return;
|
||||
|
||||
// One boulder per throw from implicit targets (no limit in DBC)
|
||||
WorldObject* target = Acore::Containers::SelectRandomContainerElement(targets);
|
||||
targets.clear();
|
||||
targets.push_back(target);
|
||||
}
|
||||
|
||||
void HandleScript(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
if (Unit* caster = GetCaster())
|
||||
caster->CastSpell(GetHitUnit(), SPELL_BOULDER_ASSAULT_HIT, true);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_sorlofs_booty_boulder_assault::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY);
|
||||
OnEffectHitTarget += SpellEffectFn(spell_sorlofs_booty_boulder_assault::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
}
|
||||
};
|
||||
|
||||
// 44966 - Boulder Assault
|
||||
class spell_sorlofs_booty_boulder_assault_hit : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_sorlofs_booty_boulder_assault_hit);
|
||||
|
||||
bool Validate(SpellInfo const* /*spellInfo*/) override
|
||||
{
|
||||
return ValidateSpellInfo({ SPELL_BOULDER_ASSAULT_FIRE });
|
||||
}
|
||||
|
||||
void HandleScript(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
if (Unit* target = GetHitUnit())
|
||||
target->CastSpell(target, SPELL_BOULDER_ASSAULT_FIRE, true);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_sorlofs_booty_boulder_assault_hit::HandleScript, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
}
|
||||
};
|
||||
|
||||
uint32 GetSorlofPathForShipEvent(uint32 eventId)
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
// Departure events of the Sister Mercy's stops (TaxiPathNode.dbc path 778)
|
||||
case 16501: return 1032780;
|
||||
case 16502: return 1032781;
|
||||
case 16503: return 1032782;
|
||||
case 16504: return 1032783;
|
||||
case 16510: return 1032784;
|
||||
case 16511: return 1032785; // Return to spawn
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
struct npc_sorlof : public ScriptedAI
|
||||
{
|
||||
npc_sorlof(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
_pathId = 0;
|
||||
_pathNode = 0;
|
||||
_advancePath = false;
|
||||
me->SetRegeneratingHealth(false);
|
||||
}
|
||||
|
||||
void SetData(uint32 id, uint32 value) override
|
||||
{
|
||||
if (id != DATA_SORLOF_TAKE_PATH)
|
||||
return;
|
||||
|
||||
_pathId = value;
|
||||
_pathNode = 0;
|
||||
_advancePath = true;
|
||||
me->SetRegeneratingHealth(value == PATH_SORLOF_RETURN);
|
||||
}
|
||||
|
||||
void MovementInform(uint32 type, uint32 id) override
|
||||
{
|
||||
if (type != POINT_MOTION_TYPE || id != POINT_SORLOF_PATH + _pathNode)
|
||||
return;
|
||||
|
||||
++_pathNode;
|
||||
_advancePath = true;
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
DoCastSelf(SPELL_SORLOFS_BOOTY, true);
|
||||
|
||||
if (Creature* gun = me->FindNearestCreature(NPC_THE_BIG_GUN, CANNON_RANGE))
|
||||
gun->AI()->SetData(DATA_SORLOF_SLAIN, DATA_SORLOF_SLAIN);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 /*diff*/) override
|
||||
{
|
||||
// Deferred out of MovementInform: that fires from the generator's DoFinalize, and
|
||||
// MotionMaster::DirectExpire then Resets the new top generator, whose DoReset stops
|
||||
// the spline it just launched. UpdateAI runs after the MotionMaster, so it sticks.
|
||||
if (_advancePath)
|
||||
{
|
||||
_advancePath = false;
|
||||
MoveToNextNode();
|
||||
}
|
||||
|
||||
if (UpdateVictim())
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
void MoveToNextNode()
|
||||
{
|
||||
WaypointPath const* path = sWaypointMgr->GetPath(_pathId);
|
||||
if (!path)
|
||||
return;
|
||||
|
||||
// Each leg ends with him milling about where the ship has drawn up
|
||||
if (_pathNode >= path->Nodes.size())
|
||||
{
|
||||
me->GetMotionMaster()->MoveRandom(SORLOF_WANDER_DISTANCE);
|
||||
return;
|
||||
}
|
||||
|
||||
WaypointNode const& node = path->Nodes[_pathNode];
|
||||
me->SetWalk(node.MoveType == WAYPOINT_MOVE_TYPE_WALK);
|
||||
me->GetMotionMaster()->MovePoint(POINT_SORLOF_PATH + _pathNode, node.X, node.Y, node.Z);
|
||||
}
|
||||
|
||||
uint32 _pathId{ 0 };
|
||||
uint32 _pathNode{ 0 };
|
||||
bool _advancePath{ false };
|
||||
};
|
||||
|
||||
struct go_sister_mercy : public GameObjectAI
|
||||
{
|
||||
go_sister_mercy(GameObject* go) : GameObjectAI(go) { }
|
||||
|
||||
// Notify Sorlof the ship is departing towards the next broadside point
|
||||
void EventInform(uint32 eventId) override
|
||||
{
|
||||
uint32 pathId = GetSorlofPathForShipEvent(eventId);
|
||||
if (!pathId)
|
||||
return;
|
||||
|
||||
if (Creature* sorlof = me->FindNearestCreature(NPC_SORLOF, SORLOF_SEARCH_RANGE))
|
||||
sorlof->AI()->SetData(DATA_SORLOF_TAKE_PATH, pathId);
|
||||
}
|
||||
};
|
||||
|
||||
// 45045 - Big Cannon Assault Primer
|
||||
class spell_sorlofs_booty_cannon_primer : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_sorlofs_booty_cannon_primer);
|
||||
|
||||
bool Validate(SpellInfo const* spellInfo) override
|
||||
{
|
||||
return ValidateSpellInfo({ uint32(spellInfo->GetEffect(EFFECT_0).CalcValue()) });
|
||||
}
|
||||
|
||||
void HandleScript(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
// Primes the gun: the clicker performs the actual, timed Big Gun Assault cast.
|
||||
if (Unit* caster = GetCaster())
|
||||
caster->CastSpell(caster, GetSpellInfo()->Effects[EFFECT_0].CalcValue(), false);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_sorlofs_booty_cannon_primer::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
}
|
||||
};
|
||||
|
||||
// 45013 - Big Gun Assault
|
||||
class spell_sorlofs_booty_big_gun_assault : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_sorlofs_booty_big_gun_assault);
|
||||
|
||||
bool Validate(SpellInfo const* /*spellInfo*/) override
|
||||
{
|
||||
return ValidateSpellInfo({ SPELL_CANNON_ASSAULT });
|
||||
}
|
||||
|
||||
void HandleDummy(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
// Implicit target of the dummy effect, resolved to The Big Gun by conditions
|
||||
Creature* gun = GetHitCreature();
|
||||
if (!gun)
|
||||
return;
|
||||
|
||||
Creature* sorlof = gun->FindNearestCreature(NPC_SORLOF, CANNON_RANGE);
|
||||
if (!sorlof)
|
||||
return;
|
||||
|
||||
if (!gun->IsWithinLOSInMap(sorlof, VMAP::ModelIgnoreFlags::M2, LINEOFSIGHT_CHECK_VMAP))
|
||||
return;
|
||||
|
||||
// Fired by the gun rather than by the player, this is correct
|
||||
gun->CastSpell(sorlof, SPELL_CANNON_ASSAULT, true);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_sorlofs_booty_big_gun_assault::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_howling_fjord()
|
||||
{
|
||||
new npc_attracted_reef_bull();
|
||||
@@ -428,4 +691,10 @@ void AddSC_howling_fjord()
|
||||
RegisterSpellScript(spell_the_cleansing_cleansing_soul);
|
||||
RegisterSpellScript(spell_the_cleansing_mirror_image_script_effect);
|
||||
RegisterSpellScript(spell_the_cleansing_on_death_cast_on_master);
|
||||
RegisterSpellScript(spell_sorlofs_booty_cannon_primer);
|
||||
RegisterSpellScript(spell_sorlofs_booty_big_gun_assault);
|
||||
RegisterSpellScript(spell_sorlofs_booty_boulder_assault);
|
||||
RegisterSpellScript(spell_sorlofs_booty_boulder_assault_hit);
|
||||
RegisterCreatureAI(npc_sorlof);
|
||||
RegisterGameObjectAI(go_sister_mercy);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user