From 795d01bc1b6b67e4d086be884f08549534f3297e Mon Sep 17 00:00:00 2001 From: Ascathor Date: Mon, 25 Feb 2013 18:14:29 +0100 Subject: Some documentation additions within player.h and Creature.h --- src/server/game/Entities/Creature/Creature.h | 8 +++----- src/server/game/Entities/Player/Player.h | 5 +++++ 2 files changed, 8 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index e8996db608f..5402ca979af 100644 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -484,15 +484,13 @@ class Creature : public Unit, public GridObject, public MapCreature SetReactState(REACT_DEFENSIVE);*/; } - ///// TODO RENAME THIS!!!!! + /// @todo Rename this to proper functions bool isCanTrainingOf(Player* player, bool msg) const; bool isCanInteractWithBattleMaster(Player* player, bool msg) const; bool isCanTrainingAndResetTalentsOf(Player* player) const; bool canCreatureAttack(Unit const* victim, bool force = true) const; - bool IsImmunedToSpell(SpellInfo const* spellInfo); - // redefine Unit::IsImmunedToSpell - bool IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index) const; - // redefine Unit::IsImmunedToSpellEffect + bool IsImmunedToSpell(SpellInfo const* spellInfo); // redefine Unit::IsImmunedToSpell + bool IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index) const; // redefine Unit::IsImmunedToSpellEffect bool isElite() const { if (isPet()) diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 362b6aca631..7da9878eddf 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -1188,10 +1188,15 @@ class Player : public Unit, public GridObject void RemovePet(Pet* pet, PetSaveMode mode, bool returnreagent = false); uint32 GetPhaseMaskForSpawn() const; // used for proper set phase for DB at GM-mode creature/GO spawn + /// Handles said message in regular chat based on declared language and in config pre-defined Range. void Say(std::string const& text, const uint32 language); + /// Handles yelled message in regular chat based on declared language and in config pre-defined Range. void Yell(std::string const& text, const uint32 language); + /// Outputs an universal text which is supposed to be an action. void TextEmote(std::string const& text); + /// Handles whispers from Addons and players based on sender, reciever's guid and language. void Whisper(std::string const& text, const uint32 language, uint64 receiver); + /// Constructs the player Chat data for the specific functions to use void BuildPlayerChat(WorldPacket* data, uint8 msgtype, std::string const& text, uint32 language) const; /*********************************************************/ -- cgit v1.2.3 From 6db8fed2ff9fd82df8ed8840058cf4d376dde4b4 Mon Sep 17 00:00:00 2001 From: Ascathor Date: Mon, 25 Feb 2013 20:43:06 +0100 Subject: Additional changes and requests as by @subv --- src/server/game/Entities/Creature/Creature.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index 5402ca979af..b40229d4748 100644 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -484,13 +484,13 @@ class Creature : public Unit, public GridObject, public MapCreature SetReactState(REACT_DEFENSIVE);*/; } - /// @todo Rename this to proper functions + /// @todo Rename these properly bool isCanTrainingOf(Player* player, bool msg) const; bool isCanInteractWithBattleMaster(Player* player, bool msg) const; bool isCanTrainingAndResetTalentsOf(Player* player) const; bool canCreatureAttack(Unit const* victim, bool force = true) const; - bool IsImmunedToSpell(SpellInfo const* spellInfo); // redefine Unit::IsImmunedToSpell - bool IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index) const; // redefine Unit::IsImmunedToSpellEffect + bool IsImmunedToSpell(SpellInfo const* spellInfo); //override Unit::IsImmunedToSpell + bool IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index) const; //override Unit::IsImmunedToSpellEffect bool isElite() const { if (isPet()) -- cgit v1.2.3 From dec38b12a0203d5cb829ee4faba02d4bccffe68e Mon Sep 17 00:00:00 2001 From: Ascathor Date: Tue, 26 Feb 2013 17:28:10 +0100 Subject: Fixing some Engrish. --- src/server/game/Entities/Creature/Creature.h | 4 ++-- src/server/game/Entities/Player/Player.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index b40229d4748..df41690c15e 100644 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -770,10 +770,10 @@ class Creature : public Unit, public GridObject, public MapCreature bool DisableReputationGain; - CreatureTemplate const* m_creatureInfo; // in difficulty mode > 0 can different from sObjectMgr->GetCreatureTemplate(GetEntry()) + CreatureTemplate const* m_creatureInfo; // Can differ from sObjectMgr->GetCreatureTemplate(GetEntry()) in difficulty mode > 0 CreatureData const* m_creatureData; - uint16 m_LootMode; // bitmask, default LOOT_MODE_DEFAULT, determines what loot will be lootable + uint16 m_LootMode; // Bitmask (default: LOOT_MODE_DEFAULT) that determines what loot will be lootable uint32 guid_transport; bool IsInvisibleDueToDespawn() const; diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 7da9878eddf..3f1bd277d0c 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -1194,7 +1194,7 @@ class Player : public Unit, public GridObject void Yell(std::string const& text, const uint32 language); /// Outputs an universal text which is supposed to be an action. void TextEmote(std::string const& text); - /// Handles whispers from Addons and players based on sender, reciever's guid and language. + /// Handles whispers from Addons and players based on sender, receiver's guid and language. void Whisper(std::string const& text, const uint32 language, uint64 receiver); /// Constructs the player Chat data for the specific functions to use void BuildPlayerChat(WorldPacket* data, uint8 msgtype, std::string const& text, uint32 language) const; -- cgit v1.2.3 From 1d3f35af18b5e8af31c41d84e63c7a33d9b5913e Mon Sep 17 00:00:00 2001 From: Ascathor Date: Tue, 26 Feb 2013 18:39:11 +0100 Subject: Additional fixes and some clean ups --- src/server/game/Battlefield/Zones/BattlefieldWG.h | 36 +++++++++++----------- .../game/Battlegrounds/Zones/BattlegroundAV.h | 28 ++++++++--------- 2 files changed, 32 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/server/game/Battlefield/Zones/BattlefieldWG.h b/src/server/game/Battlefield/Zones/BattlefieldWG.h index 2f750de7b3a..fcd000e75af 100644 --- a/src/server/game/Battlefield/Zones/BattlefieldWG.h +++ b/src/server/game/Battlefield/Zones/BattlefieldWG.h @@ -102,21 +102,21 @@ enum WintergraspData enum WintergraspAchievements { ACHIEVEMENTS_WIN_WG = 1717, - ACHIEVEMENTS_WIN_WG_100 = 1718, // todo - ACHIEVEMENTS_WG_GNOMESLAUGHTER = 1723, // todo + ACHIEVEMENTS_WIN_WG_100 = 1718, /// @todo: Has to be implemented + ACHIEVEMENTS_WG_GNOMESLAUGHTER = 1723, /// @todo: Has to be implemented ACHIEVEMENTS_WG_TOWER_DESTROY = 1727, - ACHIEVEMENTS_DESTRUCTION_DERBY_A = 1737, // todo - ACHIEVEMENTS_WG_TOWER_CANNON_KILL = 1751, // todo - ACHIEVEMENTS_WG_MASTER_A = 1752, // todo + ACHIEVEMENTS_DESTRUCTION_DERBY_A = 1737, /// @todo: Has to be implemented + ACHIEVEMENTS_WG_TOWER_CANNON_KILL = 1751, /// @todo: Has to be implemented + ACHIEVEMENTS_WG_MASTER_A = 1752, /// @todo: Has to be implemented ACHIEVEMENTS_WIN_WG_TIMER_10 = 1755, - ACHIEVEMENTS_STONE_KEEPER_50 = 2085, // todo - ACHIEVEMENTS_STONE_KEEPER_100 = 2086, // todo - ACHIEVEMENTS_STONE_KEEPER_250 = 2087, // todo - ACHIEVEMENTS_STONE_KEEPER_500 = 2088, // todo - ACHIEVEMENTS_STONE_KEEPER_1000 = 2089, // todo - ACHIEVEMENTS_WG_RANGER = 2199, // todo - ACHIEVEMENTS_DESTRUCTION_DERBY_H = 2476, // todo - ACHIEVEMENTS_WG_MASTER_H = 2776 // todo + ACHIEVEMENTS_STONE_KEEPER_50 = 2085, /// @todo: Has to be implemented + ACHIEVEMENTS_STONE_KEEPER_100 = 2086, /// @todo: Has to be implemented + ACHIEVEMENTS_STONE_KEEPER_250 = 2087, /// @todo: Has to be implemented + ACHIEVEMENTS_STONE_KEEPER_500 = 2088, /// @todo: Has to be implemented + ACHIEVEMENTS_STONE_KEEPER_1000 = 2089, /// @todo: Has to be implemented + ACHIEVEMENTS_WG_RANGER = 2199, /// @todo: Has to be implemented + ACHIEVEMENTS_DESTRUCTION_DERBY_H = 2476, /// @todo: Has to be implemented + ACHIEVEMENTS_WG_MASTER_H = 2776 /// @todo: Has to be implemented }; enum WintergraspWorldStates @@ -499,7 +499,7 @@ enum WintergraspTeamControl BATTLEFIELD_WG_TEAM_NEUTRAL }; -// TODO: Handle this with creature_text ? +/// @todo: Can this be handled with creature_text or SmartAI ? enum WintergraspText { BATTLEFIELD_WG_TEXT_WORKSHOP_NAME_NE = 12055, @@ -562,7 +562,7 @@ struct WintergraspObjectPositionData }; // ***************************************************** -// ************ Destructible (Wall, Tower..) ************ +// ************ Destructible (Wall, Tower..) *********** // ***************************************************** struct WintergraspBuildingSpawnData @@ -755,7 +755,7 @@ const WintergraspTeleporterData WGPortalDefenderData[WG_MAX_TELEPORTER] = }; // ********************************************************* -// **********Tower Element(GameObject, Creature)************* +// **********Tower Element(GameObject, Creature)************ // ********************************************************* struct WintergraspTowerData @@ -764,7 +764,7 @@ struct WintergraspTowerData uint8 nbObject; // Number of gameobjects spawned on this point WintergraspObjectPositionData GameObject[6]; // Gameobject position and entry (Horde/Alliance) - // Creature : Turrets and Guard, TODO: check if killed on tower destruction? tower damage? + // Creature: Turrets and Guard /// @todo: Killed on Tower destruction ? Tower damage ? Requires confirming uint8 nbCreatureBottom; WintergraspObjectPositionData CreatureBottom[9]; uint8 nbCreatureTop; @@ -1055,7 +1055,7 @@ const WGWorkshopData WorkshopsData[WG_MAX_WORKSHOP] = }; // ******************************************************************** -// * Structs using for Building, Graveyard, Workshop * +// * Structs using for Building, Graveyard, Workshop * // ******************************************************************** // Structure for different buildings that can be destroyed during battle struct BfWGGameObjectBuilding diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAV.h b/src/server/game/Battlegrounds/Zones/BattlegroundAV.h index 7cd4d571cad..7a0af0b06d7 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundAV.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundAV.h @@ -53,7 +53,7 @@ #define AV_EVENT_START_BATTLE 9166 // Achievement: The Alterac Blitz enum BG_AV_Sounds -{ //TODO: get out if there comes a sound when neutral team captures mine +{ /// @todo: get out if there comes a sound when neutral team captures mine /* 8212: @@ -86,7 +86,7 @@ horde: horde wins */ - AV_SOUND_NEAR_VICTORY = 8456, //not confirmed yet + AV_SOUND_NEAR_VICTORY = 8456, /// @todo: Not confirmed yet AV_SOUND_ALLIANCE_ASSAULTS = 8212, //tower, grave + enemy boss if someone tries to attack him AV_SOUND_HORDE_ASSAULTS = 8174, @@ -104,7 +104,7 @@ enum BG_AV_OTHER_VALUES AV_NORTH_MINE = 0, AV_SOUTH_MINE = 1, AV_MINE_TICK_TIMER = 45000, - AV_MINE_RECLAIM_TIMER = 1200000, //TODO: get the right value.. this is currently 20 minutes + AV_MINE_RECLAIM_TIMER = 1200000, /// @todo: get the right value.. this is currently 20 minutes AV_NEUTRAL_TEAM = 0 //this is the neutral owner of snowfall }; enum BG_AV_ObjectIds @@ -547,7 +547,7 @@ enum BG_AV_CreaturePlace AV_CPLACE_SPIRIT_FROST_HUT = 6, AV_CPLACE_SPIRIT_MAIN_ALLIANCE = 7, AV_CPLACE_SPIRIT_MAIN_HORDE = 8, -//i don't will add for all 4 positions a variable.. i think one is enough to compute the rest +//I don't add a variable for all 4 positions... I think one is enough to compute the rest AV_CPLACE_DEFENSE_STORM_AID = 9, AV_CPLACE_DEFEMSE_STORM_GRAVE = 13, AV_CPLACE_DEFENSE_STONE_GRAVE = 17, @@ -680,7 +680,7 @@ const float BG_AV_CreaturePos[AV_CPLACE_MAX][4] = {575.411f, -83.597f, 52.3626f, 6.26573f}, {571.352f, -75.6582f, 52.479f, 0.523599f}, //dun north - OK - {668.60f, -122.53f, 64.12f, 2.34f}, //not 100% ok + {668.60f, -122.53f, 64.12f, 2.34f}, /// @todo: To be confirm - Not completely okay {662.253f, -129.105f, 64.1794f, 2.77507f}, {661.209f, -138.877f, 64.2251f, 3.38594f}, {665.481f, -146.857f, 64.1271f, 3.75246f}, @@ -720,7 +720,7 @@ const float BG_AV_CreaturePos[AV_CPLACE_MAX][4] = {723.058f, -14.1548f, 50.7046f, 3.40339f}, // north {715.691f, -4.72233f, 50.2187f, 3.47321f}, // icewing {720.046f, -19.9413f, 50.2187f, 3.36849f}, // stone -//horde (coords not 100% ok) +/// horde @todo: Confirm positions {-1363.99f, -221.99f, 98.4053f, 4.93012f}, {-1370.96f, -223.532f, 98.4266f, 4.93012f}, {-1378.37f, -228.614f, 99.3546f, 5.38565f}, @@ -1039,14 +1039,14 @@ enum BG_AV_CreatureIds }; //entry, team, minlevel, maxlevel -//TODO this array should be removed, the only needed things are the entrys (for spawning(?) and handlekillunit) +/// @todo: this array should be removed, the only needed things are the entrys (for spawning(?) and handlekillunit) const uint32 BG_AV_CreatureInfo[AV_NPC_INFO_MAX][4] = { { 12050, 1216, 58, 58 }, //Stormpike Defender { 13326, 1216, 59, 59 }, //Seasoned Defender { 13331, 1216, 60, 60 }, //Veteran Defender { 13422, 1216, 61, 61 }, //Champion Defender - { 13358, 1216, 59, 60 }, //Stormpike Bowman //i think its 60, 61 and 69, 70.. but this is until now not possible TODO look if this is ok + { 13358, 1216, 59, 60 }, //Stormpike Bowman /// @todo: Confirm if this is correct. Author assumpted 60,61 & 69,70, but wouldn't work here { 11949, 469, 0, 0}, //not spawned with this data, but used for handlekillunit { 11948, 469, 0, 0}, //not spawned with this data, but used for handlekillunit { 12053, 1214, 58, 58 }, //Frostwolf Guardian @@ -1071,7 +1071,7 @@ const uint32 BG_AV_CreatureInfo[AV_NPC_INFO_MAX][4] = { 11602, 59, 54, 55 }, //Irondeep Skullthumper { 11657, 59, 58, 58 }, //Morloch - {13396, 469, 52, 53}, //irondeep alliance TODO: get the right ids + {13396, 469, 52, 53}, // irondeep alliance /// @todo: Correct and give correct ids {13080, 469, 53, 54}, {13098, 469, 54, 55}, {13078, 469, 58, 58}, @@ -1246,7 +1246,7 @@ const uint32 BG_AV_StaticCreatureInfo[51][4] = { 11675, 514, 53, 53 }, //Snowblind Windcaller { 11678, 14, 52, 53 }, //Snowblind Ambusher { 11839, 39, 56, 56 }, //Wildpaw Brute - { 11947, 1214, 61, 61 }, //Captain Galvangar --TODO: doubled + { 11947, 1214, 61, 61 }, // Captain Galvangar /// @todo: Duplicate ? Check and confirm { 11948, 1216, 63, 63 }, //Vanndar Stormpike { 11949, 1216, 61, 61 }, //Captain Balinda Stonehearth { 11997, 1334, 60, 60 }, //Stormpike Herald @@ -1277,7 +1277,7 @@ const uint32 BG_AV_StaticCreatureInfo[51][4] = { 14282, 1214, 53, 54 }, //Frostwolf Bloodhound { 14283, 1216, 53, 54 }, //Stormpike Owl { 14284, 1216, 61, 61 }, //Stormpike Battleguard - { 11946, 1214, 63, 63 }, //Drek'Thar //TODO: make the levels right (boss=0 maybe) + { 11946, 1214, 63, 63 }, //Drek'Thar /// @todo: Correct the level (Level 80 for boss ?) { 11948, 1216, 63, 63 }, //Vanndar Stormpike { 11947, 1214, 61, 61 }, //Captain Galvangar { 11949, 1216, 61, 61 } //Captain Balinda Stonehearth @@ -1310,7 +1310,7 @@ const uint32 BG_AV_GraveyardIds[9]= }; enum BG_AV_BUFF -{ //TODO add all other buffs here +{ /// @todo: Add all other buffs here AV_BUFF_ARMOR = 21163, AV_BUFF_A_CAPTAIN = 23693, //the buff which the alliance captain does AV_BUFF_H_CAPTAIN = 22751 //the buff which the horde captain does @@ -1607,7 +1607,7 @@ class BattlegroundAV : public Battleground /*general */ Creature* AddAVCreature(uint16 cinfoid, uint16 type); - uint16 GetBonusHonor(uint8 kills); //TODO remove this when the core handles this right + uint16 GetBonusHonor(uint8 kills); /// @todo: Remove this when the core handles this properly /*variables */ int32 m_Team_Scores[2]; @@ -1622,7 +1622,7 @@ class BattlegroundAV : public Battleground uint32 m_CaptainBuffTimer[2]; bool m_CaptainAlive[2]; - uint8 m_MaxLevel; //TODO remove this when battleground-getmaxlevel() returns something usefull + uint8 m_MaxLevel; /// @todo: Remove this once battleground->getmaxlevel() returns something usefull/is reworked (?) bool m_IsInformedNearVictory[2]; }; -- cgit v1.2.3 From d6d066f014417649a33229d07991e4cbd4ee9f35 Mon Sep 17 00:00:00 2001 From: Ascathor Date: Tue, 26 Feb 2013 20:05:17 +0100 Subject: Several todo corrections for documentation --- src/server/game/Entities/Creature/Creature.h | 2 +- src/server/game/Entities/Item/ItemPrototype.h | 9 ++------- src/server/game/Globals/ObjectAccessor.h | 2 +- src/server/game/Instances/InstanceSaveMgr.h | 4 ++-- 4 files changed, 6 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index df41690c15e..ab9b81009dd 100644 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -169,7 +169,7 @@ struct CreatureTemplate typedef UNORDERED_MAP CreatureTemplateContainer; // Represents max amount of expansions. -// TODO: Add MAX_EXPANSION constant. +/// @todo: Add MAX_EXPANSION constant. #define MAX_CREATURE_BASE_HP 3 // GCC have alternative #pragma pack(N) syntax and old gcc version not support pack(push, N), also any gcc version not support it at some platform diff --git a/src/server/game/Entities/Item/ItemPrototype.h b/src/server/game/Entities/Item/ItemPrototype.h index f68923706ff..5fc49c99f0a 100644 --- a/src/server/game/Entities/Item/ItemPrototype.h +++ b/src/server/game/Entities/Item/ItemPrototype.h @@ -102,10 +102,8 @@ enum ItemBondingType #define MAX_BIND_TYPE 6 -/* TODO - // need to know cases when using item is not allowed in shapeshift - ITEM_PROTO_FLAG_USABLE_WHEN_SHAPESHIFTED = 0x00800000, // Item can be used in shapeshift forms -*/ +/* /// @todo: Requiring actual cases in which using (an) item isn't allowed while shapeshifted. Else, this flag would need an implementation. + ITEM_PROTO_FLAG_USABLE_WHEN_SHAPESHIFTED = 0x00800000, // Item can be used in shapeshift forms */ enum ItemProtoFlags { @@ -143,9 +141,6 @@ enum ItemProtoFlags ITEM_PROTO_FLAG_UNK12 = 0x80000000 // ? }; -/* TODO -*/ - enum ItemFieldFlags { ITEM_FLAG_SOULBOUND = 0x00000001, // Item is soulbound and cannot be traded <<-- diff --git a/src/server/game/Globals/ObjectAccessor.h b/src/server/game/Globals/ObjectAccessor.h index 113ef1dec83..6a53d58c57f 100644 --- a/src/server/game/Globals/ObjectAccessor.h +++ b/src/server/game/Globals/ObjectAccessor.h @@ -90,7 +90,7 @@ class ObjectAccessor ObjectAccessor& operator=(const ObjectAccessor&); public: - // TODO: override these template functions for each holder type and add assertions + /// @todo: Override these template functions for each holder type and add assertions template static T* GetObjectInOrOutOfWorld(uint64 guid, T* /*typeSpecifier*/) { diff --git a/src/server/game/Instances/InstanceSaveMgr.h b/src/server/game/Instances/InstanceSaveMgr.h index a99b4c66b27..c5dcaf32463 100644 --- a/src/server/game/Instances/InstanceSaveMgr.h +++ b/src/server/game/Instances/InstanceSaveMgr.h @@ -101,8 +101,8 @@ class InstanceSave private: bool UnloadIfEmpty(); /* the only reason the instSave-object links are kept is because - the object-instSave links need to be broken at reset time - TODO: maybe it's enough to just store the number of players/groups */ + the object-instSave links need to be broken at reset time */ + /// @todo: Check if maybe it's enough to just store the number of players/groups PlayerListType m_playerList; GroupListType m_groupList; time_t m_resetTime; -- cgit v1.2.3 From 58ac8207eccbaf056cb1ae7a046bdef48a2483ad Mon Sep 17 00:00:00 2001 From: click Date: Wed, 27 Feb 2013 22:31:25 +0100 Subject: Core: Add support for compiling core in a cygwin-environment - rename/readd/add G3D-patches - give a history on the changes (some G3D-changes didn't even HAVE a patch - boo!) DON'T MESS ABOUT WITH CHANGING DEP/* LIBRARIES AND NOT LEAVING A DIFF IN THE SOURCETRE, MKAY!? --- dep/g3dlite/G3D-v8.0.diff | 520 --------------------- dep/g3dlite/G3D-v8.0_extra.diff | 25 - dep/g3dlite/G3D-v8.0_hotfix1.diff | 520 +++++++++++++++++++++ dep/g3dlite/G3D-v8.0_hotfix2.diff | 14 + dep/g3dlite/G3D-v8.0_hotfix3.diff | 12 + dep/g3dlite/G3D-v8.0_hotfix4.diff | 13 + dep/g3dlite/G3D-v8.0_hotfix5.diff | 71 +++ dep/g3dlite/Readme.txt | 11 +- dep/g3dlite/include/G3D/System.h | 1 + dep/g3dlite/include/G3D/platform.h | 2 + dep/g3dlite/source/BinaryOutput.cpp | 4 + dep/g3dlite/source/FileSystem.cpp | 4 + dep/g3dlite/source/System.cpp | 4 + src/server/collision/BoundingIntervalHierarchy.cpp | 2 + src/server/shared/Common.h | 2 +- 15 files changed, 656 insertions(+), 549 deletions(-) delete mode 100644 dep/g3dlite/G3D-v8.0.diff delete mode 100644 dep/g3dlite/G3D-v8.0_extra.diff create mode 100644 dep/g3dlite/G3D-v8.0_hotfix1.diff create mode 100644 dep/g3dlite/G3D-v8.0_hotfix2.diff create mode 100644 dep/g3dlite/G3D-v8.0_hotfix3.diff create mode 100644 dep/g3dlite/G3D-v8.0_hotfix4.diff create mode 100644 dep/g3dlite/G3D-v8.0_hotfix5.diff (limited to 'src') diff --git a/dep/g3dlite/G3D-v8.0.diff b/dep/g3dlite/G3D-v8.0.diff deleted file mode 100644 index a82d5378a8b..00000000000 --- a/dep/g3dlite/G3D-v8.0.diff +++ /dev/null @@ -1,520 +0,0 @@ -diff -urN g3d-beta4/include/G3D/debugAssert.h g3d-mangos/include/G3D/debugAssert.h ---- g3d-beta4/include/G3D/debugAssert.h 2010-02-07 23:39:20.000000000 +0100 -+++ g3d-mangos/include/G3D/debugAssert.h 2010-08-26 21:36:32.000000000 +0200 -@@ -39,10 +39,12 @@ - #ifdef G3D_LINUX - // Needed so we can define a global display - // pointer for debugAssert. -+#if 0 /* G3DFIX: Disabled to avoid requirement for X11 libraries */ - #include - #include - #include - #endif -+#endif - - - /** -@@ -178,6 +180,7 @@ - namespace G3D { namespace _internal { - - #ifdef G3D_LINUX -+#if 0 /* G3DFIX: Disabled to avoid requirement for X11 libraries */ - /** - A pointer to the X11 display. Initially NULL. If set to a - non-null value (e.g. by SDLWindow), debugAssert attempts to use -@@ -194,6 +197,7 @@ - */ - extern Window x11Window; - #endif -+#endif - - /** - Pops up an assertion dialog or prints an assertion -diff -urN g3d-beta4/include/G3D/g3dmath.h g3d-mangos/include/G3D/g3dmath.h ---- g3d-beta4/include/G3D/g3dmath.h 2010-02-07 23:39:20.000000000 +0100 -+++ g3d-mangos/include/G3D/g3dmath.h 2010-08-26 21:36:32.000000000 +0200 -@@ -65,6 +65,8 @@ - return ::rand() / double(RAND_MAX); - } - -+#if !defined(_WIN64) -+ - /** - Win32 implementation of the C99 fast rounding routines. - -@@ -99,6 +101,19 @@ - - return intgr; - } -+ -+#else -+ -+ __inline long int lrint (double flt) { -+ return (long int)floor(flt+0.5f); -+ } -+ -+ __inline long int lrintf(float flt) { -+ return (long int)floorf(flt+0.5f); -+ } -+ -+#endif -+ - #endif - - -diff -urN g3d-beta4/include/G3D/platform.h g3d-mangos/include/G3D/platform.h ---- g3d-beta4/include/G3D/platform.h 2010-02-07 23:39:20.000000000 +0100 -+++ g3d-mangos/include/G3D/platform.h 2010-08-26 21:36:32.000000000 +0200 -@@ -56,12 +57,15 @@ - // pi as a constant, which creates a conflict with G3D - #define __FP__ - #else -- #error Unknown platform -+ #error Unknown platform - #endif - - // Detect 64-bit under various compilers - #if (defined(_M_X64) || defined(_WIN64) || defined(__LP64__) || defined(_LP64)) - # define G3D_64BIT -+ #if defined(WIN32) -+ #include -+ #endif - #else - # define G3D_32BIT - #endif -@@ -126,13 +130,11 @@ - // TODO: remove - # pragma warning (disable : 4244) - --# define ZLIB_WINAPI -- - # define restrict - - /** @def G3D_CHECK_PRINTF_METHOD_ARGS() - Enables printf parameter validation on gcc. */ --# define G3D_CHECK_PRINTF_ARGS -+# define G3D_CHECK_PRINTF_ARGS - - /** @def G3D_CHECK_PRINTF_METHOD_ARGS() - Enables printf parameter validation on gcc. */ -diff -urN g3d-beta4/include/G3D/System.h g3d-mangos/include/G3D/System.h ---- g3d-beta4/include/G3D/System.h 2010-02-07 23:39:20.000000000 +0100 -+++ g3d-mangos/include/G3D/System.h 2010-08-26 21:36:32.000000000 +0200 -@@ -375,10 +375,10 @@ - // count now contains the cycle count for the intervening operation. - - */ -- static void beginCycleCount(uint64& cycleCount); -+ /* static void beginCycleCount(uint64& cycleCount); - static void endCycleCount(uint64& cycleCount); - -- static uint64 getCycleCount(); -+ static uint64 getCycleCount(); */ - - inline static void setOutOfMemoryCallback(OutOfMemoryCallback c) { - instance().m_outOfMemoryCallback = c; -@@ -438,7 +438,7 @@ - - }; - -- -+/* don't need that for MaNGOS, not portable to Win64... - #ifdef _MSC_VER - inline uint64 System::getCycleCount() { - uint32 timehi, timelo; -@@ -493,14 +493,14 @@ - cycleCount = getCycleCount() - cycleCount; - #else - AbsoluteTime end = UpTime(); -- Nanoseconds diffNS = -+ Nanoseconds diffNS = - AbsoluteDeltaToNanoseconds(end, UInt64ToUnsignedWide(cycleCount)); -- cycleCount = -- (uint64) ((double) (instance().m_OSXCPUSpeed) * -+ cycleCount = -+ (uint64) ((double) (instance().m_OSXCPUSpeed) * - (double) UnsignedWideToUInt64(diffNS) * instance().m_secondsPerNS); - #endif - } -- -+ */ - - } // namespace - -diff -urN g3d-beta4/source/BinaryInput.cpp g3d-mangos/source/BinaryInput.cpp ---- g3d-beta4/source/BinaryInput.cpp 2010-02-07 23:39:20.000000000 +0100 -+++ g3d-mangos/source/BinaryInput.cpp 2010-08-15 11:37:26.000000000 +0200 -@@ -39,7 +39,9 @@ - #include "G3D/Log.h" - #include "G3D/FileSystem.h" - #include --#include "zip.h" -+#if _HAVE_ZIP /* G3DFIX: Use ZIP-library only if defined */ -+ #include "zip.h" -+#endif - #include - - namespace G3D { -@@ -273,6 +275,7 @@ BinaryInput::BinaryInput( - _internal::currentFilesUsed.insert(m_filename); - - -+#if _HAVE_ZIP /* G3DFIX: Use ZIP-library only if defined */ - std::string zipfile; - if (FileSystem::inZipfile(m_filename, zipfile)) { - // Load from zipfile -@@ -304,6 +307,7 @@ BinaryInput::BinaryInput( - m_freeBuffer = true; - return; - } -+#endif - - // Figure out how big the file is and verify that it exists. - m_length = FileSystem::size(m_filename); -diff -urN g3d-beta4/source/debugAssert.cpp g3d-mangos/source/debugAssert.cpp ---- g3d-beta4/source/debugAssert.cpp 2010-02-07 23:39:20.000000000 +0100 -+++ g3d-mangos/source/debugAssert.cpp 2010-08-15 11:37:26.000000000 +0200 -@@ -37,9 +37,11 @@ - AssertionHook _failureHook = _handleErrorCheck_; - - #ifdef G3D_LINUX -+#if 0 /* G3DFIX: Disabled to avoid requirement for X11 libraries */ - Display* x11Display = NULL; - Window x11Window = 0; - #endif -+#endif - - - #ifdef G3D_WIN32 -@@ -250,6 +252,7 @@ - ClipCursor(NULL); - - #elif defined(G3D_LINUX) -+#if 0 /* G3DFIX: Disabled to avoid requirement for X11 libraries */ - if (x11Display != NULL) { - XUngrabPointer(x11Display, CurrentTime); - XUngrabKeyboard(x11Display, CurrentTime); -@@ -264,6 +267,7 @@ - XAllowEvents(x11Display, AsyncPointer, CurrentTime); - XFlush(x11Display); - } -+#endif - #elif defined(G3D_OSX) - // TODO: OS X - #endif -diff -urN g3d-beta4/source/FileSystem.cpp g3d-mangos/source/FileSystem.cpp ---- g3d-beta4/source/FileSystem.cpp 2010-02-07 23:39:20.000000000 +0100 -+++ g3d-mangos/source/FileSystem.cpp 2010-08-15 11:37:26.000000000 +0200 -@@ -12,7 +12,9 @@ - #include "G3D/fileutils.h" - #include - #include --#include "zip.h" -+#if _HAVE_ZIP /* G3DFIX: Use ZIP-library only if defined */ -+ #include "zip.h" -+#endif - #include "G3D/g3dfnmatch.h" - #include "G3D/BinaryInput.h" - #include "G3D/BinaryOutput.h" -@@ -78,6 +80,7 @@ bool FileSystem::Dir::contains(const std - } - - void FileSystem::Dir::computeZipListing(const std::string& zipfile, const std::string& pathInsideZipfile) { -+#if _HAVE_ZIP /* G3DFIX: Use ZIP-library only if defined */ - struct zip* z = zip_open( FilePath::removeTrailingSlash(zipfile).c_str(), ZIP_CHECKCONS, NULL ); - debugAssert(z); - -@@ -126,6 +129,7 @@ void FileSystem::Dir::computeZipListing( - - zip_close(z); - z = NULL; -+#endif - } - - -@@ -522,6 +526,7 @@ int64 FileSystem::_size(const std::strin - int result = stat64(filename.c_str(), &st); - - if (result == -1) { -+#if _HAVE_ZIP /* G3DFIX: Use ZIP-library only if defined */ - std::string zip, contents; - if (zipfileExists(filename, zip, contents)) { - int64 requiredMem; -@@ -538,8 +543,11 @@ int64 FileSystem::_size(const std::strin - zip_close(z); - return requiredMem; - } else { -+#endif - return -1; -+#if _HAVE_ZIP /* G3DFIX: Use ZIP-library only if defined */ - } -+#endif - } - - return st.st_size; -diff -urN g3d-beta4/source/fileutils.cpp g3d-mangos/source/fileutils.cpp ---- g3d-beta4/source/fileutils.cpp 2010-02-07 23:39:20.000000000 +0100 -+++ g3d-mangos/source/fileutils.cpp 2010-08-15 11:37:26.000000000 +0200 -@@ -20,7 +20,9 @@ - - #include - #include --#include "zip.h" -+#if _HAVE_ZIP /* G3DFIX: Use ZIP-library only if defined */ -+ #include "zip.h" -+#endif - - #ifdef G3D_WIN32 - // Needed for _getcwd -@@ -144,7 +146,7 @@ - void*& data, - size_t& length) { - std::string zip, desiredFile; -- -+#if _HAVE_ZIP /* G3DFIX: Use ZIP-library only if defined */ - if (zipfileExists(file, zip, desiredFile)) { - struct zip *z = zip_open( zip.c_str(), ZIP_CHECKCONS, NULL ); - { -@@ -167,6 +169,9 @@ - } else { - data = NULL; - } -+#else -+ data = NULL; -+#endif - } - - -@@ -180,6 +185,7 @@ - int result = _stat(filename.c_str(), &st); - - if (result == -1) { -+#if _HAVE_ZIP /* G3DFIX: Use ZIP-library only if defined */ - std::string zip, contents; - if(zipfileExists(filename, zip, contents)){ - int64 requiredMem; -@@ -198,6 +204,9 @@ - } else { - return -1; - } -+#else -+ return -1; -+#endif - } - - return st.st_size; -@@ -518,6 +527,7 @@ - - /////////////////////////////////////////////////////////////////////////////// - -+#if _HAVE_ZIP /* G3DFIX: Use ZIP-library only if defined */ - /* Helper methods for zipfileExists()*/ - // Given a string (the drive) and an array (the path), computes the directory - static void _zip_resolveDirectory(std::string& completeDir, const std::string& drive, const Array& path, const int length){ -@@ -551,12 +561,12 @@ - } - return true; - } -- -+#endif - - // If no zipfile exists, outZipfile and outInternalFile are unchanged - bool zipfileExists(const std::string& filename, std::string& outZipfile, - std::string& outInternalFile){ -- -+#if _HAVE_ZIP /* G3DFIX: Use ZIP-library only if defined */ - Array path; - std::string drive, base, ext, zipfile, infile; - parseFilename(filename, drive, path, base, ext); -@@ -618,7 +628,7 @@ - } - - } -- -+#endif - // not a valid directory structure ever, - // obviously no .zip was found within the path - return false; -@@ -900,7 +910,7 @@ - # endif - } - -- -+#if _HAVE_ZIP /* G3DFIX: Use ZIP-library only if defined */ - /** - @param path The zipfile name (no trailing slash) - @param prefix Directory inside the zipfile. No leading slash, must have trailing slash if non-empty. -@@ -951,13 +961,14 @@ - } - } - } -- -+#endif - - static void getFileOrDirListZip(const std::string& path, - const std::string& prefix, - Array& files, - bool wantFiles, - bool includePath){ -+#if _HAVE_ZIP /* G3DFIX: Use ZIP-library only if defined */ - struct zip *z = zip_open( path.c_str(), ZIP_CHECKCONS, NULL ); - - Set fileSet; -@@ -973,6 +984,7 @@ - zip_close( z ); - - fileSet.getMembers(files); -+#endif - } - - -diff -urN g3d-beta4/source/prompt.cpp g3d-mangos/source/prompt.cpp ---- g3d-beta4/source/prompt.cpp 2010-02-07 23:39:20.000000000 +0100 -+++ g3d-mangos/source/prompt.cpp 2010-08-15 11:37:26.000000000 +0200 -@@ -21,6 +21,7 @@ - # define _getch getchar - #endif - -+#if 0 /* G3DFIX: exclude GUI prompt code */ - #ifdef G3D_OSX - - /*#ifdef __LP64__ -@@ -37,9 +38,11 @@ - */ - - #endif -+#endif /* G3DFIX: exclude GUI prompt code */ - - namespace G3D { - -+#if 0 /* G3DFIX: exclude GUI prompt code */ - #ifdef G3D_WIN32 - - namespace _internal { -@@ -469,6 +472,7 @@ - } - - #endif -+#endif /* G3DFIX: exclude GUI prompt code */ - - - /** -@@ -531,6 +535,8 @@ - return c; - } - -+#if 0 /* G3DFIX: exclude GUI prompt code */ -+ - #ifdef G3D_OSX - - // See http://developer.apple.com/documentation/Carbon/Reference/Carbon_Event_Manager_Ref/index.html -@@ -689,13 +695,15 @@ - - #endif - -+#endif /* G3DFIX: exclude GUI prompt code */ -+ - int prompt( - const char* windowTitle, - const char* prompt, - const char** choice, - int numChoices, - bool useGui) { -- -+#if 0 /* G3DFIX: exclude GUI prompt code */ - #ifdef G3D_WIN32 - if (useGui) { - // Build the message box -@@ -709,6 +717,7 @@ - return guiPrompt(windowTitle, prompt, choice, numChoices); - } - #endif -+#endif /* G3DFIX: exclude GUI prompt code */ - return textPrompt(windowTitle, prompt, choice, numChoices); - } - -diff -urN g3d-beta4/source/RegistryUtil.cpp g3d-mangos/source/RegistryUtil.cpp ---- g3d-beta4/source/RegistryUtil.cpp 2010-02-07 23:39:20.000000000 +0100 -+++ g3d-mangos/source/RegistryUtil.cpp 2010-08-15 11:37:26.000000000 +0200 -@@ -257,7 +257,7 @@ - - - // static helpers --static HKEY getRootKeyFromString(const char* str, uint32 length) { -+static HKEY getRootKeyFromString(const char* str, size_t length) { - debugAssert(str); - - if (str) { -diff -urN g3d-beta4/source/System.cpp g3d-mangos/source/System.cpp ---- g3d-beta4/source/System.cpp 2010-02-07 23:39:20.000000000 +0100 -+++ g3d-mangos/source/System.cpp 2010-08-15 11:37:26.000000000 +0200 -@@ -80,8 +80,9 @@ - #endif - - // SIMM include -+#ifdef __SSE__ - #include -- -+#endif - - namespace G3D { - -@@ -559,7 +560,7 @@ - #endif - } - --#if defined(G3D_WIN32) -+#if defined(G3D_WIN32) && !defined(G3D_64BIT) /* G3DFIX: Don't check if on 64-bit Windows platforms */ - #pragma message("Port System::memcpy SIMD to all platforms") - /** Michael Herf's fast memcpy */ - void memcpyMMX(void* dst, const void* src, int nbytes) { -@@ -610,7 +611,7 @@ - #endif - - void System::memcpy(void* dst, const void* src, size_t numBytes) { --#if defined(G3D_WIN32) -+#if defined(G3D_WIN32) && !defined(G3D_64BIT) /* G3DFIX: Don't check if on 64-bit Windows platforms */ - memcpyMMX(dst, src, numBytes); - #else - ::memcpy(dst, src, numBytes); -@@ -620,7 +621,7 @@ - - /** Michael Herf's fastest memset. n32 must be filled with the same - character repeated. */ --#if defined(G3D_WIN32) -+#if defined(G3D_WIN32) && !defined(G3D_64BIT) /* G3DFIX: Don't check if on 64-bit Windows platforms */ - #pragma message("Port System::memfill SIMD to all platforms") - - // On x86 processors, use MMX -@@ -659,7 +660,7 @@ - - - void System::memset(void* dst, uint8 value, size_t numBytes) { --#if defined(G3D_WIN32) -+#if defined(G3D_WIN32) && !defined(G3D_64BIT) /* G3DFIX: Don't check if on 64-bit Windows platforms */ - uint32 v = value; - v = v + (v << 8) + (v << 16) + (v << 24); - G3D::memfill(dst, v, numBytes); -@@ -1676,6 +1677,7 @@ - - // VC on Intel - void System::cpuid(CPUIDFunction func, uint32& areg, uint32& breg, uint32& creg, uint32& dreg) { -+#if !defined(G3D_64BIT) /* G3DFIX: Don't check if on 64-bit platform */ - // Can't copy from assembler direct to a function argument (which is on the stack) in VC. - uint32 a,b,c,d; - -@@ -1693,6 +1695,14 @@ - breg = b; - creg = c; - dreg = d; -+#else -+ int CPUInfo[4]; -+ __cpuid(CPUInfo, func); -+ memcpy(&areg, &CPUInfo[0], 4); -+ memcpy(&breg, &CPUInfo[1], 4); -+ memcpy(&creg, &CPUInfo[2], 4); -+ memcpy(&dreg, &CPUInfo[3], 4); -+#endif - } - - #elif defined(G3D_OSX) && ! defined(G3D_OSX_INTEL) diff --git a/dep/g3dlite/G3D-v8.0_extra.diff b/dep/g3dlite/G3D-v8.0_extra.diff deleted file mode 100644 index 62c513435b9..00000000000 --- a/dep/g3dlite/G3D-v8.0_extra.diff +++ /dev/null @@ -1,25 +0,0 @@ -diff --git a/dep/g3dlite/include/G3D/GMutex.h b/dep/g3dlite/include/G3D/GMutex.h -index 3469b81..9fe098d 100644 ---- a/dep/g3dlite/include/G3D/GMutex.h -+++ b/dep/g3dlite/include/G3D/GMutex.h -@@ -16,6 +16,7 @@ - #ifndef G3D_WIN32 - # include - # include -+# include - #endif - - -diff --git a/dep/g3dlite/include/G3D/platform.h b/dep/g3dlite/include/G3D/platform.h -index c8d2f0b..11093f4 100644 ---- a/dep/g3dlite/include/G3D/platform.h -+++ b/dep/g3dlite/include/G3D/platform.h -@@ -57,7 +57,7 @@ - #elif defined(__linux__) - #define G3D_LINUX - #elif defined(__APPLE__) -- #define G3D_OSX -+ #define G3D_LINUX - - // Prevent OS X fp.h header from being included; it defines - // pi as a constant, which creates a conflict with G3D diff --git a/dep/g3dlite/G3D-v8.0_hotfix1.diff b/dep/g3dlite/G3D-v8.0_hotfix1.diff new file mode 100644 index 00000000000..ec90cebbecf --- /dev/null +++ b/dep/g3dlite/G3D-v8.0_hotfix1.diff @@ -0,0 +1,520 @@ +diff -urN a/dep/g3dlite/include/G3D/debugAssert.h b/dep/g3dlite/include/G3D/debugAssert.h +--- a/dep/g3dlite/include/G3D/debugAssert.h 2010-02-07 23:39:20.000000000 +0100 ++++ b/dep/g3dlite/include/G3D/debugAssert.h 2010-08-26 21:36:32.000000000 +0200 +@@ -39,10 +39,12 @@ + #ifdef G3D_LINUX + // Needed so we can define a global display + // pointer for debugAssert. ++#if 0 /* G3DFIX: Disabled to avoid requirement for X11 libraries */ + #include + #include + #include + #endif ++#endif + + + /** +@@ -178,6 +180,7 @@ + namespace G3D { namespace _internal { + + #ifdef G3D_LINUX ++#if 0 /* G3DFIX: Disabled to avoid requirement for X11 libraries */ + /** + A pointer to the X11 display. Initially NULL. If set to a + non-null value (e.g. by SDLWindow), debugAssert attempts to use +@@ -194,6 +197,7 @@ + */ + extern Window x11Window; + #endif ++#endif + + /** + Pops up an assertion dialog or prints an assertion +diff -urN a/dep/g3dlite/include/G3D/g3dmath.h b/dep/g3dlite/include/G3D/g3dmath.h +--- a/dep/g3dlite/include/G3D/g3dmath.h 2010-02-07 23:39:20.000000000 +0100 ++++ b/dep/g3dlite/include/G3D/g3dmath.h 2010-08-26 21:36:32.000000000 +0200 +@@ -65,6 +65,8 @@ + return ::rand() / double(RAND_MAX); + } + ++#if !defined(_WIN64) ++ + /** + Win32 implementation of the C99 fast rounding routines. + +@@ -99,6 +101,19 @@ + + return intgr; + } ++ ++#else ++ ++ __inline long int lrint (double flt) { ++ return (long int)floor(flt+0.5f); ++ } ++ ++ __inline long int lrintf(float flt) { ++ return (long int)floorf(flt+0.5f); ++ } ++ ++#endif ++ + #endif + + +diff -urN a/dep/g3dlite/include/G3D/platform.h b/dep/g3dlite/include/G3D/platform.h +--- a/dep/g3dlite/include/G3D/platform.h 2010-02-07 23:39:20.000000000 +0100 ++++ b/dep/g3dlite/include/G3D/platform.h 2010-08-26 21:36:32.000000000 +0200 +@@ -56,12 +57,15 @@ + // pi as a constant, which creates a conflict with G3D + #define __FP__ + #else +- #error Unknown platform ++ #error Unknown platform + #endif + + // Detect 64-bit under various compilers + #if (defined(_M_X64) || defined(_WIN64) || defined(__LP64__) || defined(_LP64)) + # define G3D_64BIT ++ #if defined(WIN32) ++ #include ++ #endif + #else + # define G3D_32BIT + #endif +@@ -126,13 +130,11 @@ + // TODO: remove + # pragma warning (disable : 4244) + +-# define ZLIB_WINAPI +- + # define restrict + + /** @def G3D_CHECK_PRINTF_METHOD_ARGS() + Enables printf parameter validation on gcc. */ +-# define G3D_CHECK_PRINTF_ARGS ++# define G3D_CHECK_PRINTF_ARGS + + /** @def G3D_CHECK_PRINTF_METHOD_ARGS() + Enables printf parameter validation on gcc. */ +diff -urN a/dep/g3dlite/include/G3D/System.h b/dep/g3dlite/include/G3D/System.h +--- a/dep/g3dlite/include/G3D/System.h 2010-02-07 23:39:20.000000000 +0100 ++++ b/dep/g3dlite/include/G3D/System.h 2010-08-26 21:36:32.000000000 +0200 +@@ -375,10 +375,10 @@ + // count now contains the cycle count for the intervening operation. + + */ +- static void beginCycleCount(uint64& cycleCount); ++ /* static void beginCycleCount(uint64& cycleCount); + static void endCycleCount(uint64& cycleCount); + +- static uint64 getCycleCount(); ++ static uint64 getCycleCount(); */ + + inline static void setOutOfMemoryCallback(OutOfMemoryCallback c) { + instance().m_outOfMemoryCallback = c; +@@ -438,7 +438,7 @@ + + }; + +- ++/* don't need that for MaNGOS, not portable to Win64... + #ifdef _MSC_VER + inline uint64 System::getCycleCount() { + uint32 timehi, timelo; +@@ -493,14 +493,14 @@ + cycleCount = getCycleCount() - cycleCount; + #else + AbsoluteTime end = UpTime(); +- Nanoseconds diffNS = ++ Nanoseconds diffNS = + AbsoluteDeltaToNanoseconds(end, UInt64ToUnsignedWide(cycleCount)); +- cycleCount = +- (uint64) ((double) (instance().m_OSXCPUSpeed) * ++ cycleCount = ++ (uint64) ((double) (instance().m_OSXCPUSpeed) * + (double) UnsignedWideToUInt64(diffNS) * instance().m_secondsPerNS); + #endif + } +- ++ */ + + } // namespace + +diff -urN a/dep/g3dlite/source/BinaryInput.cpp b/dep/g3dlite/source/BinaryInput.cpp +--- a/dep/g3dlite/source/BinaryInput.cpp 2010-02-07 23:39:20.000000000 +0100 ++++ b/dep/g3dlite/source/BinaryInput.cpp 2010-08-15 11:37:26.000000000 +0200 +@@ -39,7 +39,9 @@ + #include "G3D/Log.h" + #include "G3D/FileSystem.h" + #include +-#include "zip.h" ++#if _HAVE_ZIP /* G3DFIX: Use ZIP-library only if defined */ ++ #include "zip.h" ++#endif + #include + + namespace G3D { +@@ -273,6 +275,7 @@ BinaryInput::BinaryInput( + _internal::currentFilesUsed.insert(m_filename); + + ++#if _HAVE_ZIP /* G3DFIX: Use ZIP-library only if defined */ + std::string zipfile; + if (FileSystem::inZipfile(m_filename, zipfile)) { + // Load from zipfile +@@ -304,6 +307,7 @@ BinaryInput::BinaryInput( + m_freeBuffer = true; + return; + } ++#endif + + // Figure out how big the file is and verify that it exists. + m_length = FileSystem::size(m_filename); +diff -urN a/dep/g3dlite/source/debugAssert.cpp b/dep/g3dlite/source/debugAssert.cpp +--- a/dep/g3dlite/source/debugAssert.cpp 2010-02-07 23:39:20.000000000 +0100 ++++ b/dep/g3dlite/source/debugAssert.cpp 2010-08-15 11:37:26.000000000 +0200 +@@ -37,9 +37,11 @@ + AssertionHook _failureHook = _handleErrorCheck_; + + #ifdef G3D_LINUX ++#if 0 /* G3DFIX: Disabled to avoid requirement for X11 libraries */ + Display* x11Display = NULL; + Window x11Window = 0; + #endif ++#endif + + + #ifdef G3D_WIN32 +@@ -250,6 +252,7 @@ + ClipCursor(NULL); + + #elif defined(G3D_LINUX) ++#if 0 /* G3DFIX: Disabled to avoid requirement for X11 libraries */ + if (x11Display != NULL) { + XUngrabPointer(x11Display, CurrentTime); + XUngrabKeyboard(x11Display, CurrentTime); +@@ -264,6 +267,7 @@ + XAllowEvents(x11Display, AsyncPointer, CurrentTime); + XFlush(x11Display); + } ++#endif + #elif defined(G3D_OSX) + // TODO: OS X + #endif +diff -urN a/dep/g3dlite/source/FileSystem.cpp b/dep/g3dlite/source/FileSystem.cpp +--- a/dep/g3dlite/source/FileSystem.cpp 2010-02-07 23:39:20.000000000 +0100 ++++ b/dep/g3dlite/source/FileSystem.cpp 2010-08-15 11:37:26.000000000 +0200 +@@ -12,7 +12,9 @@ + #include "G3D/fileutils.h" + #include + #include +-#include "zip.h" ++#if _HAVE_ZIP /* G3DFIX: Use ZIP-library only if defined */ ++ #include "zip.h" ++#endif + #include "G3D/g3dfnmatch.h" + #include "G3D/BinaryInput.h" + #include "G3D/BinaryOutput.h" +@@ -78,6 +80,7 @@ bool FileSystem::Dir::contains(const std + } + + void FileSystem::Dir::computeZipListing(const std::string& zipfile, const std::string& pathInsideZipfile) { ++#if _HAVE_ZIP /* G3DFIX: Use ZIP-library only if defined */ + struct zip* z = zip_open( FilePath::removeTrailingSlash(zipfile).c_str(), ZIP_CHECKCONS, NULL ); + debugAssert(z); + +@@ -126,6 +129,7 @@ void FileSystem::Dir::computeZipListing( + + zip_close(z); + z = NULL; ++#endif + } + + +@@ -522,6 +526,7 @@ int64 FileSystem::_size(const std::strin + int result = stat64(filename.c_str(), &st); + + if (result == -1) { ++#if _HAVE_ZIP /* G3DFIX: Use ZIP-library only if defined */ + std::string zip, contents; + if (zipfileExists(filename, zip, contents)) { + int64 requiredMem; +@@ -538,8 +543,11 @@ int64 FileSystem::_size(const std::strin + zip_close(z); + return requiredMem; + } else { ++#endif + return -1; ++#if _HAVE_ZIP /* G3DFIX: Use ZIP-library only if defined */ + } ++#endif + } + + return st.st_size; +diff -urN a/dep/g3dlite/source/fileutils.cpp b/dep/g3dlite/source/fileutils.cpp +--- a/dep/g3dlite/source/fileutils.cpp 2010-02-07 23:39:20.000000000 +0100 ++++ b/dep/g3dlite/source/fileutils.cpp 2010-08-15 11:37:26.000000000 +0200 +@@ -20,7 +20,9 @@ + + #include + #include +-#include "zip.h" ++#if _HAVE_ZIP /* G3DFIX: Use ZIP-library only if defined */ ++ #include "zip.h" ++#endif + + #ifdef G3D_WIN32 + // Needed for _getcwd +@@ -144,7 +146,7 @@ + void*& data, + size_t& length) { + std::string zip, desiredFile; +- ++#if _HAVE_ZIP /* G3DFIX: Use ZIP-library only if defined */ + if (zipfileExists(file, zip, desiredFile)) { + struct zip *z = zip_open( zip.c_str(), ZIP_CHECKCONS, NULL ); + { +@@ -167,6 +169,9 @@ + } else { + data = NULL; + } ++#else ++ data = NULL; ++#endif + } + + +@@ -180,6 +185,7 @@ + int result = _stat(filename.c_str(), &st); + + if (result == -1) { ++#if _HAVE_ZIP /* G3DFIX: Use ZIP-library only if defined */ + std::string zip, contents; + if(zipfileExists(filename, zip, contents)){ + int64 requiredMem; +@@ -198,6 +204,9 @@ + } else { + return -1; + } ++#else ++ return -1; ++#endif + } + + return st.st_size; +@@ -518,6 +527,7 @@ + + /////////////////////////////////////////////////////////////////////////////// + ++#if _HAVE_ZIP /* G3DFIX: Use ZIP-library only if defined */ + /* Helper methods for zipfileExists()*/ + // Given a string (the drive) and an array (the path), computes the directory + static void _zip_resolveDirectory(std::string& completeDir, const std::string& drive, const Array& path, const int length){ +@@ -551,12 +561,12 @@ + } + return true; + } +- ++#endif + + // If no zipfile exists, outZipfile and outInternalFile are unchanged + bool zipfileExists(const std::string& filename, std::string& outZipfile, + std::string& outInternalFile){ +- ++#if _HAVE_ZIP /* G3DFIX: Use ZIP-library only if defined */ + Array path; + std::string drive, base, ext, zipfile, infile; + parseFilename(filename, drive, path, base, ext); +@@ -618,7 +628,7 @@ + } + + } +- ++#endif + // not a valid directory structure ever, + // obviously no .zip was found within the path + return false; +@@ -900,7 +910,7 @@ + # endif + } + +- ++#if _HAVE_ZIP /* G3DFIX: Use ZIP-library only if defined */ + /** + @param path The zipfile name (no trailing slash) + @param prefix Directory inside the zipfile. No leading slash, must have trailing slash if non-empty. +@@ -951,13 +961,14 @@ + } + } + } +- ++#endif + + static void getFileOrDirListZip(const std::string& path, + const std::string& prefix, + Array& files, + bool wantFiles, + bool includePath){ ++#if _HAVE_ZIP /* G3DFIX: Use ZIP-library only if defined */ + struct zip *z = zip_open( path.c_str(), ZIP_CHECKCONS, NULL ); + + Set fileSet; +@@ -973,6 +984,7 @@ + zip_close( z ); + + fileSet.getMembers(files); ++#endif + } + + +diff -urN a/dep/g3dlite/source/prompt.cpp b/dep/g3dlite/source/prompt.cpp +--- a/dep/g3dlite/source/prompt.cpp 2010-02-07 23:39:20.000000000 +0100 ++++ b/dep/g3dlite/source/prompt.cpp 2010-08-15 11:37:26.000000000 +0200 +@@ -21,6 +21,7 @@ + # define _getch getchar + #endif + ++#if 0 /* G3DFIX: exclude GUI prompt code */ + #ifdef G3D_OSX + + /*#ifdef __LP64__ +@@ -37,9 +38,11 @@ + */ + + #endif ++#endif /* G3DFIX: exclude GUI prompt code */ + + namespace G3D { + ++#if 0 /* G3DFIX: exclude GUI prompt code */ + #ifdef G3D_WIN32 + + namespace _internal { +@@ -469,6 +472,7 @@ + } + + #endif ++#endif /* G3DFIX: exclude GUI prompt code */ + + + /** +@@ -531,6 +535,8 @@ + return c; + } + ++#if 0 /* G3DFIX: exclude GUI prompt code */ ++ + #ifdef G3D_OSX + + // See http://developer.apple.com/documentation/Carbon/Reference/Carbon_Event_Manager_Ref/index.html +@@ -689,13 +695,15 @@ + + #endif + ++#endif /* G3DFIX: exclude GUI prompt code */ ++ + int prompt( + const char* windowTitle, + const char* prompt, + const char** choice, + int numChoices, + bool useGui) { +- ++#if 0 /* G3DFIX: exclude GUI prompt code */ + #ifdef G3D_WIN32 + if (useGui) { + // Build the message box +@@ -709,6 +717,7 @@ + return guiPrompt(windowTitle, prompt, choice, numChoices); + } + #endif ++#endif /* G3DFIX: exclude GUI prompt code */ + return textPrompt(windowTitle, prompt, choice, numChoices); + } + +diff -urN a/dep/g3dlite/source/RegistryUtil.cpp b/dep/g3dlite/source/RegistryUtil.cpp +--- a/dep/g3dlite/source/RegistryUtil.cpp 2010-02-07 23:39:20.000000000 +0100 ++++ b/dep/g3dlite/source/RegistryUtil.cpp 2010-08-15 11:37:26.000000000 +0200 +@@ -257,7 +257,7 @@ + + + // static helpers +-static HKEY getRootKeyFromString(const char* str, uint32 length) { ++static HKEY getRootKeyFromString(const char* str, size_t length) { + debugAssert(str); + + if (str) { +diff -urN a/dep/g3dlite/source/System.cpp b/dep/g3dlite/source/System.cpp +--- a/dep/g3dlite/source/System.cpp 2010-02-07 23:39:20.000000000 +0100 ++++ b/dep/g3dlite/source/System.cpp 2010-08-15 11:37:26.000000000 +0200 +@@ -80,8 +80,9 @@ + #endif + + // SIMM include ++#ifdef __SSE__ + #include +- ++#endif + + namespace G3D { + +@@ -559,7 +560,7 @@ + #endif + } + +-#if defined(G3D_WIN32) ++#if defined(G3D_WIN32) && !defined(G3D_64BIT) /* G3DFIX: Don't check if on 64-bit Windows platforms */ + #pragma message("Port System::memcpy SIMD to all platforms") + /** Michael Herf's fast memcpy */ + void memcpyMMX(void* dst, const void* src, int nbytes) { +@@ -610,7 +611,7 @@ + #endif + + void System::memcpy(void* dst, const void* src, size_t numBytes) { +-#if defined(G3D_WIN32) ++#if defined(G3D_WIN32) && !defined(G3D_64BIT) /* G3DFIX: Don't check if on 64-bit Windows platforms */ + memcpyMMX(dst, src, numBytes); + #else + ::memcpy(dst, src, numBytes); +@@ -620,7 +621,7 @@ + + /** Michael Herf's fastest memset. n32 must be filled with the same + character repeated. */ +-#if defined(G3D_WIN32) ++#if defined(G3D_WIN32) && !defined(G3D_64BIT) /* G3DFIX: Don't check if on 64-bit Windows platforms */ + #pragma message("Port System::memfill SIMD to all platforms") + + // On x86 processors, use MMX +@@ -659,7 +660,7 @@ + + + void System::memset(void* dst, uint8 value, size_t numBytes) { +-#if defined(G3D_WIN32) ++#if defined(G3D_WIN32) && !defined(G3D_64BIT) /* G3DFIX: Don't check if on 64-bit Windows platforms */ + uint32 v = value; + v = v + (v << 8) + (v << 16) + (v << 24); + G3D::memfill(dst, v, numBytes); +@@ -1676,6 +1677,7 @@ + + // VC on Intel + void System::cpuid(CPUIDFunction func, uint32& areg, uint32& breg, uint32& creg, uint32& dreg) { ++#if !defined(G3D_64BIT) /* G3DFIX: Don't check if on 64-bit platform */ + // Can't copy from assembler direct to a function argument (which is on the stack) in VC. + uint32 a,b,c,d; + +@@ -1693,6 +1695,14 @@ + breg = b; + creg = c; + dreg = d; ++#else ++ int CPUInfo[4]; ++ __cpuid(CPUInfo, func); ++ memcpy(&areg, &CPUInfo[0], 4); ++ memcpy(&breg, &CPUInfo[1], 4); ++ memcpy(&creg, &CPUInfo[2], 4); ++ memcpy(&dreg, &CPUInfo[3], 4); ++#endif + } + + #elif defined(G3D_OSX) && ! defined(G3D_OSX_INTEL) diff --git a/dep/g3dlite/G3D-v8.0_hotfix2.diff b/dep/g3dlite/G3D-v8.0_hotfix2.diff new file mode 100644 index 00000000000..bb66c4a6a29 --- /dev/null +++ b/dep/g3dlite/G3D-v8.0_hotfix2.diff @@ -0,0 +1,14 @@ +diff --git a/dep/g3dlite/source/g3dmath.cpp b/dep/g3dlite/source/g3dmath.cpp +index e846f8c..84e8345 100644 +--- a/dep/g3dlite/source/g3dmath.cpp ++++ b/dep/g3dlite/source/g3dmath.cpp +@@ -41,7 +41,7 @@ double inf() { + } + + bool isNaN(float x) { +- static const float n = nan(); ++ static const float n = fnan(); + return memcmp(&x, &n, sizeof(float)) == 0; + } + + diff --git a/dep/g3dlite/G3D-v8.0_hotfix3.diff b/dep/g3dlite/G3D-v8.0_hotfix3.diff new file mode 100644 index 00000000000..d556103c96d --- /dev/null +++ b/dep/g3dlite/G3D-v8.0_hotfix3.diff @@ -0,0 +1,12 @@ +diff --git a/dep/g3dlite/include/G3D/GMutex.h b/dep/g3dlite/include/G3D/GMutex.h +index 3469b81..9fe098d 100644 +--- a/dep/g3dlite/include/G3D/GMutex.h ++++ b/dep/g3dlite/include/G3D/GMutex.h +@@ -16,6 +16,7 @@ + #ifndef G3D_WIN32 + # include + # include ++# include + #endif + + diff --git a/dep/g3dlite/G3D-v8.0_hotfix4.diff b/dep/g3dlite/G3D-v8.0_hotfix4.diff new file mode 100644 index 00000000000..cae92747a9a --- /dev/null +++ b/dep/g3dlite/G3D-v8.0_hotfix4.diff @@ -0,0 +1,13 @@ +diff --git a/dep/g3dlite/include/G3D/platform.h b/dep/g3dlite/include/G3D/platform.h +index c8d2f0b..11093f4 100644 +--- a/dep/g3dlite/include/G3D/platform.h ++++ b/dep/g3dlite/include/G3D/platform.h +@@ -57,7 +57,7 @@ + #elif defined(__linux__) + #define G3D_LINUX + #elif defined(__APPLE__) +- #define G3D_OSX ++ #define G3D_LINUX + + // Prevent OS X fp.h header from being included; it defines + // pi as a constant, which creates a conflict with G3D diff --git a/dep/g3dlite/G3D-v8.0_hotfix5.diff b/dep/g3dlite/G3D-v8.0_hotfix5.diff new file mode 100644 index 00000000000..29b7eba811b --- /dev/null +++ b/dep/g3dlite/G3D-v8.0_hotfix5.diff @@ -0,0 +1,71 @@ +diff --git a/dep/g3dlite/include/G3D/System.h b/dep/g3dlite/include/G3D/System.h +index 1c0cf99..f160774 100644 +--- a/dep/g3dlite/include/G3D/System.h ++++ b/dep/g3dlite/include/G3D/System.h +@@ -19,6 +19,7 @@ + #include "G3D/G3DGameUnits.h" + #include "G3D/BinaryFormat.h" + #include ++#include + + #ifdef G3D_OSX + # include +diff --git a/dep/g3dlite/include/G3D/platform.h b/dep/g3dlite/include/G3D/platform.h +index 11093f4..614c0ed 100644 +--- a/dep/g3dlite/include/G3D/platform.h ++++ b/dep/g3dlite/include/G3D/platform.h +@@ -56,6 +56,8 @@ + #define G3D_LINUX + #elif defined(__linux__) + #define G3D_LINUX ++#elif defined(__CYGWIN__) ++ #define G3D_LINUX + #elif defined(__APPLE__) + #define G3D_LINUX + +diff --git a/dep/g3dlite/source/BinaryOutput.cpp b/dep/g3dlite/source/BinaryOutput.cpp +index 054211d..81fa982 100644 +--- a/dep/g3dlite/source/BinaryOutput.cpp ++++ b/dep/g3dlite/source/BinaryOutput.cpp +@@ -22,6 +22,10 @@ + # include + #endif + ++#ifdef __CYGWIN__ ++# include ++#endif ++ + // Largest memory buffer that the system will use for writing to + // disk. After this (or if the system runs out of memory) + // chunks of the file will be dumped to disk. +diff --git a/dep/g3dlite/source/FileSystem.cpp b/dep/g3dlite/source/FileSystem.cpp +index 2cf890a..76a3611 100644 +--- a/dep/g3dlite/source/FileSystem.cpp ++++ b/dep/g3dlite/source/FileSystem.cpp +@@ -35,6 +35,10 @@ + # define _stat stat + #endif + ++#ifdef __CYGWIN__ ++#define stat64 stat ++#endif ++ + namespace G3D { + + static FileSystem* common = NULL; +diff --git a/dep/g3dlite/source/System.cpp b/dep/g3dlite/source/System.cpp +index 809f05c..f6b0e03 100644 +--- a/dep/g3dlite/source/System.cpp ++++ b/dep/g3dlite/source/System.cpp +@@ -888,7 +888,11 @@ void System::initTime() { + + if (localTimeVals) { + // tm_gmtoff is already corrected for daylight savings. ++ #ifdef __CYGWIN__ ++ local = local + _timezone; ++ #else + local = local + localTimeVals->tm_gmtoff; ++ #endif + } + + m_realWorldGetTickTime0 = local; diff --git a/dep/g3dlite/Readme.txt b/dep/g3dlite/Readme.txt index b91c20dce38..055574ee654 100644 --- a/dep/g3dlite/Readme.txt +++ b/dep/g3dlite/Readme.txt @@ -1,3 +1,8 @@ - Due to issues with G3D (normally requiring X11 and the ZIP-library), the -sourcetree version contains a modified version. The applied patch is -commited to the repository for future reference. + Due to issues with G3D normally requiring X11 and the ZIP-library, the library version in this sourcetree contains a modified version. +The applied patches are added as .diff-files to the repository for future reference (knowing what was changed is quite handy). + +G3D-v8.0_hotfix1.diff - 2010-08-27 - remove dependency on zip/z11 libraries, add support for 64-bit arch +G3D-v8.0_hotfix2.diff - 2012-01-14 - fix typo in isNaN(float x) +G3D-v8.0_hotfix3.diff - 2012-08-26 - fix compilation on Fedora Linux +G3D-v8.0_hotfix4.diff - 2012-11-09 - fix compilation on OSX +G3D-v8.0_hotfix5.diff - 2013-02-27 - fix compilation in cygwin environments diff --git a/dep/g3dlite/include/G3D/System.h b/dep/g3dlite/include/G3D/System.h index 1c0cf99410c..f1607747bbe 100644 --- a/dep/g3dlite/include/G3D/System.h +++ b/dep/g3dlite/include/G3D/System.h @@ -19,6 +19,7 @@ #include "G3D/G3DGameUnits.h" #include "G3D/BinaryFormat.h" #include +#include #ifdef G3D_OSX # include diff --git a/dep/g3dlite/include/G3D/platform.h b/dep/g3dlite/include/G3D/platform.h index 11093f4a6ce..614c0ed7cad 100644 --- a/dep/g3dlite/include/G3D/platform.h +++ b/dep/g3dlite/include/G3D/platform.h @@ -56,6 +56,8 @@ #define G3D_LINUX #elif defined(__linux__) #define G3D_LINUX +#elif defined(__CYGWIN__) + #define G3D_LINUX #elif defined(__APPLE__) #define G3D_LINUX diff --git a/dep/g3dlite/source/BinaryOutput.cpp b/dep/g3dlite/source/BinaryOutput.cpp index 054211d906c..81fa9822206 100644 --- a/dep/g3dlite/source/BinaryOutput.cpp +++ b/dep/g3dlite/source/BinaryOutput.cpp @@ -22,6 +22,10 @@ # include #endif +#ifdef __CYGWIN__ +# include +#endif + // Largest memory buffer that the system will use for writing to // disk. After this (or if the system runs out of memory) // chunks of the file will be dumped to disk. diff --git a/dep/g3dlite/source/FileSystem.cpp b/dep/g3dlite/source/FileSystem.cpp index 2cf890a1cd5..76a361162c9 100644 --- a/dep/g3dlite/source/FileSystem.cpp +++ b/dep/g3dlite/source/FileSystem.cpp @@ -35,6 +35,10 @@ # define _stat stat #endif +#ifdef __CYGWIN__ +#define stat64 stat +#endif + namespace G3D { static FileSystem* common = NULL; diff --git a/dep/g3dlite/source/System.cpp b/dep/g3dlite/source/System.cpp index 809f05c0ab4..f6b0e038f27 100644 --- a/dep/g3dlite/source/System.cpp +++ b/dep/g3dlite/source/System.cpp @@ -888,7 +888,11 @@ void System::initTime() { if (localTimeVals) { // tm_gmtoff is already corrected for daylight savings. + #ifdef __CYGWIN__ + local = local + _timezone; + #else local = local + localTimeVals->tm_gmtoff; + #endif } m_realWorldGetTickTime0 = local; diff --git a/src/server/collision/BoundingIntervalHierarchy.cpp b/src/server/collision/BoundingIntervalHierarchy.cpp index bca738d1ff6..4c1f449da25 100644 --- a/src/server/collision/BoundingIntervalHierarchy.cpp +++ b/src/server/collision/BoundingIntervalHierarchy.cpp @@ -20,6 +20,8 @@ #if defined __APPLE__ #define isnan std::isnan +#elif defined __CYGWIN__ + #define isnan std::isnan #elif defined _MSC_VER #define isnan _isnan #endif diff --git a/src/server/shared/Common.h b/src/server/shared/Common.h index f4e4ce7fe06..44a7749334d 100644 --- a/src/server/shared/Common.h +++ b/src/server/shared/Common.h @@ -170,7 +170,7 @@ enum LocaleConstant }; const uint8 TOTAL_LOCALES = 9; -const LocaleConstant DEFAULT_LOCALE = LOCALE_enUS; +#define DEFAULT_LOCALE LOCALE_enUS #define MAX_LOCALES 8 #define MAX_ACCOUNT_TUTORIAL_VALUES 8 -- cgit v1.2.3 From 6801314881598f0b1cce7a2e614ca7f314c1e129 Mon Sep 17 00:00:00 2001 From: Trista Date: Thu, 28 Feb 2013 18:44:07 +0200 Subject: Scripts/Eye of Eternity: Rewrite most of it. Closes: #1133, #8212, #1150, #5003, #6794 * More stuff will be done, a lot to clean maybe, as of raiding it's good to go now pretty much*. * Big thx to Shauren, Horn, manuel, Machiavelli, Nay, Krofna and rest who helped. --- .../world/2013_02_28_00_world_eye_of_eternity.sql | 200 ++ src/server/game/Spells/SpellMgr.cpp | 31 +- .../Northrend/Nexus/EyeOfEternity/boss_malygos.cpp | 2762 +++++++++++++++----- .../Nexus/EyeOfEternity/eye_of_eternity.h | 32 +- .../EyeOfEternity/instance_eye_of_eternity.cpp | 83 +- 5 files changed, 2385 insertions(+), 723 deletions(-) create mode 100644 sql/updates/world/2013_02_28_00_world_eye_of_eternity.sql (limited to 'src') diff --git a/sql/updates/world/2013_02_28_00_world_eye_of_eternity.sql b/sql/updates/world/2013_02_28_00_world_eye_of_eternity.sql new file mode 100644 index 00000000000..9aef8f358d2 --- /dev/null +++ b/sql/updates/world/2013_02_28_00_world_eye_of_eternity.sql @@ -0,0 +1,200 @@ +-- Add spell script names +DELETE FROM `spell_script_names` WHERE `spell_id` IN (56046,56047,61693,61694,57459,56438,61210,56397,58842,59084,59099,56070,56072,60936,60939,61028,61023); +INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES +(56046, 'spell_malygos_portal_beam'), +(56047, 'spell_malygos_random_portal'), +(61693, 'spell_malygos_arcane_storm'), -- Phase I /10/ +(61694, 'spell_malygos_arcane_storm'), -- Phase I /25/ +(57459, 'spell_malygos_arcane_storm'), -- Phase III +(56438, 'spell_arcane_overload'), +(61210, 'spell_nexus_lord_align_disk_aggro'), +(56397, 'spell_scion_of_eternity_arcane_barrage'), +(58842, 'spell_malygos_destroy_platform_channel'), +(59084, 'spell_alexstrasza_bunny_destroy_platform_boom_visual'), +(59099, 'spell_alexstrasza_bunny_destroy_platform_event'), +(56070, 'spell_wyrmrest_skytalon_summon_red_dragon_buddy'), +(56072, 'spell_wyrmrest_skytalon_ride_red_dragon_buddy_trigger'), +(60936, 'spell_malygos_surge_of_power_25'), +(60939, 'spell_malygos_surge_of_power_warning_selector_25'), +(61028, 'spell_alexstrasza_gift_beam'), +(61023, 'spell_alexstrasza_gift_beam_visual'); + +-- Add spell difficulties +DELETE FROM `spelldifficulty_dbc` WHERE `id` IN (61693,56272,57058); +INSERT INTO `spelldifficulty_dbc` (`id`,`spellid0`,`spellid1`,`spellid2`,`spellid3`) VALUES +(61693,61693,61694,0,0), -- Arcane Storm - Phase I +(56272,56272,60072,0,0), -- Arcane Breath +(57058,57058,60073,0,0); -- Arcane Shock (Nexus Lord) + +-- Insert missing creature template addon +DELETE FROM `creature_template_addon` WHERE `entry` IN (28859,30234,30248,32295,30592,31748,31749); +INSERT INTO `creature_template_addon` (`entry`,`path_id`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES +(28859,0,0,0x1000000|0x2000000,0x1,0, ''), -- Malygos +(30234,0,0,0x1000000|0x2000000,0x1,0, '43775'), -- Hover Disk (Nexus Lord), add aura "Flight" +(30248,0,0,0x1000000|0x2000000,0x1,0, '43775'), -- Hover Disk (Scion of Eternity), add aura "Flight" +(31748,0,0,0x1000000|0x2000000,0x1,0, '43775'), -- Hover Disk Difficulty (Nexus Lord), add aura "Flight" +(31749,0,0,0x1000000|0x2000000,0x1,0, '43775'), -- Hover Disk Difficulty (Scion of Eternity), add aura "Flight" +(32295,0,0,0x1000000|0x2000000,0x1,0, ''), -- Alexstrasza +(30592,0,0,0x1000000|0x2000000,0x1,0, '57428'); -- Static Field bunny + +-- Add, restructure and update missing texts and sounds +DELETE FROM `creature_text` WHERE `entry` IN (28859,32295); +INSERT INTO `creature_text` (`entry`,`groupid`,`id`,`text`,`type`,`language`,`probability`,`emote`,`duration`,`sound`,`comment`) VALUES +(28859,0,0, 'Lesser beings, intruding here! A shame that your excess courage does not compensate for your stupidity!',14,0,100,0,10000,14512,'Malygos - Intro'), +(28859,0,1, 'None but the blue dragonflight are welcome here. Perhaps this is the work of Alexstrasza? Well, then, she has sent you to your deaths!',14,0,100,0,11000,14513,'Malygos - Intro'), +(28859,0,2, 'What could you hope to accomplish? To storm brazenly into my domain... to employ magic... against ME?',14,0,100,0,13000,14514,'Malygos - Intro'), +(28859,0,3, 'I am without limits here. The rules of your cherished reality do not apply. In this realm, I am in control!',14,0,100,0,10000,14515,'Malygos - Intro'), +(28859,0,4, 'I give you one chance. Pledge fealty to me, and perhaps I will not slaughter you for your insolence.',14,0,100,0,7000,14516,'Malygos - Intro'), +(28859,1,0, 'My patience has reached its limit, I will be rid of you!',14,0,100,0,4000,14517,'Malygos - Start phase 1'), +(28859,2,0, 'You will not succeed while I draw breath!',14,0,100,0,3000,14518,'Malygos - Begin to cast Deep Breath'), +(28859,3,0, 'Your stupidity has finally caught up to you!',14,0,100,0,3250,14519,'Malygos - Killed Player (Phase 1)'), +(28859,3,1, 'More artifacts to confiscate...',14,0,100,0,2800,14520,'Malygos - Killed Player (Phase 1)'), +(28859,3,2, 'How very naive.',14,0,100,0,4800,14521,'Malygos - Killed Player (Phase 1)'), +(28859,4,0, 'I had hoped to end your lives quickly, but you have proven more... resilient than I anticipated. Nonetheless, your efforts are in vain. It is you reckless, careless mortals who are to blame for this war. I do what I must, and if it means your extinction.... then SO BE IT!!',14,0,100,0,22900,14522,'Malygos - End Phase One'), +(28859,5,0, 'Few have experienced the pain I will now inflict upon you!',14,0,100,0,5500,14523,'Malygos - Start phase 2'), -- Unused by Blizzard for some reason +(28859,6,0, 'I will teach you IGNORANT children just how little you know of magic...',14,0,100,0,7000,14524,'Malygos - Anti-Magic Shell'), +(28859,7,0, 'Watch helplessly as your hopes are swept away...',14,0,100,0,4000,14525,'Malygos - Magic Blast'), +(28859,8,0, 'Your energy will be put to good use!',14,0,100,0,2000,14526,'Malygos - Killed Player (Phase 2)'), +(28859,8,1, 'I am the spell-weaver! My power is infinite!',14,0,100,0,5200,14527,'Malygos - Killed Player (Phase 2)'), +(28859,8,2, 'Your spirit will linger here forever!',14,0,100,0,3800,14528,'Malygos - Killed Player (Phase 2)'), +(28859,9,0, 'ENOUGH! If you intend to reclaim Azeroth''s magic, then you shall have it...',14,0,100,0,7000,14529,'Malygos - End Phase 2'), +(28859,10,0, 'Now your benefactors make their appearance... But they are too late. The powers contained here are sufficient to destroy the world ten times over! What do you think they will do to you?',14,0,100,0,13000,14530,'Intro Phase 3'), +(28859,11,0, 'SUBMIT!',14,0,100,0,1000,14531,'Malygos - Start phase 3'), -- Unused by Blizzard for some reason +(28859,12,0, 'Malygos takes a deep breath.',41,0,100,0,10000,0,'Malygos - Surge of Power warning (Phase 2)'), +(28859,13,0, 'The powers at work here exceed anything you could possibly imagine!',14,0,100,0,5000,14532,'Malygos - Surge of Power'), +(28859,14,0, 'I AM UNSTOPPABLE!',14,0,100,0,2000,14533,'Malygos - Buffed by a spark'), +(28859,15,0, 'Alexstrasza! Another of your brood falls!',14,0,100,0,3600,14534,'Malygos - Killed Player (Phase 3)'), +(28859,15,1, 'Little more then gnats!',14,0,100,0,2650,14535,'Malygos - Killed Player (Phase 3)'), +(28859,15,2, 'Your red allies will share your fate...',14,0,100,0,3000,14536,'Malygos - Killed Player (Phase 3)'), +(28859,16,0, 'Still standing? Not for long...',14,0,100,0,3600,14537,'Malygos - Spell Casting 1(Phase 3)'), +(28859,16,1, 'Your cause is lost!',14,0,100,0,2000,14538,'Malygos - Spell Casting 2 (Phase 3)'), +(28859,16,2, 'Your fragile mind will be shattered!',14,0,100,0,4000,14539,'Malygos - Spell Casting 3 (Phase 3)'), +(28859,17,0, 'Unthinkable! The mortals will destroy... everything! My sister, what have you...',14,0,100,0,8500,14540,'Malygos - Death'), +(28859,18,0, '%s fixes his eyes on you!',42,0,100,0,3000,0,'Malygos - Surge of Power warning (Phase 3)'), +(28859,19,0, '%s goes into a berserker rage!',41,0,100,0,10000,0,'Malygos - Hit berserk timer (Any phase)'), +(32295,0,0, 'I did what I had to, brother. You gave me no alternative.',14,0,100,0,4000,14406,'Alexstrasza - Yell text 1'), +(32295,1,0, 'And so ends the Nexus War.',14,0,100,0,4000,14407,'Alexstrasza - Yell text 2'), +(32295,2,0, 'This resolution pains me deeply, but the destruction, the monumental loss of life had to end. Regardless of Malygos''s recent transgressions, I will mourn his loss. He was once a guardian, a protector. This day, one of the world''s mightiest has fallen.',14,0,100,0,24000,14408,'Alexstrasza - Yell text 3'), +(32295,3,0, 'The red dragonflight will take on the burden of mending the devastation wrought on Azeroth. Return home to your people and rest. Tomorrow will bring you new challenges, and you must be ready to face them. Life... goes on.',14,0,100,0,22000,14409,'Alexstrasza - Yell text 4'); +-- Update wrong sound and add duration for Power Sparks warning +UPDATE `creature_text` SET `duration`=10000,`sound`=0 WHERE `entry`=30084 AND `groupid`=0 AND`id`=0; + +-- Add conditions +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry` IN (56047,58846,61028,56429,56505,59099,61714,61715,57432,57429,61210,56548,56431,56438); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`SourceId`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionTarget`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`,`NegativeCondition`,`ErrorType`,`ErrorTextId`,`ScriptName`,`Comment`) VALUES +(13,1,56047,0,0,31,0,3,30118,0,0,0,0,'', 'Random Portal can implicitly hit only Portal (Malygos)'), +(13,1,56047,0,0,29,0,28859,30,0,1,0,0,'', 'Random Portal can implicitly hit only target that is not in 30 yards near Malygos'), +(13,1,58846,0,0,32,0,0x0010,0,0,0,0,0,'', 'Summon Red Dragon Buddy force cast can implicitly hit only players'), +(13,1,61028,0,0,31,0,3,32448,0,0,0,0,'', 'Alexstrasza''s Gift Beam can hit only Alexstrasza''s Gift'), +(13,1,56429,0,0,31,0,3,31253,0,0,0,0,'', 'Summon Arcane Bomb can hit only Alexstrasza the Life-Binder (bunny)'), +(13,1,56505,0,0,31,0,3,30334,0,0,0,0,'', 'Surge of Power (phase II) can hit only Surge of Power'), +(13,1,56548,0,0,31,0,3,30234,0,1,0,0,'', 'Surge of Power triggered damage spell (phase II) can''t hit melee Hover Disk'), +(13,3,56431,0,0,31,0,3,30234,0,1,0,0,'', 'Arcane Overload damage and knockback spell can''t hit melee Hover Disk'), +(13,1,56438,0,0,1,0,1,56438,0,1,0,0,'', 'Arcane Overload damage reduce aura can''t apply to target that already is affected by such'), +(13,6,59099,0,0,32,0,0x0010,0,0,0,0,0,'', 'Destroy Platform Event effect 1 and 2 can hit only players'), +(13,7,61714,0,0,31,0,3,30245,0,0,0,0,'', 'Berserk (spell 2) can hit Nexus Lord'), +(13,7,61714,0,1,31,0,3,30249,0,0,0,0,'', 'Berserk (spell 2) can hit Scion of Eternity'), +(13,7,61715,0,0,31,0,3,30592,0,0,0,0,'', 'Berserk (spell 3) can hit Static Field bunny'), +(13,1,57432,0,0,31,0,3,30161,0,0,0,0,'', 'Arcane Pulse can hit only drakes'), +(13,3,57429,0,0,31,0,3,30161,0,0,0,0,'', 'Static Field can hit only drakes'), +(13,1,61210,0,0,33,1,0,4,0,0,0,0,'', 'Align Disk Aggro can only hit the vehicle of the passenger caster'); + +-- Add missing equipment +DELETE FROM `creature_equip_template` WHERE `entry` IN (30245,31750,30249,31751); +INSERT INTO `creature_equip_template` (`entry`,`id`,`itemEntry1`,`itemEntry2`,`itemEntry3`) VALUES +(30245,1,30714,0,0), -- Nexus Lord +(31750,1,30714,0,0), -- Nexus Lord (Difficulty) +(30249,1,29107,0,0), -- Scion of Eternity +(31751,1,29107,0,0); -- Scion of Eternity (Difficulty) + +-- Update accessories of hover disks to die with the vehicle and have lower despawn time. They should fall from hover disks, +-- and despawn after 5 sec, but for some reason they keep staying standing while dead. This needs to be fixed coreside. +UPDATE `vehicle_template_accessory` SET `minion`=1,`summontype`=6,`summontimer`=1000 WHERE `entry`=30234 AND `seat_id`=0; +UPDATE `vehicle_template_accessory` SET `minion`=1,`summontype`=6,`summontimer`=1000 WHERE `entry`=30248 AND `seat_id`=0; + +-- Add flag GO not selectable for both and extra condition for Heart of Magic +UPDATE `gameobject_template` SET `flags`=16 WHERE `entry`=193967; -- Alexstrasza Gift +UPDATE `gameobject_template` SET `flags`=20 WHERE `entry`=194159; -- Heart of Magic + +-- Add some gameobject data update +UPDATE `gameobject` SET `animprogress`=255,`spawntimesecs`=300 WHERE `guid` IN (151791,193960); -- that spawn time has no influence, but having different values doesn't look correct + +-- Delete static GO spawns of Alexstrasza's Gift Boxes, they are dynamic (10/25) +DELETE FROM `gameobject` WHERE `guid` IN (151792,151793); + +-- Add map difficulty checks for achievement "Denyin the Scion" +DELETE FROM `achievement_criteria_data` WHERE `criteria_id` IN (7573,7574) AND `type`=12; +INSERT INTO `achievement_criteria_data` (`criteria_id`,`type`,`value1`) VALUES +(7573,12,0), -- 10 mode +(7574,12,1); -- 25 mode + +-- Delete Nexus Lords SAI script, because of incapacity to handle the combat spell mechanic of Arcane Shock correctly +-- Delete Scions of Eternity SAI script, because of incapacity to handle non reactive AI when being attacked in a way it won't bug other encounter mechanics. +DELETE FROM `smart_scripts` WHERE `entryorguid` IN (30245,30249) AND `source_type`=0; + +-- Add SAI support for Alexstrasza since is only short timed event after boss mechanic ends +SET @NPC_ALEXSTRASZA := 32295; +SET @ACTIONLIST := @NPC_ALEXSTRASZA * 100; +SET @SPELL_GIFT_BEAM := 61028; + +UPDATE `creature_template` SET `AIName`='SmartAI',`ScriptName`='' WHERE `entry`=@NPC_ALEXSTRASZA; +DELETE FROM `smart_scripts` WHERE `entryorguid`=@NPC_ALEXSTRASZA AND `source_type`=0; +DELETE FROM `smart_scripts` WHERE `entryorguid`=@ACTIONLIST AND `source_type`=9; +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`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES +(@NPC_ALEXSTRASZA,0,0,0,54,0,100,0,0,0,0,0,69,1,0,0,0,0,0,8,0,0,0,788.07,1276.09,246.9,0,'Alexstrasza - On just summoned - Move to pos'), +(@NPC_ALEXSTRASZA,0,1,0,34,0,100,0,8,1,0,0,80,@ACTIONLIST,2,0,0,0,0,1,0,0,0,0,0,0,0,'Alexstrasza - On point 1 reached - Start actionlist'), +(@ACTIONLIST,9,0,0,0,0,100,0,0,0,0,0,11,@SPELL_GIFT_BEAM,0,0,0,0,0,1,0,0,0,0,0,0,0,'Alexstrasza - Action 0 - Cast Gift Beam'), +(@ACTIONLIST,9,1,0,0,0,100,0,4000,4000,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,'Alexstrasza - Action 1 - Yell 0'), +(@ACTIONLIST,9,2,0,0,0,100,0,6000,6000,0,0,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,'Alexstrasza - Action 2 - Yell 1'), +(@ACTIONLIST,9,3,0,0,0,100,0,5000,5000,0,0,1,2,0,0,0,0,0,1,0,0,0,0,0,0,0,'Alexstrasza - Action 3 - Yell 2'), +(@ACTIONLIST,9,4,0,0,0,100,0,24000,24000,0,0,1,3,0,0,0,0,0,1,0,0,0,0,0,0,0,'Alexstrasza - Action 4 - Yell 3'); + +-- Add areatrigger script for the improvised platform that is killing/rooting falling players +DELETE FROM `areatrigger_scripts` WHERE `entry`=5342; +INSERT INTO `areatrigger_scripts` (`entry`,`ScriptName`) VALUES +(5342, 'at_eye_of_eternity_improvised_floor'); + +-- /////////////// Various misc in creature, creature template and creature addon /////////////// +-- Update some guids spawn positions +UPDATE `creature` SET `position_x`=754.362,`position_y`=1301.61,`position_z`=266.171,`orientation`=4.24115 WHERE `guid`=132302; -- Alexstrasza the Life-Binder (Bunny) +UPDATE `creature` SET `position_x`=747.61,`position_y`=1393.43,`position_z`=295.9722,`orientation`=3.03832 WHERE `guid`=132313; -- Malygos + +-- Update some creature guids to be have static MovementType and spawn dist to 0 accordingly +UPDATE `creature` SET `spawndist`=0,`MovementType`=0 WHERE `guid` IN +(132313, -- Malygos +132314, -- Alexstrasza''s Gift Bunny +132302); -- Alexstrasza the Life-Binder (Bunny) + +-- Update template to InhabitType "Air" for various creatures +UPDATE `creature_template` SET `InhabitType`=4 WHERE `entry` IN (28859,31734,30245,31750,30249,31751,32295,32448); + +-- Clear scripts names for Alexstrasza the Life-Binder (Bunny) +UPDATE `creature_template` SET `AIName`='',`ScriptName`='' WHERE `entry`=31253; + +-- Update Portal (Malygos) initial flags before the encounter starts +UPDATE `creature_template` SET `unit_flags`=`unit_flags`|0x00000100|0x02000000,`flags_extra`=128 WHERE `entry`=30118; -- Immunity to Players + Not selectable + +-- Update flags extra to trigger & civilian for Static Field and add script name +UPDATE `creature_template` SET `AIName`='',`ScriptName`='npc_static_field',`flags_extra`=130 WHERE `entry`=30592; + +-- Update flags extra to extra trigger & extra civilian for Alexstrasza Bunny +UPDATE `creature_template` SET `flags_extra`=130, `ScriptName`='' WHERE `entry`=31253; + +-- Remove uneeded creature_addon data +DELETE FROM `creature_addon` WHERE `guid` IN +(30592, -- The spawn for Static Field is dynamique, so not fixed guid. +132313); -- Malygos is boss so is unique and needs only the template addon. + +-- Update templates for both types of hover disks +UPDATE `creature_template` SET `faction_A`=14,`faction_H`=14,`VehicleId`=223,`InhabitType`=4 WHERE `entry` IN (30248,31749); -- Hover disk for Scions +UPDATE `creature_template` SET `ScriptName`='npc_caster_hover_disk' WHERE `entry`=30248; +UPDATE `creature_template` SET `faction_A`=14,`faction_H`=14,`InhabitType`=4 WHERE `entry` IN (30234,31748); -- Hover disk for Nexus Lords +UPDATE `creature_template` SET `ScriptName`='npc_melee_hover_disk' WHERE `entry`=30234; +UPDATE `creature_template` SET `AIName`='',`ScriptName`='npc_nexus_lord' WHERE `entry`=30245; -- Nexus Lord +UPDATE `creature_template` SET `AIName`='',`ScriptName`='npc_scion_of_eternity' WHERE `entry`=30249; -- Scion of Eternity + +-- Fix model display for Vortex Triggers (in creature handling). +-- Remove extra trigger flag because for some reason it was bugging model displaying as always visible, +-- since it has the invisible one for triggers first and other as second, this is the only nonhacky way (don't try to change it unless core side != c++ hack in instance script) +UPDATE `creature_template` SET `flags_extra`=flags_extra &~ 0x00000080 WHERE `entry`=30090; +UPDATE `creature` SET `modelid`=11686 WHERE `guid` BETWEEN 132304 AND 132308; diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 1795c46b342..059e552d95e 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -3609,6 +3609,30 @@ void SpellMgr::LoadDbcDataCorrections() break; // ENDOF RUBY SANCTUM SPELLS // + // EYE OF ETERNITY SPELLS + // All spells below work even without these changes. The LOS attribute is due to problem + // from collision between maps & gos with active destroyed state. + case 57473: // Arcane Storm bonus explicit visual spell + case 57430: // Summon Static Field + case 56091: // Flame Spike (Wyrmrest Skytalon) + case 56092: // Engulf in Flames (Wyrmrest Skytalon) + case 57090: // Revivify (Wyrmrest Skytalon) + case 57143: // Life Burst (Wyrmrest Skytalon) + spellInfo->AttributesEx2 |= SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS; + break; + // ENDOF EYE OF ETERNITY SPELLS + // + // OCULUS SPELLS + // The spells below are here because their effect 1 is giving warning due to + // triggered spell not found in any dbc and is missing from encounter source* of data. + // Even judged as clientside these spells can't be guessed for* now. + case 49462: // Call Ruby Drake + case 49461: // Call Amber Drake + case 49345: // Call Emerald Drake + spellInfo->Effect[1] = 0; + break; + // ENDOF OCULUS SPELLS + // case 40055: // Introspection case 40165: // Introspection case 40166: // Introspection @@ -3622,13 +3646,6 @@ void SpellMgr::LoadDbcDataCorrections() spellInfo->manaCost = 0; spellInfo->manaPerSecond = 0; break; - // OCULUS SPELLS - // The spells below are here, because their effect 1 is giving warning, because the triggered spell is not found in dbc and is missing from encounter sniff. - case 49462: // Call Ruby Drake - case 49461: // Call Amber Drake - case 49345: // Call Emerald Drake - spellInfo->Effect[1] = 0; - break; case 24314: // Threatening Gaze spellInfo->AuraInterruptFlags |= AURA_INTERRUPT_FLAG_CAST | AURA_INTERRUPT_FLAG_MOVE | AURA_INTERRUPT_FLAG_JUMP; default: diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp index b0a34047c0e..658fa48fd3a 100644 --- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp +++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp @@ -16,143 +16,208 @@ */ /* Script Data Start -SDName: Boss malygos +SDName: Boss Malygos Script Data End */ -// TO-DOs: -// Implement a better pathing for Malygos. -// Find sniffed spawn position for chest -// Implement a better way to disappear the gameobjects -// Implement achievements -// Remove hack that re-adds targets to the aggro list after they enter to a vehicle when it works as expected -// Improve whatever can be improved :) +/* Check TO DOs in the script, but here is one essential hack to be removed only if core changes are made: + At Wyrmrest Skytalon script I make it kill player if the drake dies, because at 100.0f z yards the map is + supposed to handle the air as ground or something to which you will fall and die. However, currently maps/movements + stop flying below it, however they don't stop movementflag FALLING. Which leads to % player falling at - 1200000.0 z, + Which leads due to some desynch to not being able to press "release spirit". + Also the teleport using while on vehicle is lacking support, but soon will have. + You can still click afer leaving vehicle. */ #include "ScriptMgr.h" #include "ScriptedCreature.h" #include "SpellScript.h" #include "SpellAuraEffects.h" -#include "PassiveAI.h" #include "eye_of_eternity.h" -#include "ScriptedEscortAI.h" #include "Player.h" #include "Vehicle.h" #include "CombatAI.h" +#include "GameObjectAI.h" #include "CreatureTextMgr.h" - -enum Achievements -{ - ACHIEV_TIMED_START_EVENT = 20387, -}; +#include "MoveSplineInit.h" enum Events { - // =========== PHASE ONE =============== - EVENT_ARCANE_BREATH = 1, - EVENT_ARCANE_STORM = 2, - EVENT_VORTEX = 3, - EVENT_POWER_SPARKS = 4, + // =========== INTRO BEFORE WE START ENCOUNTER =============== + EVENT_STOP_PORTAL_BEAM = 1, + EVENT_RANDOM_PORTAL = 2, + EVENT_SAY_INTRO = 3, + EVENT_LAND_START_ENCOUNTER = 4, - // =========== PHASE TWO =============== - EVENT_SURGE_POWER = 5, // wowhead is wrong, Surge of Power is casted instead of Arcane Pulse (source sniffs!) - EVENT_SUMMON_ARCANE = 6, + // =========== PHASE ONE =============== + EVENT_ARCANE_BREATH = 5, + EVENT_ARCANE_STORM = 6, + EVENT_VORTEX = 7, + EVENT_POWER_SPARKS = 8, // =========== PHASE TWO =============== - EVENT_SURGE_POWER_PHASE_3 = 7, - EVENT_STATIC_FIELD = 8, - - // =============== YELLS =============== - EVENT_YELL_0 = 9, - EVENT_YELL_1 = 10, - EVENT_YELL_2 = 11, - EVENT_YELL_3 = 12, - EVENT_YELL_4 = 13, + EVENT_FLY_OUT_OF_PLATFORM = 9, + EVENT_DELAYED_REINFORCEMENTS = 10, + EVENT_PATHING_AROUND_PLATFORM = 11, + EVENT_SURGE_OF_POWER_P_TWO = 12, + EVENT_SUMMON_ARCANE_BOMB = 13, + EVENT_MOVE_TO_POINT_SURGE_P_TWO = 14, + EVENT_LIGHT_DIMENSION_CHANGE = 15, + EVENT_MOVE_TO_P_THREE_POINT = 16, + EVENT_START_P_THREE = 17, + + // =========== PHASE THREE ============= + EVENT_ARCANE_PULSE = 18, + EVENT_SURGE_OF_POWER_P_THREE = 19, + EVENT_STATIC_FIELD = 20, + + // ========== MISC MECHANICS =========== + EVENT_PREVENT_SAY_SPAM_ON_KILL = 21, + EVENT_MOVE_TO_VORTEX_POINT = 22, // This should be fixed someday in core, we can't call new movement from MovementInform + EVENT_START_FIRST_RANDOM_PORTAL = 23, // There is something that is still loading when we first enter instance and it breaks + // first visual cast of intro portal beam mechanic, so we need short delay from the event. + // ============ NEXUS LORDS ============ + EVENT_ARCANE_SHOCK = 1, + EVENT_HASTE_BUFF = 2, + EVENT_NUKE_DUMMY = 3, + + // ======== SCIONS OF ETERNITY ========= + EVENT_ARCANE_BARRAGE = 1 }; enum Phases { - PHASE_ONE = 1, - PHASE_TWO = 2, - PHASE_THREE = 3 + PHASE_NOT_STARTED = 1, + PHASE_ONE = 2, + PHASE_TWO = 3, + PHASE_THREE = 4 }; enum Spells { - SPELL_ARCANE_BREATH = 56272, - SPELL_ARCANE_STORM = 57459, - SPELL_BERSEKER = 60670, - - SPELL_VORTEX_1 = 56237, // seems that frezze object animation - SPELL_VORTEX_2 = 55873, // visual effect - SPELL_VORTEX_3 = 56105, // this spell must handle all the script - casted by the boss and to himself - //SPELL_VORTEX_4 = 55853, // damage | used to enter to the vehicle - defined in eye_of_eternity.h - //SPELL_VORTEX_5 = 56263, // damage | used to enter to the vehicle - defined in eye_of_eternity.h - SPELL_VORTEX_6 = 73040, // teleport - (casted to all raid) | caster 30090 | target player - - SPELL_PORTAL_VISUAL_CLOSED = 55949, - SPELL_SUMMON_POWER_PARK = 56142, - SPELL_POWER_SPARK_DEATH = 55852, - SPELL_POWER_SPARK_MALYGOS = 56152, - - SPELL_SURGE_POWER = 56505, // used in phase 2 - SPELL_SUMMON_ARCANE_BOMB = 56429, - SPELL_ARCANE_OVERLOAD = 56432, - SPELL_SUMMOM_RED_DRAGON = 56070, - SPELL_SURGE_POWER_PHASE_3 = 57407, - SPELL_STATIC_FIELD = 57430 + // Intro + SPELL_RANDOM_PORTAL = 56047, + SPELL_PORTAL_BEAM = 56046, // Malygos cast on portal to activate it during PHASE_NOT_STARTED + + //Phase I + SPELL_BERSEKER = 60670, + SPELL_MALYGOS_BERSERK = 47008, // it's the berserk spell that will hit only Malygos after 10 min of 60670 + SPELL_PORTAL_VISUAL_CLOSED = 55949, + SPELL_SUMMON_POWER_PARK = 56142, + SPELL_POWER_SPARK_DEATH = 55852, + SPELL_POWER_SPARK_MALYGOS = 56152, + SPELL_ARCANE_BREATH = 56272, + SPELL_ARCANE_STORM_P_I = 61693, + SPELL_VORTEX_1 = 56237, // seems that frezze object animation + SPELL_VORTEX_2 = 55873, // visual effect + SPELL_VORTEX_3 = 56105, // this spell must handle all the script - casted by the boss and to himself + SPELL_VORTEX_6 = 73040, // teleport - (casted to all raid), caster vortex bunnies, targets players. + + // Phase II + SPELL_TELEPORT_VISUAL_ONLY = 41232, // Light blue animation cast by arcane NPCs when spawned on Hover Disks + SPELL_RIDE_HOVER_DISK = 61421, + SPELL_ALIGN_DISK_AGGRO = 61210, + SPELL_DUMMY_NUKE = 61215, + SPELL_SUMMON_ARCANE_BOMB = 56429, + SPELL_ARCANE_BOMB_TRIGGER = 56430, + SPELL_ARCANE_BOMB_KNOCKBACK_DAMAGE = 56431, + SPELL_ARCANE_OVERLOAD_1 = 56432, // casted by npc Arcane Overload ID: 30282 + // SPELL_ARCANE_OVERLOAD_2 = 56435, // Triggered by 56432 + // SPELL_ARCANE_OVERLOAD_3 = 56438, // Triggered by 56432 + SPELL_SURGE_OF_POWER_P_II = 56505, + // SPELL_SURGE_OF_POWER_TRIGGERED = 56548, + SPELL_ARCANE_SHOCK = 57058, // used by Nexus Lords + SPELL_HASTE = 57060, // used by Nexus Lords + SPELL_ARCANE_BARRAGE = 56397, // used by Scions of Eternity + + // Transition /II-III/ + SPELL_SUMMOM_RED_DRAGON_BUDYY = 56070, + SPELL_RIDE_RED_DRAGON_BUDDY = 56071, + SPELL_SUMMON_RED_DRAGON_BUDDY_F_CAST = 58846, // After implicitly hit player targets they will force cast 56070 on self + SPELL_DESTROY_PLATFORM_CHANNEL = 58842, + SPELL_DESTROY_PLATFORM_BOOM_VISUAL = 59084, + SPELL_DESTROY_PLATFORM_EVENT = 59099, + + // Phase III + SPELL_CLEAR_ALL_DEBUFFS = 34098, + SPELL_IMMUNE_CURSES = 64515, + SPELL_STATIC_FIELD_MISSLE = 57430, + SPELL_ARCANE_PULSE = 57432, + SPELL_SURGE_OF_POWER_PHASE_3_10 = 57407, + SPELL_SURGE_OF_POWER_PHASE_3_25 = 60936, + SPELL_SURGE_OF_POWER_WARNING_SELECTOR_25 = 60939, // used in 25 player mode for selecting targets for warnings and then sends to actual spell + SPELL_ARCANE_STORM_P_III = 57459, + + // Phase I and III + SPELL_ARCANE_STORM_EXTRA_VISUAL = 57473, + + // Outro + SPELL_ALEXSTRASZAS_GIFT_BEAM_VISUAL = 61023 }; enum Movements { - MOVE_VORTEX = 1, - MOVE_PHASE_TWO, - MOVE_DEEP_BREATH_ROTATION, - MOVE_INIT_PHASE_ONE, - MOVE_CENTER_PLATFORM + POINT_NEAR_RANDOM_PORTAL_P_NONE = 1, + POINT_LAND_P_ONE, + POINT_VORTEX_P_ONE, + POINT_LAND_AFTER_VORTEX_P_ONE, + POINT_LIFT_IN_AIR_P_ONE, + POINT_PHASE_ONE_TO_TWO_TRANSITION, + POINT_FLY_OUT_OF_PLATFORM_P_TWO, + POINT_SURGE_OF_POWER_P_TWO, + POINT_DESTROY_PLATFORM_P_TWO, + POINT_IDLE_P_THREE, }; enum Seats { - SEAT_0 = 0, + SEAT_0 = 0 }; enum Factions { - FACTION_FRIENDLY = 35, - FACTION_HOSTILE = 14 + // Needed for melee hover disks /when Nexus Lords die/ + FACTION_FRIENDLY = 35 }; enum Actions { - ACTION_HOVER_DISK_START_WP_1, - ACTION_HOVER_DISK_START_WP_2 -}; - -enum MalygosEvents -{ - DATA_SUMMON_DEATHS, // phase 2 - DATA_PHASE + // Malygos + ACTION_LAND_ENCOUNTER_START = 0, + ACTION_EXECUTE_VORTEX = 1, + ACTION_HANDLE_P_THREE_INTRO = 2, + ACTION_LIFT_IN_AIR = 3, + ACTION_HANDLE_RESPAWN = 4, + ACTION_CYCLIC_MOVEMENT = 5, + + // Caster hover disk despawn action + ACTION_DELAYED_DESPAWN = 8, + + // Nexus Lord's action used to shedule casting spell that determine disk's target to chase + ACTION_SET_DISK_VICTIM_CHASE = 0 }; -#define TEN_MINUTES 600000 - enum Texts { // Malygos - SAY_AGGRO_P_ONE = 0, - SAY_KILLED_PLAYER_P_ONE = 1, - SAY_END_P_ONE = 2, - SAY_AGGRO_P_TWO = 3, - SAY_ANTI_MAGIC_SHELL = 4, // not sure when execute it - SAY_MAGIC_BLAST = 5, // not sure when execute it - SAY_KILLED_PLAYER_P_TWO = 6, - SAY_END_P_TWO = 7, - SAY_INTRO_P_THREE = 8, - SAY_AGGRO_P_THREE = 9, - SAY_SURGE_POWER = 10, // not sure when execute it - SAY_BUFF_SPARK = 11, - SAY_KILLED_PLAYER_P_THREE = 12, - SAY_SPELL_CASTING_P_THREE = 13, - SAY_DEATH, + SAY_INTRO_EVENT = 0, + SAY_START_P_ONE = 1, + SAY_DEEP_BREATH = 2, + SAY_KILLED_PLAYER_P_ONE = 3, + SAY_END_P_ONE = 4, + // SAY_START_P_TWO = 5, // Unused by Blizzard for some reason on any version + SAY_ANTI_MAGIC_SHELL = 6, + SAY_MAGIC_BLAST = 7, + SAY_KILLED_PLAYER_P_TWO = 8, + SAY_END_P_TWO = 9, + SAY_START_P_THREE = 10, + // SAY_START_P_THREE = 11, // Unused by Blizzard for some reason on any version + EMOTE_SURGE_OF_POWER_WARNING_P2 = 12, + SAY_SURGE_OF_POWER = 13, + SAY_BUFF_SPARK = 14, + SAY_KILLED_PLAYER_P_THREE = 15, + SAY_SPELL_CASTING_P_THREE = 16, + SAY_DEATH = 17, + EMOTE_SURGE_OF_POWER_WARNING_P3 = 18, + EMOTE_HIT_BERSERKER_TIMER = 19, // Alexstrasza SAY_ONE = 0, @@ -161,252 +226,438 @@ enum Texts SAY_FOUR = 3, // Power Sparks - EMOTE_POWER_SPARK_SUMMONED = 0 + EMOTE_POWER_SPARK_SUMMONED = 0 +}; + +#define MAX_SUMMONS_PHASE_TWO_10MAN 6 +#define MAX_SUMMONS_PHASE_TWO_25MAN 12 + +#define MAX_RANGE_HOVER_DISK_SPAWNPOINTS 8 +Position const RangeHoverDisksSpawnPositions[MAX_RANGE_HOVER_DISK_SPAWNPOINTS] = +{ + { 782.9821f, 1296.652f, 282.1114f, 0.0f }, + { 764.3126f, 1328.871f, 282.3091f, 0.0f }, + { 725.8506f, 1306.749f, 282.2698f, 0.0f }, + { 744.5175f, 1274.396f, 282.3402f, 0.0f }, + { 764.3936f, 1274.371f, 282.6011f, 0.0f }, + { 779.3761f, 1316.166f, 282.1653f, 0.0f }, + { 744.4915f, 1328.901f, 282.2112f, 0.0f }, + { 729.2364f, 1287.328f, 282.4173f, 0.0f } }; +#define MAX_MELEE_HOVER_DISK_SPAWNPOINTS 4 +Position const MeleeHoverDisksSpawnPositions[MAX_RANGE_HOVER_DISK_SPAWNPOINTS] = +{ + { 754.4617f, 1283.859f, 285.0522f, 0.0f }, + { 771.7864f, 1301.853f, 285.0522f, 0.0f }, + { 753.9635f, 1319.003f, 285.0522f, 0.0f }, + { 736.4914f, 1301.683f, 285.0522f, 0.0f } +}; -#define MAX_HOVER_DISK_WAYPOINTS 18 +#define MAX_MELEE_HOVER_DISK_WAYPOINTS 16 +Position const MeleeHoverDisksWaypoints[MAX_MELEE_HOVER_DISK_WAYPOINTS] = +{ + // First melee hover disk wps + { 766.2931f, 1312.904f, 277.0551f, 0.0f }, + { 754.3397f, 1319.759f, 274.0536f, 0.0f }, + { 742.1018f, 1312.714f, 270.1367f, 0.0f }, + { 735.6851f, 1301.422f, 266.7208f, 0.0f }, + // Second melee hover disk wps + { 742.6257f, 1313.471f, 275.9713f, 0.0f }, + { 736.8845f, 1301.921f, 274.0264f, 0.0f }, + { 742.6632f, 1289.951f, 269.8603f, 0.0f }, + { 754.3682f, 1283.942f, 266.6098f, 0.0f }, + // Third melee hover disk wps + { 742.2078f, 1290.518f, 276.2484f, 0.0f }, + { 754.5398f, 1284.311f, 273.5815f, 0.0f }, + { 766.5588f, 1290.345f, 269.6655f, 0.0f }, + { 773.4768f, 1301.474f, 266.5821f, 0.0f }, + // Forth melee hover disk wps + { 766.1189f, 1290.197f, 276.9436f, 0.0f }, + { 771.9507f, 1301.602f, 273.9712f, 0.0f }, + { 766.1253f, 1313.451f, 270.4991f, 0.0f }, + { 754.5378f, 1319.399f, 266.6653f, 0.0f } +}; -// Sniffed data (x, y, z) -const Position HoverDiskWaypoints[MAX_HOVER_DISK_WAYPOINTS] = +#define MAX_MALYGOS_POS 10 +Position const MalygosPositions[MAX_MALYGOS_POS] = { - {782.9821f, 1296.652f, 282.1114f, 0.0f}, - {779.5459f, 1287.228f, 282.1393f, 0.0f}, - {773.0028f, 1279.52f, 282.4164f, 0.0f}, - {764.3626f, 1274.476f, 282.4731f, 0.0f}, - {754.3961f, 1272.639f, 282.4171f, 0.0f}, - {744.4422f, 1274.412f, 282.222f, 0.0f}, - {735.575f, 1279.742f, 281.9674f, 0.0f}, - {729.2788f, 1287.187f, 281.9943f, 0.0f}, - {726.1191f, 1296.688f, 282.2997f, 0.0f}, - {725.9396f, 1306.531f, 282.2448f, 0.0f}, - {729.3045f, 1316.122f, 281.9108f, 0.0f}, - {735.8322f, 1323.633f, 282.1887f, 0.0f}, - {744.4616f, 1328.999f, 281.9948f, 0.0f}, - {754.4739f, 1330.666f, 282.049f, 0.0f}, - {764.074f, 1329.053f, 281.9949f, 0.0f}, - {772.8409f, 1323.951f, 282.077f, 0.0f}, - {779.5085f, 1316.412f, 281.9145f, 0.0f}, - {782.8365f, 1306.778f, 282.3035f, 0.0f}, + { 754.544f, 1301.71f, 320.01f, 0.0f }, // Point destroy platform + { 754.393f, 1301.27f, 292.91f, 0.0f }, // Point vortex + { 754.362f, 1301.61f, 266.17f, 0.0f }, // Land after vortex + { 754.695f, 1301.66f, 316.65f, 0.0f }, // Point surge of Power phase II + { 755.681f, 1298.41f, 220.06f, 0.0f } // Point idle phase III }; -#define GROUND_Z 268 +Position const AlexstraszaSpawnPos = { 854.551f, 1225.31f, 300.901f, 0.0f }; // Alexstrasza's spawn position +Position const HeartOfMagicSpawnPos = { 755.351f, 1298.31f, 223.909f, 0.0f }; // Heart of Magic spawn position + +#define TEN_MINUTES (10*MINUTE*IN_MILLISECONDS) + +enum Achievements +{ + ACHIEV_TIMED_START_EVENT = 20387 +}; -// Source: Sniffs (x, y, z) -#define MALYGOS_MAX_WAYPOINTS 16 -const Position MalygosPhaseTwoWaypoints[MALYGOS_MAX_WAYPOINTS] = +enum AreaIds { - {812.7299f, 1391.672f, 283.2763f, 0.0f}, - {848.2912f, 1358.61f, 283.2763f, 0.0f}, - {853.9227f, 1307.911f, 283.2763f, 0.0f}, - {847.1437f, 1265.538f, 283.2763f, 0.0f}, - {839.9229f, 1245.245f, 283.2763f, 0.0f}, - {827.3463f, 1221.818f, 283.2763f, 0.0f}, - {803.2727f, 1203.851f, 283.2763f, 0.0f}, - {772.9372f, 1197.981f, 283.2763f, 0.0f}, - {732.1138f, 1200.647f, 283.2763f, 0.0f}, - {693.8761f, 1217.995f, 283.2763f, 0.0f}, - {664.5038f, 1256.539f, 283.2763f, 0.0f}, - {650.1497f, 1303.485f, 283.2763f, 0.0f}, - {662.9109f, 1350.291f, 283.2763f, 0.0f}, - {677.6391f, 1377.607f, 283.2763f, 0.0f}, - {704.8198f, 1401.162f, 283.2763f, 0.0f}, - {755.2642f, 1417.1f, 283.2763f, 0.0f}, + AREA_EYE_OF_ETERNITY = 4500 }; -#define MAX_SUMMONS_PHASE_TWO 4 +enum MiscData +{ + // Lights + LIGHT_GET_DEFAULT_FOR_MAP = 0, + LIGHT_OBSCURE_SPACE = 1822, + LIGHT_CHANGE_DIMENSIONS = 1823, + LIGHT_ARCANE_RUNES = 1824, + LIGHT_OBSCURE_ARCANE_RUNES = 1825, + + // Data (setters/getters) + DATA_SUMMON_DEATHS = 0, // phase 2 + DATA_PHASE = 1, + + // Target guids + DATA_LAST_OVERLOAD_GUID = 13, // used to store last Arcane Overload guid + DATA_FIRST_SURGE_TARGET_GUID = 14, + DATA_SECOND_SURGE_TARGET_GUID = 15, + DATA_THIRD_SURGE_TARGET_GUID = 16 +}; -#define MAX_MALYGOS_POS 2 -const Position MalygosPositions[MAX_MALYGOS_POS] = +// Used to check if summons guids come from vehicles +class VehicleCheckPredicate { - {754.544f, 1301.71f, 320.0f, 0.0f}, - {754.39f, 1301.27f, 292.91f, 0.0f}, + public: + bool operator()(uint64 guid) { return IS_VEHICLE_GUID(guid); } }; class boss_malygos : public CreatureScript { public: - boss_malygos() : CreatureScript("boss_malygos") {} - - CreatureAI* GetAI(Creature* creature) const - { - return new boss_malygosAI(creature); - } + boss_malygos() : CreatureScript("boss_malygos") { } struct boss_malygosAI : public BossAI { boss_malygosAI(Creature* creature) : BossAI(creature, DATA_MALYGOS_EVENT) { - // If we enter in combat when MovePoint generator is active, it overrwrites our homeposition - _homePosition = creature->GetHomePosition(); + _despawned = false; // We determine if Malygos will be realocated to spawning position on reset triggered by boss despawn on evade + _flySpeed = me->GetSpeed(MOVE_FLIGHT); // Get initial fly speed, otherwise on each wipe fly speed would add up if we get it } void Reset() { - _Reset(); - - _bersekerTimer = 0; - _currentPos = 0; - - SetPhase(PHASE_ONE, true); - - _delayedMovementTimer = 8000; - _delayedMovement = false; + // EnterEvadeMode and Reset() links are cut for the sake of properly functioning despawner. + if (!_despawned) + _Reset(); _summonDeaths = 0; + _preparingPulsesChecker = 0; + _arcaneOverloadGUID = NULL; + _firstSelectedSurgeTargetGUID = NULL; + _secondSelectedSurgeTargetGUID = NULL; + _thirdSelectedSurgeTargetGUID = NULL; + + _killSpamFilter = false; + _canAttack = false; + _executingVortex = false; + _arcaneReinforcements = true; + _flyingOutOfPlatform = false; + _firstCyclicMovementStarted = false; + _performingSurgeOfPower = false; + _performingDestroyPlatform = false; + me->SetDisableGravity(true); + me->SetByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_HOVER); + // TO DO: find what in core is making boss slower than in retail (when correct speed data) or find missing movement flag update or forced spline change + me->SetSpeed(MOVE_FLIGHT, _flySpeed * 0.25f); + if (_despawned) + DoAction(ACTION_HANDLE_RESPAWN); + + SetPhase(PHASE_NOT_STARTED, true); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - - _cannotMove = true; - - me->SetCanFly(true); - + me->SetReactState(REACT_PASSIVE); if (instance) instance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMED_START_EVENT); } uint32 GetData(uint32 data) const { - if (data == DATA_SUMMON_DEATHS) - return _summonDeaths; - else if (data == DATA_PHASE) - return _phase; + switch (data) + { + case DATA_SUMMON_DEATHS: + return _summonDeaths; + case DATA_PHASE: + return _phase; + } return 0; } void SetData(uint32 data, uint32 value) { - if (data == DATA_SUMMON_DEATHS && _phase == PHASE_TWO) + if (data == DATA_SUMMON_DEATHS && _phase == PHASE_TWO && !_despawned) { _summonDeaths = value; - if (_summonDeaths >= MAX_SUMMONS_PHASE_TWO) - StartPhaseThree(); - } + if (GetDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL) + { + if (_summonDeaths == MAX_SUMMONS_PHASE_TWO_10MAN) + { + _performingDestroyPlatform = true; + DoAction(ACTION_HANDLE_P_THREE_INTRO); + } + } + else if (GetDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL) + { + if (_summonDeaths == MAX_SUMMONS_PHASE_TWO_25MAN) + { + _performingDestroyPlatform = true; + DoAction(ACTION_HANDLE_P_THREE_INTRO); + } + } + } } - void EnterEvadeMode() + uint64 GetGUID(int32 data) const { - me->SetHomePosition(_homePosition); + switch (data) + { + case DATA_FIRST_SURGE_TARGET_GUID: + return _firstSelectedSurgeTargetGUID; + case DATA_SECOND_SURGE_TARGET_GUID: + return _secondSelectedSurgeTargetGUID; + case DATA_THIRD_SURGE_TARGET_GUID: + return _thirdSelectedSurgeTargetGUID; + } - me->SetDisableGravity(true); + return 0; + } - BossAI::EnterEvadeMode(); + void SetGUID(uint64 guid, int32 type) + { + switch (type) + { + case DATA_LAST_OVERLOAD_GUID: + _arcaneOverloadGUID = guid; + case DATA_FIRST_SURGE_TARGET_GUID: + _firstSelectedSurgeTargetGUID = guid; + case DATA_SECOND_SURGE_TARGET_GUID: + _secondSelectedSurgeTargetGUID = guid; + case DATA_THIRD_SURGE_TARGET_GUID: + _thirdSelectedSurgeTargetGUID = guid; + } + } - if (instance) - instance->SetBossState(DATA_MALYGOS_EVENT, FAIL); + void DoAction(int32 action) + { + switch (action) + { + case ACTION_LAND_ENCOUNTER_START: + events.CancelEventGroup(1); + if (Creature* alexstraszaBunny = me->GetMap()->GetCreature(instance->GetData64(DATA_ALEXSTRASZA_BUNNY_GUID))) + { + Position pos; + pos.m_positionZ = alexstraszaBunny->GetPositionZ(); + alexstraszaBunny->GetNearPoint2D(pos.m_positionX, pos.m_positionY, 30.0f, alexstraszaBunny->GetAngle(me)); + me->GetMotionMaster()->MoveLand(POINT_LAND_P_ONE, pos); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + me->SetReactState(REACT_AGGRESSIVE); + me->SetInCombatWithZone(); + events.ScheduleEvent(EVENT_LAND_START_ENCOUNTER, 7*IN_MILLISECONDS, 1, PHASE_NOT_STARTED); + } + break; + case ACTION_EXECUTE_VORTEX: + DoCast(me, SPELL_VORTEX_1, true); + DoCast(me, SPELL_VORTEX_2, true); + // the vortex execution continues in the dummy effect of this spell (see it's script) + DoCast(me, SPELL_VORTEX_3, true); + break; + case ACTION_LIFT_IN_AIR: + Position _zToLift; + me->GetPosition(&_zToLift); + if (_phase == PHASE_ONE) + { + _zToLift.m_positionZ += 20.0f; + me->GetMotionMaster()->MoveTakeoff(POINT_LIFT_IN_AIR_P_ONE, _zToLift); + } + else if (_phase == PHASE_TWO) + { + _zToLift.m_positionZ = 300.1f; + me->GetMotionMaster()->MoveTakeoff(POINT_PHASE_ONE_TO_TWO_TRANSITION, _zToLift); + } + break; + case ACTION_HANDLE_P_THREE_INTRO: + events.CancelEventGroup(0); + events.CancelEventGroup(1); + events.CancelEventGroup(2); + me->GetMotionMaster()->Initialize(); + me->StopMoving(); + // Vehicles shouldn't be despawned with 0 delay if the call comes from virtual function that overrides PassengerBoarded. + // Aside from that he doesn't despawn both vehicles and arcane overloads right away, but with some delay. + DummyEntryCheckPredicate pred; + summons.DoAction(ACTION_DELAYED_DESPAWN, pred); + Talk(SAY_END_P_TWO); + me->GetMotionMaster()->MovePoint(POINT_DESTROY_PLATFORM_P_TWO, MalygosPositions[0]); + events.ScheduleEvent(EVENT_LIGHT_DIMENSION_CHANGE, 1*IN_MILLISECONDS, 0, PHASE_TWO); + break; + case ACTION_HANDLE_RESPAWN: + // Teleport to spawn position, we can't use normal relocate + float x, y, z, o; + me->GetRespawnPosition(x, y, z, &o); + me->NearTeleportTo(x, y, z, o); + // Respawn Iris + instance->SetData(DATA_RESPAWN_IRIS, 0); + _despawned = false; + break; + case ACTION_CYCLIC_MOVEMENT: + Movement::MoveSplineInit init(me); + FillCirclePath(MalygosPositions[3], 130.0f, 283.2763f, init.Path(), true); + init.SetFly(); + init.SetCyclic(); + init.Launch(); + break; + } } void SetPhase(uint8 phase, bool setEvents = false) { events.Reset(); - events.SetPhase(phase); _phase = phase; - if (setEvents) SetPhaseEvents(); } - void StartPhaseThree() - { - if (!instance) - return; - - SetPhase(PHASE_THREE, true); - - // this despawns Hover Disks - summons.DespawnAll(); - // players that used Hover Disk are no in the aggro list - me->SetInCombatWithZone(); - ThreatContainer::StorageType const& m_threatlist = me->getThreatManager().getThreatList(); - for (ThreatContainer::StorageType::const_iterator itr = m_threatlist.begin(); itr!= m_threatlist.end(); ++itr) - { - if (Unit* target = (*itr)->getTarget()) - { - if (target->GetTypeId() != TYPEID_PLAYER) - continue; - - // The rest is handled in the AI of the vehicle. - target->CastSpell(target, SPELL_SUMMOM_RED_DRAGON, true); - me->Attack(target, false); - } - } - - if (GameObject* go = GameObject::GetGameObject(*me, instance->GetData64(DATA_PLATFORM))) - go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_DESTROYED); // In sniffs it has this flag, but i don't know how is applied. - - // pos sniffed - me->GetMotionMaster()->MoveIdle(); - me->GetMotionMaster()->MovePoint(MOVE_CENTER_PLATFORM, MalygosPositions[0].GetPositionX(), MalygosPositions[0].GetPositionY(), MalygosPositions[0].GetPositionZ()); - } - void SetPhaseEvents() { switch (_phase) { + case PHASE_NOT_STARTED: + events.ScheduleEvent(EVENT_SAY_INTRO, 1*IN_MILLISECONDS, 1, _phase); + events.ScheduleEvent(EVENT_START_FIRST_RANDOM_PORTAL, 2*IN_MILLISECONDS, 1, _phase); + break; case PHASE_ONE: events.ScheduleEvent(EVENT_ARCANE_BREATH, urand(15, 20)*IN_MILLISECONDS, 0, _phase); - events.ScheduleEvent(EVENT_ARCANE_STORM, urand(5, 10)*IN_MILLISECONDS, 0, _phase); + events.ScheduleEvent(EVENT_ARCANE_STORM, 10*IN_MILLISECONDS, 0, _phase); events.ScheduleEvent(EVENT_VORTEX, urand(30, 40)*IN_MILLISECONDS, 0, _phase); events.ScheduleEvent(EVENT_POWER_SPARKS, urand(30, 35)*IN_MILLISECONDS, 0, _phase); break; case PHASE_TWO: - events.ScheduleEvent(EVENT_YELL_0, 0, 0, _phase); - events.ScheduleEvent(EVENT_YELL_1, 24*IN_MILLISECONDS, 0, _phase); - events.ScheduleEvent(EVENT_SURGE_POWER, urand(60, 70)*IN_MILLISECONDS, 0, _phase); - events.ScheduleEvent(EVENT_SUMMON_ARCANE, urand(2, 5)*IN_MILLISECONDS, 0, _phase); + events.ScheduleEvent(EVENT_MOVE_TO_POINT_SURGE_P_TWO, 60*IN_MILLISECONDS, 0, _phase); + me->AI()->DoAction(ACTION_LIFT_IN_AIR); break; case PHASE_THREE: - events.ScheduleEvent(EVENT_YELL_2, 0, 0, _phase); - events.ScheduleEvent(EVENT_YELL_3, 8*IN_MILLISECONDS, 0, _phase); - events.ScheduleEvent(EVENT_YELL_4, 16*IN_MILLISECONDS, 0, _phase); - events.ScheduleEvent(EVENT_SURGE_POWER_PHASE_3, urand(7, 16)*IN_MILLISECONDS, 0, _phase); + events.ScheduleEvent(EVENT_ARCANE_PULSE, 13*IN_MILLISECONDS, 0, _phase); + events.ScheduleEvent(EVENT_ARCANE_STORM, 20*IN_MILLISECONDS, 0, _phase); + events.ScheduleEvent(EVENT_SURGE_OF_POWER_P_THREE, urand(7, 16)*IN_MILLISECONDS, 0, _phase); events.ScheduleEvent(EVENT_STATIC_FIELD, urand(20, 30)*IN_MILLISECONDS, 0, _phase); break; - default: - break; } } + // There are moments where boss will do nothing while being attacked + void AttackStart(Unit* target) + { + if (_canAttack) + BossAI::AttackStart(target); + } + void EnterCombat(Unit* /*who*/) { - _EnterCombat(); + // We can't call full function here since it includes DoZoneInCombat(), + // if someone does it will be returned with a warning. + me->setActive(true); + if (instance) + { + if (!instance->CheckRequiredBosses(DATA_MALYGOS_EVENT)) + { + EnterEvadeMode(); + return; + } + + instance->SetBossState(DATA_MALYGOS_EVENT, IN_PROGRESS); + } + + Talk(SAY_START_P_ONE); + DoCast(SPELL_BERSEKER); // periodic aura, first tick in 10 minutes + if (instance) + instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMED_START_EVENT); + } + + void EnterEvadeMode() + { + if (instance) + instance->SetBossState(DATA_MALYGOS_EVENT, FAIL); - me->SetDisableGravity(false); - me->SetCanFly(false); + SendLightOverride(LIGHT_GET_DEFAULT_FOR_MAP, 1*IN_MILLISECONDS); + + if (_phase == PHASE_THREE) + me->SetControlled(false, UNIT_STATE_ROOT); - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + uint32 corpseDelay = me->GetCorpseDelay(); + uint32 respawnDelay = me->GetRespawnDelay(); + me->SetCorpseDelay(1); + me->SetRespawnDelay(29); + me->DespawnOrUnsummon(); + me->SetCorpseDelay(corpseDelay); + me->SetRespawnDelay(respawnDelay); - Talk(SAY_AGGRO_P_ONE); + // Set speed to normal value + me->SetSpeed(MOVE_FLIGHT, _flySpeed); + me->RemoveAllAuras(); + me->CombatStop(); // Sometimes threat can remain, so it's a safety measure - DoCast(SPELL_BERSEKER); // periodic aura, first tick in 10 minutes + if (!_despawned) + _despawned = true; + me->ResetLootMode(); + events.Reset(); + if (!summons.empty()) + { + if (_phase == PHASE_TWO) + { + VehicleCheckPredicate pred; + summons.DoAction(ACTION_DELAYED_DESPAWN, pred); + summons.remove_if(pred); + summons.DespawnAll(); + } + else if (_phase == PHASE_THREE) + summons.DespawnAll(); + } + if (instance) - instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMED_START_EVENT); + instance->SetBossState(DATA_MALYGOS_EVENT, NOT_STARTED); } - void KilledUnit(Unit* who) + void KilledUnit(Unit* victim) { - if (who->GetTypeId() != TYPEID_PLAYER) + if (victim->GetTypeId() != TYPEID_PLAYER) return; - - switch (_phase) + + if (!_killSpamFilter) { - case PHASE_ONE: - Talk(SAY_KILLED_PLAYER_P_ONE); - break; - case PHASE_TWO: - Talk(SAY_KILLED_PLAYER_P_TWO); - break; - case PHASE_THREE: - Talk(SAY_KILLED_PLAYER_P_THREE); - break; + switch (_phase) + { + case PHASE_ONE: + Talk(SAY_KILLED_PLAYER_P_ONE); + events.ScheduleEvent(EVENT_PREVENT_SAY_SPAM_ON_KILL, 5*IN_MILLISECONDS, 0, _phase); + _killSpamFilter = true; + break; + case PHASE_TWO: + Talk(SAY_KILLED_PLAYER_P_TWO); + events.ScheduleEvent(EVENT_PREVENT_SAY_SPAM_ON_KILL, 5*IN_MILLISECONDS, 0, _phase); + _killSpamFilter = true; + break; + case PHASE_THREE: + Talk(SAY_KILLED_PLAYER_P_THREE); + events.ScheduleEvent(EVENT_PREVENT_SAY_SPAM_ON_KILL, 5*IN_MILLISECONDS, 0, _phase); + _killSpamFilter = true; + break; + } } } - void SpellHit(Unit* caster, const SpellInfo* spell) + void SpellHit(Unit* caster, SpellInfo const* spell) { if (spell->Id == SPELL_POWER_SPARK_MALYGOS) { @@ -415,346 +666,415 @@ public: Talk(SAY_BUFF_SPARK); } + else if (spell->Id == SPELL_MALYGOS_BERSERK) + sCreatureTextMgr->SendChat(me, EMOTE_HIT_BERSERKER_TIMER, 0, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_MAP); } void MoveInLineOfSight(Unit* who) { - if (!me->isInCombat()) + if (!me->isInCombat() || _phase != PHASE_ONE) return; if (who->GetEntry() == NPC_POWER_SPARK) - { - // not sure about the distance | I think it is better check this here than in the UpdateAI function... if (who->GetDistance(me) <= 2.5f) who->CastSpell(me, SPELL_POWER_SPARK_MALYGOS, true); - } - } - - void PrepareForVortex() - { - me->SetDisableGravity(true); - me->SetCanFly(true); - - me->GetMotionMaster()->MovementExpired(); - me->GetMotionMaster()->MovePoint(MOVE_VORTEX, MalygosPositions[1].GetPositionX(), MalygosPositions[1].GetPositionY(), MalygosPositions[1].GetPositionZ()); - // continues in MovementInform function. - } - - void ExecuteVortex() - { - DoCast(me, SPELL_VORTEX_1, true); - DoCast(me, SPELL_VORTEX_2, true); - - // the vortex execution continues in the dummy effect of this spell (see its script) - DoCast(me, SPELL_VORTEX_3, true); } - + void MovementInform(uint32 type, uint32 id) { - if (type != POINT_MOTION_TYPE) + if (type != POINT_MOTION_TYPE && type != EFFECT_MOTION_TYPE) return; switch (id) { - case MOVE_VORTEX: + case POINT_NEAR_RANDOM_PORTAL_P_NONE: + if (Creature* portal = me->FindNearestCreature(NPC_PORTAL_TRIGGER, 31.0f, true)) + { + events.ScheduleEvent(EVENT_STOP_PORTAL_BEAM, 10*IN_MILLISECONDS, 1, PHASE_NOT_STARTED); + events.ScheduleEvent(EVENT_RANDOM_PORTAL, 14*IN_MILLISECONDS, 1, PHASE_NOT_STARTED); + DoCast(portal, SPELL_PORTAL_BEAM); + } + break; + case POINT_LAND_P_ONE: + me->SetDisableGravity(false); + break; + case POINT_VORTEX_P_ONE: me->GetMotionMaster()->MoveIdle(); - ExecuteVortex(); + DoAction(ACTION_EXECUTE_VORTEX); break; - case MOVE_DEEP_BREATH_ROTATION: - _currentPos = _currentPos == MALYGOS_MAX_WAYPOINTS - 1 ? 0 : _currentPos+1; - me->GetMotionMaster()->MovementExpired(); - me->GetMotionMaster()->MovePoint(MOVE_DEEP_BREATH_ROTATION, MalygosPhaseTwoWaypoints[_currentPos]); + case POINT_LAND_AFTER_VORTEX_P_ONE: + me->SetDisableGravity(false); + _executingVortex = false; + _canAttack = true; break; - case MOVE_INIT_PHASE_ONE: - me->SetInCombatWithZone(); + case POINT_LIFT_IN_AIR_P_ONE: + me->SetDisableGravity(true); + events.ScheduleEvent(EVENT_MOVE_TO_VORTEX_POINT, 1, 0, PHASE_ONE); break; - case MOVE_CENTER_PLATFORM: - // Malygos is already flying here, there is no need to set it again. - _cannotMove = false; - // malygos will move into center of platform and then he does not chase dragons, he just turns to his current target. - me->GetMotionMaster()->MoveIdle(); + case POINT_FLY_OUT_OF_PLATFORM_P_TWO: + if (!_firstCyclicMovementStarted) + { + _firstCyclicMovementStarted = true; + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + me->SetFacingToObject(me->GetMap()->GetCreature(instance->GetData64(DATA_ALEXSTRASZA_BUNNY_GUID))); + events.ScheduleEvent(EVENT_SUMMON_ARCANE_BOMB, 1*IN_MILLISECONDS, 0, PHASE_TWO); + } + _flyingOutOfPlatform = false; + _performingSurgeOfPower = false; + events.ScheduleEvent(EVENT_PATHING_AROUND_PLATFORM, 1*IN_MILLISECONDS, 0, PHASE_TWO); + break; + case POINT_PHASE_ONE_TO_TWO_TRANSITION: + me->SetDisableGravity(true); + me->SetFacingToObject(me->GetMap()->GetCreature(instance->GetData64(DATA_ALEXSTRASZA_BUNNY_GUID))); + SendLightOverride(LIGHT_ARCANE_RUNES, 5*IN_MILLISECONDS); + events.ScheduleEvent(EVENT_FLY_OUT_OF_PLATFORM, 18*IN_MILLISECONDS, 0, PHASE_TWO); + break; + case POINT_SURGE_OF_POWER_P_TWO: + if (!_performingDestroyPlatform) + { + Talk(EMOTE_SURGE_OF_POWER_WARNING_P2); + DoCastAOE(SPELL_SURGE_OF_POWER_P_II, true); + events.ScheduleEvent(EVENT_FLY_OUT_OF_PLATFORM, 7*IN_MILLISECONDS, 0, PHASE_TWO); + } + break; + case POINT_DESTROY_PLATFORM_P_TWO: + SendLightOverride(LIGHT_OBSCURE_SPACE, 1*IN_MILLISECONDS); + DoCast(me, SPELL_DESTROY_PLATFORM_CHANNEL); + events.ScheduleEvent(EVENT_MOVE_TO_P_THREE_POINT, 11*IN_MILLISECONDS, 0, PHASE_TWO); + break; + case POINT_IDLE_P_THREE: + me->SetControlled(true, UNIT_STATE_ROOT); + events.ScheduleEvent(EVENT_START_P_THREE, 5*IN_MILLISECONDS, 0, PHASE_TWO); break; - } - } - - void StartPhaseTwo() - { - SetPhase(PHASE_TWO, true); - - me->SetDisableGravity(true); - me->SetCanFly(true); - - me->GetMotionMaster()->MoveIdle(); - me->GetMotionMaster()->MovePoint(MOVE_DEEP_BREATH_ROTATION, MalygosPhaseTwoWaypoints[0]); - - for (uint8 i = 0; i < 2; i++) - { - // Starting position. One starts from the first waypoint and another from the last. - uint8 pos = !i ? MAX_HOVER_DISK_WAYPOINTS-1 : 0; - if (Creature* summon = me->SummonCreature(NPC_HOVER_DISK_CASTER, HoverDiskWaypoints[pos])) - if (summon->IsAIEnabled) - summon->AI()->DoAction(ACTION_HOVER_DISK_START_WP_1+i); - - // not sure about its position. - if (Creature* summon = me->SummonCreature(NPC_HOVER_DISK_MELEE, HoverDiskWaypoints[0])) - summon->SetInCombatWithZone(); } } void UpdateAI(uint32 diff) { - if (!UpdateVictim()) + if (!UpdateVictim() && _phase != PHASE_NOT_STARTED && _phase != PHASE_TWO) return; events.Update(diff); - if (_phase == PHASE_THREE) - { - if (!_cannotMove) - { - // it can change if the player falls from the vehicle. - if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() != IDLE_MOTION_TYPE) - { - me->GetMotionMaster()->MovementExpired(); - me->GetMotionMaster()->MoveIdle(); - } - } else - { - if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() != POINT_MOTION_TYPE) - { - me->GetMotionMaster()->MovementExpired(); - me->GetMotionMaster()->MovePoint(MOVE_CENTER_PLATFORM, MalygosPositions[0].GetPositionX(), MalygosPositions[0].GetPositionY(), MalygosPositions[0].GetPositionZ()); - } - } - } + // we can't cast if we are casting already unless in PHASE_NOT_STARTED channeling PORTAL_BEAM + if (me->HasUnitState(UNIT_STATE_CASTING) && _phase != PHASE_NOT_STARTED) + return; - // we need a better way for pathing - if (_delayedMovement) + // at 50% hp Malygos switchs to phase 2 and removes hovering until reset or end of encounter + if (_phase == PHASE_ONE && me->GetHealthPct() <= 50.0f) { - if (_delayedMovementTimer <= diff) - { - me->GetMotionMaster()->MovePoint(MOVE_DEEP_BREATH_ROTATION, MalygosPhaseTwoWaypoints[_currentPos]); - _delayedMovementTimer = 8000; - _delayedMovement = false; - } _delayedMovementTimer -= diff; + SetPhase(PHASE_TWO, true); + _canAttack = false; + me->AttackStop(); + Talk(SAY_END_P_ONE); } - // at 50 % health malygos switch to phase 2 - if (me->GetHealthPct() <= 50.0f && _phase == PHASE_ONE) - StartPhaseTwo(); - - // the boss is handling vortex - if (me->HasAura(SPELL_VORTEX_2)) - return; - - // We can't cast if we are casting already. - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { - case EVENT_YELL_2: - Talk(SAY_END_P_TWO); - break; - case EVENT_YELL_3: - Talk(SAY_INTRO_P_THREE); + case EVENT_START_FIRST_RANDOM_PORTAL: + me->CastCustomSpell(SPELL_RANDOM_PORTAL, SPELLVALUE_MAX_TARGETS, 1); break; - case EVENT_YELL_4: - Talk(SAY_AGGRO_P_THREE); + case EVENT_STOP_PORTAL_BEAM: + me->InterruptNonMeleeSpells(true); break; - case EVENT_YELL_0: - Talk(SAY_END_P_ONE); + case EVENT_RANDOM_PORTAL: + me->CastCustomSpell(SPELL_RANDOM_PORTAL, SPELLVALUE_MAX_TARGETS, 1); break; - case EVENT_YELL_1: - Talk(SAY_AGGRO_P_TWO); - break; - case EVENT_ARCANE_BREATH: - DoCast(me->getVictim(), SPELL_ARCANE_BREATH); - events.ScheduleEvent(EVENT_ARCANE_BREATH, urand(35, 60)*IN_MILLISECONDS, 0, PHASE_ONE); + case EVENT_LAND_START_ENCOUNTER: + if (GameObject* iris = me->GetMap()->GetGameObject(instance->GetData64(DATA_FOCUSING_IRIS_GUID))) + { + me->SetFacingToObject(iris); + iris->Delete(); // this is not the best way. + } + _canAttack = true; + SetPhase(PHASE_ONE, true); break; - case EVENT_ARCANE_STORM: - DoCast(me->getVictim(), SPELL_ARCANE_STORM); - events.ScheduleEvent(EVENT_ARCANE_STORM, urand(5, 10)*IN_MILLISECONDS, 0, PHASE_ONE); + case EVENT_SAY_INTRO: + Talk(SAY_INTRO_EVENT); + events.ScheduleEvent(EVENT_SAY_INTRO, urand(85, 95)*IN_MILLISECONDS, 1, PHASE_NOT_STARTED); break; case EVENT_VORTEX: - PrepareForVortex(); + _executingVortex = true; + DoAction(ACTION_LIFT_IN_AIR); events.ScheduleEvent(EVENT_VORTEX, urand(60, 80)*IN_MILLISECONDS, 0, PHASE_ONE); break; + case EVENT_MOVE_TO_VORTEX_POINT: + _canAttack = false; + me->AttackStop(); + me->GetMotionMaster()->MovePoint(POINT_VORTEX_P_ONE, MalygosPositions[1]); + break; case EVENT_POWER_SPARKS: instance->SetData(DATA_POWER_SPARKS_HANDLING, 0); events.ScheduleEvent(EVENT_POWER_SPARKS, urand(30, 35)*IN_MILLISECONDS, 0, PHASE_ONE); break; - case EVENT_SURGE_POWER: - me->GetMotionMaster()->MoveIdle(); - _delayedMovement = true; - DoCast(SPELL_SURGE_POWER); - events.ScheduleEvent(EVENT_SURGE_POWER, urand(60, 70)*IN_MILLISECONDS, 0, PHASE_TWO); - break; - case EVENT_SUMMON_ARCANE: - DoCast(SPELL_SUMMON_ARCANE_BOMB); - events.ScheduleEvent(EVENT_SUMMON_ARCANE, urand(12, 15)*IN_MILLISECONDS, 0, PHASE_TWO); - break; - case EVENT_SURGE_POWER_PHASE_3: - DoCast(GetTargetPhaseThree(), SPELL_SURGE_POWER_PHASE_3); - events.ScheduleEvent(EVENT_SURGE_POWER_PHASE_3, urand(7, 16)*IN_MILLISECONDS, 0, PHASE_THREE); - break; - case EVENT_STATIC_FIELD: - DoCast(GetTargetPhaseThree(), SPELL_STATIC_FIELD); - events.ScheduleEvent(EVENT_STATIC_FIELD, urand(20, 30)*IN_MILLISECONDS, 0, PHASE_THREE); + case EVENT_ARCANE_BREATH: + if (_executingVortex) + { + events.ScheduleEvent(EVENT_ARCANE_BREATH, 20*IN_MILLISECONDS, 0, PHASE_ONE); + break; + } + + me->CastSpell(me->getVictim(), SPELL_ARCANE_BREATH); + events.ScheduleEvent(EVENT_ARCANE_BREATH, 20*IN_MILLISECONDS, 0, PHASE_ONE); break; - default: + case EVENT_ARCANE_STORM: + if (_phase == PHASE_ONE) + { + if (_executingVortex) + { + events.ScheduleEvent(EVENT_ARCANE_STORM, 10*IN_MILLISECONDS, 0, PHASE_ONE); + break; + } + + DoCast(me, SPELL_ARCANE_STORM_P_I, true); + events.ScheduleEvent(EVENT_ARCANE_STORM, 10*IN_MILLISECONDS, 0, PHASE_ONE); + } + else if (_phase == PHASE_THREE) + { + DoCast(me, SPELL_ARCANE_STORM_P_III, true); + events.ScheduleEvent(EVENT_ARCANE_STORM, urand(6, 12)*IN_MILLISECONDS, 0, PHASE_THREE); + } break; - } - } + case EVENT_FLY_OUT_OF_PLATFORM: + if (Creature* alexstraszaBunny = me->GetMap()->GetCreature(instance->GetData64(DATA_ALEXSTRASZA_BUNNY_GUID))) + { + Position randomPosOnRadius; + // Hardcodded retail value, reason is Z getters can fail... (TO DO: Change to getter when height calculation works on 100%!) + randomPosOnRadius.m_positionZ = 283.0521f; + alexstraszaBunny->GetNearPoint2D(randomPosOnRadius.m_positionX, randomPosOnRadius.m_positionY, 130.0f, alexstraszaBunny->GetAngle(me)); + me->GetMotionMaster()->MovePoint(POINT_FLY_OUT_OF_PLATFORM_P_TWO, randomPosOnRadius); + _flyingOutOfPlatform = true; + } - DoMeleeAttackIfReady(); - } + if (_arcaneReinforcements && instance) + { + for (uint8 rangeDisks = 0; rangeDisks < (GetDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL ? 4 : 5); rangeDisks++) + { + Creature* casterDiskSummon = me->SummonCreature(NPC_HOVER_DISK_CASTER, RangeHoverDisksSpawnPositions[rangeDisks]); - Unit* GetTargetPhaseThree() - { - Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0); + if (casterDiskSummon->IsAIEnabled) + casterDiskSummon->AI()->DoAction(rangeDisks); + } - // we are a drake - if (target->GetVehicleKit()) - return target; + for (uint8 meleeDisks = 0; meleeDisks < 2; meleeDisks++) + { + Creature* meleeDiskSummon = me->SummonCreature(NPC_HOVER_DISK_MELEE, MeleeHoverDisksSpawnPositions[meleeDisks]); + meleeDiskSummon->GetMotionMaster()->MovePoint(meleeDisks * MAX_MELEE_HOVER_DISK_SPAWNPOINTS, MeleeHoverDisksWaypoints[meleeDisks * MAX_MELEE_HOVER_DISK_SPAWNPOINTS]); + } - // we are a player using a drake (or at least you should) - if (target->GetTypeId() == TYPEID_PLAYER) - { - if (Unit* base = target->GetVehicleBase()) - return base; - } + _arcaneReinforcements = false; - // is a player falling from a vehicle? - return NULL; - } + if (GetDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL) + events.ScheduleEvent(EVENT_DELAYED_REINFORCEMENTS, 1*IN_MILLISECONDS, 0, PHASE_TWO); + } + break; + case EVENT_DELAYED_REINFORCEMENTS: + for (uint8 rangeDisks = 5; rangeDisks < 8; rangeDisks++) + { + Creature* casterDiskSummon = me->SummonCreature(NPC_HOVER_DISK_CASTER, RangeHoverDisksSpawnPositions[rangeDisks]); - void JustDied(Unit* /*killer*/) - { - Talk(SAY_DEATH); - _JustDied(); - } + if (casterDiskSummon->IsAIEnabled) + casterDiskSummon->AI()->DoAction(rangeDisks); + } - private: - uint8 _phase; - uint32 _bersekerTimer; - uint8 _currentPos; // used for phase 2 rotation... - bool _delayedMovement; // used in phase 2. - uint32 _delayedMovementTimer; // used in phase 2 - uint8 _summonDeaths; - Position _homePosition; // it can get bugged because core thinks we are pathing - bool _mustTalk; - bool _cannotMove; - }; -}; + for (uint8 meleeDisks = 2; meleeDisks < 4; meleeDisks++) + { + Creature* meleeDiskSummon = me->SummonCreature(NPC_HOVER_DISK_MELEE, MeleeHoverDisksSpawnPositions[meleeDisks]); + meleeDiskSummon->GetMotionMaster()->MovePoint(meleeDisks * MAX_MELEE_HOVER_DISK_SPAWNPOINTS, MeleeHoverDisksWaypoints[meleeDisks * MAX_MELEE_HOVER_DISK_SPAWNPOINTS]); + } + break; + case EVENT_PATHING_AROUND_PLATFORM: + DoAction(ACTION_CYCLIC_MOVEMENT); + break; + case EVENT_MOVE_TO_POINT_SURGE_P_TWO: + if (!_performingDestroyPlatform) + { + _performingSurgeOfPower = true; + Talk(SAY_DEEP_BREATH); + me->GetMotionMaster()->MovePoint(POINT_SURGE_OF_POWER_P_TWO, MalygosPositions[3]); + events.ScheduleEvent(EVENT_MOVE_TO_POINT_SURGE_P_TWO, 60*IN_MILLISECONDS, 2, PHASE_TWO); + } + break; + case EVENT_SUMMON_ARCANE_BOMB: + if (!_performingSurgeOfPower && !_performingDestroyPlatform) + { + me->StopMoving(); + events.ScheduleEvent(EVENT_PATHING_AROUND_PLATFORM, 3*IN_MILLISECONDS, 0, PHASE_TWO); + } -class spell_malygos_vortex_dummy : public SpellScriptLoader -{ -public: - spell_malygos_vortex_dummy() : SpellScriptLoader("spell_malygos_vortex_dummy") {} - - class spell_malygos_vortex_dummy_SpellScript : public SpellScript - { - PrepareSpellScript(spell_malygos_vortex_dummy_SpellScript) - - void HandleScript(SpellEffIndex /*effIndex*/) - { - Unit* caster = GetCaster(); - - if (!caster) - return; + if (!_flyingOutOfPlatform) + { + DoCast(me, SPELL_SUMMON_ARCANE_BOMB, true); + if (Creature* lastArcaneOverloadBunny = me->GetMap()->GetCreature(_arcaneOverloadGUID)) + DoCast(lastArcaneOverloadBunny, SPELL_ARCANE_BOMB_TRIGGER, true); + } + events.ScheduleEvent(EVENT_SUMMON_ARCANE_BOMB, urand(15, 16)*IN_MILLISECONDS, 2, PHASE_TWO); + break; + case EVENT_ARCANE_PULSE: + if (_preparingPulsesChecker < 2) + { + DoCastAOE(SPELL_ARCANE_PULSE, true); + events.ScheduleEvent(EVENT_ARCANE_PULSE, 7*IN_MILLISECONDS, 0, PHASE_THREE); + _preparingPulsesChecker++; + } + else + { + DoCastAOE(SPELL_ARCANE_PULSE, true); + events.ScheduleEvent(EVENT_ARCANE_PULSE, 2*IN_MILLISECONDS, 0, PHASE_THREE); + } + break; + case EVENT_LIGHT_DIMENSION_CHANGE: + SendLightOverride(LIGHT_CHANGE_DIMENSIONS, 2*IN_MILLISECONDS); + break; + case EVENT_MOVE_TO_P_THREE_POINT: + Talk(SAY_START_P_THREE); + me->GetMotionMaster()->MovePoint(POINT_IDLE_P_THREE, MalygosPositions[4]); + break; + case EVENT_START_P_THREE: + SendLightOverride(LIGHT_OBSCURE_ARCANE_RUNES, 1*IN_MILLISECONDS); + DoCast(me, SPELL_CLEAR_ALL_DEBUFFS); + DoCast(me, SPELL_IMMUNE_CURSES); + _canAttack = true; + UpdateVictim(); + me->SetFacingToObject(me->getVictim()); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + SetPhase(PHASE_THREE, true); + break; + case EVENT_SURGE_OF_POWER_P_THREE: + if (GetDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL) + { + _tempSurgeTarget = NULL; + _drakeVehicle = NULL; + _playerSurgeTarget = NULL; + if ((_tempSurgeTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, false, SPELL_RIDE_RED_DRAGON_BUDDY))) + if ((_drakeVehicle = _tempSurgeTarget->GetVehicleKit())) + if ((_playerSurgeTarget = _drakeVehicle->GetPassenger(0)->ToPlayer())) + { + Talk(EMOTE_SURGE_OF_POWER_WARNING_P3, _playerSurgeTarget->GetGUID()); + DoCast(_tempSurgeTarget, SPELL_SURGE_OF_POWER_PHASE_3_10); + } + } + else if (GetDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL) + { + _firstSelectedSurgeTargetGUID = NULL; + _secondSelectedSurgeTargetGUID = NULL; + _thirdSelectedSurgeTargetGUID = NULL; + DoCastAOE(SPELL_SURGE_OF_POWER_WARNING_SELECTOR_25); + } - // each player will enter to the trigger vehicle (entry 30090) already spawned (each one can hold up to 5 players, it has 5 seats) - // the players enter to the vehicles casting SPELL_VORTEX_4 OR SPELL_VORTEX_5 - if (InstanceScript* instance = caster->GetInstanceScript()) - instance->SetData(DATA_VORTEX_HANDLING, 0); + events.ScheduleEvent(EVENT_SURGE_OF_POWER_P_THREE, urand(9, 18)*IN_MILLISECONDS, 0, PHASE_THREE); + break; + case EVENT_STATIC_FIELD: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 60.0f, false, SPELL_RIDE_RED_DRAGON_BUDDY)) + DoCast(target, SPELL_STATIC_FIELD_MISSLE); - // the rest of the vortex execution continues when SPELL_VORTEX_2 is removed. - } + events.ScheduleEvent(EVENT_STATIC_FIELD, urand(15, 30)*IN_MILLISECONDS, 0, PHASE_THREE); + break; + case EVENT_PREVENT_SAY_SPAM_ON_KILL: + _killSpamFilter = false; + break; + default: + break; + } + } - void Register() - { - OnEffectHitTarget += SpellEffectFn(spell_malygos_vortex_dummy_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY); + if (_phase != PHASE_THREE) + DoMeleeAttackIfReady(); } - }; - - SpellScript* GetSpellScript() const - { - return new spell_malygos_vortex_dummy_SpellScript(); - } -}; - -class spell_malygos_vortex_visual : public SpellScriptLoader -{ - public: - spell_malygos_vortex_visual() : SpellScriptLoader("spell_malygos_vortex_visual") { } - class spell_malygos_vortex_visual_AuraScript : public AuraScript + void JustDied(Unit* /*killer*/) { - PrepareAuraScript(spell_malygos_vortex_visual_AuraScript); - - void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + _JustDied(); + Talk(SAY_DEATH); + if (Creature* alexstraszaGiftBoxBunny = me->GetMap()->GetCreature(instance->GetData64(DATA_GIFT_BOX_BUNNY_GUID))) { - if (Unit* caster = GetCaster()) - { - ThreatContainer::StorageType const& m_threatlist = caster->getThreatManager().getThreatList(); - for (ThreatContainer::StorageType::const_iterator itr = m_threatlist.begin(); itr!= m_threatlist.end(); ++itr) - { - if (Unit* target = (*itr)->getTarget()) - { - Player* targetPlayer = target->ToPlayer(); - - if (!targetPlayer || targetPlayer->isGameMaster()) - continue; - - if (InstanceScript* instance = caster->GetInstanceScript()) - { - // teleport spell - i am not sure but might be it must be casted by each vehicle when its passenger leaves it - if (Creature* trigger = caster->GetMap()->GetCreature(instance->GetData64(DATA_TRIGGER))) - trigger->CastSpell(targetPlayer, SPELL_VORTEX_6, true); - } - } - } - - if (Creature* malygos = caster->ToCreature()) - { - // This is a hack, we have to re add players to the threat list because when they enter to the vehicles they are removed. - // Anyway even with this issue, the boss does not enter in evade mode - this prevents iterate an empty list in the next vortex execution. - malygos->SetInCombatWithZone(); - - malygos->SetDisableGravity(false); - malygos->SetCanFly(false); + if (GetDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL) + alexstraszaGiftBoxBunny->SummonGameObject(GO_HEART_OF_MAGIC_10, HeartOfMagicSpawnPos.GetPositionX(), HeartOfMagicSpawnPos.GetPositionY(), + HeartOfMagicSpawnPos.GetPositionZ(), HeartOfMagicSpawnPos.GetOrientation(), 0.0f, 0.0f, 0.0f, 1.0f, 0); + else if (GetDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL) + alexstraszaGiftBoxBunny->SummonGameObject(GO_HEART_OF_MAGIC_25, HeartOfMagicSpawnPos.GetPositionX(), HeartOfMagicSpawnPos.GetPositionY(), + HeartOfMagicSpawnPos.GetPositionZ(), HeartOfMagicSpawnPos.GetOrientation(), 0.0f, 0.0f, 0.0f, 1.0f, 0); + } - malygos->GetMotionMaster()->MoveChase(caster->getVictim()); - malygos->RemoveAura(SPELL_VORTEX_1); - } - } + me->SummonCreature(NPC_ALEXSTRASZA, AlexstraszaSpawnPos, TEMPSUMMON_MANUAL_DESPAWN); + me->DespawnOrUnsummon(5*IN_MILLISECONDS); + } - } + private: + // Used to generate perfect cyclic movements (Enter Circle). + void FillCirclePath(Position const& centerPos, float radius, float z, Movement::PointsArray& path, bool clockwise) + { + float step = clockwise ? -M_PI / 8.0f : M_PI / 8.0f; + float angle = centerPos.GetAngle(me->GetPositionX(), me->GetPositionY()); - void Register() + for (uint8 i = 0; i < 16; angle += step, ++i) { - AfterEffectRemove += AuraEffectRemoveFn(spell_malygos_vortex_visual_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + G3D::Vector3 point; + point.x = centerPos.GetPositionX() + radius * cosf(angle); + point.y = centerPos.GetPositionY() + radius * sinf(angle); + point.z = z; // Don't use any height getters unless all bugs are fixed. + path.push_back(point); } - }; + } + + // Function that will change lights of map for all players on map. + void SendLightOverride(uint32 overrideId, uint32 fadeInTime) const + { + WorldPacket data(SMSG_OVERRIDE_LIGHT, 12); + data << uint32(1773); // Light.dbc entry (map default) + data << uint32(overrideId); // Light.dbc entry (override) + data << uint32(fadeInTime); + SendPacketToPlayers(&data); + } - AuraScript* GetAuraScript() const + // Send packet to all players in Eye of Eternity + void SendPacketToPlayers(WorldPacket const* data) const { - return new spell_malygos_vortex_visual_AuraScript(); + Map::PlayerList const& players = me->GetMap()->GetPlayers(); + if (!players.isEmpty()) + for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) + if (Player* player = itr->getSource()) + if (player->GetAreaId() == AREA_EYE_OF_ETERNITY) + player->GetSession()->SendPacket(data); } -}; -class npc_portal_eoe: public CreatureScript -{ -public: - npc_portal_eoe() : CreatureScript("npc_portal_eoe") {} + uint8 _phase; // Counter for phases used with a getter. + uint8 _summonDeaths; // Keeps count of arcane trash. + uint8 _preparingPulsesChecker; // In retail they use 2 preparing pulses with 7 sec CD, after they pass 2 seconds. + uint64 _arcaneOverloadGUID; // Last Arcane Overload summoned to know to which should visual be cast to (the purple ball, not bubble). + uint64 _firstSelectedSurgeTargetGUID; // All these three are used to keep current tagets to which warning should be sent + uint64 _secondSelectedSurgeTargetGUID; // during Surge of Power 25 man, also they act as sent targets because of that mechanic. + uint64 _thirdSelectedSurgeTargetGUID; + + Unit* _tempSurgeTarget; // These three are used for 10 man Surge of Power targeting. + Vehicle* _drakeVehicle; + Player* _playerSurgeTarget; + + bool _killSpamFilter; // Prevent text spamming on killed player by helping implement a CD. + bool _canAttack; // Used to control attacking (Move Chase not being applied after Stop Attack, only few times should act like this). + bool _despawned; // Checks if boss pass through evade on reset. + bool _executingVortex; // Prevents some events being sheduled during Vortex takeoff/land. + bool _arcaneReinforcements; // Checks if 10 or 25 man arcane trash will be spawned. + bool _flyingOutOfPlatform; // Used to prevent Malygos casting Arcane Overload shields while leaving platform. + bool _firstCyclicMovementStarted; // At first movement start he throws one shield asap, so this check is needed for it only. + bool _performingSurgeOfPower; // Used to prevent starting Cyclic Movement called in Arcane Bomb event. + bool _performingDestroyPlatform; // Used to prevent starting some movements right when Destroy Platfrom event starts. + + float _flySpeed; // Used to store base fly speed to prevent stacking on each evade. + }; CreatureAI* GetAI(Creature* creature) const { - return new npc_portal_eoeAI(creature); + return new boss_malygosAI(creature); } +}; + +class npc_portal_eoe: public CreatureScript +{ +public: + npc_portal_eoe() : CreatureScript("npc_portal_eoe") { } struct npc_portal_eoeAI : public ScriptedAI { @@ -763,27 +1083,29 @@ public: _instance = creature->GetInstanceScript(); } - void SpellHit(Unit* /*caster*/, const SpellInfo* spell) + void SpellHit(Unit* /*caster*/, SpellInfo const* spell) { if (spell->Id == SPELL_PORTAL_OPENED) { - DoCast(me, SPELL_SUMMON_POWER_PARK, true); + if (Creature* malygos = me->GetMap()->GetCreature(_instance->GetData64(DATA_MALYGOS))) + { + if (malygos->AI()->GetData(DATA_PHASE) == PHASE_ONE) + DoCast(me, SPELL_SUMMON_POWER_PARK, true); + } } } void UpdateAI(uint32 /*diff*/) { - // When duration of oppened riff visual ends, - // closed one should be cast - if (!me->HasAura(SPELL_PORTAL_VISUAL_CLOSED) && - !me->HasAura(SPELL_PORTAL_OPENED)) + // When duration of opened riff visual ends, closed one should be cast + if (!me->HasAura(SPELL_PORTAL_VISUAL_CLOSED) && !me->HasAura(SPELL_PORTAL_OPENED)) DoCast(me, SPELL_PORTAL_VISUAL_CLOSED, true); if (_instance) { - if (Creature* malygos = Unit::GetCreature(*me, _instance->GetData64(DATA_MALYGOS))) + if (Creature* malygos = me->GetMap()->GetCreature(_instance->GetData64(DATA_MALYGOS))) { - if (malygos->AI()->GetData(DATA_PHASE) != PHASE_ONE) + if (malygos->AI()->GetData(DATA_PHASE) != PHASE_ONE && me->HasAura(SPELL_PORTAL_OPENED)) { me->RemoveAura(SPELL_PORTAL_OPENED); DoCast(me, SPELL_PORTAL_VISUAL_CLOSED, true); @@ -792,42 +1114,29 @@ public: } } - void JustSummoned(Creature* summon) - { - summon->SetInCombatWithZone(); - } - private: - uint32 _summonTimer; InstanceScript* _instance; }; -}; + CreatureAI* GetAI(Creature* creature) const + { + return new npc_portal_eoeAI(creature); + } +}; class npc_power_spark: public CreatureScript { public: - npc_power_spark() : CreatureScript("npc_power_spark") {} - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_power_sparkAI(creature); - } + npc_power_spark() : CreatureScript("npc_power_spark") { } struct npc_power_sparkAI : public ScriptedAI { npc_power_sparkAI(Creature* creature) : ScriptedAI(creature) { _instance = creature->GetInstanceScript(); - - MoveToMalygos(); // Talk range was not enough for this encounter sCreatureTextMgr->SendChat(me, EMOTE_POWER_SPARK_SUMMONED, 0, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_MAP); - } - - void EnterEvadeMode() - { - me->DespawnOrUnsummon(); + MoveToMalygos(); } void MoveToMalygos() @@ -835,10 +1144,8 @@ public: me->GetMotionMaster()->MoveIdle(); if (_instance) - { - if (Creature* malygos = Unit::GetCreature(*me, _instance->GetData64(DATA_MALYGOS))) + if (Creature* malygos = me->GetMap()->GetCreature(_instance->GetData64(DATA_MALYGOS))) me->GetMotionMaster()->MoveFollow(malygos, 0.0f, 0.0f); - } } void UpdateAI(uint32 /*diff*/) @@ -846,9 +1153,9 @@ public: if (!_instance) return; - if (Creature* malygos = Unit::GetCreature(*me, _instance->GetData64(DATA_MALYGOS))) + if (Creature* malygos = me->GetMap()->GetCreature(_instance->GetData64(DATA_MALYGOS))) { - if (malygos->AI()->GetData(DATA_PHASE) != PHASE_ONE) + if (malygos->AI()->GetData(DATA_PHASE) != PHASE_ONE || _instance->GetBossState(DATA_MALYGOS_EVENT) == FAIL) { me->DespawnOrUnsummon(); return; @@ -873,28 +1180,33 @@ public: private: InstanceScript* _instance; }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_power_sparkAI(creature); + } }; -class npc_hover_disk : public CreatureScript +class npc_melee_hover_disk : public CreatureScript { public: - npc_hover_disk() : CreatureScript("npc_hover_disk") { } + npc_melee_hover_disk() : CreatureScript("npc_melee_hover_disk") { } - CreatureAI* GetAI(Creature* creature) const + struct npc_melee_hover_diskAI : public VehicleAI { - return new npc_hover_diskAI(creature); - } + npc_melee_hover_diskAI(Creature* creature) : VehicleAI(creature) + { + _instance = creature->GetInstanceScript(); + me->SetReactState(REACT_PASSIVE); + // TO DO: These were a bit faster than what they should be. Not sure what is the reason. + me->SetSpeed(MOVE_FLIGHT, 1.25f); + } - struct npc_hover_diskAI : public npc_escortAI - { - npc_hover_diskAI(Creature* creature) : npc_escortAI(creature) + void Reset() { - if (me->GetEntry() == NPC_HOVER_DISK_CASTER) - me->SetReactState(REACT_PASSIVE); - else - me->SetInCombatWithZone(); + VehicleAI::Reset(); - _instance = creature->GetInstanceScript(); + _wpCount = 0; } void PassengerBoarded(Unit* unit, int8 /*seat*/, bool apply) @@ -903,208 +1215,1284 @@ public: { if (unit->GetTypeId() == TYPEID_UNIT) { - me->setFaction(FACTION_HOSTILE); + unit->CastSpell(unit, SPELL_TELEPORT_VISUAL_ONLY); unit->ToCreature()->SetInCombatWithZone(); } + else if (unit->GetTypeId() == TYPEID_PLAYER) + me->SetDisableGravity(true); } - else + else if (!apply) { - // Error found: This is not called if the passenger is a player - if (unit->GetTypeId() == TYPEID_UNIT || unit->GetTypeId() == TYPEID_PLAYER) + if (unit->GetTypeId() != TYPEID_PLAYER) { - // This will only be called if the passenger dies - if (_instance) - { - if (Creature* malygos = Unit::GetCreature(*me, _instance->GetData64(DATA_MALYGOS))) - malygos->AI()->SetData(DATA_SUMMON_DEATHS, malygos->AI()->GetData(DATA_SUMMON_DEATHS)+1); - } + me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation()); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + me->SetDisableGravity(false); + me->SetCanFly(false); } - - me->GetMotionMaster()->MoveIdle(); - - if (me->GetEntry() == NPC_HOVER_DISK_MELEE || me->GetEntry() == NPC_HOVER_DISK_CASTER) + else if (unit->GetTypeId() == TYPEID_PLAYER) { - // Hack: Fall ground function can fail (remember the platform is a gameobject), we will teleport the disk to the ground - if (me->GetPositionZ() > GROUND_Z) - me->NearTeleportTo(me->GetPositionX(), me->GetPositionY(), GROUND_Z, 0); - me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation()); - me->setFaction(FACTION_FRIENDLY); - me->AI()->EnterEvadeMode(); + me->SetDisableGravity(false); + me->SetCanFly(false); } - } - } - void EnterEvadeMode() - { - // we dont evade + me->setFaction(FACTION_FRIENDLY); + me->RemoveAllAuras(); + } } - void DoAction(int32 action) + void UpdateAI(uint32 diff) { - if (me->GetEntry() != NPC_HOVER_DISK_CASTER) - return; - - switch (action) - { - case ACTION_HOVER_DISK_START_WP_1: - for (uint8 i = 0; i < MAX_HOVER_DISK_WAYPOINTS; i++) - AddWaypoint(i, HoverDiskWaypoints[i].GetPositionX(), HoverDiskWaypoints[i].GetPositionY(), HoverDiskWaypoints[i].GetPositionZ()); - break; - case ACTION_HOVER_DISK_START_WP_2: - { - uint8 count = 0; - for (uint8 i = MAX_HOVER_DISK_WAYPOINTS-1; i > 0; i--) - { - AddWaypoint(count, HoverDiskWaypoints[i].GetPositionX(), HoverDiskWaypoints[i].GetPositionY(), HoverDiskWaypoints[i].GetPositionZ()); - count++; - } - break; - } - default: - return; - } + _events.Update(diff); - Start(true, false, 0, 0, false, true); + while (uint32 eventId = _events.ExecuteEvent()) + me->GetMotionMaster()->MovePoint(eventId, MeleeHoverDisksWaypoints[eventId]); } - void UpdateEscortAI(const uint32 /*diff*/) + void DoAction(int32 /*action*/) { - // we dont do melee damage! + if (Vehicle* vehicleTemp = me->GetVehicleKit()) + if (vehicleTemp->GetPassenger(0) && vehicleTemp->GetPassenger(0)->GetTypeId() == TYPEID_PLAYER) + { + vehicleTemp->RemoveAllPassengers(); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + } + + me->DespawnOrUnsummon(3*IN_MILLISECONDS); } - void WaypointReached(uint32 /*waypointId*/) + void MovementInform(uint32 type, uint32 id) { + if (type != POINT_MOTION_TYPE) + return; + if (_wpCount < 3) + { + _events.ScheduleEvent(id + 1, 1); + ++_wpCount; + } + else if (Vehicle* hoverDisk = me->GetVehicleKit()) + if (Unit* lordPassenger = hoverDisk->GetPassenger(0)) + lordPassenger->ToCreature()->AI()->DoAction(ACTION_SET_DISK_VICTIM_CHASE); } private: + uint8 _wpCount; // how many points are triggered InstanceScript* _instance; + EventMap _events; }; -}; - - -// The reason of this AI is to make the creature able to enter in combat otherwise the spell casting of SPELL_ARCANE_OVERLOAD fails. -class npc_arcane_overload : public CreatureScript -{ -public: - npc_arcane_overload() : CreatureScript("npc_arcane_overload") {} CreatureAI* GetAI(Creature* creature) const { - return new npc_arcane_overloadAI (creature); + return new npc_melee_hover_diskAI(creature); } +}; - struct npc_arcane_overloadAI : public ScriptedAI - { - npc_arcane_overloadAI(Creature* creature) : ScriptedAI(creature) {} +class npc_caster_hover_disk : public CreatureScript +{ +public: + npc_caster_hover_disk() : CreatureScript("npc_caster_hover_disk") { } - void AttackStart(Unit* who) + struct npc_caster_hover_diskAI : public VehicleAI + { + npc_caster_hover_diskAI(Creature* creature) : VehicleAI(creature) { - DoStartNoMovement(who); + _instance = creature->GetInstanceScript(); + me->SetReactState(REACT_PASSIVE); + // TO DO: Something is wrong with calculations for flying creatures that are on WP/Cyclic path. + // They should get the same difference as to when at ground from run creature switch to walk. + me->SetSpeed(MOVE_FLIGHT, 0.45f); } void Reset() { - DoCast(me, SPELL_ARCANE_OVERLOAD, false); + VehicleAI::Reset(); } - void UpdateAI(uint32 /*diff*/) + void EnterEvadeMode() { - // we dont do melee damage! } - }; -}; - -// SmartAI does not work correctly for vehicles -class npc_wyrmrest_skytalon : public CreatureScript -{ -public: - npc_wyrmrest_skytalon() : CreatureScript("npc_wyrmrest_skytalon") {} - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_wyrmrest_skytalonAI (creature); - } - - struct npc_wyrmrest_skytalonAI : public VehicleAI - { - npc_wyrmrest_skytalonAI(Creature* creature) : VehicleAI(creature) { } + void PassengerBoarded(Unit* unit, int8 /*seat*/, bool apply) + { + if (apply) + { + if (unit->GetTypeId() == TYPEID_UNIT) + unit->CastSpell(unit, SPELL_TELEPORT_VISUAL_ONLY); + } + else if (!apply) + { + me->StopMoving(); + me->SetDisableGravity(false); + me->SetCanFly(false); + me->RemoveAllAuras(); + } + } - void IsSummonedBy(Unit* summoner) + void DoAction(int32 action) { - summoner->CastSpell(me, SPELL_RIDE_RED_DRAGON, true); + if (action < ACTION_DELAYED_DESPAWN) + { + Movement::MoveSplineInit init(me); + FillCirclePath(MalygosPositions[3], 35.0f, 282.3402f, init.Path(), true); + init.SetFly(); + init.SetCyclic(); + init.Launch(); + } + else + { + me->DespawnOrUnsummon(3*IN_MILLISECONDS); + } } - void PassengerBoarded(Unit* /*unit*/, int8 /*seat*/, bool apply) + private: + void FillCirclePath(Position const& centerPos, float radius, float z, Movement::PointsArray& path, bool clockwise) { - if (!apply) - me->DespawnOrUnsummon(); + float step = clockwise ? -M_PI / 9.0f : M_PI / 9.0f; + float angle = centerPos.GetAngle(me->GetPositionX(), me->GetPositionY()); + + for (uint8 i = 0; i < 18; angle += step, ++i) + { + G3D::Vector3 point; + point.x = centerPos.GetPositionX() + radius * cosf(angle); + point.y = centerPos.GetPositionY() + radius * sinf(angle); + point.z = z; // Don't use any height getters unless all bugs are fixed. + path.push_back(point); + } } + + InstanceScript* _instance; }; -}; - -class npc_alexstrasza_eoe : public CreatureScript -{ -public: - npc_alexstrasza_eoe() : CreatureScript("npc_alexstrasza_eoe") {} CreatureAI* GetAI(Creature* creature) const { - return new npc_alexstrasza_eoeAI (creature); + return new npc_caster_hover_diskAI(creature); } +}; - struct npc_alexstrasza_eoeAI : public ScriptedAI - { - npc_alexstrasza_eoeAI(Creature* creature) : ScriptedAI(creature) {} +class npc_nexus_lord : public CreatureScript +{ + public: + npc_nexus_lord() : CreatureScript("npc_nexus_lord") { } - void Reset() + struct npc_nexus_lordAI : public ScriptedAI { - _events.Reset(); - _events.ScheduleEvent(EVENT_YELL_1, 0); - } + npc_nexus_lordAI(Creature* creature) : ScriptedAI(creature) + { + _instance = creature->GetInstanceScript(); + } - void UpdateAI(uint32 /*diff*/) - { - while (uint32 eventId = _events.ExecuteEvent()) + void Reset() { - switch (eventId) - { - case EVENT_YELL_1: - Talk(SAY_ONE); - _events.ScheduleEvent(EVENT_YELL_2, 4*IN_MILLISECONDS); - break; - case EVENT_YELL_2: - Talk(SAY_TWO); - _events.ScheduleEvent(EVENT_YELL_3, 4*IN_MILLISECONDS); - break; - case EVENT_YELL_3: - Talk(SAY_THREE); - _events.ScheduleEvent(EVENT_YELL_4, 7*IN_MILLISECONDS); - break; - case EVENT_YELL_4: - Talk(SAY_FOUR); - break; + _events.Reset(); + } + + void EnterEvadeMode() + { + } + + void IsSummonedBy(Unit* /*summoner*/) + { + _events.ScheduleEvent(EVENT_ARCANE_SHOCK, 2*IN_MILLISECONDS); + _events.ScheduleEvent(EVENT_HASTE_BUFF, 12*IN_MILLISECONDS); + } + + void DoAction(int32 /*action*/) + { + _events.ScheduleEvent(EVENT_NUKE_DUMMY, 1); + } + + void UpdateAI(uint32 diff) + { + if (!UpdateVictim()) + return; + + _events.Update(diff); + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_ARCANE_SHOCK: + DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0, 5.0f, true), SPELL_ARCANE_SHOCK); + _events.ScheduleEvent(EVENT_ARCANE_SHOCK, 3*IN_MILLISECONDS); + break; + case EVENT_HASTE_BUFF: + DoCast(me, SPELL_HASTE); + _events.ScheduleEvent(EVENT_HASTE_BUFF, 15*IN_MILLISECONDS); + break; + case EVENT_NUKE_DUMMY: + DoCast(me->getVictim(), SPELL_DUMMY_NUKE, true); + DoCast(me, SPELL_ALIGN_DISK_AGGRO, true); + _events.ScheduleEvent(EVENT_NUKE_DUMMY, 1*IN_MILLISECONDS); + break; + } + } + + DoMeleeAttackIfReady(); + } + + void JustDied(Unit* /*killer*/) + { + if (Creature* malygos = me->GetMap()->GetCreature(_instance->GetData64(DATA_MALYGOS))) + malygos->AI()->SetData(DATA_SUMMON_DEATHS, malygos->AI()->GetData(DATA_SUMMON_DEATHS) + 1); + } + + private: + InstanceScript* _instance; + EventMap _events; + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_nexus_lordAI(creature); + } +}; + +class npc_scion_of_eternity : public CreatureScript +{ + public: + npc_scion_of_eternity() : CreatureScript("npc_scion_of_eternity") { } + + struct npc_scion_of_eternityAI : public ScriptedAI + { + npc_scion_of_eternityAI(Creature* creature) : ScriptedAI(creature) + { + _instance = creature->GetInstanceScript(); + } + + void Reset() + { + _events.Reset(); + } + + void IsSummonedBy(Unit* /*summoner*/) + { + _events.SetPhase(PHASE_TWO); + _events.ScheduleEvent(EVENT_ARCANE_BARRAGE, urand(14, 17)*IN_MILLISECONDS, 0, PHASE_TWO); + } + + void EnterCombat(Unit* /*who*/) + { + } + + void AttackStart(Unit* /*target*/) + { + } + + void EnterEvadeMode() + { + } + + void UpdateAI(uint32 diff) + { + _events.Update(diff); + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_ARCANE_BARRAGE: + DoCast(me, SPELL_ARCANE_BARRAGE); + _events.ScheduleEvent(EVENT_ARCANE_BARRAGE, urand(4, 12)*IN_MILLISECONDS, 0, PHASE_TWO); + break; + } + } + } + + void JustDied(Unit* /*killer*/) + { + if (Creature* malygos = me->GetMap()->GetCreature(_instance->GetData64(DATA_MALYGOS))) + malygos->AI()->SetData(DATA_SUMMON_DEATHS, malygos->AI()->GetData(DATA_SUMMON_DEATHS) + 1); + } + + private: + InstanceScript* _instance; + EventMap _events; + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_scion_of_eternityAI(creature); + } +}; + +class npc_arcane_overload : public CreatureScript +{ +public: + npc_arcane_overload() : CreatureScript("npc_arcane_overload") { } + + struct npc_arcane_overloadAI : public ScriptedAI + { + npc_arcane_overloadAI(Creature* creature) : ScriptedAI(creature) + { + _instance = creature->GetInstanceScript(); + me->SetReactState(REACT_PASSIVE); + } + + void IsSummonedBy(Unit* summoner) + { + if ((_malygos = summoner->ToCreature())) + _malygos->AI()->SetGUID(me->GetGUID(), DATA_LAST_OVERLOAD_GUID); + } + + void UpdateAI (uint32 /*diff*/) + { + } + + void DoAction(int32 /*action*/) + { + if (Creature* malygos = me->GetMap()->GetCreature(_instance->GetData64(DATA_MALYGOS))) + { + if (malygos->AI()->GetData(DATA_PHASE) == PHASE_TWO) + me->DespawnOrUnsummon(6*IN_MILLISECONDS); + // If evade is hit during phase II shields should disappear with no delay + else if (malygos->AI()->GetData(DATA_PHASE) == 0) + me->DespawnOrUnsummon(); + } + } + + void SpellHit(Unit* /*caster*/, SpellInfo const* spell) + { + if (spell->Id == SPELL_ARCANE_BOMB_TRIGGER) + { + DoCastAOE(SPELL_ARCANE_BOMB_KNOCKBACK_DAMAGE, true); + DoCast(me, SPELL_ARCANE_OVERLOAD_1, true); + } + } + + private: + InstanceScript* _instance; + Creature* _malygos; + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_arcane_overloadAI (creature); + } +}; + +// SmartAI does not work correctly for vehicles +class npc_wyrmrest_skytalon : public CreatureScript +{ +public: + npc_wyrmrest_skytalon() : CreatureScript("npc_wyrmrest_skytalon") { } + + struct npc_wyrmrest_skytalonAI : public VehicleAI + { + npc_wyrmrest_skytalonAI(Creature* creature) : VehicleAI(creature) + { + } + + void IsSummonedBy(Unit* summoner) + { + me->CastSpell(summoner, SPELL_RIDE_RED_DRAGON_TRIGGERED, true); + } + + void PassengerBoarded(Unit* unit, int8 /*seat*/, bool apply) + { + if (apply) + { + _playerController = NULL; + _playerController = unit->ToPlayer(); + } + if (!apply) + { + me->DespawnOrUnsummon(2050); + me->SetOrientation(2.5f); + me->SetSpeed(MOVE_FLIGHT, 1.0f, true); + Position pos; + me->GetPosition(&pos); + pos.m_positionX += 10.0f; + pos.m_positionY += 10.0f; + pos.m_positionZ += 12.0f; + me->GetMotionMaster()->MovePoint(1, pos); + } + } + + void JustDied(Unit* /*killer*/) + { + // TO DOs: check script beginning for more info. + _playerController->Kill(_playerController, true); + } + + private: + Player* _playerController; + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_wyrmrest_skytalonAI (creature); + } +}; + +// We shouldn't use SAI for stuff that aren't within boss main mechanic +// and SAI type of despawn can cause problems here. +class npc_static_field : public CreatureScript +{ + public: + npc_static_field() : CreatureScript("npc_static_field") { } + + struct npc_static_fieldAI : public ScriptedAI + { + npc_static_fieldAI(Creature* creature) : ScriptedAI(creature) + { + } + + void IsSummonedBy(Unit* /*summoner*/) + { + // For some great reason the spell doesn't time it... + me->DespawnOrUnsummon(30*IN_MILLISECONDS); + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_static_fieldAI (creature); + } +}; + +class spell_malygos_portal_beam : public SpellScriptLoader +{ + public: + spell_malygos_portal_beam() : SpellScriptLoader("spell_malygos_portal_beam") { } + + class spell_malygos_portal_beam_AuraScript : public AuraScript + { + PrepareAuraScript(spell_malygos_portal_beam_AuraScript); + + bool Load() + { + return GetCaster()->GetTypeId() == TYPEID_UNIT; + } + + bool Validate(SpellInfo const* /*spell*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_PORTAL_OPENED)) + return false; + + return true; + } + + void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (Creature* target = GetTarget()->ToCreature()) + target->CastSpell(target, SPELL_PORTAL_OPENED); + } + + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (Creature* target = GetTarget()->ToCreature()) + target->RemoveAura(SPELL_PORTAL_OPENED); + } + + void Register() + { + OnEffectApply += AuraEffectApplyFn(spell_malygos_portal_beam_AuraScript::OnApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + AfterEffectRemove += AuraEffectRemoveFn(spell_malygos_portal_beam_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_malygos_portal_beam_AuraScript(); + } +}; + +class spell_malygos_random_portal : public SpellScriptLoader +{ + public: + spell_malygos_random_portal() : SpellScriptLoader("spell_malygos_random_portal") { } + + class spell_malygos_random_portal_SpellScript : public SpellScript + { + PrepareSpellScript(spell_malygos_random_portal_SpellScript); + + bool Load() + { + return GetCaster()->GetTypeId() == TYPEID_UNIT; + } + + void HandleDummy(SpellEffIndex /*effIndex*/) + { + Creature* malygos = GetCaster()->ToCreature(); + if (Creature* target = GetHitCreature()) + { + Position pos; + pos.m_positionZ = target->GetPositionZ(); + target->GetNearPoint2D(pos.m_positionX, pos.m_positionY, frand(29.1f, 30.0f), target->GetAngle(malygos)); + malygos->GetMotionMaster()->MovePoint(POINT_NEAR_RANDOM_PORTAL_P_NONE, pos); + } + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_malygos_random_portal_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_malygos_random_portal_SpellScript(); + } +}; + +class isPlayerOnVehicleChecker +{ + public: + isPlayerOnVehicleChecker(Unit* source) : _source(source) { } + + bool operator()(WorldObject* unit) + { + if (Unit* target = ObjectAccessor::GetUnit(*_source, unit->GetGUID())) + if (target->IsOnVehicle(target->GetVehicleBase())) + return true; + + return false; + } + + private: + Unit* _source; +}; + +class spell_malygos_arcane_storm : public SpellScriptLoader +{ + public: + spell_malygos_arcane_storm() : SpellScriptLoader("spell_malygos_arcane_storm") { } + + class spell_malygos_arcane_storm_SpellScript : public SpellScript + { + PrepareSpellScript(spell_malygos_arcane_storm_SpellScript); + + bool Load() + { + return GetCaster()->GetTypeId() == TYPEID_UNIT; + } + + bool Validate(SpellInfo const* /*spell*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_ARCANE_STORM_EXTRA_VISUAL)) + return false; + + return true; + } + + void FilterTargets(std::list& targets) + { + Creature* malygos = GetCaster()->ToCreature(); + if (GetSpellInfo()->Id == SPELL_ARCANE_STORM_P_III) + targets.remove_if(isPlayerOnVehicleChecker(malygos)); + + if (!targets.empty()) + Trinity::Containers::RandomResizeList(targets, (malygos->GetMap()->GetDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL ? 4 : 10)); + + for (std::list::const_iterator itr = targets.begin(); itr != targets.end(); ++itr) + malygos->CastSpell((*itr)->ToUnit(), SPELL_ARCANE_STORM_EXTRA_VISUAL, true); + } + + void Register() + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_malygos_arcane_storm_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_malygos_arcane_storm_SpellScript(); + } +}; + +class spell_malygos_vortex_dummy : public SpellScriptLoader +{ +public: + spell_malygos_vortex_dummy() : SpellScriptLoader("spell_malygos_vortex_dummy") { } + + class spell_malygos_vortex_dummy_SpellScript : public SpellScript + { + PrepareSpellScript(spell_malygos_vortex_dummy_SpellScript) + + bool Load() + { + return GetCaster()->GetTypeId() == TYPEID_UNIT; + } + + void HandleScript(SpellEffIndex /*effIndex*/) + { + Creature* caster = GetCaster()->ToCreature(); + // Each player will enter to the trigger vehicle (entry 30090) which is already spawned (each one can hold up to 5 players, it has 5 seats, + // the players enter the vehicles casting SPELL_VORTEX_4 or SPELL_VORTEX_5. + if (InstanceScript* instance = caster->GetInstanceScript()) + instance->SetData(DATA_VORTEX_HANDLING, 0); + + // the rest of the vortex execution continues when SPELL_VORTEX_2 is removed. + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_malygos_vortex_dummy_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_malygos_vortex_dummy_SpellScript(); + } +}; + +class spell_malygos_vortex_visual : public SpellScriptLoader +{ + public: + spell_malygos_vortex_visual() : SpellScriptLoader("spell_malygos_vortex_visual") { } + + class spell_malygos_vortex_visual_AuraScript : public AuraScript + { + PrepareAuraScript(spell_malygos_vortex_visual_AuraScript); + + bool Load() + { + return GetCaster()->GetTypeId() == TYPEID_UNIT; + } + + bool Validate(SpellInfo const* /*spell*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_VORTEX_1) || !sSpellMgr->GetSpellInfo(SPELL_VORTEX_6)) + return false; + + return true; + } + + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (Creature* caster = GetCaster()->ToCreature()) + { + ThreatContainer::StorageType const& m_threatlist = caster->getThreatManager().getThreatList(); + for (ThreatContainer::StorageType::const_iterator itr = m_threatlist.begin(); itr!= m_threatlist.end(); ++itr) + { + if (Unit* target = (*itr)->getTarget()) + { + Player* targetPlayer = target->ToPlayer(); + if (!targetPlayer || targetPlayer->isGameMaster()) + continue; + + if (InstanceScript* instance = caster->GetInstanceScript()) + { + // Teleport spell - I'm not sure but might be it must be casted by each vehicle when it's passenger leaves it. + if (Creature* trigger = caster->GetMap()->GetCreature(instance->GetData64(DATA_TRIGGER))) + trigger->CastSpell(targetPlayer, SPELL_VORTEX_6, true); + } + } + } + + if (Creature* malygos = caster->ToCreature()) + { + malygos->GetMotionMaster()->MoveLand(POINT_LAND_AFTER_VORTEX_P_ONE, MalygosPositions[2]); + malygos->RemoveAura(SPELL_VORTEX_1); + } + } + } + + void Register() + { + AfterEffectRemove += AuraEffectRemoveFn(spell_malygos_vortex_visual_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_malygos_vortex_visual_AuraScript(); + } +}; + +class ExactDistanceCheck +{ + public: + ExactDistanceCheck(Unit* source, float dist) : _source(source), _dist(dist) { } + + bool operator()(WorldObject* unit) + { + return _source->GetExactDist2d(unit) > _dist; + } + + private: + Unit* _source; + float _dist; +}; + +class spell_arcane_overload : public SpellScriptLoader +{ + public: + spell_arcane_overload() : SpellScriptLoader("spell_arcane_overload") { } + + class spell_arcane_overload_SpellScript : public SpellScript + { + PrepareSpellScript(spell_arcane_overload_SpellScript); + + bool Load() + { + return GetCaster()->GetTypeId() == TYPEID_UNIT; + } + + void ResizeEffectRadiusTargetChecker(std::list& targets) + { + Creature* arcaneOverload = GetCaster()->ToCreature(); + targets.remove_if(ExactDistanceCheck(arcaneOverload, + GetSpellInfo()->Effects[EFFECT_0].CalcRadius(arcaneOverload) * arcaneOverload->GetFloatValue(OBJECT_FIELD_SCALE_X))); + } + + void Register() + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_arcane_overload_SpellScript::ResizeEffectRadiusTargetChecker, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_arcane_overload_SpellScript(); + } +}; + +class spell_nexus_lord_align_disk_aggro : public SpellScriptLoader +{ + public: + spell_nexus_lord_align_disk_aggro() : SpellScriptLoader("spell_nexus_lord_align_disk_aggro") { } + + class spell_nexus_lord_align_disk_aggro_SpellScript : public SpellScript + { + PrepareSpellScript(spell_nexus_lord_align_disk_aggro_SpellScript); + + bool Load() + { + return GetCaster()->GetTypeId() == TYPEID_UNIT; + } + + void HandleScript(SpellEffIndex /*effIndex*/) + { + Creature* caster = GetCaster()->ToCreature(); + + if (Creature* target = GetHitCreature()) + target->GetMotionMaster()->MoveChase(caster->getVictim()); + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_nexus_lord_align_disk_aggro_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_nexus_lord_align_disk_aggro_SpellScript(); + } +}; + +class IsPlayerOnHoverDiskCheck +{ + public: + IsPlayerOnHoverDiskCheck(Unit* source, bool isOnHoverDisk) : _source(source), _isOnHoverDisk(isOnHoverDisk) { } + + bool operator()(WorldObject* unit) + { + if (_isOnHoverDisk) + { + if (Unit* passenger = ObjectAccessor::GetUnit(*_source, unit->GetGUID())) + if (passenger->GetVehicleBase() && passenger->GetVehicleBase()->GetEntry() == NPC_HOVER_DISK_MELEE) + return true; + } + else if (!_isOnHoverDisk) + { + if (Unit* passenger = ObjectAccessor::GetUnit(*_source, unit->GetGUID())) + if (!passenger->GetVehicleBase()) + return true; + } + + return false; + } + + private: + Unit* _source; + + bool _isOnHoverDisk; +}; + +class spell_scion_of_eternity_arcane_barrage : public SpellScriptLoader +{ + public: + spell_scion_of_eternity_arcane_barrage() : SpellScriptLoader("spell_scion_of_eternity_arcane_barrage") { } + + class spell_scion_of_eternity_arcane_barrage_SpellScript : public SpellScript + { + PrepareSpellScript(spell_scion_of_eternity_arcane_barrage_SpellScript); + + bool Load() + { + return GetCaster()->GetTypeId() == TYPEID_UNIT; + } + + void FilterMeleeHoverDiskPassangers(std::list& targets) + { + if (targets.empty()) + return; + + Creature* caster = GetCaster()->ToCreature(); + for (std::list::const_iterator itr = targets.begin(); itr != targets.end(); ++itr) + _playersWithoutDisk.push_back((*itr)); + + _playersWithoutDisk.remove_if(IsPlayerOnHoverDiskCheck(caster, false)); + if (_playersWithoutDisk.empty()) + targets.remove_if(IsPlayerOnHoverDiskCheck(caster, true)); + } + + void Register() + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_scion_of_eternity_arcane_barrage_SpellScript::FilterMeleeHoverDiskPassangers, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + } + + std::list _playersWithoutDisk; + }; + + SpellScript* GetSpellScript() const + { + return new spell_scion_of_eternity_arcane_barrage_SpellScript(); + } +}; + +class spell_malygos_destroy_platform_channel : public SpellScriptLoader +{ + public: + spell_malygos_destroy_platform_channel() : SpellScriptLoader("spell_malygos_destroy_platform_channel") { } + + class spell_malygos_destroy_platform_channel_AuraScript : public AuraScript + { + PrepareAuraScript(spell_malygos_destroy_platform_channel_AuraScript); + + bool Load() + { + return GetCaster()->GetTypeId() == TYPEID_UNIT; + } + + bool Validate(SpellInfo const* /*spell*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_DESTROY_PLATFORM_BOOM_VISUAL)) + return false; + + return true; + } + + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (Creature* target = GetTarget()->ToCreature()) + if (InstanceScript* instance = target->GetInstanceScript()) + if (Creature* platformTrigger = target->GetMap()->GetCreature(instance->GetData64(DATA_ALEXSTRASZA_BUNNY_GUID))) + platformTrigger->CastSpell(platformTrigger, SPELL_DESTROY_PLATFORM_BOOM_VISUAL); + } + + void Register() + { + AfterEffectRemove += AuraEffectRemoveFn(spell_malygos_destroy_platform_channel_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_malygos_destroy_platform_channel_AuraScript(); + } +}; + +class spell_alexstrasza_bunny_destroy_platform_boom_visual : public SpellScriptLoader +{ + public: + spell_alexstrasza_bunny_destroy_platform_boom_visual() : SpellScriptLoader("spell_alexstrasza_bunny_destroy_platform_boom_visual") { } + + class spell_alexstrasza_bunny_destroy_platform_boom_visual_SpellScript : public SpellScript + { + PrepareSpellScript(spell_alexstrasza_bunny_destroy_platform_boom_visual_SpellScript); + + bool Load() + { + return GetCaster()->GetTypeId() == TYPEID_UNIT; + } + + bool Validate(SpellInfo const* /*spell*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_DESTROY_PLATFORM_EVENT)) + return false; + + return true; + } + + void HandleDummy(SpellEffIndex /*effIndex*/) + { + if (Creature* target = GetHitCreature()) + { + target->CastSpell(target, SPELL_DESTROY_PLATFORM_EVENT); } } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_alexstrasza_bunny_destroy_platform_boom_visual_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_alexstrasza_bunny_destroy_platform_boom_visual_SpellScript(); + } +}; + +class spell_alexstrasza_bunny_destroy_platform_event : public SpellScriptLoader +{ + public: + spell_alexstrasza_bunny_destroy_platform_event() : SpellScriptLoader("spell_alexstrasza_bunny_destroy_platform_event") { } + + class spell_alexstrasza_bunny_destroy_platform_event_SpellScript : public SpellScript + { + PrepareSpellScript(spell_alexstrasza_bunny_destroy_platform_event_SpellScript); + + bool Load() + { + return GetCaster()->GetTypeId() == TYPEID_UNIT; + } + + void HandleSendEvent(SpellEffIndex /*effIndex*/) + { + Creature* caster = GetCaster()->ToCreature(); + if (InstanceScript* instance = caster->GetInstanceScript()) + if (GameObject* platform = caster->GetMap()->GetGameObject(instance->GetData64(DATA_PLATFORM))) + platform->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_DESTROYED); + } + + void HandleScript(SpellEffIndex /*effIndex*/) + { + Creature* caster = GetCaster()->ToCreature(); + caster->CastSpell(caster, SPELL_SUMMON_RED_DRAGON_BUDDY_F_CAST, true); + } + + void Register() + { + OnEffectHit += SpellEffectFn(spell_alexstrasza_bunny_destroy_platform_event_SpellScript::HandleSendEvent, EFFECT_0, SPELL_EFFECT_SEND_EVENT); + OnEffectHitTarget += SpellEffectFn(spell_alexstrasza_bunny_destroy_platform_event_SpellScript::HandleScript, EFFECT_2, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_alexstrasza_bunny_destroy_platform_event_SpellScript(); + } +}; + +class spell_wyrmrest_skytalon_summon_red_dragon_buddy : public SpellScriptLoader +{ + public: + spell_wyrmrest_skytalon_summon_red_dragon_buddy() : SpellScriptLoader("spell_wyrmrest_skytalon_summon_red_dragon_buddy") { } + + class spell_wyrmrest_skytalon_summon_red_dragon_buddy_SpellScript : public SpellScript + { + PrepareSpellScript(spell_wyrmrest_skytalon_summon_red_dragon_buddy_SpellScript); + + bool Load() + { + return GetCaster()->GetTypeId() == TYPEID_PLAYER; + } + + void ChangeSummonPos(SpellEffIndex /*effIndex*/) + { + // Adjust effect summon position to lower Z + WorldLocation summonPos = *GetExplTargetDest(); + Position offset = { 0.0f, 0.0f, -80.0f, 0.0f }; + summonPos.RelocateOffset(offset); + SetExplTargetDest(summonPos); + GetHitDest()->RelocateOffset(offset); + } + + void Register() + { + OnEffectHit += SpellEffectFn(spell_wyrmrest_skytalon_summon_red_dragon_buddy_SpellScript::ChangeSummonPos, EFFECT_0, SPELL_EFFECT_SUMMON); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_wyrmrest_skytalon_summon_red_dragon_buddy_SpellScript(); + } +}; + +class spell_wyrmrest_skytalon_ride_red_dragon_buddy_trigger : public SpellScriptLoader +{ + public: + spell_wyrmrest_skytalon_ride_red_dragon_buddy_trigger() : SpellScriptLoader("spell_wyrmrest_skytalon_ride_red_dragon_buddy_trigger") { } + + class spell_wyrmrest_skytalon_ride_red_dragon_buddy_trigger_SpellScript : public SpellScript + { + PrepareSpellScript(spell_wyrmrest_skytalon_ride_red_dragon_buddy_trigger_SpellScript); + + bool Load() + { + return GetCaster()->GetTypeId() == TYPEID_UNIT; + } + + void HandleScript(SpellEffIndex /*effIndex*/) + { + if (Unit* target = GetHitUnit()) + target->CastSpell(GetCaster(), GetEffectValue(), true); + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_wyrmrest_skytalon_ride_red_dragon_buddy_trigger_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_wyrmrest_skytalon_ride_red_dragon_buddy_trigger_SpellScript(); + } +}; + +class spell_malygos_surge_of_power_warning_selector_25 : public SpellScriptLoader +{ + public: + spell_malygos_surge_of_power_warning_selector_25() : SpellScriptLoader("spell_malygos_surge_of_power_warning_selector_25") { } + + class spell_malygos_surge_of_power_warning_selector_25_SpellScript : public SpellScript + { + PrepareSpellScript(spell_malygos_surge_of_power_warning_selector_25_SpellScript) + + bool Load() + { + return GetCaster()->GetTypeId() == TYPEID_UNIT; + } + + bool Validate(SpellInfo const* /*spell*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_SURGE_OF_POWER_PHASE_3_25)) + return false; + + return true; + } + + void SendThreeTargets(std::list& targets) + { + Creature* caster = GetCaster()->ToCreature(); + targets.remove_if(isPlayerOnVehicleChecker(caster)); + if (targets.empty()) + return; + + for (std::list::const_iterator itr = targets.begin(); itr != targets.end(); ++itr) + _filteredSelectedTargets.push_back((*itr)); + + if (_filteredSelectedTargets.empty()) + return; + + uint8 guidDataSlot = 14; // SetGuid in Malygos AI is reserved for 14th, 15th and 16th Id for the three targets + Trinity::Containers::RandomResizeList(_filteredSelectedTargets, 3); + for (std::list::const_iterator itr = _filteredSelectedTargets.begin(); itr != _filteredSelectedTargets.end(); ++itr) + { + caster->AI()->SetGUID((*itr)->GetGUID(), guidDataSlot++); + if (IS_VEHICLE_GUID((*itr)->GetGUID())) + { + if (Vehicle* tempVehicle = (*itr)->ToCreature()->GetVehicleKit()) + if (tempVehicle->GetPassenger(0)) + if (Player* tempPlayer = tempVehicle->GetPassenger(0)->ToPlayer()) + caster->AI()->Talk(EMOTE_SURGE_OF_POWER_WARNING_P3, tempPlayer->GetGUID()); + } + else if (IS_PLAYER_GUID((*itr)->GetGUID())) + { + caster->AI()->Talk(EMOTE_SURGE_OF_POWER_WARNING_P3, (*itr)->GetGUID()); + } + } + } + + void ExecuteMainSpell() + { + // We shouldn't cast stuff from target selector hooks + Creature* caster = GetCaster()->ToCreature(); + caster->AI()->DoCastAOE(SPELL_SURGE_OF_POWER_PHASE_3_25); + } + + void Register() + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_malygos_surge_of_power_warning_selector_25_SpellScript::SendThreeTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + AfterHit += SpellHitFn(spell_malygos_surge_of_power_warning_selector_25_SpellScript::ExecuteMainSpell); + } + + std::list _filteredSelectedTargets; + }; + + SpellScript* GetSpellScript() const + { + return new spell_malygos_surge_of_power_warning_selector_25_SpellScript(); + } +}; + +class spell_malygos_surge_of_power_25 : public SpellScriptLoader +{ + public: + spell_malygos_surge_of_power_25() : SpellScriptLoader("spell_malygos_surge_of_power_25") { } + + class spell_malygos_surge_of_power_25_SpellScript : public SpellScript + { + PrepareSpellScript(spell_malygos_surge_of_power_25_SpellScript) + + bool Load() + { + return GetCaster()->GetTypeId() == TYPEID_UNIT; + } + + void FilterTargets(std::list& targets) + { + Creature* caster = GetCaster()->ToCreature(); + if (!targets.empty()) + targets.clear(); + + for (int guidSlot = 14; guidSlot <= 16; guidSlot++) + { + uint64 guidTypeChecker = caster->AI()->GetGUID(guidSlot); + if (IS_EMPTY_GUID(guidTypeChecker)) + continue; + + if (IS_VEHICLE_GUID(guidTypeChecker)) + { + WorldObject* tempTarget = caster->GetMap()->GetCreature(guidTypeChecker); + targets.push_back(tempTarget); + } + else if (IS_PLAYER_GUID(guidTypeChecker)) + { + WorldObject* tempTarget = ObjectAccessor::GetPlayer(*caster, guidTypeChecker); + targets.push_back(tempTarget); + } + } + } + + void Register() + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_malygos_surge_of_power_25_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_malygos_surge_of_power_25_SpellScript(); + } +}; + +class spell_alexstrasza_gift_beam : public SpellScriptLoader +{ + public: + spell_alexstrasza_gift_beam() : SpellScriptLoader("spell_alexstrasza_gift_beam") { } + + class spell_alexstrasza_gift_beam_AuraScript : public AuraScript + { + PrepareAuraScript(spell_alexstrasza_gift_beam_AuraScript); + + bool Load() + { + return GetCaster()->GetTypeId() == TYPEID_UNIT; + } + + bool Validate(SpellInfo const* /*spell*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_ALEXSTRASZAS_GIFT_BEAM_VISUAL)) + return false; + + return true; + } + + void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (Creature* target = GetTarget()->ToCreature()) + target->CastSpell(target, SPELL_ALEXSTRASZAS_GIFT_BEAM_VISUAL); + } + + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (Creature* target = GetTarget()->ToCreature()) + target->RemoveAura(SPELL_ALEXSTRASZAS_GIFT_BEAM_VISUAL); + } + + void Register() + { + OnEffectApply += AuraEffectApplyFn(spell_alexstrasza_gift_beam_AuraScript::OnApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + AfterEffectRemove += AuraEffectRemoveFn(spell_alexstrasza_gift_beam_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_alexstrasza_gift_beam_AuraScript(); + } +}; + +class spell_alexstrasza_gift_beam_visual : public SpellScriptLoader +{ + public: + spell_alexstrasza_gift_beam_visual() : SpellScriptLoader("spell_alexstrasza_gift_beam_visual") { } + + class spell_alexstrasza_gift_beam_visual_AuraScript : public AuraScript + { + PrepareAuraScript(spell_alexstrasza_gift_beam_visual_AuraScript); + + bool Load() + { + return GetCaster()->GetTypeId() == TYPEID_UNIT; + } + + void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (Creature* target = GetTarget()->ToCreature()) + { + if (target->GetMap()->GetDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL) + _alexstraszaGift = target->SummonGameObject(GO_ALEXSTRASZA_S_GIFT_10, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), target->GetOrientation(), 0.0f, 0.0f, 0.0f, 0.0f, 0); + else if (target->GetMap()->GetDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL) + _alexstraszaGift = target->SummonGameObject(GO_ALEXSTRASZA_S_GIFT_25, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), target->GetOrientation(), 0.0f, 0.0f, 0.0f, 0.0f, 0); + } + } + + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (Creature* target = GetTarget()->ToCreature()) + if (InstanceScript* instance = GetCaster()->GetInstanceScript()) + { + _alexstraszaGift->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); + if ((_heartMagic = target->GetMap()->GetGameObject(instance->GetData64(DATA_HEART_OF_MAGIC_GUID)))) + { + _heartMagic->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); + // TO DO: This is hack, core doesn't have support for these flags, + // remove line below if it ever gets supported otherwise object won't be accessible. + _heartMagic->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_INTERACT_COND); + } + } + } + + void Register() + { + OnEffectApply += AuraEffectApplyFn(spell_alexstrasza_gift_beam_visual_AuraScript::OnApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + AfterEffectRemove += AuraEffectRemoveFn(spell_alexstrasza_gift_beam_visual_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } + + GameObject* _alexstraszaGift; + GameObject* _heartMagic; + }; + + AuraScript* GetAuraScript() const + { + return new spell_alexstrasza_gift_beam_visual_AuraScript(); } - private: - EventMap _events; - }; }; class achievement_denyin_the_scion : public AchievementCriteriaScript { public: - achievement_denyin_the_scion() : AchievementCriteriaScript("achievement_denyin_the_scion") {} + achievement_denyin_the_scion() : AchievementCriteriaScript("achievement_denyin_the_scion") { } bool OnCheck(Player* source, Unit* /*target*/) { + // Only melee disks can be used if (Unit* disk = source->GetVehicleBase()) - if (disk->GetEntry() == NPC_HOVER_DISK_CASTER || disk->GetEntry() == NPC_HOVER_DISK_MELEE) + if (disk->GetEntry() == NPC_HOVER_DISK_MELEE) return true; + return false; } }; @@ -1114,11 +2502,29 @@ void AddSC_boss_malygos() new boss_malygos(); new npc_portal_eoe(); new npc_power_spark(); - new npc_hover_disk(); + new npc_melee_hover_disk(); + new npc_caster_hover_disk(); + new npc_nexus_lord(); + new npc_scion_of_eternity(); new npc_arcane_overload(); new npc_wyrmrest_skytalon(); + new npc_static_field(); + new spell_malygos_portal_beam(); + new spell_malygos_random_portal(); + new spell_malygos_arcane_storm(); new spell_malygos_vortex_dummy(); new spell_malygos_vortex_visual(); - new npc_alexstrasza_eoe(); + new spell_arcane_overload(); + new spell_nexus_lord_align_disk_aggro(); + new spell_scion_of_eternity_arcane_barrage(); + new spell_malygos_destroy_platform_channel(); + new spell_alexstrasza_bunny_destroy_platform_boom_visual(); + new spell_alexstrasza_bunny_destroy_platform_event(); + new spell_wyrmrest_skytalon_summon_red_dragon_buddy(); + new spell_wyrmrest_skytalon_ride_red_dragon_buddy_trigger(); + new spell_malygos_surge_of_power_warning_selector_25(); + new spell_malygos_surge_of_power_25(); + new spell_alexstrasza_gift_beam(); + new spell_alexstrasza_gift_beam_visual(); new achievement_denyin_the_scion(); } diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/eye_of_eternity.h b/src/server/scripts/Northrend/Nexus/EyeOfEternity/eye_of_eternity.h index c25feaafaf8..db879eab6fb 100644 --- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/eye_of_eternity.h +++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/eye_of_eternity.h @@ -24,14 +24,19 @@ enum InstanceData MAX_ENCOUNTER, DATA_VORTEX_HANDLING, - DATA_POWER_SPARKS_HANDLING + DATA_POWER_SPARKS_HANDLING, + DATA_RESPAWN_IRIS }; enum InstanceData64 { DATA_TRIGGER, DATA_MALYGOS, - DATA_PLATFORM + DATA_PLATFORM, + DATA_ALEXSTRASZA_BUNNY_GUID, + DATA_HEART_OF_MAGIC_GUID, + DATA_FOCUSING_IRIS_GUID, + DATA_GIFT_BOX_BUNNY_GUID }; enum InstanceNpcs @@ -44,16 +49,22 @@ enum InstanceNpcs NPC_HOVER_DISK_CASTER = 30248, NPC_ARCANE_OVERLOAD = 30282, NPC_WYRMREST_SKYTALON = 30161, - NPC_ALEXSTRASZA = 32295 + NPC_ALEXSTRASZA = 32295, + NPC_ALEXSTRASZA_BUNNY = 31253, + NPC_ALEXSTRASZAS_GIFT = 32448, + NPC_SURGE_OF_POWER = 30334 }; enum InstanceGameObjects { GO_NEXUS_RAID_PLATFORM = 193070, GO_EXIT_PORTAL = 193908, - GO_FOCUSING_IRIS = 193958, - GO_ALEXSTRASZA_S_GIFT = 193905, - GO_ALEXSTRASZA_S_GIFT_2 = 193967 + GO_FOCUSING_IRIS_10 = 193958, + GO_FOCUSING_IRIS_25 = 193960, + GO_ALEXSTRASZA_S_GIFT_10 = 193905, + GO_ALEXSTRASZA_S_GIFT_25 = 193967, + GO_HEART_OF_MAGIC_10 = 194158, + GO_HEART_OF_MAGIC_25 = 194159 }; enum InstanceEvents @@ -63,10 +74,11 @@ enum InstanceEvents enum InstanceSpells { - SPELL_VORTEX_4 = 55853, // damage | used to enter to the vehicle - SPELL_VORTEX_5 = 56263, // damage | used to enter to the vehicle - SPELL_PORTAL_OPENED = 61236, - SPELL_RIDE_RED_DRAGON = 56071, + SPELL_VORTEX_4 = 55853, // damage | used to enter to the vehicle + SPELL_VORTEX_5 = 56263, // damage | used to enter to the vehicle + SPELL_PORTAL_OPENED = 61236, + SPELL_RIDE_RED_DRAGON_TRIGGERED = 56072, + SPELL_IRIS_OPENED = 61012 // visual when starting encounter }; #endif diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp b/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp index 6b1be15f110..601e58fc323 100644 --- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp +++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp @@ -24,7 +24,7 @@ class instance_eye_of_eternity : public InstanceMapScript { public: - instance_eye_of_eternity() : InstanceMapScript("instance_eye_of_eternity", 616) {} + instance_eye_of_eternity() : InstanceMapScript("instance_eye_of_eternity", 616) { } InstanceScript* GetInstanceScript(InstanceMap* map) const { @@ -41,9 +41,11 @@ public: portalTriggers.clear(); malygosGUID = 0; + irisGUID = 0; lastPortalGUID = 0; platformGUID = 0; exitPortalGUID = 0; + alexstraszaBunnyGUID = 0; }; bool SetBossState(uint32 type, EncounterState state) @@ -54,7 +56,7 @@ public: if (type == DATA_MALYGOS_EVENT) { if (state == FAIL) - { + { for (std::list::const_iterator itr_trigger = portalTriggers.begin(); itr_trigger != portalTriggers.end(); ++itr_trigger) { if (Creature* trigger = instance->GetCreature(*itr_trigger)) @@ -65,31 +67,18 @@ public: } } - SpawnGameObject(GO_FOCUSING_IRIS, focusingIrisPosition); SpawnGameObject(GO_EXIT_PORTAL, exitPortalPosition); if (GameObject* platform = instance->GetGameObject(platformGUID)) platform->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_DESTROYED); } else if (state == DONE) - { - if (Creature* malygos = instance->GetCreature(malygosGUID)) - malygos->SummonCreature(NPC_ALEXSTRASZA, 829.0679f, 1244.77f, 279.7453f, 2.32f); - SpawnGameObject(GO_EXIT_PORTAL, exitPortalPosition); - - // we make the platform appear again because at the moment we don't support looting using a vehicle - if (GameObject* platform = instance->GetGameObject(platformGUID)) - platform->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_DESTROYED); - - if (GameObject* chest = instance->GetGameObject(chestGUID)) - chest->SetRespawnTime(7*DAY); - } } return true; } - //TODO: this should be handled in map, maybe add a summon function in map + // TO DO: this should be handled in map, maybe add a summon function in map // There is no other way afaik... void SpawnGameObject(uint32 entry, Position& pos) { @@ -112,16 +101,31 @@ public: case GO_NEXUS_RAID_PLATFORM: platformGUID = go->GetGUID(); break; - case GO_FOCUSING_IRIS: - go->GetPosition(&focusingIrisPosition); + case GO_FOCUSING_IRIS_10: + if (instance->GetDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL) + { + irisGUID = go->GetGUID(); + go->GetPosition(&focusingIrisPosition); + } + break; + case GO_FOCUSING_IRIS_25: + if (instance->GetDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL) + { + irisGUID = go->GetGUID(); + go->GetPosition(&focusingIrisPosition); + } break; case GO_EXIT_PORTAL: exitPortalGUID = go->GetGUID(); go->GetPosition(&exitPortalPosition); break; - case GO_ALEXSTRASZA_S_GIFT: - case GO_ALEXSTRASZA_S_GIFT_2: - chestGUID = go->GetGUID(); + case GO_HEART_OF_MAGIC_10: + if (instance->GetDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL) + heartOfMagicGUID = go->GetGUID(); + break; + case GO_HEART_OF_MAGIC_25: + if (instance->GetDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL) + heartOfMagicGUID = go->GetGUID(); break; } } @@ -139,18 +143,27 @@ public: case NPC_PORTAL_TRIGGER: portalTriggers.push_back(creature->GetGUID()); break; + case NPC_ALEXSTRASZA_BUNNY: + alexstraszaBunnyGUID = creature->GetGUID(); + break; + case NPC_ALEXSTRASZAS_GIFT: + giftBoxBunnyGUID = creature->GetGUID(); + break; } } - void ProcessEvent(WorldObject* obj, uint32 eventId) + void ProcessEvent(WorldObject* /*obj*/, uint32 eventId) { if (eventId == EVENT_FOCUSING_IRIS) - { - if (GameObject* go = obj->ToGameObject()) - go->Delete(); // this is not the best way. + { + if (Creature* alexstraszaBunny = instance->GetCreature(alexstraszaBunnyGUID)) + { + alexstraszaBunny->CastSpell(alexstraszaBunny, SPELL_IRIS_OPENED); + instance->GetGameObject(irisGUID)->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_IN_USE); + } if (Creature* malygos = instance->GetCreature(malygosGUID)) - malygos->GetMotionMaster()->MovePoint(4, 770.10f, 1275.33f, 267.23f); // MOVE_INIT_PHASE_ONE + malygos->AI()->DoAction(0); // ACTION_LAND_ENCOUNTER_START if (GameObject* exitPortal = instance->GetGameObject(exitPortalGUID)) exitPortal->Delete(); @@ -194,7 +207,7 @@ public: void PowerSparksHandling() { - bool next = (lastPortalGUID == portalTriggers.back() || !lastPortalGUID ? true : false); + bool next = (lastPortalGUID == portalTriggers.back() || !lastPortalGUID ? true : false); for (std::list::const_iterator itr_trigger = portalTriggers.begin(); itr_trigger != portalTriggers.end(); ++itr_trigger) { @@ -223,6 +236,9 @@ public: case DATA_POWER_SPARKS_HANDLING: PowerSparksHandling(); break; + case DATA_RESPAWN_IRIS: + SpawnGameObject(instance->GetDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL ? GO_FOCUSING_IRIS_10 : GO_FOCUSING_IRIS_25, focusingIrisPosition); + break; } } @@ -236,6 +252,14 @@ public: return malygosGUID; case DATA_PLATFORM: return platformGUID; + case DATA_ALEXSTRASZA_BUNNY_GUID: + return alexstraszaBunnyGUID; + case DATA_HEART_OF_MAGIC_GUID: + return heartOfMagicGUID; + case DATA_FOCUSING_IRIS_GUID: + return irisGUID; + case DATA_GIFT_BOX_BUNNY_GUID: + return giftBoxBunnyGUID; } return 0; @@ -287,10 +311,13 @@ public: std::list vortexTriggers; std::list portalTriggers; uint64 malygosGUID; + uint64 irisGUID; uint64 lastPortalGUID; uint64 platformGUID; uint64 exitPortalGUID; - uint64 chestGUID; + uint64 heartOfMagicGUID; + uint64 alexstraszaBunnyGUID; + uint64 giftBoxBunnyGUID; Position focusingIrisPosition; Position exitPortalPosition; }; -- cgit v1.2.3 From 6343a28030e5ca7ad337226ef5e37704714aa594 Mon Sep 17 00:00:00 2001 From: Vincent_Michael Date: Thu, 28 Feb 2013 18:29:43 +0100 Subject: Core: Whitespace cleanup --- src/server/game/Entities/Player/Player.h | 2 +- .../Northrend/Nexus/EyeOfEternity/boss_malygos.cpp | 48 +++++++++++----------- .../EyeOfEternity/instance_eye_of_eternity.cpp | 4 +- 3 files changed, 27 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index a3327e20c93..a7c0cb2e736 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -1189,7 +1189,7 @@ class Player : public Unit, public GridObject void RemovePet(Pet* pet, PetSaveMode mode, bool returnreagent = false); uint32 GetPhaseMaskForSpawn() const; // used for proper set phase for DB at GM-mode creature/GO spawn - /// Handles said message in regular chat based on declared language and in config pre-defined Range. + /// Handles said message in regular chat based on declared language and in config pre-defined Range. void Say(std::string const& text, const uint32 language); /// Handles yelled message in regular chat based on declared language and in config pre-defined Range. void Yell(std::string const& text, const uint32 language); diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp index 658fa48fd3a..b258be20feb 100644 --- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp +++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp @@ -156,7 +156,7 @@ enum Spells enum Movements { POINT_NEAR_RANDOM_PORTAL_P_NONE = 1, - POINT_LAND_P_ONE, + POINT_LAND_P_ONE, POINT_VORTEX_P_ONE, POINT_LAND_AFTER_VORTEX_P_ONE, POINT_LIFT_IN_AIR_P_ONE, @@ -286,7 +286,7 @@ Position const MalygosPositions[MAX_MALYGOS_POS] = { 754.393f, 1301.27f, 292.91f, 0.0f }, // Point vortex { 754.362f, 1301.61f, 266.17f, 0.0f }, // Land after vortex { 754.695f, 1301.66f, 316.65f, 0.0f }, // Point surge of Power phase II - { 755.681f, 1298.41f, 220.06f, 0.0f } // Point idle phase III + { 755.681f, 1298.41f, 220.06f, 0.0f } // Point idle phase III }; Position const AlexstraszaSpawnPos = { 854.551f, 1225.31f, 300.901f, 0.0f }; // Alexstrasza's spawn position @@ -372,10 +372,10 @@ public: me->SetSpeed(MOVE_FLIGHT, _flySpeed * 0.25f); if (_despawned) DoAction(ACTION_HANDLE_RESPAWN); - + SetPhase(PHASE_NOT_STARTED, true); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - me->SetReactState(REACT_PASSIVE); + me->SetReactState(REACT_PASSIVE); if (instance) instance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMED_START_EVENT); } @@ -383,7 +383,7 @@ public: uint32 GetData(uint32 data) const { switch (data) - { + { case DATA_SUMMON_DEATHS: return _summonDeaths; case DATA_PHASE: @@ -415,7 +415,7 @@ public: DoAction(ACTION_HANDLE_P_THREE_INTRO); } } - } + } } uint64 GetGUID(int32 data) const @@ -624,7 +624,7 @@ public: else if (_phase == PHASE_THREE) summons.DespawnAll(); } - + if (instance) instance->SetBossState(DATA_MALYGOS_EVENT, NOT_STARTED); } @@ -633,7 +633,7 @@ public: { if (victim->GetTypeId() != TYPEID_PLAYER) return; - + if (!_killSpamFilter) { switch (_phase) @@ -667,7 +667,7 @@ public: Talk(SAY_BUFF_SPARK); } else if (spell->Id == SPELL_MALYGOS_BERSERK) - sCreatureTextMgr->SendChat(me, EMOTE_HIT_BERSERKER_TIMER, 0, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_MAP); + sCreatureTextMgr->SendChat(me, EMOTE_HIT_BERSERKER_TIMER, 0, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_MAP); } void MoveInLineOfSight(Unit* who) @@ -679,7 +679,7 @@ public: if (who->GetDistance(me) <= 2.5f) who->CastSpell(me, SPELL_POWER_SPARK_MALYGOS, true); } - + void MovementInform(uint32 type, uint32 id) { if (type != POINT_MOTION_TYPE && type != EFFECT_MOTION_TYPE) @@ -928,7 +928,7 @@ public: case EVENT_LIGHT_DIMENSION_CHANGE: SendLightOverride(LIGHT_CHANGE_DIMENSIONS, 2*IN_MILLISECONDS); break; - case EVENT_MOVE_TO_P_THREE_POINT: + case EVENT_MOVE_TO_P_THREE_POINT: Talk(SAY_START_P_THREE); me->GetMotionMaster()->MovePoint(POINT_IDLE_P_THREE, MalygosPositions[4]); break; @@ -1002,7 +1002,7 @@ public: me->DespawnOrUnsummon(5*IN_MILLISECONDS); } - private: + private: // Used to generate perfect cyclic movements (Enter Circle). void FillCirclePath(Position const& centerPos, float radius, float z, Movement::PointsArray& path, bool clockwise) { @@ -1018,7 +1018,7 @@ public: path.push_back(point); } } - + // Function that will change lights of map for all players on map. void SendLightOverride(uint32 overrideId, uint32 fadeInTime) const { @@ -1051,7 +1051,7 @@ public: Unit* _tempSurgeTarget; // These three are used for 10 man Surge of Power targeting. Vehicle* _drakeVehicle; Player* _playerSurgeTarget; - + bool _killSpamFilter; // Prevent text spamming on killed player by helping implement a CD. bool _canAttack; // Used to control attacking (Move Chase not being applied after Stop Attack, only few times should act like this). bool _despawned; // Checks if boss pass through evade on reset. @@ -1361,7 +1361,7 @@ public: path.push_back(point); } } - + InstanceScript* _instance; }; @@ -1680,7 +1680,7 @@ class spell_malygos_portal_beam : public SpellScriptLoader if (Creature* target = GetTarget()->ToCreature()) target->CastSpell(target, SPELL_PORTAL_OPENED); } - + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { if (Creature* target = GetTarget()->ToCreature()) @@ -2005,13 +2005,13 @@ class IsPlayerOnHoverDiskCheck if (!passenger->GetVehicleBase()) return true; } - + return false; } private: Unit* _source; - + bool _isOnHoverDisk; }; @@ -2065,7 +2065,7 @@ class spell_malygos_destroy_platform_channel : public SpellScriptLoader class spell_malygos_destroy_platform_channel_AuraScript : public AuraScript { PrepareAuraScript(spell_malygos_destroy_platform_channel_AuraScript); - + bool Load() { return GetCaster()->GetTypeId() == TYPEID_UNIT; @@ -2149,7 +2149,7 @@ class spell_alexstrasza_bunny_destroy_platform_event : public SpellScriptLoader class spell_alexstrasza_bunny_destroy_platform_event_SpellScript : public SpellScript { PrepareSpellScript(spell_alexstrasza_bunny_destroy_platform_event_SpellScript); - + bool Load() { return GetCaster()->GetTypeId() == TYPEID_UNIT; @@ -2157,12 +2157,12 @@ class spell_alexstrasza_bunny_destroy_platform_event : public SpellScriptLoader void HandleSendEvent(SpellEffIndex /*effIndex*/) { - Creature* caster = GetCaster()->ToCreature(); + Creature* caster = GetCaster()->ToCreature(); if (InstanceScript* instance = caster->GetInstanceScript()) if (GameObject* platform = caster->GetMap()->GetGameObject(instance->GetData64(DATA_PLATFORM))) platform->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_DESTROYED); } - + void HandleScript(SpellEffIndex /*effIndex*/) { Creature* caster = GetCaster()->ToCreature(); @@ -2316,7 +2316,7 @@ class spell_malygos_surge_of_power_warning_selector_25 : public SpellScriptLoade OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_malygos_surge_of_power_warning_selector_25_SpellScript::SendThreeTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); AfterHit += SpellHitFn(spell_malygos_surge_of_power_warning_selector_25_SpellScript::ExecuteMainSpell); } - + std::list _filteredSelectedTargets; }; @@ -2385,7 +2385,7 @@ class spell_alexstrasza_gift_beam : public SpellScriptLoader class spell_alexstrasza_gift_beam_AuraScript : public AuraScript { PrepareAuraScript(spell_alexstrasza_gift_beam_AuraScript); - + bool Load() { return GetCaster()->GetTypeId() == TYPEID_UNIT; diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp b/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp index 601e58fc323..52ce259117f 100644 --- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp +++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp @@ -56,7 +56,7 @@ public: if (type == DATA_MALYGOS_EVENT) { if (state == FAIL) - { + { for (std::list::const_iterator itr_trigger = portalTriggers.begin(); itr_trigger != portalTriggers.end(); ++itr_trigger) { if (Creature* trigger = instance->GetCreature(*itr_trigger)) @@ -155,7 +155,7 @@ public: void ProcessEvent(WorldObject* /*obj*/, uint32 eventId) { if (eventId == EVENT_FOCUSING_IRIS) - { + { if (Creature* alexstraszaBunny = instance->GetCreature(alexstraszaBunnyGUID)) { alexstraszaBunny->CastSpell(alexstraszaBunny, SPELL_IRIS_OPENED); -- cgit v1.2.3 From f3e788693423a29c027c1f083f9597968660eda7 Mon Sep 17 00:00:00 2001 From: Shauren Date: Thu, 28 Feb 2013 20:25:20 +0100 Subject: Core/Spells: Defined two spell attributes --- src/server/game/Entities/Unit/Unit.cpp | 2 +- src/server/game/Miscellaneous/SharedDefines.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 508f4b602de..9989988aa7e 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -11780,7 +11780,7 @@ bool Unit::_IsValidAssistTarget(Unit const* target, SpellInfo const* bySpell) co && target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE)) return false; - if (!bySpell || !(bySpell->AttributesEx6 & SPELL_ATTR6_UNK3)) + if (!bySpell || !(bySpell->AttributesEx6 & SPELL_ATTR6_ASSIST_IGNORE_IMMUNE_FLAG)) { if (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE)) { diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index 6f60aec4beb..dd64b2d88dc 100644 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -486,7 +486,7 @@ enum SpellAttr6 SPELL_ATTR6_DONT_DISPLAY_COOLDOWN = 0x00000001, // 0 client doesn't display cooldown in tooltip for these spells SPELL_ATTR6_ONLY_IN_ARENA = 0x00000002, // 1 only usable in arena SPELL_ATTR6_IGNORE_CASTER_AURAS = 0x00000004, // 2 - SPELL_ATTR6_UNK3 = 0x00000008, // 3 + SPELL_ATTR6_ASSIST_IGNORE_IMMUNE_FLAG = 0x00000008, // 3 skips checking UNIT_FLAG_IMMUNE_TO_PC and UNIT_FLAG_IMMUNE_TO_NPC flags on assist SPELL_ATTR6_UNK4 = 0x00000010, // 4 SPELL_ATTR6_UNK5 = 0x00000020, // 5 SPELL_ATTR6_PRINT_SPELLNAME = 0x00000040, // 6 when activated, spell name is shown at the center of the screen: (client-side attribute) @@ -547,7 +547,7 @@ enum SpellAttr7 SPELL_ATTR7_UNK25 = 0x02000000, // 25 SPELL_ATTR7_UNK26 = 0x04000000, // 26 SPELL_ATTR7_UNK27 = 0x08000000, // 27 Not set - SPELL_ATTR7_BENEFIT_FROM_SPELLMOD = 0x10000000, // 28 Non-permanent, non-passive buffs that may benefit from spellmods + SPELL_ATTR7_CONSOLIDATED_RAID_BUFF = 0x10000000, // 28 May be collapsed in raid buff frame (clientside attribute) SPELL_ATTR7_UNK29 = 0x20000000, // 29 only 69028, 71237 SPELL_ATTR7_UNK30 = 0x40000000, // 30 Burning Determination, Divine Sacrifice, Earth Shield, Prayer of Mending SPELL_ATTR7_CLIENT_INDICATOR = 0x80000000 -- cgit v1.2.3 From 4a6f5d2b54831f2f02aae8fe55a8caa761cedaaf Mon Sep 17 00:00:00 2001 From: Shauren Date: Thu, 28 Feb 2013 20:46:50 +0100 Subject: Core/Spells: Defined & implemented SPELL_ATTR6_IGNORE_CATEGORY_COOLDOWN_MODS --- src/server/game/Entities/Player/Player.cpp | 2 +- src/server/game/Entities/Unit/Unit.cpp | 2 +- src/server/game/Miscellaneous/SharedDefines.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 8647d9d6f5e..cae664ffa1a 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -21474,7 +21474,7 @@ void Player::AddSpellAndCategoryCooldowns(SpellInfo const* spellInfo, uint32 ite if (rec > 0) ApplySpellMod(spellInfo->Id, SPELLMOD_COOLDOWN, rec, spell); - if (catrec > 0) + if (catrec > 0 && !(spellInfo->AttributesEx6 & SPELL_ATTR6_IGNORE_CATEGORY_COOLDOWN_MODS)) ApplySpellMod(spellInfo->Id, SPELLMOD_COOLDOWN, catrec, spell); // replace negative cooldowns by 0 diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 9989988aa7e..e899e5d5930 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -11827,7 +11827,7 @@ bool Unit::_IsValidAssistTarget(Unit const* target, SpellInfo const* bySpell) co // PvC case - player can assist creature only if has specific type flags // !target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE) && else if (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE) - && (!bySpell || !(bySpell->AttributesEx6 & SPELL_ATTR6_UNK3)) + && (!bySpell || !(bySpell->AttributesEx6 & SPELL_ATTR6_ASSIST_IGNORE_IMMUNE_FLAG)) && !((target->GetByteValue(UNIT_FIELD_BYTES_2, 1) & UNIT_BYTE2_FLAG_PVP))) { if (Creature const* creatureTarget = target->ToCreature()) diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index dd64b2d88dc..ace844f7cdf 100644 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -489,7 +489,7 @@ enum SpellAttr6 SPELL_ATTR6_ASSIST_IGNORE_IMMUNE_FLAG = 0x00000008, // 3 skips checking UNIT_FLAG_IMMUNE_TO_PC and UNIT_FLAG_IMMUNE_TO_NPC flags on assist SPELL_ATTR6_UNK4 = 0x00000010, // 4 SPELL_ATTR6_UNK5 = 0x00000020, // 5 - SPELL_ATTR6_PRINT_SPELLNAME = 0x00000040, // 6 when activated, spell name is shown at the center of the screen: (client-side attribute) + SPELL_ATTR6_USE_SPELL_CAST_EVENT = 0x00000040, // 6 Auras with this attribute trigger SPELL_CAST combat log event instead of SPELL_AURA_START (clientside attribute) SPELL_ATTR6_UNK7 = 0x00000080, // 7 SPELL_ATTR6_CANT_TARGET_CROWD_CONTROLLED = 0x00000100, // 8 SPELL_ATTR6_UNK9 = 0x00000200, // 9 @@ -514,7 +514,7 @@ enum SpellAttr6 SPELL_ATTR6_UNK28 = 0x10000000, // 28 Death Grip SPELL_ATTR6_NO_DONE_PCT_DAMAGE_MODS = 0x20000000, // 29 ignores done percent damage mods? SPELL_ATTR6_UNK30 = 0x40000000, // 30 - SPELL_ATTR6_UNK31 = 0x80000000 // 31 some special cooldown calc? only 2894 + SPELL_ATTR6_IGNORE_CATEGORY_COOLDOWN_MODS = 0x80000000 // 31 Spells with this attribute skip applying modifiers to category cooldowns }; enum SpellAttr7 -- cgit v1.2.3 From d069e1b6b4d9f839df1a823d0ec1ddfa6dea303c Mon Sep 17 00:00:00 2001 From: Shauren Date: Thu, 28 Feb 2013 21:20:40 +0100 Subject: Core/Spells: Defined spell attributes related to aura visibility --- src/server/game/Miscellaneous/SharedDefines.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index ace844f7cdf..c6e58e9cb3a 100644 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -474,8 +474,8 @@ enum SpellAttr5 SPELL_ATTR5_UNK24 = 0x01000000, // 24 SPELL_ATTR5_UNK25 = 0x02000000, // 25 SPELL_ATTR5_UNK26 = 0x04000000, // 26 aoe related - Boulder, Cannon, Corpse Explosion, Fire Nova, Flames, Frost Bomb, Living Bomb, Seed of Corruption, Starfall, Thunder Clap, Volley - SPELL_ATTR5_UNK27 = 0x08000000, // 27 - SPELL_ATTR5_UNK28 = 0x10000000, // 28 + SPELL_ATTR5_DONT_SHOW_AURA_IF_SELF_CAST = 0x08000000, // 27 Auras with this attribute are not visible on units that are the caster + SPELL_ATTR5_DONT_SHOW_AURA_IF_NOT_SELF_CAST = 0x10000000, // 28 Auras with this attribute are not visible on units that are not the caster SPELL_ATTR5_UNK29 = 0x20000000, // 29 SPELL_ATTR5_UNK30 = 0x40000000, // 30 SPELL_ATTR5_UNK31 = 0x80000000 // 31 Forces all nearby enemies to focus attacks caster @@ -503,7 +503,7 @@ enum SpellAttr6 SPELL_ATTR6_UNK17 = 0x00020000, // 17 Mount spell SPELL_ATTR6_CAST_BY_CHARMER = 0x00040000, // 18 client won't allow to cast these spells when unit is not possessed && charmer of caster will be original caster SPELL_ATTR6_UNK19 = 0x00080000, // 19 only 47488, 50782 - SPELL_ATTR6_UNK20 = 0x00100000, // 20 only 58371, 62218 + SPELL_ATTR6_ONLY_VISIBLE_TO_CASTER = 0x00100000, // 20 Auras with this attribute are only visible to their caster (or pet's owner) SPELL_ATTR6_CLIENT_UI_TARGET_EFFECTS = 0x00200000, // 21 it's only client-side attribute SPELL_ATTR6_UNK22 = 0x00400000, // 22 only 72054 SPELL_ATTR6_UNK23 = 0x00800000, // 23 -- cgit v1.2.3