diff --git a/apps/installer/includes/functions.sh b/apps/installer/includes/functions.sh index ea901c288..8b70e4acb 100644 --- a/apps/installer/includes/functions.sh +++ b/apps/installer/includes/functions.sh @@ -223,7 +223,7 @@ function inst_simple_restarter { function inst_download_client_data { # change the following version when needed - local VERSION=v15 + local VERSION=v14 echo "#######################" echo "Client data downloader" diff --git a/data/sql/updates/db_world/2022_05_11_00.sql b/data/sql/updates/db_world/2022_05_11_00.sql new file mode 100644 index 000000000..bb30091af --- /dev/null +++ b/data/sql/updates/db_world/2022_05_11_00.sql @@ -0,0 +1,3 @@ +-- DB update 2022_05_09_00 -> 2022_05_11_00 +-- +DELETE FROM `spell_script_names` WHERE `ScriptName`='aura_class_call_berserk'; diff --git a/data/sql/updates/db_world/2022_05_11_01.sql b/data/sql/updates/db_world/2022_05_11_01.sql new file mode 100644 index 000000000..c6757e371 --- /dev/null +++ b/data/sql/updates/db_world/2022_05_11_01.sql @@ -0,0 +1,55 @@ +-- DB update 2022_05_11_00 -> 2022_05_11_01 +-- Add major mattingly and overlord rhuntak creature_text +DELETE FROM `creature_text` WHERE `CreatureID` IN (14394, 14392); +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(14394, 0, 0, 'Citizens and allies of Stormwind, on this day, history has been made. $n has laid waste to that which had attempted to usurp the rule of the kingdom. Gather round and join me in honoring our heroes.', 14, 0, 100, 0, 0, 0, 9495, 0, 'Major Mattingly'), +(14394, 1, 0, 'Behold the might of the Alliance! The dread lady, Onyxia, hangs from the arches! Let the rallying cry of the dragon slayer lift your spirits!', 14, 0, 100, 0, 0, 0, 9496, 0, 'Major Mattingly'), +(14392, 0, 0, 'People of the Horde, citizens of Orgrimmar, come, gather round and celebrate a hero of the Horde. On this day, $n, under the auspices of our glorious Warchief, laid a mortal blow against the Black Dragonflight. The brood mother, Onyxia, has been slain!', 14, 0, 100, 0, 0, 0, 9491, 0, 'overlord runthak'), +(14392, 1, 0, 'Bear witness to the undeniable power of your Warchief! Be lifted by the rallying cry of your dragon slayers!', 14, 0, 100, 0, 0, 0, 9492, 0, 'overlord runthak'), +(14392, 2, 0, 'NEFARIAN IS SLAIN! People of Orgrimmar, bow down before the might of $n and $g his:her; allies for they have laid a blow against the Black Dragonflight that is sure to stir the Aspects from their malaise! This defeat shall surely be felt by the father of the Black Flight: Deathwing reels in pain and anguish this day!', 14, 0, 100, 0, 0, 0, 9867, 0, 'overlord runthak'), +(14392, 3, 0, 'Be lifted by $n\'s accomplishment! Revel in $g his:her; rallying cry!', 14, 0, 100, 0, 0, 0, 9868, 0, 'overlord runthak'); +-- Add major mattingly and rhuntak smartai +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` IN (14394, 14392); +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` IN (14394, 14392)) OR (`source_type` = 9 AND `entryorguid` IN (1439400, 1439200, 1439201)); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(14394, 0, 0, 1, 20, 0, 100, 512, 7496, 0, 0, 0, 0, 80, 1439400, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Major Mattingly - On Quest Celebrating Good Times Finished - Run Script'), +(14394, 0, 1, 0, 61, 0, 100, 512, 0, 0, 0, 0, 0, 64, 1, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Major Mattingly - On Quest Celebrating Good Times Finished - Store Targetlist'), +(1439400, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Major Mattingly - Actionlist - Set Active On'), +(1439400, 9, 1, 0, 0, 0, 100, 0, 1000, 1000, 0, 0, 0, 83, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Major Mattingly - Actionlist - Remove Npc Flags Questgiver'), +(1439400, 9, 2, 0, 0, 0, 100, 0, 5000, 5000, 0, 0, 0, 1, 0, 8000, 0, 0, 0, 0, 12, 1, 0, 0, 0, 0, 0, 0, 0, 'Major Mattingly - Actionlist - Say Line 0'), +(1439400, 9, 3, 0, 0, 0, 100, 0, 8000, 8000, 0, 0, 0, 1, 1, 10000, 0, 0, 0, 0, 12, 1, 0, 0, 0, 0, 0, 0, 0, 'Major Mattingly - Actionlist - Say Line 1'), +(1439400, 9, 4, 0, 0, 0, 100, 0, 3000, 3000, 0, 0, 0, 50, 179558, 7200, 1, 0, 0, 0, 8, 0, 0, 0, 0, -8971.19, 554.141, 105.972, -2.25147, 'Major Mattingly - Actionlist - Summon Gameobject \'The Severed Head of Onyxia\''), +(1439400, 9, 5, 0, 0, 0, 100, 0, 1000, 1000, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 20, 179558, 100, 0, 0, 0, 0, 0, 0, 'Major Mattingly - Actionlist - Activate Gameobject'), +(1439400, 9, 6, 0, 0, 0, 100, 0, 6000, 6000, 0, 0, 0, 11, 22888, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Major Mattingly - Actionlist - Cast \'Rallying Cry of the Dragonslayer\''), +(1439400, 9, 7, 0, 0, 0, 100, 0, 1000, 1000, 0, 0, 0, 82, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Major Mattingly - Actionlist - Add Npc Flags Questgiver'), +(1439400, 9, 8, 0, 0, 0, 100, 0, 7200000, 7200000, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 14, 0, 179558, 0, 0, 0, 0, 0, 0, 'Major Mattingly - Actionlist - Despawn Instant'), +(1439400, 9, 9, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Major Mattingly - Actionlist - Set Active Off'), +(14392, 0, 0, 2, 20, 0, 100, 512, 7491, 0, 0, 0, 0, 80, 1439200, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Overlord Runthak - On Quest \'For All To See\' Finished - Run Script'), +(14392, 0, 2, 0, 61, 0, 100, 512, 0, 0, 0, 0, 0, 64, 1, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Overlord Runthak - On Quest \'For All To See\' Finished - Store Targetlist'), +(14392, 0, 3, 5, 20, 0, 100, 512, 7784, 0, 0, 0, 0, 80, 1439201, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Overlord Runthak - On Quest \'The Lord of Blackrock\' Finished - Run Script'), +(14392, 0, 5, 0, 61, 0, 100, 512, 0, 0, 0, 0, 0, 64, 2, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Overlord Runthak - On Quest \'The Lord of Blackrock\' Finished - Store Targetlist'), +(1439200, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Overlord Runthak - Actionlist - Set Active On'), +(1439200, 9, 1, 0, 0, 0, 100, 0, 1000, 1000, 0, 0, 0, 83, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Overlord Runthak - Actionlist - Remove Npc Flags Questgiver'), +(1439200, 9, 2, 0, 0, 0, 100, 0, 5000, 5000, 0, 0, 0, 1, 0, 8000, 0, 0, 0, 0, 12, 1, 0, 0, 0, 0, 0, 0, 0, 'Overlord Runthak - Actionlist - Say Line 0'), +(1439200, 9, 3, 0, 0, 0, 100, 0, 8000, 8000, 0, 0, 0, 1, 1, 10000, 0, 0, 0, 0, 12, 1, 0, 0, 0, 0, 0, 0, 0, 'Overlord Runthak - Actionlist - Say Line 1'), +(1439200, 9, 4, 0, 0, 0, 100, 0, 3000, 3000, 0, 0, 0, 50, 179556, 7200, 1, 0, 0, 0, 8, 0, 0, 0, 0, 1536.94, -4409.44, 8.05935, 1.64061, 'Overlord Runthak - Actionlist - Summon Gameobject \'The Severed Head of Onyxia\''), +(1439200, 9, 5, 0, 0, 0, 100, 0, 1000, 1000, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 20, 179556, 100, 0, 0, 0, 0, 0, 0, 'Overlord Runthak - Actionlist - Activate Gameobject'), +(1439200, 9, 6, 0, 0, 0, 100, 0, 6000, 6000, 0, 0, 0, 11, 22888, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Overlord Runthak - Actionlist - Cast \'Rallying Cry of the Dragonslayer\''), +(1439200, 9, 7, 0, 0, 0, 100, 0, 1000, 1000, 0, 0, 0, 82, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Overlord Runthak - Actionlist - Add Npc Flags Questgiver'), +(1439200, 9, 8, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 41, 7200000, 0, 0, 0, 0, 0, 14, 0, 179556, 0, 0, 0, 0, 0, 0, 'Overlord Runthak - Actionlist - Despawn In 7200000 ms'), +(1439200, 9, 9, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Overlord Runthak - Actionlist - Set Active Off'), +(1439201, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Overlord Runthak - Actionlist - Set Active On'), +(1439201, 9, 1, 0, 0, 0, 100, 0, 1000, 1000, 0, 0, 0, 83, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Overlord Runthak - Actionlist - Remove Npc Flags Questgiver'), +(1439201, 9, 2, 0, 0, 0, 100, 0, 5000, 5000, 0, 0, 0, 1, 2, 8000, 0, 0, 0, 0, 12, 2, 0, 0, 0, 0, 0, 0, 0, 'Overlord Runthak - Actionlist - Say Line 2'), +(1439201, 9, 3, 0, 0, 0, 100, 0, 8000, 8000, 0, 0, 0, 1, 3, 10000, 0, 0, 0, 0, 12, 2, 0, 0, 0, 0, 0, 0, 0, 'Overlord Runthak - Actionlist - Say Line 3'), +(1439201, 9, 4, 0, 0, 0, 100, 0, 3000, 3000, 0, 0, 0, 50, 179881, 7200, 1, 0, 0, 0, 8, 0, 0, 0, 0, 1536.94, -4421.62, 7.55304, -1.15192, 'Overlord Runthak - Actionlist - Summon Gameobject \'The Severed Head of Nefarian\''), +(1439201, 9, 5, 0, 0, 0, 100, 0, 1000, 1000, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 20, 179881, 100, 0, 0, 0, 0, 0, 0, 'Overlord Runthak - Actionlist - Activate Gameobject'), +(1439201, 9, 6, 0, 0, 0, 100, 0, 6000, 6000, 0, 0, 0, 11, 22888, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Overlord Runthak - Actionlist - Cast \'Rallying Cry of the Dragonslayer\''), +(1439201, 9, 7, 0, 0, 0, 100, 0, 1000, 1000, 0, 0, 0, 82, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Overlord Runthak - Actionlist - Add Npc Flags Questgiver'), +(1439201, 9, 8, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 41, 7200000, 0, 0, 0, 0, 0, 14, 0, 179881, 0, 0, 0, 0, 0, 0, 'Overlord Runthak - Actionlist - Despawn In 7200000 ms'), +(1439201, 9, 9, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Overlord Runthak - Actionlist - Set Active Off'); +-- add conditions so the timed action does not happen if the gameobject is there. +DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 22) AND (`SourceGroup` = 1) AND (`SourceEntry` = 14392) AND (`SourceId` = 0) AND (`ElseGroup` = 0) AND (`ConditionTypeOrReference` = 30) AND (`ConditionTarget` = 0) AND (`ConditionValue1` = 179556) AND (`ConditionValue2` = 120) AND (`ConditionValue3` = 0) OR (`SourceTypeOrReferenceId` = 22) AND (`SourceGroup` = 4) AND (`SourceEntry` = 14392) AND (`SourceId` = 0) AND (`ElseGroup` = 0) AND (`ConditionTypeOrReference` = 30) AND (`ConditionTarget` = 0) AND (`ConditionValue1` = 179881) AND (`ConditionValue2` = 120) AND (`ConditionValue3` = 0); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(22, 1, 14392, 0, 0, 30, 0, 179556, 120, 0, 1, 0, 0, '', ''), +(22, 4, 14392, 0, 0, 30, 0, 179881, 120, 0, 1, 0, 0, '', ''); diff --git a/data/sql/updates/db_world/2022_05_11_02.sql b/data/sql/updates/db_world/2022_05_11_02.sql new file mode 100644 index 000000000..832d1981c --- /dev/null +++ b/data/sql/updates/db_world/2022_05_11_02.sql @@ -0,0 +1,17 @@ +-- DB update 2022_05_11_01 -> 2022_05_11_02 +-- update Wintergrasp battle announce Chinese translation +UPDATE `acore_string` SET `locale_zhCN` = '|cffff0000[冬拥湖]:|r 战斗开始了!|r' WHERE `entry` = 20078; + +-- add object's Chinese translation +DELETE from `gameobject_template_locale` where `entry` IN (175226,175230,175233,176191,176197,176198) AND `locale` = 'zhCN'; +INSERT INTO `gameobject_template_locale` (`entry`, `locale`, `name`, `castBarCaption`, `VerifiedBuild`) VALUES +(175226, 'zhCN', '搁浅的海洋生物', '', 0), +(175230, 'zhCN', '搁浅的海洋生物', '', 0), +(175233, 'zhCN', '搁浅的海洋生物', '', 0), +(176191, 'zhCN', '搁浅的海龟', '', 0), +(176197, 'zhCN', '搁浅的海龟', '', 0), +(176198, 'zhCN', '搁浅的海龟', '', 0); + +-- add an item's Chinese translation +DELETE from `item_template_locale` where `ID` = 27808 AND `locale` = 'zhCN'; +INSERT INTO `item_template_locale` (`ID`, `locale`, `Name`, `Description`, `VerifiedBuild`) VALUES ( 27808, 'zhCN', '超级蹦床4000型的钥匙', '钥匙上刻有一行小字:瓦萨特不对使用超级蹦床4000型所造成的任何后果负责。', -12340); diff --git a/data/sql/updates/db_world/2022_05_12_00.sql b/data/sql/updates/db_world/2022_05_12_00.sql new file mode 100644 index 000000000..a20deb916 --- /dev/null +++ b/data/sql/updates/db_world/2022_05_12_00.sql @@ -0,0 +1,4 @@ +-- DB update 2022_05_11_02 -> 2022_05_12_00 +-- +UPDATE `quest_template_addon` SET `PrevQuestId`=0 WHERE `ID`=1699; +UPDATE `quest_template_addon` SET `NextQuestId`=1699 WHERE `ID` IN (1698,10371); diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index eb5d57836..b05986825 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -2257,9 +2257,9 @@ LiquidData const Map::GetLiquidData(uint32 phaseMask, float x, float y, float z, // Get position delta if (delta > collisionHeight) liquidData.Status = LIQUID_MAP_UNDER_WATER; - if (delta > 0.0f) + else if (delta > 0.0f) liquidData.Status = LIQUID_MAP_IN_WATER; - if (delta > -0.1f) + else if (delta > -0.1f) liquidData.Status = LIQUID_MAP_WATER_WALK; else liquidData.Status = LIQUID_MAP_ABOVE_WATER; @@ -2440,6 +2440,14 @@ float Map::GetWaterLevel(float x, float y) const bool Map::isInLineOfSight(float x1, float y1, float z1, float x2, float y2, float z2, uint32 phasemask, LineOfSightChecks checks, VMAP::ModelIgnoreFlags ignoreFlags) const { + if (!sWorld->getBoolConfig(CONFIG_VMAP_BLIZZLIKE_PVP_LOS)) + { + if (IsBattlegroundOrArena()) + { + ignoreFlags = VMAP::ModelIgnoreFlags::Nothing; + } + } + if ((checks & LINEOFSIGHT_CHECK_VMAP) && !VMAP::VMapFactory::createOrGetVMapMgr()->isInLineOfSight(GetId(), x1, y1, z1, x2, y2, z2, ignoreFlags)) { return false; diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index 3922dda20..b1058e4c6 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -316,6 +316,8 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater) uint32 processedPackets = 0; time_t currentTime = GameTime::GetGameTime().count(); + constexpr uint32 MAX_PROCESSED_PACKETS_IN_SAME_WORLDSESSION_UPDATE = 150; + while (m_Socket && _recvQueue.next(packet, updater)) { OpcodeClient opcode = static_cast(packet->GetOpcode()); @@ -358,6 +360,8 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater) sScriptMgr->OnPacketReceived(this, *packet); } + else + processedPackets = MAX_PROCESSED_PACKETS_IN_SAME_WORLDSESSION_UPDATE; // break out of packet processing loop break; case STATUS_TRANSFER: if (_player && !_player->IsInWorld() && AntiDOS.EvaluateOpcode(*packet, currentTime)) @@ -372,6 +376,8 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater) sScriptMgr->OnPacketReceived(this, *packet); } + else + processedPackets = MAX_PROCESSED_PACKETS_IN_SAME_WORLDSESSION_UPDATE; // break out of packet processing loop break; case STATUS_AUTHED: if (m_inQueue) // prevent cheating @@ -389,6 +395,8 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater) sScriptMgr->OnPacketReceived(this, *packet); } + else + processedPackets = MAX_PROCESSED_PACKETS_IN_SAME_WORLDSESSION_UPDATE; // break out of packet processing loop break; case STATUS_NEVER: LOG_ERROR("network.opcode", "Received not allowed opcode {} from {}", @@ -440,7 +448,6 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater) deletePacket = true; -#define MAX_PROCESSED_PACKETS_IN_SAME_WORLDSESSION_UPDATE 150 processedPackets++; //process only a max amout of packets in 1 Update() call. diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 93c8f5ed6..dbc1db87e 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -1407,19 +1407,214 @@ void Spell::SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplici } case TARGET_DEST_CASTER_FRONT_LEAP: { - Unit* unitCaster = m_caster->ToUnit(); - if (!unitCaster) + float distance = m_spellInfo->Effects[effIndex].CalcRadius(m_caster); + Map* map = m_caster->GetMap(); + uint32 mapid = m_caster->GetMapId(); + uint32 phasemask = m_caster->GetPhaseMask(); + float collisionHeight = m_caster->GetCollisionHeight(); + float destx = 0.0f, desty = 0.0f, destz = 0.0f, ground = 0.0f, startx = 0.0f, starty = 0.0f, startz = 0.0f, starto = 0.0f; + + Position pos; + Position lastpos; + m_caster->GetPosition(startx, starty, startz, starto); + pos.Relocate(startx, starty, startz, starto); + destx = pos.GetPositionX() + distance * cos(pos.GetOrientation()); + desty = pos.GetPositionY() + distance * sin(pos.GetOrientation()); + + ground = map->GetHeight(phasemask, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ()); + + bool isCasterInWater = m_caster->IsInWater(); + if (!m_caster->HasUnitMovementFlag(MOVEMENTFLAG_FALLING) || (pos.GetPositionZ() - ground < distance)) { - break; + float tstX = 0.0f, tstY = 0.0f, tstZ = 0.0f, prevX = 0.0f, prevY = 0.0f, prevZ = 0.0f; + float tstZ1 = 0.0f, tstZ2 = 0.0f, tstZ3 = 0.0f, destz1 = 0.0f, destz2 = 0.0f, destz3 = 0.0f, srange = 0.0f, srange1 = 0.0f, srange2 = 0.0f, srange3 = 0.0f; + float maxtravelDistZ = 2.65f; + float overdistance = 0.0f; + float totalpath = 0.0f; + float beforewaterz = 0.0f; + bool inwater = false; + bool wcol = false; + const float step = 2.0f; + const uint8 numChecks = ceil(fabs(distance / step)); + const float DELTA_X = (destx - pos.GetPositionX()) / numChecks; + const float DELTA_Y = (desty - pos.GetPositionY()) / numChecks; + int j = 1; + for (; j < (numChecks + 1); j++) + { + prevX = pos.GetPositionX() + (float(j - 1) * DELTA_X); + prevY = pos.GetPositionY() + (float(j - 1) * DELTA_Y); + tstX = pos.GetPositionX() + (float(j) * DELTA_X); + tstY = pos.GetPositionY() + (float(j) * DELTA_Y); + + if (j < 2) + { + prevZ = pos.GetPositionZ(); + } + else + { + prevZ = tstZ; + } + + tstZ = map->GetHeight(phasemask, tstX, tstY, prevZ + maxtravelDistZ, true); + ground = tstZ; + + if (!isCasterInWater) + { + if (map->IsInWater(phasemask, tstX, tstY, tstZ, collisionHeight)) + { + if (!(beforewaterz != 0.0f)) + { + beforewaterz = prevZ; + } + tstZ = beforewaterz; + srange = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX)); + //TC_LOG_ERROR("server", "(start was from land) step in water , number of cycle = %i , distance of step = %f, total path = %f, Z = %f", j, srange, totalpath, tstZ); + } + } + else if (map->IsInWater(phasemask, tstX, tstY, tstZ, collisionHeight)) + { + prevZ = pos.GetPositionZ(); + tstZ = pos.GetPositionZ(); + srange = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX)); + + inwater = true; + if (inwater && (fabs(tstZ - ground) < 2.0f)) + { + wcol = true; + //TC_LOG_ERROR("server", "step in water with collide and use standart check (for continue way after possible collide), number of cycle = %i ", j); + } + + // if (j < 2) + // TC_LOG_ERROR("server", "(start in water) step in water, number of cycle = %i , distance of step = %f, total path = %f", j, srange, totalpath); + // else + // TC_LOG_ERROR("server", "step in water, number of cycle = %i , distance of step = %f, total path = %f", j, srange, totalpath); + } + + bool IsInWater = map->IsInWater(phasemask, tstX, tstY, tstZ, collisionHeight); + if ((!IsInWater && tstZ != beforewaterz) || wcol) // second safety check z for blink way if on the ground + { + if (inwater && !IsInWater) + inwater = false; + + // highest available point + tstZ1 = map->GetHeight(phasemask, tstX, tstY, prevZ + maxtravelDistZ, true, 25.0f); + // upper or floor + tstZ2 = map->GetHeight(phasemask, tstX, tstY, prevZ, true, 25.0f); + //lower than floor + tstZ3 = map->GetHeight(phasemask, tstX, tstY, prevZ - maxtravelDistZ / 2, true, 25.0f); + + //distance of rays, will select the shortest in 3D + srange1 = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX) + (tstZ1 - prevZ) * (tstZ1 - prevZ)); + //TC_LOG_ERROR("server", "step = %i, distance of ray1 = %f", j, srange1); + srange2 = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX) + (tstZ2 - prevZ) * (tstZ2 - prevZ)); + //TC_LOG_ERROR("server", "step = %i, distance of ray2 = %f", j, srange2); + srange3 = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX) + (tstZ3 - prevZ) * (tstZ3 - prevZ)); + //TC_LOG_ERROR("server", "step = %i, distance of ray3 = %f", j, srange3); + + if (srange1 < srange2) + { + tstZ = tstZ1; + srange = srange1; + } + else if (srange3 < srange2) + { + tstZ = tstZ3; + srange = srange3; + } + else + { + tstZ = tstZ2; + srange = srange2; + } + + //TC_LOG_ERROR("server", "step on ground, number of cycle = %i , distance of step = %f, total path = %f", j, srange, totalpath); + } + + destx = tstX; + desty = tstY; + destz = tstZ; + + totalpath += srange; + + if (totalpath > distance) + { + overdistance = totalpath - distance; + //TC_LOG_ERROR("server", "total path > than distance in 3D , need to move back a bit for save distance, total path = %f, overdistance = %f", totalpath, overdistance); + } + + bool col = VMAP::VMapFactory::createOrGetVMapMgr()->GetObjectHitPos(mapid, prevX, prevY, prevZ + 0.5f, tstX, tstY, tstZ + 0.5f, tstX, tstY, tstZ, -0.5f); + // check dynamic collision + bool dcol = m_caster->GetMap()->GetObjectHitPos(phasemask, prevX, prevY, prevZ + 0.5f, tstX, tstY, tstZ + 0.5f, tstX, tstY, tstZ, -0.5f); + + // collision occured + if (col || dcol || (overdistance > 0.0f && !map->IsInWater(phasemask, tstX, tstY, ground, collisionHeight)) || (fabs(prevZ - tstZ) > maxtravelDistZ && (tstZ > prevZ))) + { + if ((overdistance > 0.0f) && (overdistance < step)) + { + destx = prevX + overdistance * cos(pos.GetOrientation()); + desty = prevY + overdistance * sin(pos.GetOrientation()); + //TC_LOG_ERROR("server", "(collision) collision occured 1"); + } + else + { + // move back a bit + destx = tstX - (0.6 * cos(pos.GetOrientation())); + desty = tstY - (0.6 * sin(pos.GetOrientation())); + //TC_LOG_ERROR("server", "(collision) collision occured 2"); + } + + // highest available point + destz1 = map->GetHeight(phasemask, destx, desty, prevZ + maxtravelDistZ, true, 25.0f); + // upper or floor + destz2 = map->GetHeight(phasemask, destx, desty, prevZ, true, 25.0f); + //lower than floor + destz3 = map->GetHeight(phasemask, destx, desty, prevZ - maxtravelDistZ / 2, true, 25.0f); + + //distance of rays, will select the shortest in 3D + srange1 = sqrt((desty - prevY) * (desty - prevY) + (destx - prevX) * (destx - prevX) + (destz1 - prevZ) * (destz1 - prevZ)); + srange2 = sqrt((desty - prevY) * (desty - prevY) + (destx - prevX) * (destx - prevX) + (destz2 - prevZ) * (destz2 - prevZ)); + srange3 = sqrt((desty - prevY) * (desty - prevY) + (destx - prevX) * (destx - prevX) + (destz3 - prevZ) * (destz3 - prevZ)); + + if (srange1 < srange2) + destz = destz1; + else if (srange3 < srange2) + destz = destz3; + else + destz = destz2; + + if (inwater && destz < prevZ && !wcol) + destz = prevZ; + //TC_LOG_ERROR("server", "(collision) destZ rewrited in prevZ"); + + break; + } + // we have correct destz now + } + //} + + lastpos.Relocate(destx, desty, destz + 0.5f, pos.GetOrientation()); + dest = SpellDestination(lastpos); } + else + { + float z = pos.GetPositionZ(); + bool col = VMAP::VMapFactory::createOrGetVMapMgr()->GetObjectHitPos(mapid, pos.GetPositionX(), pos.GetPositionY(), z + 0.5f, destx, desty, z + 0.5f, destx, desty, z, -0.5f); + // check dynamic collision + bool dcol = m_caster->GetMap()->GetObjectHitPos(phasemask, pos.GetPositionX(), pos.GetPositionY(), z + 0.5f, destx, desty, z + 0.5f, destx, desty, z, -0.5f); - float dist = m_spellInfo->Effects[effIndex].CalcRadius(unitCaster); - float angle = targetType.CalcDirectionAngle(); + // collision occured + if (col || dcol) + { + // move back a bit + destx = destx - (0.6 * cos(pos.GetOrientation())); + desty = desty - (0.6 * sin(pos.GetOrientation())); + } - Position pos = dest._position; - - unitCaster->MovePositionToFirstCollision(pos, dist, angle); - dest.Relocate(pos); + lastpos.Relocate(destx, desty, z, pos.GetOrientation()); + dest = SpellDestination(lastpos); + //float range = sqrt((desty - pos.GetPositionY())*(desty - pos.GetPositionY()) + (destx - pos.GetPositionX())*(destx - pos.GetPositionX())); + //TC_LOG_ERROR("server", "Blink number 2, in falling but at a hight, distance of blink = %f", range); + } break; } default: diff --git a/src/server/game/Spells/SpellInfoCorrections.cpp b/src/server/game/Spells/SpellInfoCorrections.cpp index cf630937c..98dbaf6e4 100644 --- a/src/server/game/Spells/SpellInfoCorrections.cpp +++ b/src/server/game/Spells/SpellInfoCorrections.cpp @@ -4257,6 +4257,19 @@ void SpellMgr::LoadSpellInfoCorrections() spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPRESS_TARGET_PROCS; }); + // Everlasting Affliction + ApplySpellFix({ 47422 }, [](SpellInfo* spellInfo) + { + spellInfo->SchoolMask = SPELL_SCHOOL_MASK_SHADOW; + }); + + // Flametongue Weapon (Passive) (Rank 6) + ApplySpellFix({ 16312 }, [](SpellInfo* spellInfo) + { + spellInfo->Attributes |= SPELL_ATTR0_PASSIVE; + spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(21); + }); + for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i) { SpellInfo* spellInfo = mSpellInfoMap[i]; diff --git a/src/server/game/World/IWorld.h b/src/server/game/World/IWorld.h index 3510f98ab..6c87e64f0 100644 --- a/src/server/game/World/IWorld.h +++ b/src/server/game/World/IWorld.h @@ -175,6 +175,7 @@ enum WorldBoolConfigs CONFIG_ALLOW_JOIN_BG_AND_LFG, CONFIG_MISS_CHANCE_MULTIPLIER_ONLY_FOR_PLAYERS, CONFIG_LEAVE_GROUP_ON_LOGOUT, + CONFIG_VMAP_BLIZZLIKE_PVP_LOS, BOOL_CONFIG_VALUE_COUNT }; diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 14ff03af3..ae1a3c5c9 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1298,6 +1298,7 @@ void World::LoadConfigSettings(bool reload) bool enableLOS = sConfigMgr->GetOption("vmap.enableLOS", true); bool enableHeight = sConfigMgr->GetOption("vmap.enableHeight", true); bool enablePetLOS = sConfigMgr->GetOption("vmap.petLOS", true); + m_bool_configs[CONFIG_VMAP_BLIZZLIKE_PVP_LOS] = sConfigMgr->GetOption("vmap.BlizzlikePvPLOS", true); if (!enableHeight) LOG_ERROR("server.loading", "VMap height checking disabled! Creatures movements and other various things WILL be broken! Expect no support."); diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp index 2b1164d0d..bbe76efe5 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp @@ -1157,29 +1157,6 @@ class spell_class_call_polymorph : public SpellScript } }; -class aura_class_call_berserk : public AuraScript -{ - PrepareAuraScript(aura_class_call_berserk); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_WARRIOR_BERSERK }); - } - - void HandleOnEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - if (Unit* target = GetTarget()) - { - target->CastSpell(target, SPELL_WARRIOR_BERSERK); - } - } - - void Register() override - { - OnEffectRemove += AuraEffectRemoveFn(aura_class_call_berserk::HandleOnEffectRemove, EFFECT_0, SPELL_AURA_MOD_SHAPESHIFT, AURA_EFFECT_HANDLE_REAL); - } -}; - class spell_corrupted_totems : public SpellScript { PrepareSpellScript(spell_corrupted_totems); @@ -1314,7 +1291,6 @@ void AddSC_boss_nefarian() RegisterSpellScript(aura_class_call_wild_magic); RegisterSpellScript(aura_class_call_siphon_blessing); RegisterSpellScript(spell_class_call_polymorph); - RegisterSpellScript(aura_class_call_berserk); RegisterSpellScript(spell_corrupted_totems); RegisterSpellScript(spell_shadowblink); RegisterSpellScript(spell_spawn_drakonid); diff --git a/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp b/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp index e88d067aa..db5eebad7 100644 --- a/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp +++ b/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp @@ -373,8 +373,6 @@ public: void UpdateAI(uint32 diff) override { - return; - events2.Update(diff); switch (events2.ExecuteEvent()) { diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist index 45ff2bdc3..a8cefe623 100644 --- a/src/server/worldserver/worldserver.conf.dist +++ b/src/server/worldserver/worldserver.conf.dist @@ -385,6 +385,13 @@ vmap.enableHeight = 1 vmap.petLOS = 1 +# vmap.BlizzlikePvPLOS +# Description: Check line of sight for battleground and arena gameobjects and other doodads (such as WSG treestumps). +# Default: 1 - (Enabled, players will be able to fire spells through treestumps and other objects). +# 0 - (Disabled, players will NOT be able to fire spells through treestumps and other objects). + +vmap.BlizzlikePvPLOS = 1 + # # vmap.enableIndoorCheck # Description: VMap based indoor check to remove outdoor-only auras (mounts etc.).