diff --git a/sql/ashamane/world/2018_07_08_00_world_warrior_class_hall_tp.sql b/sql/ashamane/world/2018_07_08_00_world_warrior_class_hall_tp.sql new file mode 100644 index 0000000000000..93e38a215caf3 --- /dev/null +++ b/sql/ashamane/world/2018_07_08_00_world_warrior_class_hall_tp.sql @@ -0,0 +1,34 @@ +-- Link the gossip menu to the creature +UPDATE `creature_template` SET `gossip_menu_id`=18724 WHERE `entry`=96679; -- Aerylia + +UPDATE `gossip_menu_option` SET `OptionBroadcastTextId`=0 WHERE (`MenuId`=18724 AND `OptionIndex`=2); +UPDATE `gossip_menu_option` SET `OptionBroadcastTextId`=0 WHERE (`MenuId`=18724 AND `OptionIndex`=3); +UPDATE `gossip_menu_option` SET `OptionBroadcastTextId`=0 WHERE (`MenuId`=18724 AND `OptionIndex`=4); +UPDATE `gossip_menu_option` SET `OptionBroadcastTextId`=0 WHERE (`MenuId`=18724 AND `OptionIndex`=5); +UPDATE `gossip_menu_option` SET `OptionBroadcastTextId`=0 WHERE (`MenuId`=18724 AND `OptionIndex`=6); +UPDATE `gossip_menu_option` SET `OptionBroadcastTextId`=0 WHERE (`MenuId`=18724 AND `OptionIndex`=7); +UPDATE `gossip_menu_option` SET `OptionBroadcastTextId`=0 WHERE (`MenuId`=18724 AND `OptionIndex`=8); + +UPDATE `gossip_menu_option` SET `OptionType`=1, `OptionNpcFlag`=1 WHERE `MenuId`=18724; + +DELETE FROM `spell_script_names` WHERE `spell_id` IN (191473, 225220, 225163, 225115, 205813, 225233, 241928); +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(191473, 'spell_class_hall_warrior_jump_exit'), +(225220, 'spell_class_hall_warrior_jump_exit'), +(225163, 'spell_class_hall_warrior_jump_exit'), +(225115, 'spell_class_hall_warrior_jump_exit'), +(205813, 'spell_class_hall_warrior_jump_exit'), +(225233, 'spell_class_hall_warrior_jump_exit'), +(241928, 'spell_class_hall_warrior_jump_exit'); + +DELETE FROM `spell_script_names` WHERE `spell_id` IN (191474, 225219, 225162, 225114, 205814, 225232, 241931); +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(191474, 'spell_class_hall_warrior_jump_teleport'), +(225219, 'spell_class_hall_warrior_jump_teleport'), +(225162, 'spell_class_hall_warrior_jump_teleport'), +(225114, 'spell_class_hall_warrior_jump_teleport'), +(205814, 'spell_class_hall_warrior_jump_teleport'), +(225232, 'spell_class_hall_warrior_jump_teleport'), +(241931, 'spell_class_hall_warrior_jump_teleport'); + +UPDATE `creature_template` SET `ScriptName` = 'npc_class_hall_warrior_aerylia' WHERE `entry`=96679; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 5139262bdb8c3..e6f6e26887324 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -196,6 +196,7 @@ Player::Player(WorldSession* session) : Unit(true), m_sceneMgr(this), m_archaeol m_bCanDelayTeleport = false; m_bHasDelayedTeleport = false; m_teleport_options = 0; + m_teleport_option_param = 0; m_trade = nullptr; @@ -1459,7 +1460,7 @@ uint8 Player::GetChatFlags() const return tag; } -bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options) +bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options, uint32 optionParam) { if (!MapManager::IsValidMapCoord(mapid, x, y, z, orientation)) { @@ -1538,6 +1539,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati //lets save teleport destination for player m_teleport_dest = WorldLocation(mapid, x, y, z, orientation); m_teleport_options = options; + m_teleport_option_param = optionParam; return true; } @@ -1554,6 +1556,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati // this will be used instead of the current location in SaveToDB m_teleport_dest = WorldLocation(mapid, x, y, z, orientation); m_teleport_options = options; + m_teleport_option_param = optionParam; SetFallInformation(0, z); // code for finish transfer called in WorldSession::HandleMovementOpcodes() @@ -1604,6 +1607,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati //lets save teleport destination for player m_teleport_dest = WorldLocation(mapid, x, y, z, orientation); m_teleport_options = options; + m_teleport_option_param = optionParam; return true; } @@ -1695,16 +1699,16 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati return true; } -bool Player::TeleportTo(uint32 mapid, Position const &pos, uint32 options /*= 0*/) +bool Player::TeleportTo(uint32 mapid, Position const &pos, uint32 options /*= 0*/, uint32 optionParam /*= 0*/) { WorldLocation loc(mapid); loc.Relocate(pos); - return TeleportTo(loc, options); + return TeleportTo(loc, options, optionParam); } -bool Player::TeleportTo(WorldLocation const &loc, uint32 options /*= 0*/) +bool Player::TeleportTo(WorldLocation const &loc, uint32 options /*= 0*/, uint32 optionParam /*= 0*/) { - return TeleportTo(loc.GetMapId(), loc.GetPositionX(), loc.GetPositionY(), loc.GetPositionZ(), loc.GetOrientation(), options); + return TeleportTo(loc.GetMapId(), loc.GetPositionX(), loc.GetPositionY(), loc.GetPositionZ(), loc.GetOrientation(), options, optionParam); } bool Player::TeleportTo(AreaTriggerTeleportStruct const* at) diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 1c239f302fa4b..982cf82a7e931 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -770,7 +770,8 @@ enum TeleportToOptions TELE_TO_NOT_LEAVE_COMBAT = 0x04, TELE_TO_NOT_UNSUMMON_PET = 0x08, TELE_TO_SPELL = 0x10, - TELE_TO_SEAMLESS = 0x20 + TELE_TO_SEAMLESS = 0x20, + TELE_TO_CAST_ON_ARRIVAL = 0x40 }; /// Type of environmental damages @@ -1091,9 +1092,9 @@ class TC_GAME_API Player : public Unit, public GridObject void SetObjectScale(float scale) override; - bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options = 0); - bool TeleportTo(uint32 mapid, Position const &pos, uint32 options = 0); - bool TeleportTo(WorldLocation const &loc, uint32 options = 0); + bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options = 0, uint32 optionParam = 0); + bool TeleportTo(uint32 mapid, Position const &pos, uint32 options = 0, uint32 optionParam = 0); + bool TeleportTo(WorldLocation const &loc, uint32 options = 0, uint32 optionParam = 0); bool TeleportTo(AreaTriggerTeleportStruct const* at); bool SeamlessTeleportToMap(uint32 mapid, uint32 options = 0); bool TeleportToBGEntryPoint(); @@ -2008,6 +2009,9 @@ class TC_GAME_API Player : public Unit, public GridObject bool IsBeingTeleportedNear() const { return mSemaphoreTeleport_Near; } bool IsBeingTeleportedFar() const { return mSemaphoreTeleport_Far; } bool IsBeingTeleportedSeamlessly() const { return IsBeingTeleportedFar() && m_teleport_options & TELE_TO_SEAMLESS; } + bool IsBeingTeleportedWithCastOnArrival() const { return IsBeingTeleportedFar() && m_teleport_options & TELE_TO_CAST_ON_ARRIVAL; } + uint32 GetOnArrivalCastSpellTeleport() const { return IsBeingTeleportedWithCastOnArrival() ? m_teleport_option_param : 0; } + void ResetOnArrivalCastSpellTeleport() { m_teleport_option_param = 0; } void SetSemaphoreTeleportNear(bool semphsetting) { mSemaphoreTeleport_Near = semphsetting; } void SetSemaphoreTeleportFar(bool semphsetting) { mSemaphoreTeleport_Far = semphsetting; } void ProcessDelayedOperations(); @@ -2836,6 +2840,7 @@ class TC_GAME_API Player : public Unit, public GridObject // Current teleport data WorldLocation m_teleport_dest; uint32 m_teleport_options; + uint32 m_teleport_option_param; bool mSemaphoreTeleport_Near; bool mSemaphoreTeleport_Far; diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp index 7d3993459c936..a3ddbed41bdc3 100644 --- a/src/server/game/Handlers/MovementHandler.cpp +++ b/src/server/game/Handlers/MovementHandler.cpp @@ -47,6 +47,9 @@ void WorldSession::HandleMoveWorldportAck() if (!GetPlayer()->IsBeingTeleportedFar()) return; + // We must calculate this before SetSemaphoreTeleportFar(false) + uint32 castOnArrivalSpellId = GetPlayer()->GetOnArrivalCastSpellTeleport(); + bool seamlessTeleport = GetPlayer()->IsBeingTeleportedSeamlessly(); GetPlayer()->SetSemaphoreTeleportFar(false); @@ -215,6 +218,13 @@ void WorldSession::HandleMoveWorldportAck() // resummon pet GetPlayer()->ResummonPetTemporaryUnSummonedIfAny(); + // now that the player has been relocated, it's time to cast the arrival spell (if any) + if (castOnArrivalSpellId != 0) + { + GetPlayer()->CastSpell(GetPlayer(), castOnArrivalSpellId, true); + GetPlayer()->ResetOnArrivalCastSpellTeleport(); + } + //lets process all delayed operations on successful teleport GetPlayer()->ProcessDelayedOperations(); } diff --git a/src/server/scripts/BrokenIsles/ClassHalls/class_hall_warrior.cpp b/src/server/scripts/BrokenIsles/ClassHalls/class_hall_warrior.cpp index 2cc59ef0f69e4..8823ef1240850 100644 --- a/src/server/scripts/BrokenIsles/ClassHalls/class_hall_warrior.cpp +++ b/src/server/scripts/BrokenIsles/ClassHalls/class_hall_warrior.cpp @@ -17,7 +17,121 @@ */ #include "ScriptMgr.h" +#include "Spell.h" +#include "SpellPackets.h" +#include "ScriptedGossip.h" + +// Jump to teleport out of the class hall +// 191473 (Dalaran), 225220 (Stormheim), 225163 (Aszuna), 225115 (Val'sharah), +// 205813 (Highmountain), 225233 (Suramar), 241928 (Broken Shore) +class spell_class_hall_warrior_jump_exit : public SpellScript +{ + PrepareSpellScript(spell_class_hall_warrior_jump_exit); + + void SetDest(SpellDestination& dest) + { + dest.Relocate(Position(1108.74f, 7222.535f, 39.45004f)); + } + + void Register() override + { + OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_class_hall_warrior_jump_exit::SetDest, EFFECT_0, TARGET_DEST_DEST_RANDOM); + } +}; + +// Teleport to destination: override it to add TELE_TO_CAST_ON_ARRIVAL and cast the final animation +// 191474 (Dalaran), 225219 (Stormheim), 225162 (Aszuna), 225114 (Val'sharah), +// 205814 (Highmountain), 225232 (Suramar), 241931 (Broken Shore) +class spell_class_hall_warrior_jump_teleport : public SpellScript +{ + PrepareSpellScript(spell_class_hall_warrior_jump_teleport); + + void SaveDest(SpellDestination& dest) + { + _loc = dest._position; + } + + void HandleTeleport(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + if (Player* player = GetHitPlayer()) + { + player->SendDirectMessage(WorldPackets::Spells::CustomLoadScreen(GetSpellInfo()->Id, GetSpellInfo()->GetEffect(effIndex)->MiscValue).Write()); + player->TeleportTo(_loc.GetMapId(), _loc.GetPositionX(), _loc.GetPositionY(), _loc.GetPositionZ(), _loc.GetOrientation(), + TELE_TO_SPELL | TELE_TO_NOT_LEAVE_COMBAT | TELE_TO_CAST_ON_ARRIVAL, 247832); // 247832 = SkyJump, visual of the landing + stun removal + } + } + + void Register() override + { + OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_class_hall_warrior_jump_teleport::SaveDest, EFFECT_0, TARGET_DEST_DB); + OnEffectHitTarget += SpellEffectFn(spell_class_hall_warrior_jump_teleport::HandleTeleport, EFFECT_0, SPELL_EFFECT_TELEPORT_UNITS); + } + +private: + WorldLocation _loc; +}; + +enum classHallTeleportSpells +{ + SPELL_TELE_DALARAN = 191473, + SPELL_TELE_STORMHEIM = 225220, + SPELL_TELE_ASZUNA = 225163, + SPELL_TELE_VALSHARAH = 225115, + SPELL_TELE_HIGHMOUNTAIN = 205813, + SPELL_TELE_SURAMAR = 225233, + SPELL_TELE_BROKEN_SHORE = 241928 +}; + +// 96679 +struct npc_class_hall_warrior_aerylia : public ScriptedAI +{ + npc_class_hall_warrior_aerylia(Creature* creature) : ScriptedAI(creature) { } + + void sGossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override + { + uint32 spellId = 0; + switch (gossipListId) + { + case 2: + spellId = SPELL_TELE_DALARAN; + break; + case 3: + spellId = SPELL_TELE_STORMHEIM; + break; + case 4: + spellId = SPELL_TELE_ASZUNA; + break; + case 5: + spellId = SPELL_TELE_VALSHARAH; + break; + case 6: + spellId = SPELL_TELE_HIGHMOUNTAIN; + break; + case 7: + spellId = SPELL_TELE_SURAMAR; + break; + case 8: + spellId = SPELL_TELE_BROKEN_SHORE; + break; + default: + break; + } + + if (spellId != 0) + { + player->InterruptNonMeleeSpells(true); + player->CastSpell(player, spellId, false); + } + + CloseGossipMenuFor(player); + } +}; void AddSC_class_hall_warrior() { + RegisterSpellScript(spell_class_hall_warrior_jump_exit); + RegisterSpellScript(spell_class_hall_warrior_jump_teleport); + + RegisterCreatureAI(npc_class_hall_warrior_aerylia); }