mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-31 01:23:47 +00:00
feat(Core/WorldState): improved WorldState scripting (#20141)
* implement world state script
based on
0b87ca9d9e
Co-authored-by: killerwife <killerwife@gmail.com>
* refactor to use onleave and onenter instead of spell_area
allows players to right click remove adal's buff
* add MapMgr.h
* refactor: use condition enum instead of uint32, prefix WORLD_STATE where needed
* remove lock from WorldState::Update
sWorldState->Update() is only called from World::Update
* remove unsafe SmartAI action of setWorldState
---------
Co-authored-by: killerwife <killerwife@gmail.com>
This commit is contained in:
149
data/sql/updates/pending_db_world/rev_1727679643827269473.sql
Normal file
149
data/sql/updates/pending_db_world/rev_1727679643827269473.sql
Normal file
@@ -0,0 +1,149 @@
|
||||
--
|
||||
DELETE FROM `spell_script_names` WHERE `spell_id`=39953 AND `ScriptName`='spell_gen_adals_song_of_battle';
|
||||
-- A'dal
|
||||
UPDATE `smart_scripts` SET `link` = 5 WHERE (`entryorguid` = 18481) AND (`source_type` = 0) AND (`id` = 4);
|
||||
DELETE FROM `smart_scripts` WHERE (`entryorguid` = 18481) AND (`source_type` = 0) AND (`id` = 5);
|
||||
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
|
||||
(18481, 0, 5, 0, 61, 0, 100, 512, 0, 0, 0, 0, 0, 0, 237, 39953, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'A Dal - On Quest Reward 11007 - Run World State Script Event 39953');
|
||||
|
||||
-- Magtheridon's Head
|
||||
UPDATE `gameobject_template` SET `ScriptName` = 'go_magtheridons_head' WHERE (`entry` = 184640);
|
||||
|
||||
-- Trollbane
|
||||
UPDATE `smart_scripts` SET `link` = 4 WHERE (`entryorguid` = 16819) AND (`source_type` = 0) AND (`id` = 2);
|
||||
DELETE FROM `smart_scripts` WHERE (`entryorguid` = 16819) AND (`source_type` = 0) AND (`id` = 4);
|
||||
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
|
||||
(16819, 0, 4, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 50, 184640, 7200, 0, 0, 0, 0, 8, 0, 0, 0, 0, -732.28, 2670.99, 94.5875, -0.541051, 'Force Commander Danath Trollbane - On Quest \'The Fall of Magtheridon\' Finished - Summon Gameobject \'Magtheridon\'s Head\' Alliance');
|
||||
DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 22) AND (`SourceGroup` = 5) AND (`SourceEntry` = 16819);
|
||||
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
|
||||
(22, 5, 16819, 3, 0, 103, 0, 39911, 0, 0, 1, 0, 0, '', 'if Gameobject \'Magtheridon\'s Head\' Alliance is not already spawned');
|
||||
|
||||
-- Nazgrel
|
||||
UPDATE `smart_scripts` SET `link` = 3 WHERE (`entryorguid` = 3230) AND (`source_type` = 0) AND (`id` = 1);
|
||||
DELETE FROM `smart_scripts` WHERE (`entryorguid` = 3230) AND (`source_type` = 0) AND (`id` = 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`, `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
|
||||
(3230, 0, 3, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 50, 184640, 7200, 0, 0, 0, 0, 8, 0, 0, 0, 0, 143.417, 2673.36, 85.3014, 3.01941, 'Nazgrel - On Quest \'The Fall of Magtheridon\' Finished - Summon Gameobject \'Magtheridon\'s Head\' Horde');
|
||||
DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 22) AND (`SourceGroup` = 4) AND (`SourceEntry` = 3230);
|
||||
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
|
||||
(22, 4, 3230, 3, 0, 103, 0, 39913, 0, 0, 1, 0, 0, '', 'if Gameobject \'Magtheridon\'s Head\' Horde is not already spawned');
|
||||
|
||||
-- Zeppelin transports
|
||||
SET @RADIUS:=24; -- radius unknown
|
||||
-- arrival events, play zeppelin horn
|
||||
DELETE FROM `event_scripts` WHERE `command` = 16 and `id` IN (15312, 15314, 15318, 15320, 15322, 15324, 15430, 15431, 19126, 19127, 19137, 19139, 21868, 21870);
|
||||
INSERT INTO `event_scripts` (`id`, `delay`, `command`, `datalong`, `datalong2`, `dataint`, `x`, `y`, `z`, `o`) VALUES
|
||||
(15312, 0, 16, 11804, 4, @RADIUS, 0.0, 0.0, 0.0, 0.0),
|
||||
(15314, 0, 16, 11804, 4, @RADIUS, 0.0, 0.0, 0.0, 0.0),
|
||||
(15318, 0, 16, 11804, 4, @RADIUS, 0.0, 0.0, 0.0, 0.0),
|
||||
(15320, 0, 16, 11804, 4, @RADIUS, 0.0, 0.0, 0.0, 0.0),
|
||||
(15322, 0, 16, 11804, 4, @RADIUS, 0.0, 0.0, 0.0, 0.0),
|
||||
(15324, 0, 16, 11804, 4, @RADIUS, 0.0, 0.0, 0.0, 0.0),
|
||||
(15430, 0, 16, 11804, 4, @RADIUS, 0.0, 0.0, 0.0, 0.0),
|
||||
(15431, 0, 16, 11804, 4, @RADIUS, 0.0, 0.0, 0.0, 0.0),
|
||||
(19126, 0, 16, 11804, 4, @RADIUS, 0.0, 0.0, 0.0, 0.0),
|
||||
(19127, 0, 16, 11804, 4, @RADIUS, 0.0, 0.0, 0.0, 0.0),
|
||||
(19137, 0, 16, 11804, 4, @RADIUS, 0.0, 0.0, 0.0, 0.0),
|
||||
(19139, 0, 16, 11804, 4, @RADIUS, 0.0, 0.0, 0.0, 0.0),
|
||||
(21868, 0, 16, 11804, 4, @RADIUS, 0.0, 0.0, 0.0, 0.0),
|
||||
(21870, 0, 16, 11804, 4, @RADIUS, 0.0, 0.0, 0.0, 0.0);
|
||||
|
||||
-- The Iron Eagle - Grom'Gol to Orgrimmar
|
||||
UPDATE `gameobject_template` SET `ScriptName` = 'go_transport_the_iron_eagle' WHERE (`entry` = 175080);
|
||||
|
||||
-- Snurk Bucksquick Master Orgrimmar The Iron Eagle
|
||||
DELETE FROM `gossip_menu_option` WHERE `MenuID` = 3841;
|
||||
INSERT INTO `gossip_menu_option` (`MenuID`, `OptionID`, `OptionIcon`, `OptionText`, `OptionBroadcastTextID`, `OptionType`, `OptionNpcFlag`, `ActionMenuID`, `ActionPoiID`, `BoxCoded`, `BoxMoney`, `BoxText`, `BoxBroadcastTextID`, `VerifiedBuild`) VALUES
|
||||
(3841, 0, 0, 'Where is the zeppelin now?', 22086, 1, 1, 8764, 0, 0, 0, '', 0, 0);
|
||||
DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 15) AND (`SourceGroup` = 3841) AND (`SourceEntry` = 0);
|
||||
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
|
||||
(15, 3841, 0, 0, 0, 103, 0, 175080, 15322, 0, 1, 0, 0, '', 'The zeppelin should not have just arrived at Orgrimmar');
|
||||
|
||||
-- Zez'raz Master Grom'gol The Iron Eagle
|
||||
DELETE FROM `gossip_menu_option` WHERE `MenuID` = 2441;
|
||||
INSERT INTO `gossip_menu_option` (`MenuID`, `OptionID`, `OptionIcon`, `OptionText`, `OptionBroadcastTextID`, `OptionType`, `OptionNpcFlag`, `ActionMenuID`, `ActionPoiID`, `BoxCoded`, `BoxMoney`, `BoxText`, `BoxBroadcastTextID`, `VerifiedBuild`) VALUES
|
||||
(2441, 0, 0, 'Where is the zeppelin now?', 22086, 1, 1, 8764, 0, 0, 0, '', 0, 0);
|
||||
DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 15) AND (`SourceGroup` = 2441);
|
||||
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
|
||||
(15, 2441, 0, 0, 0, 103, 0, 175080, 15324, 0, 1, 0, 0, '', 'The zeppelin should not have just arrived at Grom\'gol');
|
||||
|
||||
-- Krixx Engineer Orgrimmar The Iron Eagle, The Thundercaller
|
||||
DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 14) AND (`SourceGroup` = 8764);
|
||||
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
|
||||
(14, 8764, 11167, 0, 0, 103, 0, 175080, 15324, 0, 0, 0, 0, '', 'The zeppelin should have just arrived at Grom\'gol'),
|
||||
(14, 8764, 11169, 0, 1, 103, 0, 175080, 15322, 0, 0, 0, 0, '', 'The zeppelin should have just arrived at Orgrimmar'),
|
||||
(14, 8764, 11170, 0, 2, 103, 0, 175080, 15323, 0, 0, 0, 0, '', 'The zeppelin should have just departed from Orgrimmar'),
|
||||
(14, 8764, 11172, 0, 3, 103, 0, 175080, 15325, 0, 0, 0, 0, '', 'The zeppelin should have just departed from Grom\'gol'),
|
||||
(14, 8764, 11163, 0, 4, 103, 0, 175080, 0, 0, 0, 0, 0, '', 'I\'m not sure where the zeppelin is right now, actually...');
|
||||
DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 14) AND (`SourceGroup` = 8765);
|
||||
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
|
||||
(14, 8765, 11165, 0, 0, 103, 0, 164871, 15318, 0, 0, 0, 0, '', 'The zeppelin should have just arrived at Orgrimmar'),
|
||||
(14, 8765, 11173, 0, 1, 103, 0, 164871, 15320, 0, 0, 0, 0, '', 'The zeppelin should have just arrived at Undercity'),
|
||||
(14, 8765, 11174, 0, 2, 103, 0, 164871, 15319, 0, 0, 0, 0, '', 'The zeppelin should have just departed from Orgrimmar'),
|
||||
(14, 8765, 11175, 0, 3, 103, 0, 164871, 15321, 0, 0, 0, 0, '', 'The zeppelin should have just departed from Undercity'),
|
||||
(14, 8765, 11163, 0, 4, 103, 0, 164871, 0, 0, 0, 0, 0, '', 'I\'m not sure where the zeppelin is right now, actually...');
|
||||
|
||||
-- The Thundercaller - Undercity to Orgrimmar
|
||||
UPDATE `gameobject_template` SET `ScriptName` = 'go_transport_the_thundercaller' WHERE (`entry` = 164871);
|
||||
|
||||
-- Frezza Master Orgrimmar The Thundercaller
|
||||
DELETE FROM `gossip_menu_option` WHERE `MenuID` = 1969;
|
||||
INSERT INTO `gossip_menu_option` (`MenuID`, `OptionID`, `OptionIcon`, `OptionText`, `OptionBroadcastTextID`, `OptionType`, `OptionNpcFlag`, `ActionMenuID`, `ActionPoiID`, `BoxCoded`, `BoxMoney`, `BoxText`, `BoxBroadcastTextID`, `VerifiedBuild`) VALUES
|
||||
(1969, 0, 0, 'Where is the zeppelin now?', 22086, 1, 1, 8765, 0, 0, 0, '', 0, 0);
|
||||
DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 15) AND (`SourceGroup` = 1969) AND (`SourceEntry` = 0);
|
||||
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
|
||||
(15, 1969, 0, 0, 0, 103, 0, 164871, 15318, 0, 1, 0, 0, '', 'The zeppelin should not have just arrived at Orgrimmar');
|
||||
|
||||
-- Zapetta Master Undercity The Thundercaller
|
||||
DELETE FROM `gossip_menu_option` WHERE `MenuID` = 1971;
|
||||
INSERT INTO `gossip_menu_option` (`MenuID`, `OptionID`, `OptionIcon`, `OptionText`, `OptionBroadcastTextID`, `OptionType`, `OptionNpcFlag`, `ActionMenuID`, `ActionPoiID`, `BoxCoded`, `BoxMoney`, `BoxText`, `BoxBroadcastTextID`, `VerifiedBuild`) VALUES
|
||||
(1971, 0, 0, 'Where is the zeppelin now?', 22086, 1, 1, 8765, 0, 0, 0, '', 0, 0);
|
||||
DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 15) AND (`SourceGroup` = 1971) AND (`SourceEntry` = 0);
|
||||
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
|
||||
(15, 1971, 0, 0, 0, 103, 0, 164871, 15320, 0, 1, 0, 0, '', 'The zeppelin should not have just arrived at Undercity');
|
||||
DELETE FROM `creature_text` WHERE (`CreatureID` = 9566) AND (`GroupID` = 1);
|
||||
INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES
|
||||
(9566, 1, 0, 'There goes the zeppelin to Orgrimmar. I hope there\'s no explosions this time.', 12, 0, 100, 0, 0, 0, 22080, 0, 'Zapetta - Departure');
|
||||
UPDATE `creature_text` SET `comment` = 'Zapetta - Arrival' WHERE (`CreatureID` = 9566) AND (`GroupID` = 0);
|
||||
|
||||
-- The Purple Princess - Grom'Gol to Undercity
|
||||
UPDATE `gameobject_template` SET `ScriptName` = 'go_transport_the_purple_princess' WHERE (`entry` = 176495);
|
||||
|
||||
-- Hin Denburg Master Undercity The Purple Princess
|
||||
DELETE FROM `gossip_menu` WHERE `MenuID` = 8766 AND `TextID` IN (11179, 11182);
|
||||
INSERT INTO `gossip_menu` (`MenuID`, `TextID`) VALUES
|
||||
(8766, 11179),
|
||||
(8766, 11182);
|
||||
DELETE FROM `gossip_menu_option` WHERE `MenuID` = 2101;
|
||||
INSERT INTO `gossip_menu_option` (`MenuID`, `OptionID`, `OptionIcon`, `OptionText`, `OptionBroadcastTextID`, `OptionType`, `OptionNpcFlag`, `ActionMenuID`, `ActionPoiID`, `BoxCoded`, `BoxMoney`, `BoxText`, `BoxBroadcastTextID`, `VerifiedBuild`) VALUES
|
||||
(2101, 0, 0, 'Where is the zeppelin now?', 22086, 1, 1, 8766, 0, 0, 0, '', 0, 0);
|
||||
DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 15) AND (`SourceGroup` = 2101) AND (`SourceEntry` = 0);
|
||||
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
|
||||
(15, 2101, 0, 0, 0, 103, 0, 176495, 15312, 0, 1, 0, 0, '', 'The zeppelin should not have just arrived at Undercity');
|
||||
|
||||
-- Squibby Overspeck Master Grom'gol The Purple Princess
|
||||
DELETE FROM `gossip_menu_option` WHERE `MenuID` = 3842;
|
||||
INSERT INTO `gossip_menu_option` (`MenuID`, `OptionID`, `OptionIcon`, `OptionText`, `OptionBroadcastTextID`, `OptionType`, `OptionNpcFlag`, `ActionMenuID`, `ActionPoiID`, `BoxCoded`, `BoxMoney`, `BoxText`, `BoxBroadcastTextID`, `VerifiedBuild`) VALUES
|
||||
(3842, 0, 0, 'Where is the zeppelin now?', 22086, 1, 1, 8766, 0, 0, 0, '', 0, 0);
|
||||
DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 15) AND (`SourceGroup` = 3842) AND (`SourceEntry` = 0) AND (`SourceId` = 0);
|
||||
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
|
||||
(15, 3842, 0, 0, 0, 103, 0, 176495, 15314, 0, 1, 0, 0, '', 'The zeppelin should not have just arrived at Grom\'gol');
|
||||
|
||||
-- Kraxx Engineer Undercity The Thundercaller, The Purple Princess
|
||||
DELETE FROM `gossip_menu_option` WHERE `MenuID` = 8786;
|
||||
INSERT INTO `gossip_menu_option` (`MenuID`, `OptionID`, `OptionIcon`, `OptionText`, `OptionBroadcastTextID`, `OptionType`, `OptionNpcFlag`, `ActionMenuID`, `ActionPoiID`, `BoxCoded`, `BoxMoney`, `BoxText`, `BoxBroadcastTextID`, `VerifiedBuild`) VALUES
|
||||
(8786, 0, 0, 'Where is the zeppelin to Orgrimmar right now?', 22185, 1, 1, 8765, 0, 0, 0, '', 0, 0),
|
||||
(8786, 1, 0, 'Where is the zeppelin to Grom\'gol right now?', 22199, 1, 1, 8766, 0, 0, 0, '', 0, 0);
|
||||
DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 14) AND (`SourceGroup` = 8766);
|
||||
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
|
||||
(14, 8766, 11179, 0, 0, 103, 0, 176495, 15312, 0, 0, 0, 0, '', 'The zeppelin should have just arrived at Undercity'),
|
||||
(14, 8766, 11180, 0, 1, 103, 0, 176495, 15314, 0, 0, 0, 0, '', 'The zeppelin should have just arrived at Grom\'gol'),
|
||||
(14, 8766, 11182, 0, 2, 103, 0, 176495, 15313, 0, 0, 0, 0, '', 'The zeppelin should have just departed from Undercity'),
|
||||
(14, 8766, 11181, 0, 3, 103, 0, 176495, 15315, 0, 0, 0, 0, '', 'The zeppelin should have just departed from Grom\'gol'),
|
||||
(14, 8766, 11163, 0, 4, 103, 0, 176495, 0, 0, 0, 0, 0, '', 'I\'m not sure where the zeppelin is right now, actually...');
|
||||
|
||||
-- I\'m not sure where the zeppelin is right now, actually...
|
||||
DELETE FROM `gossip_menu` WHERE (`MenuID` IN (8764, 8765, 8766)) and `TextID` = 11163;
|
||||
INSERT INTO `gossip_menu` (`MenuID`, `TextID`) VALUES
|
||||
(8764, 11163),
|
||||
(8765, 11163),
|
||||
(8766, 11163);
|
||||
@@ -35,6 +35,7 @@
|
||||
#include "SmartAI.h"
|
||||
#include "SpellMgr.h"
|
||||
#include "Vehicle.h"
|
||||
#include "WorldState.h"
|
||||
|
||||
/// @todo: this import is not necessary for compilation and marked as unused by the IDE
|
||||
// however, for some reasons removing it would cause a damn linking issue
|
||||
@@ -3269,6 +3270,11 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
|
||||
|
||||
break;
|
||||
}
|
||||
case SMART_ACTION_WORLD_SCRIPT:
|
||||
{
|
||||
sWorldState->HandleExternalEvent(static_cast<WorldStateEvent>(e.action.worldStateScript.eventId), e.action.worldStateScript.param);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
LOG_ERROR("sql.sql", "SmartScript::ProcessAction: Entry {} SourceType {}, Event {}, Unhandled Action type {}", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType());
|
||||
break;
|
||||
|
||||
@@ -777,6 +777,7 @@ bool SmartAIMgr::CheckUnusedActionParams(SmartScriptHolder const& e)
|
||||
case SMART_ACTION_MOVEMENT_STOP: return NO_PARAMS;
|
||||
case SMART_ACTION_MOVEMENT_PAUSE: return sizeof(SmartAction::move);
|
||||
case SMART_ACTION_MOVEMENT_RESUME: return sizeof(SmartAction::move);
|
||||
case SMART_ACTION_WORLD_SCRIPT: return sizeof(SmartAction::worldStateScript);
|
||||
default:
|
||||
LOG_WARN("sql.sql", "SmartAIMgr: entryorguid {} source_type {} id {} action_type {} is using an action with no unused params specified in SmartAIMgr::CheckUnusedActionParams(), please report this.",
|
||||
e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType());
|
||||
@@ -1960,6 +1961,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
|
||||
case SMART_ACTION_MOVEMENT_STOP:
|
||||
case SMART_ACTION_MOVEMENT_PAUSE:
|
||||
case SMART_ACTION_MOVEMENT_RESUME:
|
||||
case SMART_ACTION_WORLD_SCRIPT:
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR("sql.sql", "SmartAIMgr: Not handled action_type({}), event_type({}), Entry {} SourceType {} Event {}, skipped.", e.GetActionType(), e.GetEventType(), e.entryOrGuid, e.GetScriptType(), e.event_id);
|
||||
|
||||
@@ -727,8 +727,9 @@ enum SMART_ACTION
|
||||
SMART_ACTION_MOVEMENT_STOP = 234, //
|
||||
SMART_ACTION_MOVEMENT_PAUSE = 235, // timer
|
||||
SMART_ACTION_MOVEMENT_RESUME = 236, // timerOverride
|
||||
SMART_ACTION_WORLD_SCRIPT = 237, // eventId, param
|
||||
|
||||
SMART_ACTION_AC_END = 237, // placeholder
|
||||
SMART_ACTION_AC_END = 238, // placeholder
|
||||
};
|
||||
|
||||
enum class SmartActionSummonCreatureFlags
|
||||
@@ -1472,6 +1473,12 @@ struct SmartAction
|
||||
{
|
||||
uint32 timer;
|
||||
} move;
|
||||
|
||||
struct
|
||||
{
|
||||
uint32 eventId;
|
||||
uint32 param;
|
||||
} worldStateScript;
|
||||
//! Note for any new future actions
|
||||
//! All parameters must have type uint32
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "Spell.h"
|
||||
#include "SpellAuras.h"
|
||||
#include "SpellMgr.h"
|
||||
#include "WorldState.h"
|
||||
|
||||
// Checks if object meets the condition
|
||||
// Can have CONDITION_SOURCE_TYPE_NONE && !mReferenceId if called from a special event (ie: eventAI)
|
||||
@@ -570,6 +571,11 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo)
|
||||
condMeets = unit->IsCharmed();
|
||||
break;
|
||||
}
|
||||
case CONDITION_WORLD_SCRIPT:
|
||||
{
|
||||
condMeets = sWorldState->IsConditionFulfilled(static_cast<WorldStateCondition>(ConditionValue1), static_cast<WorldStateConditionState>(ConditionValue2));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
condMeets = false;
|
||||
break;
|
||||
@@ -770,6 +776,9 @@ uint32 Condition::GetSearcherTypeMaskForCondition()
|
||||
case CONDITION_CHARMED:
|
||||
mask |= GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_PLAYER;
|
||||
break;
|
||||
case CONDITION_WORLD_SCRIPT:
|
||||
mask |= GRID_MAP_TYPE_MASK_ALL;
|
||||
break;
|
||||
default:
|
||||
ASSERT(false && "Condition::GetSearcherTypeMaskForCondition - missing condition handling!");
|
||||
break;
|
||||
|
||||
@@ -86,7 +86,9 @@ enum ConditionTypes
|
||||
CONDITION_AC_START = 100,
|
||||
CONDITION_QUEST_SATISFY_EXCLUSIVE = 101, // quest_id 0 0 true if satisfied exclusive group
|
||||
CONDITION_HAS_AURA_TYPE = 102, // aura_type 0 0 true if has aura type
|
||||
CONDITION_AC_END = 103 // placeholder
|
||||
CONDITION_WORLD_SCRIPT = 103, // conditionId state 0 true if WorldState::IsConditionFulfilled returns true
|
||||
|
||||
CONDITION_AC_END = 104 // placeholder
|
||||
};
|
||||
|
||||
/*! Documentation on implementing a new ConditionSourceType:
|
||||
|
||||
@@ -83,6 +83,7 @@
|
||||
#include "World.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "WorldSession.h"
|
||||
#include "WorldState.h"
|
||||
#include <cmath>
|
||||
|
||||
/// @todo: this import is not necessary for compilation and marked as unused by the IDE
|
||||
@@ -1722,6 +1723,7 @@ void Player::RemoveFromWorld()
|
||||
m_session->DoLootRelease(lguid);
|
||||
sOutdoorPvPMgr->HandlePlayerLeaveZone(this, m_zoneUpdateId);
|
||||
sBattlefieldMgr->HandlePlayerLeaveZone(this, m_zoneUpdateId);
|
||||
sWorldState->HandlePlayerLeaveZone(this, static_cast<WorldStateZoneId>(m_zoneUpdateId));
|
||||
}
|
||||
|
||||
// Remove items from world before self - player must be found in Item::RemoveFromObjectUpdate
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "Vehicle.h"
|
||||
#include "Weather.h"
|
||||
#include "WeatherMgr.h"
|
||||
#include "WorldState.h"
|
||||
#include "WorldStatePackets.h"
|
||||
|
||||
/// @todo: this import is not necessary for compilation and marked as unused by the IDE
|
||||
@@ -1215,6 +1216,8 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea)
|
||||
{
|
||||
sOutdoorPvPMgr->HandlePlayerLeaveZone(this, m_zoneUpdateId);
|
||||
sOutdoorPvPMgr->HandlePlayerEnterZone(this, newZone);
|
||||
sWorldState->HandlePlayerLeaveZone(this, static_cast<WorldStateZoneId>(m_zoneUpdateId));
|
||||
sWorldState->HandlePlayerEnterZone(this, static_cast<WorldStateZoneId>(newZone));
|
||||
sBattlefieldMgr->HandlePlayerLeaveZone(this, m_zoneUpdateId);
|
||||
sBattlefieldMgr->HandlePlayerEnterZone(this, newZone);
|
||||
SendInitWorldStates(newZone,
|
||||
|
||||
@@ -180,6 +180,7 @@ enum eScriptFlags
|
||||
// Playsound flags
|
||||
SF_PLAYSOUND_TARGET_PLAYER = 0x1,
|
||||
SF_PLAYSOUND_DISTANCE_SOUND = 0x2,
|
||||
SF_PLAYSOUND_DISTANCE_RADIUS = 0x4,
|
||||
|
||||
// Orientation flags
|
||||
SF_ORIENTATION_FACE_TARGET = 0x1,
|
||||
@@ -307,6 +308,7 @@ struct ScriptInfo
|
||||
{
|
||||
uint32 SoundID; // datalong
|
||||
uint32 Flags; // datalong2
|
||||
int32 Radius; // dataint
|
||||
} Playsound;
|
||||
|
||||
struct // SCRIPT_COMMAND_CREATE_ITEM (17)
|
||||
|
||||
@@ -730,8 +730,10 @@ void Map::ScriptsProcess()
|
||||
break;
|
||||
}
|
||||
|
||||
// Playsound.Flags bitmask: 0/2=without/with distance dependent
|
||||
if (step.script->Playsound.Flags & SF_PLAYSOUND_DISTANCE_SOUND)
|
||||
// Playsound.Flags bitmask: 0/2/4=without/with distance dependent/radius
|
||||
if (step.script->Playsound.Flags & SF_PLAYSOUND_DISTANCE_RADIUS)
|
||||
object->PlayRadiusSound(step.script->Playsound.SoundID, step.script->Playsound.Radius);
|
||||
else if (step.script->Playsound.Flags & SF_PLAYSOUND_DISTANCE_SOUND)
|
||||
object->PlayDistanceSound(step.script->Playsound.SoundID, player);
|
||||
else
|
||||
object->PlayDirectSound(step.script->Playsound.SoundID, player);
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#include "World.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "WorldSocket.h"
|
||||
#include "WorldState.h"
|
||||
#include <zlib.h>
|
||||
|
||||
#include "BanMgr.h"
|
||||
@@ -617,6 +618,7 @@ void WorldSession::LogoutPlayer(bool save)
|
||||
_player->RepopAtGraveyard();
|
||||
|
||||
sOutdoorPvPMgr->HandlePlayerLeaveZone(_player, _player->GetZoneId());
|
||||
sWorldState->HandlePlayerLeaveZone(_player, static_cast<WorldStateZoneId>(_player->GetZoneId()));
|
||||
|
||||
// pussywizard: remove from battleground queues on logout
|
||||
for (int i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
|
||||
|
||||
@@ -1389,18 +1389,6 @@ void SpellMgr::LoadSpellInfoCorrections()
|
||||
spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(13); // 50000yd
|
||||
});
|
||||
|
||||
// A'dal's Song of Battle
|
||||
ApplySpellFix({ 39953 }, [](SpellInfo* spellInfo)
|
||||
{
|
||||
spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_SRC_CASTER);
|
||||
spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_SRC_CASTER);
|
||||
spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo(TARGET_SRC_CASTER);
|
||||
spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ALLY);
|
||||
spellInfo->Effects[EFFECT_1].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ALLY);
|
||||
spellInfo->Effects[EFFECT_2].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ALLY);
|
||||
spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(367); // 2 Hours
|
||||
});
|
||||
|
||||
ApplySpellFix({
|
||||
57607, // WintergraspCatapult - Spell Plague Barrel - EffectRadiusIndex
|
||||
57619, // WintergraspDemolisher - Spell Hourl Boulder - EffectRadiusIndex
|
||||
|
||||
@@ -92,6 +92,7 @@
|
||||
#include "WhoListCacheMgr.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "WorldSession.h"
|
||||
#include "WorldState.h"
|
||||
#include <boost/asio/ip/address.hpp>
|
||||
#include <cmath>
|
||||
|
||||
@@ -2411,6 +2412,11 @@ void World::Update(uint32 diff)
|
||||
sOutdoorPvPMgr->Update(diff);
|
||||
}
|
||||
|
||||
{
|
||||
METRIC_TIMER("world_update_time", METRIC_TAG("type", "Update worldstate"));
|
||||
sWorldState->Update(diff);
|
||||
}
|
||||
|
||||
{
|
||||
METRIC_TIMER("world_update_time", METRIC_TAG("type", "Update battlefields"));
|
||||
sBattlefieldMgr->Update(diff);
|
||||
|
||||
293
src/server/game/World/WorldState.cpp
Normal file
293
src/server/game/World/WorldState.cpp
Normal file
@@ -0,0 +1,293 @@
|
||||
/*
|
||||
* 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 "MapMgr.h"
|
||||
#include "Player.h"
|
||||
#include "SharedDefines.h"
|
||||
#include "WorldState.h"
|
||||
|
||||
WorldState* WorldState::instance()
|
||||
{
|
||||
static WorldState instance;
|
||||
return &instance;
|
||||
}
|
||||
|
||||
WorldState::WorldState() : _isMagtheridonHeadSpawnedHorde(false), _isMagtheridonHeadSpawnedAlliance(false)
|
||||
{
|
||||
_transportStates[WORLD_STATE_CONDITION_THE_IRON_EAGLE] = WORLD_STATE_CONDITION_STATE_NONE;
|
||||
_transportStates[WORLD_STATE_CONDITION_THE_PURPLE_PRINCESS] = WORLD_STATE_CONDITION_STATE_NONE;
|
||||
_transportStates[WORLD_STATE_CONDITION_THE_THUNDERCALLER] = WORLD_STATE_CONDITION_STATE_NONE;
|
||||
}
|
||||
|
||||
WorldState::~WorldState()
|
||||
{
|
||||
}
|
||||
|
||||
bool WorldState::IsConditionFulfilled(WorldStateCondition conditionId, WorldStateConditionState state) const
|
||||
{
|
||||
switch (conditionId)
|
||||
{
|
||||
case WORLD_STATE_CONDITION_TROLLBANES_COMMAND:
|
||||
return _isMagtheridonHeadSpawnedAlliance;
|
||||
case WORLD_STATE_CONDITION_NAZGRELS_FAVOR:
|
||||
return _isMagtheridonHeadSpawnedHorde;
|
||||
case WORLD_STATE_CONDITION_THE_IRON_EAGLE:
|
||||
case WORLD_STATE_CONDITION_THE_PURPLE_PRINCESS:
|
||||
case WORLD_STATE_CONDITION_THE_THUNDERCALLER:
|
||||
return _transportStates.at(conditionId) == state;
|
||||
default:
|
||||
LOG_ERROR("scripts", "WorldState::IsConditionFulfilled: Unhandled WorldStateCondition {}", conditionId);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void WorldState::HandleConditionStateChange(WorldStateCondition conditionId, WorldStateConditionState state)
|
||||
{
|
||||
_transportStates[conditionId] = state;
|
||||
}
|
||||
|
||||
void WorldState::HandleExternalEvent(WorldStateEvent eventId, uint32 param)
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(_mutex);
|
||||
switch (eventId)
|
||||
{
|
||||
case WORLD_STATE_CUSTOM_EVENT_ON_ADALS_SONG_OF_BATTLE:
|
||||
if (!_adalSongOfBattleTimer)
|
||||
{
|
||||
_adalSongOfBattleTimer = 120 * MINUTE * IN_MILLISECONDS;
|
||||
BuffAdalsSongOfBattle();
|
||||
}
|
||||
break;
|
||||
case WORLD_STATE_CUSTOM_EVENT_ON_MAGTHERIDON_HEAD_SPAWN:
|
||||
if (param == TEAM_ALLIANCE)
|
||||
{
|
||||
_isMagtheridonHeadSpawnedAlliance = true;
|
||||
BuffMagtheridonTeam(TEAM_ALLIANCE);
|
||||
}
|
||||
else
|
||||
{
|
||||
_isMagtheridonHeadSpawnedHorde = true;
|
||||
BuffMagtheridonTeam(TEAM_HORDE);
|
||||
}
|
||||
break;
|
||||
case WORLD_STATE_CUSTOM_EVENT_ON_MAGTHERIDON_HEAD_DESPAWN:
|
||||
if (param == TEAM_ALLIANCE)
|
||||
{
|
||||
_isMagtheridonHeadSpawnedAlliance = false;
|
||||
DispelMagtheridonTeam(TEAM_ALLIANCE);
|
||||
}
|
||||
else
|
||||
{
|
||||
_isMagtheridonHeadSpawnedHorde = false;
|
||||
DispelMagtheridonTeam(TEAM_HORDE);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void WorldState::Update(uint32 diff)
|
||||
{
|
||||
if (_adalSongOfBattleTimer)
|
||||
{
|
||||
if (_adalSongOfBattleTimer <= diff)
|
||||
{
|
||||
_adalSongOfBattleTimer = 0;
|
||||
DispelAdalsSongOfBattle();
|
||||
}
|
||||
else
|
||||
{
|
||||
_adalSongOfBattleTimer -= diff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WorldState::HandlePlayerEnterZone(Player* player, WorldStateZoneId zoneId)
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(_mutex);
|
||||
switch (zoneId)
|
||||
{
|
||||
case ZONEID_SHATTRATH:
|
||||
case ZONEID_BOTANICA:
|
||||
case ZONEID_MECHANAR:
|
||||
case ZONEID_ARCATRAZ:
|
||||
if (_adalSongOfBattleTimer)
|
||||
player->CastSpell(player, SPELL_ADAL_SONG_OF_BATTLE, true);
|
||||
break;
|
||||
case ZONEID_HELLFIRE_PENINSULA:
|
||||
case ZONEID_HELLFIRE_RAMPARTS:
|
||||
case ZONEID_HELLFIRE_CITADEL:
|
||||
case ZONEID_BLOOD_FURNACE:
|
||||
case ZONEID_SHATTERED_HALLS:
|
||||
case ZONEID_MAGTHERIDON_LAIR:
|
||||
if (_isMagtheridonHeadSpawnedAlliance && player->GetTeamId() == TEAM_ALLIANCE)
|
||||
player->CastSpell(player, SPELL_TROLLBANES_COMMAND, true);
|
||||
else if (_isMagtheridonHeadSpawnedHorde && player->GetTeamId() == TEAM_HORDE)
|
||||
player->CastSpell(player, SPELL_NAZGRELS_FAVOR, true);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
void WorldState::HandlePlayerLeaveZone(Player* player, WorldStateZoneId zoneId)
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(_mutex);
|
||||
switch (zoneId)
|
||||
{
|
||||
case ZONEID_SHATTRATH:
|
||||
case ZONEID_BOTANICA:
|
||||
case ZONEID_MECHANAR:
|
||||
case ZONEID_ARCATRAZ:
|
||||
if (!_adalSongOfBattleTimer)
|
||||
player->RemoveAurasDueToSpell(SPELL_ADAL_SONG_OF_BATTLE);
|
||||
break;
|
||||
case ZONEID_HELLFIRE_PENINSULA:
|
||||
case ZONEID_HELLFIRE_RAMPARTS:
|
||||
case ZONEID_HELLFIRE_CITADEL:
|
||||
case ZONEID_BLOOD_FURNACE:
|
||||
case ZONEID_SHATTERED_HALLS:
|
||||
case ZONEID_MAGTHERIDON_LAIR:
|
||||
if (player->GetTeamId() == TEAM_ALLIANCE)
|
||||
player->RemoveAurasDueToSpell(SPELL_TROLLBANES_COMMAND);
|
||||
else if (player->GetTeamId() == TEAM_HORDE)
|
||||
player->RemoveAurasDueToSpell(SPELL_NAZGRELS_FAVOR);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
void WorldState::BuffMagtheridonTeam(TeamId team)
|
||||
{
|
||||
sMapMgr->DoForAllMaps([&](Map* map) -> void
|
||||
{
|
||||
switch (map->GetId())
|
||||
{
|
||||
case 530: // Outland
|
||||
map->DoForAllPlayers([&](Player* player)
|
||||
{
|
||||
if (player->GetZoneId() == ZONEID_HELLFIRE_PENINSULA && player->GetTeamId() == TEAM_ALLIANCE && team == TEAM_ALLIANCE)
|
||||
player->CastSpell(player, SPELL_TROLLBANES_COMMAND, true);
|
||||
else if (player->GetZoneId() == ZONEID_HELLFIRE_PENINSULA && player->GetTeamId() == TEAM_HORDE && team == TEAM_HORDE)
|
||||
player->CastSpell(player, SPELL_NAZGRELS_FAVOR, true);
|
||||
});
|
||||
break;
|
||||
case 540: // The Shattered Halls
|
||||
case 542: // The Blood Furnace
|
||||
case 543: // Ramparts
|
||||
case 544: // Magtheridon's Lair
|
||||
map->DoForAllPlayers([&](Player* player)
|
||||
{
|
||||
if (player->GetTeamId() == TEAM_ALLIANCE && team == TEAM_ALLIANCE)
|
||||
player->CastSpell(player, SPELL_TROLLBANES_COMMAND, true);
|
||||
else if (player->GetTeamId() == TEAM_HORDE && team == TEAM_HORDE)
|
||||
player->CastSpell(player, SPELL_NAZGRELS_FAVOR, true);
|
||||
});
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void WorldState::DispelMagtheridonTeam(TeamId team)
|
||||
{
|
||||
sMapMgr->DoForAllMaps([&](Map* map) -> void
|
||||
{
|
||||
switch (map->GetId())
|
||||
{
|
||||
case 530: // Outland
|
||||
map->DoForAllPlayers([&](Player* player)
|
||||
{
|
||||
if (player->GetZoneId() == ZONEID_HELLFIRE_PENINSULA && player->GetTeamId() == TEAM_ALLIANCE && team == TEAM_ALLIANCE)
|
||||
player->RemoveAurasDueToSpell(SPELL_TROLLBANES_COMMAND);
|
||||
else if (player->GetZoneId() == ZONEID_HELLFIRE_PENINSULA && player->GetTeamId() == TEAM_HORDE && team == TEAM_HORDE)
|
||||
player->RemoveAurasDueToSpell(SPELL_NAZGRELS_FAVOR);
|
||||
});
|
||||
break;
|
||||
case 540: // The Shattered Halls
|
||||
case 542: // The Blood Furnace
|
||||
case 543: // Ramparts
|
||||
case 544: // Magtheridon's Lair
|
||||
map->DoForAllPlayers([&](Player* player)
|
||||
{
|
||||
if (player->GetTeamId() == TEAM_ALLIANCE && team == TEAM_ALLIANCE)
|
||||
player->RemoveAurasDueToSpell(SPELL_TROLLBANES_COMMAND);
|
||||
else if (player->GetTeamId() == TEAM_HORDE && team == TEAM_HORDE)
|
||||
player->RemoveAurasDueToSpell(SPELL_NAZGRELS_FAVOR);
|
||||
});
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void WorldState::BuffAdalsSongOfBattle()
|
||||
{
|
||||
sMapMgr->DoForAllMaps([&](Map* map) -> void
|
||||
{
|
||||
switch (map->GetId())
|
||||
{
|
||||
case 530: // Outland
|
||||
map->DoForAllPlayers([&](Player* player)
|
||||
{
|
||||
if (player->GetZoneId() == ZONEID_SHATTRATH)
|
||||
player->CastSpell(player, SPELL_ADAL_SONG_OF_BATTLE, true);
|
||||
});
|
||||
break;
|
||||
case 552: // Arcatraz
|
||||
case 553: // Botanica
|
||||
case 554: // Mechanar
|
||||
map->DoForAllPlayers([&](Player* player)
|
||||
{
|
||||
player->CastSpell(player, SPELL_ADAL_SONG_OF_BATTLE, true);
|
||||
});
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void WorldState::DispelAdalsSongOfBattle()
|
||||
{
|
||||
sMapMgr->DoForAllMaps([&](Map* map) -> void
|
||||
{
|
||||
switch (map->GetId())
|
||||
{
|
||||
case 530: // Outland
|
||||
map->DoForAllPlayers([&](Player* player)
|
||||
{
|
||||
if (player->GetZoneId() == ZONEID_SHATTRATH)
|
||||
player->RemoveAurasDueToSpell(SPELL_ADAL_SONG_OF_BATTLE);
|
||||
});
|
||||
break;
|
||||
case 552: // Arcatraz
|
||||
case 553: // Botanica
|
||||
case 554: // Mechanar
|
||||
map->DoForAllPlayers([&](Player* player)
|
||||
{
|
||||
player->RemoveAurasDueToSpell(SPELL_ADAL_SONG_OF_BATTLE);
|
||||
});
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
95
src/server/game/World/WorldState.h
Normal file
95
src/server/game/World/WorldState.h
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef WORLD_STATE_H
|
||||
#define WORLD_STATE_H
|
||||
|
||||
#include "Player.h"
|
||||
#include <atomic>
|
||||
|
||||
enum WorldStateCondition
|
||||
{
|
||||
WORLD_STATE_CONDITION_TROLLBANES_COMMAND = 39911,
|
||||
WORLD_STATE_CONDITION_NAZGRELS_FAVOR = 39913,
|
||||
// Zeppelins
|
||||
WORLD_STATE_CONDITION_THE_THUNDERCALLER = 164871,
|
||||
WORLD_STATE_CONDITION_THE_IRON_EAGLE = 175080,
|
||||
WORLD_STATE_CONDITION_THE_PURPLE_PRINCESS = 176495,
|
||||
};
|
||||
|
||||
enum WorldStateConditionState
|
||||
{
|
||||
WORLD_STATE_CONDITION_STATE_NONE = 0,
|
||||
};
|
||||
|
||||
enum WorldStateEvent
|
||||
{
|
||||
WORLD_STATE_CUSTOM_EVENT_ON_ADALS_SONG_OF_BATTLE = 39953,
|
||||
WORLD_STATE_CUSTOM_EVENT_ON_MAGTHERIDON_HEAD_SPAWN = 184640,
|
||||
WORLD_STATE_CUSTOM_EVENT_ON_MAGTHERIDON_HEAD_DESPAWN = 184641,
|
||||
};
|
||||
|
||||
enum WorldStateZoneId
|
||||
{
|
||||
ZONEID_SHATTRATH = 3703,
|
||||
ZONEID_BOTANICA = 3847,
|
||||
ZONEID_ARCATRAZ = 3848,
|
||||
ZONEID_MECHANAR = 3849,
|
||||
|
||||
ZONEID_HELLFIRE_PENINSULA = 3483,
|
||||
ZONEID_HELLFIRE_RAMPARTS = 3562,
|
||||
ZONEID_HELLFIRE_CITADEL = 3563,
|
||||
ZONEID_BLOOD_FURNACE = 3713,
|
||||
ZONEID_SHATTERED_HALLS = 3714,
|
||||
ZONEID_MAGTHERIDON_LAIR = 3836,
|
||||
};
|
||||
|
||||
enum WorldStateSpells
|
||||
{
|
||||
SPELL_ADAL_SONG_OF_BATTLE = 39953,
|
||||
|
||||
SPELL_TROLLBANES_COMMAND = 39911,
|
||||
SPELL_NAZGRELS_FAVOR = 39913,
|
||||
};
|
||||
|
||||
// Intended for implementing server wide scripts, note: all behaviour must be safeguarded towards multithreading
|
||||
class WorldState
|
||||
{
|
||||
public:
|
||||
WorldState();
|
||||
virtual ~WorldState();
|
||||
static WorldState* instance();
|
||||
void HandlePlayerEnterZone(Player* player, WorldStateZoneId zoneId);
|
||||
void HandlePlayerLeaveZone(Player* player, WorldStateZoneId zoneId);
|
||||
bool IsConditionFulfilled(WorldStateCondition conditionId, WorldStateConditionState state = WORLD_STATE_CONDITION_STATE_NONE) const;
|
||||
void HandleConditionStateChange(WorldStateCondition conditionId, WorldStateConditionState state);
|
||||
void HandleExternalEvent(WorldStateEvent eventId, uint32 param);
|
||||
void Update(uint32 diff);
|
||||
private:
|
||||
void BuffAdalsSongOfBattle();
|
||||
void DispelAdalsSongOfBattle();
|
||||
uint32 _adalSongOfBattleTimer;
|
||||
void BuffMagtheridonTeam(TeamId team);
|
||||
void DispelMagtheridonTeam(TeamId team);
|
||||
bool _isMagtheridonHeadSpawnedHorde;
|
||||
bool _isMagtheridonHeadSpawnedAlliance;
|
||||
std::map<WorldStateCondition, std::atomic<WorldStateConditionState>> _transportStates; // atomic to avoid having to lock
|
||||
std::mutex _mutex; // all World State operations are threat unsafe
|
||||
};
|
||||
|
||||
#define sWorldState WorldState::instance()
|
||||
#endif
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "ScriptedGossip.h"
|
||||
#include "SpellScript.h"
|
||||
#include "SpellScriptLoader.h"
|
||||
#include "WorldState.h"
|
||||
|
||||
enum q10935Exorcism
|
||||
{
|
||||
@@ -602,6 +603,26 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
struct go_magtheridons_head : public GameObjectAI
|
||||
{
|
||||
go_magtheridons_head(GameObject* gameObject) : GameObjectAI(gameObject) { }
|
||||
|
||||
void InitializeAI() override
|
||||
{
|
||||
me->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE); // spawn head on spike
|
||||
me->SetGameObjectFlag(GO_FLAG_NOT_SELECTABLE);
|
||||
sWorldState->HandleExternalEvent(WORLD_STATE_CUSTOM_EVENT_ON_MAGTHERIDON_HEAD_SPAWN, me->GetPositionX() > 0.f ? TEAM_HORDE : TEAM_ALLIANCE);
|
||||
}
|
||||
|
||||
void OnStateChanged(uint32 state, Unit* /*unit*/) override
|
||||
{
|
||||
if (state == GO_JUST_DEACTIVATED)
|
||||
{
|
||||
sWorldState->HandleExternalEvent(WORLD_STATE_CUSTOM_EVENT_ON_MAGTHERIDON_HEAD_DESPAWN, me->GetPositionX() > 0.f ? TEAM_HORDE : TEAM_ALLIANCE);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_hellfire_peninsula()
|
||||
{
|
||||
// Ours
|
||||
@@ -615,4 +636,5 @@ void AddSC_hellfire_peninsula()
|
||||
new go_beacon();
|
||||
|
||||
RegisterCreatureAI(npc_magister_aledis);
|
||||
RegisterGameObjectAI(go_magtheridons_head);
|
||||
}
|
||||
|
||||
@@ -554,26 +554,6 @@ class spell_gen_rallying_cry_of_the_dragonslayer : public SpellScript
|
||||
}
|
||||
};
|
||||
|
||||
// 39953 - A'dal's Song of Battle
|
||||
class spell_gen_adals_song_of_battle : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_gen_adals_song_of_battle);
|
||||
|
||||
void SelectTarget(std::list<WorldObject*>& targets)
|
||||
{
|
||||
targets.clear();
|
||||
Map::PlayerList const& pList = GetCaster()->GetMap()->GetPlayers();
|
||||
for (Map::PlayerList::const_iterator itr = pList.begin(); itr != pList.end(); ++itr)
|
||||
if (itr->GetSource()->GetZoneId() == 3703 /*Shattrath*/)
|
||||
targets.push_back(itr->GetSource());
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_gen_adals_song_of_battle::SelectTarget, EFFECT_ALL, TARGET_UNIT_SRC_AREA_ALLY);
|
||||
}
|
||||
};
|
||||
|
||||
/* 15366 - Songflower Serenade
|
||||
22888 - Rallying Cry of the Dragonslayer */
|
||||
class spell_gen_disabled_above_63 : public AuraScript
|
||||
@@ -5336,7 +5316,6 @@ void AddSC_generic_spell_scripts()
|
||||
RegisterSpellScript(spell_pet_hit_expertise_scalling);
|
||||
RegisterSpellScript(spell_gen_grow_flower_patch);
|
||||
RegisterSpellScript(spell_gen_rallying_cry_of_the_dragonslayer);
|
||||
RegisterSpellScript(spell_gen_adals_song_of_battle);
|
||||
RegisterSpellScript(spell_gen_disabled_above_63);
|
||||
RegisterSpellScript(spell_gen_black_magic_enchant);
|
||||
RegisterSpellScript(spell_gen_area_aura_select_players);
|
||||
|
||||
68
src/server/scripts/World/transport_zeppelin.h
Normal file
68
src/server/scripts/World/transport_zeppelin.h
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
enum ZeppelinEvent
|
||||
{
|
||||
EVENT_UC_FROM_GROMGOL_ARRIVAL = 15312,
|
||||
EVENT_GROMGOL_FROM_UC_ARRIVAL = 15314,
|
||||
EVENT_OG_FROM_UC_ARRIVAL = 15318,
|
||||
EVENT_UC_FROM_OG_ARRIVAL = 15320,
|
||||
EVENT_OG_FROM_GROMGOL_ARRIVAL = 15322,
|
||||
EVENT_GROMGOL_FROM_OG_ARRIVAL = 15324,
|
||||
EVENT_WK_ARRIVAL = 15431,
|
||||
EVENT_VL_FROM_UC_ARRIVAL = 19126,
|
||||
EVENT_UC_FROM_VL_ARRIVAL = 19127,
|
||||
EVENT_OG_FROM_BT_ARRIVAL = 19137,
|
||||
EVENT_BT_FROM_OG_ARRIVAL = 19139,
|
||||
EVENT_OG_FROM_TB_ARRIVAL = 21868,
|
||||
EVENT_TB_FROM_OG_ARRIVAL = 21870,
|
||||
EVENT_OG_TO_GROMGOL_DEPARTURE = 15323,
|
||||
EVENT_GROMGOL_TO_OG_DEPARTURE = 15325,
|
||||
EVENT_OG_TO_UC_DEPARTURE = 15319,
|
||||
EVENT_UC_TO_OG_DEPARTURE = 15321,
|
||||
EVENT_UC_TO_GROMGOL_DEPARTURE = 15313,
|
||||
EVENT_GROMGOL_TO_UC_DEPARTURE = 15315,
|
||||
};
|
||||
|
||||
enum ZeppelinMaster
|
||||
{
|
||||
NPC_NEZRAZ = 3149,
|
||||
NPC_HINDENBURG = 3150,
|
||||
NPC_FREZZA = 9564,
|
||||
NPC_ZAPETTA = 9566,
|
||||
NPC_SNURK_BUCKSQUICK = 12136,
|
||||
NPC_SQUIBBY_OVERSPECK = 12137,
|
||||
NPC_HARROWMEISER = 23823,
|
||||
NPC_GREEB_RAMROCKET = 26537,
|
||||
NPC_NARGO_SCREWBORE = 26538,
|
||||
NPC_MEEFI_FARTHROTTLE = 26539,
|
||||
NPC_DRENK_SPANNERSPARK = 26540,
|
||||
NPC_ZELLI_HOTNOZZLE = 34765,
|
||||
NPC_KRENDLE_BIGPOCKETS = 34766,
|
||||
};
|
||||
|
||||
const float SEARCH_RANGE_ZEPPELIN_MASTER = 32.0f;
|
||||
|
||||
enum ZeppelinPassenger
|
||||
{
|
||||
// The Thundercaller
|
||||
NPC_SKY_CAPTAIN_CLOUDKICKER = 25077,
|
||||
NPC_CHIEF_OFFICER_COPPERNUT = 25070,
|
||||
// The Purple Princess
|
||||
NPC_SKY_CAPTAIN_CABLELAMP = 25105,
|
||||
NPC_WATCHER_UMJIN = 25107,
|
||||
};
|
||||
109
src/server/scripts/World/transport_zeppelins.cpp
Normal file
109
src/server/scripts/World/transport_zeppelins.cpp
Normal file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* 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 "GameObjectAI.h"
|
||||
#include "GameObjectScript.h"
|
||||
#include "WorldState.h"
|
||||
#include "transport_zeppelin.h"
|
||||
|
||||
// 175080 The Iron Eagle - Grom'gol to Orgrimmar
|
||||
struct go_transport_the_iron_eagle : GameObjectAI
|
||||
{
|
||||
go_transport_the_iron_eagle(GameObject *object) : GameObjectAI(object) { };
|
||||
|
||||
void EventInform(uint32 eventId) override
|
||||
{
|
||||
sWorldState->HandleConditionStateChange(WORLD_STATE_CONDITION_THE_IRON_EAGLE, static_cast<WorldStateConditionState>(eventId));
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_GROMGOL_FROM_OG_ARRIVAL:
|
||||
if (Creature *creature = me->FindNearestCreature(NPC_NEZRAZ, SEARCH_RANGE_ZEPPELIN_MASTER))
|
||||
creature->AI()->Talk(0);
|
||||
break;
|
||||
case EVENT_OG_FROM_GROMGOL_ARRIVAL:
|
||||
if (Creature *creature = me->FindNearestCreature(NPC_SNURK_BUCKSQUICK, 150.0f))
|
||||
creature->AI()->Talk(0);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 164871 The Thundercaller - Undercity to Orgrimmar
|
||||
struct go_transport_the_thundercaller : GameObjectAI
|
||||
{
|
||||
go_transport_the_thundercaller(GameObject *object) : GameObjectAI(object) { };
|
||||
|
||||
void EventInform(uint32 eventId) override
|
||||
{
|
||||
sWorldState->HandleConditionStateChange(WORLD_STATE_CONDITION_THE_THUNDERCALLER, static_cast<WorldStateConditionState>(eventId));
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_OG_FROM_UC_ARRIVAL:
|
||||
if (Creature *creature = me->FindNearestCreature(NPC_FREZZA, SEARCH_RANGE_ZEPPELIN_MASTER))
|
||||
creature->AI()->Talk(0);
|
||||
break;
|
||||
case EVENT_UC_FROM_OG_ARRIVAL:
|
||||
if (Creature *creature = me->FindNearestCreature(NPC_ZAPETTA, SEARCH_RANGE_ZEPPELIN_MASTER))
|
||||
creature->AI()->Talk(0);
|
||||
break;
|
||||
case EVENT_OG_TO_UC_DEPARTURE:
|
||||
break;
|
||||
case EVENT_UC_TO_OG_DEPARTURE:
|
||||
if (Creature *creature = me->FindNearestCreature(NPC_ZAPETTA, SEARCH_RANGE_ZEPPELIN_MASTER))
|
||||
creature->AI()->Talk(1);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 176495 The Purple Princess - Grom'Gol to Undercity
|
||||
struct go_transport_the_purple_princess : GameObjectAI
|
||||
{
|
||||
go_transport_the_purple_princess(GameObject *object) : GameObjectAI(object) { };
|
||||
|
||||
void EventInform(uint32 eventId) override
|
||||
{
|
||||
sWorldState->HandleConditionStateChange(WORLD_STATE_CONDITION_THE_PURPLE_PRINCESS, static_cast<WorldStateConditionState>(eventId));
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_GROMGOL_FROM_UC_ARRIVAL:
|
||||
if (Creature *creature = me->FindNearestCreature(NPC_SQUIBBY_OVERSPECK, SEARCH_RANGE_ZEPPELIN_MASTER))
|
||||
creature->AI()->Talk(0);
|
||||
break;
|
||||
case EVENT_UC_FROM_GROMGOL_ARRIVAL:
|
||||
if (Creature *creature = me->FindNearestCreature(NPC_HINDENBURG, SEARCH_RANGE_ZEPPELIN_MASTER))
|
||||
creature->AI()->Talk(0);
|
||||
break;
|
||||
case EVENT_UC_TO_GROMGOL_DEPARTURE:
|
||||
case EVENT_GROMGOL_TO_UC_DEPARTURE:
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_transport_zeppelins()
|
||||
{
|
||||
RegisterGameObjectAI(go_transport_the_iron_eagle);
|
||||
RegisterGameObjectAI(go_transport_the_thundercaller);
|
||||
RegisterGameObjectAI(go_transport_the_purple_princess);
|
||||
}
|
||||
@@ -32,6 +32,7 @@ void AddSC_action_ip_logger(); // location: scripts\World\action_ip_logger.cpp
|
||||
void AddSC_player_scripts();
|
||||
void AddSC_npc_stave_of_ancients();
|
||||
void AddSC_server_mail();
|
||||
void AddSC_transport_zeppelins();
|
||||
|
||||
// The name of this function should match:
|
||||
// void Add${NameOfDirectory}Scripts()
|
||||
@@ -53,4 +54,5 @@ void AddWorldScripts()
|
||||
AddSC_player_scripts();
|
||||
AddSC_npc_stave_of_ancients();
|
||||
AddSC_server_mail();
|
||||
AddSC_transport_zeppelins();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user