From e79507fe668474310b46124757409e63d5b5a399 Mon Sep 17 00:00:00 2001 From: Dan <83884799+elthehablo@users.noreply.github.com> Date: Sun, 31 Mar 2024 18:59:10 +0200 Subject: [PATCH 01/30] fix(DB/TheEye): remove faulty talon of al'ar reference from reference loot template (#18641) * init * Update alar-loot.sql used to be Reference 34377 and chance 8.3333333 --- data/sql/updates/pending_db_world/alar-loot.sql | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 data/sql/updates/pending_db_world/alar-loot.sql diff --git a/data/sql/updates/pending_db_world/alar-loot.sql b/data/sql/updates/pending_db_world/alar-loot.sql new file mode 100644 index 000000000..085ae166c --- /dev/null +++ b/data/sql/updates/pending_db_world/alar-loot.sql @@ -0,0 +1,2 @@ +-- +UPDATE `reference_loot_template` SET `Item` = 30448, `Reference` = 0, `Chance` = 0, `Comment` = 'Talon of Al\'ar' WHERE `Entry` = 34053 AND `Item` = 1; From 102bf7c9c5c9837e31468e8bc82c8f2724e4aadf Mon Sep 17 00:00:00 2001 From: Dan <83884799+elthehablo@users.noreply.github.com> Date: Sun, 31 Mar 2024 18:59:27 +0200 Subject: [PATCH 02/30] fix(Scripts/Hyjal): Shadowy Necromancers now use Unholy Frenzy + Skeleton mage abilities (#18640) init --- .../pending_db_world/skeletonmages.sql | 10 ++++++ .../BattleForMountHyjal/hyjal.cpp | 31 +++++++++++++++++++ .../CavernsOfTime/BattleForMountHyjal/hyjal.h | 4 +++ 3 files changed, 45 insertions(+) create mode 100644 data/sql/updates/pending_db_world/skeletonmages.sql diff --git a/data/sql/updates/pending_db_world/skeletonmages.sql b/data/sql/updates/pending_db_world/skeletonmages.sql new file mode 100644 index 000000000..a16c945f7 --- /dev/null +++ b/data/sql/updates/pending_db_world/skeletonmages.sql @@ -0,0 +1,10 @@ +-- +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 17903; + +DELETE FROM `smart_scripts` WHERE `entryorguid` = 17903 AND `source_type` = 0; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `event_param6`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(17903, 0, 0, 0, 4, 0, 100, 512, 0, 0, 0, 0, 0, 0, 30, 1, 2, 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Skeleton Mage - On Aggro - Set Event Phase Random'), +(17903, 0, 1, 0, 0, 1, 100, 0, 0, 0, 3000, 3500, 0, 0, 11, 31622, 64, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Skeleton Mage - In Combat - Cast Frostbolt'), +(17903, 0, 2, 0, 0, 2, 100, 0, 0, 0, 3000, 3500, 0, 0, 11, 31618, 64, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Skeleton Mage - In Combat - Cast Shadow Bolt'), +(17903, 0, 3, 0, 0, 4, 100, 0, 0, 0, 3000, 3500, 0, 0, 11, 31620, 64, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Skeleton Mage - In Combat - Cast Fireball'); + diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.cpp index d46a0fb33..9768ba034 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.cpp @@ -55,6 +55,7 @@ enum Spells SPELL_RAISE_DEAD_1 = 31617, SPELL_RAISE_DEAD_2 = 31624, SPELL_RAISE_DEAD_3 = 31625, + SPELL_UNHOLY_FRENZY = 31626, SPELL_SHADOW_BOLT = 31627, // Banshee (Ranged) @@ -84,6 +85,8 @@ enum Talk SAY_TELEPORT = 7 }; +const float UNHOLY_FRENZY_RANGE = 30.0f; + class npc_hyjal_jaina : public CreatureScript { public: @@ -411,6 +414,13 @@ struct npc_hyjal_ground_trash : public ScriptedAI break; } context.Repeat(10s, 20s); + }).Schedule(15s, 20s, [this](TaskContext context) + { + if (Creature* target = GetNearbyFriendlyTrashCreature(UNHOLY_FRENZY_RANGE)) + { + DoCast(target, SPELL_UNHOLY_FRENZY); + } + context.Repeat(15s, 20s); }); break; } @@ -501,6 +511,27 @@ struct npc_hyjal_ground_trash : public ScriptedAI } } + Creature* GetNearbyFriendlyTrashCreature(float radius) + { + //need accurate timer + Creature* creatureToReturn = nullptr; + std::list creatureList; + GetCreatureListWithEntryInGrid(creatureList, me, NPC_ABOMI, radius); + GetCreatureListWithEntryInGrid(creatureList, me, NPC_BANSH, radius); + GetCreatureListWithEntryInGrid(creatureList, me, NPC_STALK, radius); + GetCreatureListWithEntryInGrid(creatureList, me, NPC_NECRO, radius); + GetCreatureListWithEntryInGrid(creatureList, me, NPC_CRYPT, radius); + GetCreatureListWithEntryInGrid(creatureList, me, NPC_GHOUL, radius); + GetCreatureListWithEntryInGrid(creatureList, me, NPC_SKELETON_INVADER, radius); + Acore::Containers::RandomResize(creatureList, 1); + if (creatureList.size() > 0) + { + creatureToReturn = creatureList.front(); + } + creatureList.clear(); + return creatureToReturn; + } + void UpdateAI(uint32 diff) override { if (!UpdateVictim()) diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.h b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.h index 954d2a838..b0c127f49 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.h +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.h @@ -78,6 +78,10 @@ enum HyjalCreaturesIds NPC_STALK = 17916, NPC_BUILD = 18304, // Serverside creature? Not found in CreateObject packets, but seen as targets + // Summoned necromancer mobs + NPC_SKELETON_INVADER = 17902, + NPC_SKELETON_MAGE = 17903, + // Alliance Base NPC_JAINA = 17772, NPC_ALLIANCE_PEASANT = 17931, From 2aaf8474ba7c7e88614a55fe2ba1ec50bc1239da Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 31 Mar 2024 16:59:59 +0000 Subject: [PATCH 03/30] chore(DB): import pending files Referenced commit(s): e79507fe668474310b46124757409e63d5b5a399 --- .../alar-loot.sql => db_world/2024_03_31_00.sql} | 1 + .../skeletonmages.sql => db_world/2024_03_31_01.sql} | 1 + 2 files changed, 2 insertions(+) rename data/sql/updates/{pending_db_world/alar-loot.sql => db_world/2024_03_31_00.sql} (77%) rename data/sql/updates/{pending_db_world/skeletonmages.sql => db_world/2024_03_31_01.sql} (96%) diff --git a/data/sql/updates/pending_db_world/alar-loot.sql b/data/sql/updates/db_world/2024_03_31_00.sql similarity index 77% rename from data/sql/updates/pending_db_world/alar-loot.sql rename to data/sql/updates/db_world/2024_03_31_00.sql index 085ae166c..2ee8bb336 100644 --- a/data/sql/updates/pending_db_world/alar-loot.sql +++ b/data/sql/updates/db_world/2024_03_31_00.sql @@ -1,2 +1,3 @@ +-- DB update 2024_03_30_01 -> 2024_03_31_00 -- UPDATE `reference_loot_template` SET `Item` = 30448, `Reference` = 0, `Chance` = 0, `Comment` = 'Talon of Al\'ar' WHERE `Entry` = 34053 AND `Item` = 1; diff --git a/data/sql/updates/pending_db_world/skeletonmages.sql b/data/sql/updates/db_world/2024_03_31_01.sql similarity index 96% rename from data/sql/updates/pending_db_world/skeletonmages.sql rename to data/sql/updates/db_world/2024_03_31_01.sql index a16c945f7..d3fa5d1c3 100644 --- a/data/sql/updates/pending_db_world/skeletonmages.sql +++ b/data/sql/updates/db_world/2024_03_31_01.sql @@ -1,3 +1,4 @@ +-- DB update 2024_03_31_00 -> 2024_03_31_01 -- UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 17903; From aee2eefb92fbd9a6ac64dc446193703d16d26d7c Mon Sep 17 00:00:00 2001 From: Anton Popovichenko Date: Mon, 1 Apr 2024 10:49:42 +0200 Subject: [PATCH 04/30] feat(Core/Optimization): Reduce CPU consumption by allocating sendBuffer only when it is needed. (#18628) * feat(Core/Optimization): Reduce CPU consumption by allocating the sendBuffer only when it is needed. * Remove whitespaces. --- src/server/game/Server/WorldSocket.cpp | 67 ++++++++++++++------------ 1 file changed, 35 insertions(+), 32 deletions(-) diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp index 05235bc6f..2b44a26ee 100644 --- a/src/server/game/Server/WorldSocket.cpp +++ b/src/server/game/Server/WorldSocket.cpp @@ -161,43 +161,46 @@ void WorldSocket::CheckIpCallback(PreparedQueryResult result) bool WorldSocket::Update() { EncryptableAndCompressiblePacket* queued; - MessageBuffer buffer(_sendBufferSize); - while (_bufferQueue.Dequeue(queued)) + if (_bufferQueue.Dequeue(queued)) { - queued->CompressIfNeeded(); - - ServerPktHeader header(queued->size() + 2, queued->GetOpcode()); - if (queued->NeedsEncryption()) - _authCrypt.EncryptSend(header.header, header.getHeaderLength()); - - if (buffer.GetRemainingSpace() < queued->size() + header.getHeaderLength()) + // Allocate buffer only when it's needed but not on every Update() call. + MessageBuffer buffer(_sendBufferSize); + do { + queued->CompressIfNeeded(); + ServerPktHeader header(queued->size() + 2, queued->GetOpcode()); + if (queued->NeedsEncryption()) + _authCrypt.EncryptSend(header.header, header.getHeaderLength()); + + if (buffer.GetRemainingSpace() < queued->size() + header.getHeaderLength()) + { + QueuePacket(std::move(buffer)); + buffer.Resize(_sendBufferSize); + } + + if (buffer.GetRemainingSpace() >= queued->size() + header.getHeaderLength()) + { + buffer.Write(header.header, header.getHeaderLength()); + if (!queued->empty()) + buffer.Write(queued->contents(), queued->size()); + } + else // single packet larger than 4096 bytes + { + MessageBuffer packetBuffer(queued->size() + header.getHeaderLength()); + packetBuffer.Write(header.header, header.getHeaderLength()); + if (!queued->empty()) + packetBuffer.Write(queued->contents(), queued->size()); + + QueuePacket(std::move(packetBuffer)); + } + + delete queued; + } while (_bufferQueue.Dequeue(queued)); + + if (buffer.GetActiveSize() > 0) QueuePacket(std::move(buffer)); - buffer.Resize(_sendBufferSize); - } - - if (buffer.GetRemainingSpace() >= queued->size() + header.getHeaderLength()) - { - buffer.Write(header.header, header.getHeaderLength()); - if (!queued->empty()) - buffer.Write(queued->contents(), queued->size()); - } - else // single packet larger than 4096 bytes - { - MessageBuffer packetBuffer(queued->size() + header.getHeaderLength()); - packetBuffer.Write(header.header, header.getHeaderLength()); - if (!queued->empty()) - packetBuffer.Write(queued->contents(), queued->size()); - - QueuePacket(std::move(packetBuffer)); - } - - delete queued; } - if (buffer.GetActiveSize() > 0) - QueuePacket(std::move(buffer)); - if (!BaseSocket::Update()) return false; From 47f9d668741b095a5f8f372d18ffbce38a2125a8 Mon Sep 17 00:00:00 2001 From: Anton Popovichenko Date: Mon, 1 Apr 2024 10:50:12 +0200 Subject: [PATCH 05/30] feat(Core/Optimization): Create index for sSkillLineAbilityStore to speedup search by skillLine. (#18622) * feat(Core/Optimization): Create index for sSkillLineAbilityStore to speedup search by skillLine. * Remove whitespace. --- src/server/game/DataStores/DBCStores.cpp | 15 +++++++++++++++ src/server/game/DataStores/DBCStores.h | 4 ++++ src/server/game/Entities/Player/Player.cpp | 14 +++----------- src/server/game/Spells/SpellMgr.cpp | 13 +------------ src/server/scripts/Commands/cs_learn.cpp | 10 +--------- 5 files changed, 24 insertions(+), 32 deletions(-) diff --git a/src/server/game/DataStores/DBCStores.cpp b/src/server/game/DataStores/DBCStores.cpp index 9f6699118..33cb2ace1 100644 --- a/src/server/game/DataStores/DBCStores.cpp +++ b/src/server/game/DataStores/DBCStores.cpp @@ -139,6 +139,7 @@ DBCStorage sScalingStatValuesStore(ScalingStatValuesfmt DBCStorage sSkillLineStore(SkillLinefmt); DBCStorage sSkillLineAbilityStore(SkillLineAbilityfmt); +SkillLineAbilityIndexBySkillLine sSkillLineAbilityIndexBySkillLine; DBCStorage sSkillRaceClassInfoStore(SkillRaceClassInfofmt); SkillRaceClassInfoMap SkillRaceClassInfoBySkill; DBCStorage sSkillTiersStore(SkillTiersfmt); @@ -454,6 +455,9 @@ void LoadDBCStores(const std::string& dataPath) } } + for (SkillLineAbilityEntry const* skillLine : sSkillLineAbilityStore) + sSkillLineAbilityIndexBySkillLine[skillLine->SkillLine].push_back(skillLine); + // Create Spelldifficulty searcher for (SpellDifficultyEntry const* spellDiff : sSpellDifficultyStore) { @@ -908,3 +912,14 @@ SkillRaceClassInfoEntry const* GetSkillRaceClassInfo(uint32 skill, uint8 race, u return nullptr; } + +const std::vector& GetSkillLineAbilitiesBySkillLine(uint32 skillLine) +{ + auto it = sSkillLineAbilityIndexBySkillLine.find(skillLine); + if (it == sSkillLineAbilityIndexBySkillLine.end()) + { + static const std::vector emptyVector; + return emptyVector; + } + return it->second; +} diff --git a/src/server/game/DataStores/DBCStores.h b/src/server/game/DataStores/DBCStores.h index da147e61d..9bc8090e2 100644 --- a/src/server/game/DataStores/DBCStores.h +++ b/src/server/game/DataStores/DBCStores.h @@ -72,6 +72,9 @@ typedef std::unordered_multimap SkillRac typedef std::pair SkillRaceClassInfoBounds; SkillRaceClassInfoEntry const* GetSkillRaceClassInfo(uint32 skill, uint8 race, uint8 class_); +typedef std::unordered_map > SkillLineAbilityIndexBySkillLine; +const std::vector& GetSkillLineAbilitiesBySkillLine(uint32 skillLine); + extern DBCStorage sAchievementStore; extern DBCStorage sAchievementCriteriaStore; extern DBCStorage sAchievementCategoryStore; @@ -151,6 +154,7 @@ extern DBCStorage sScalingStatDistributionStore; extern DBCStorage sScalingStatValuesStore; extern DBCStorage sSkillLineStore; extern DBCStorage sSkillLineAbilityStore; +extern SkillLineAbilityIndexBySkillLine sSkillLineAbilityIndexBySkillLine; extern DBCStorage sSkillTiersStore; extern DBCStorage sSoundEntriesStore; extern DBCStorage sSpellCastTimesStore; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 19fff250e..fd173a16b 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -5313,10 +5313,8 @@ void Player::SetSkill(uint16 id, uint16 step, uint16 newVal, uint16 maxVal) mSkillStatus.erase(itr); // remove all spells that related to this skill - for (uint32 j = 0; j < sSkillLineAbilityStore.GetNumRows(); ++j) - if (SkillLineAbilityEntry const* pAbility = sSkillLineAbilityStore.LookupEntry(j)) - if (pAbility->SkillLine == id) - removeSpell(sSpellMgr->GetFirstSpellInChain(pAbility->Spell), SPEC_MASK_ALL, false); + for (SkillLineAbilityEntry const* pAbility : GetSkillLineAbilitiesBySkillLine(id)) + removeSpell(sSpellMgr->GetFirstSpellInChain(pAbility->Spell), SPEC_MASK_ALL, false); } } else if (newVal) //add @@ -11935,14 +11933,8 @@ void Player::learnSkillRewardedSpells(uint32 skill_id, uint32 skill_value) { uint32 raceMask = getRaceMask(); uint32 classMask = getClassMask(); - for (uint32 j = 0; j < sSkillLineAbilityStore.GetNumRows(); ++j) + for (SkillLineAbilityEntry const* pAbility : GetSkillLineAbilitiesBySkillLine(skill_id)) { - SkillLineAbilityEntry const* pAbility = sSkillLineAbilityStore.LookupEntry(j); - if (!pAbility || pAbility->SkillLine != skill_id) - { - continue; - } - SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(pAbility->Spell); if (!spellInfo) { diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 0e29e95d8..1bd906594 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -2323,19 +2323,8 @@ void SpellMgr::LoadPetLevelupSpellMap() if (!creatureFamily->skillLine[j]) continue; - for (uint32 k = 0; k < sSkillLineAbilityStore.GetNumRows(); ++k) + for (SkillLineAbilityEntry const* skillLine : GetSkillLineAbilitiesBySkillLine(creatureFamily->skillLine[j])) { - SkillLineAbilityEntry const* skillLine = sSkillLineAbilityStore.LookupEntry(k); - if (!skillLine) - continue; - - //if (skillLine->skillId != creatureFamily->skillLine[0] && - // (!creatureFamily->skillLine[1] || skillLine->skillId != creatureFamily->skillLine[1])) - // continue; - - if (skillLine->SkillLine != creatureFamily->skillLine[j]) - continue; - if (skillLine->AcquireMethod != SKILL_LINE_ABILITY_LEARNED_ON_SKILL_LEARN) continue; diff --git a/src/server/scripts/Commands/cs_learn.cpp b/src/server/scripts/Commands/cs_learn.cpp index efe99283f..6664a294d 100644 --- a/src/server/scripts/Commands/cs_learn.cpp +++ b/src/server/scripts/Commands/cs_learn.cpp @@ -390,16 +390,8 @@ public: { uint32 classmask = player->getClassMask(); - for (uint32 j = 0; j < sSkillLineAbilityStore.GetNumRows(); ++j) + for (SkillLineAbilityEntry const* skillLine : GetSkillLineAbilitiesBySkillLine(skillId)) { - SkillLineAbilityEntry const* skillLine = sSkillLineAbilityStore.LookupEntry(j); - if (!skillLine) - continue; - - // wrong skill - if (skillLine->SkillLine != skillId) - continue; - // not high rank if (skillLine->SupercededBySpell) continue; From 1e52f715d09ca1877f32d4412d0b1d51cd01aeac Mon Sep 17 00:00:00 2001 From: Dan <83884799+elthehablo@users.noreply.github.com> Date: Mon, 1 Apr 2024 20:56:55 +0200 Subject: [PATCH 06/30] fix(Scripts/TheEye): fix targetting logic in Void Reaver (#18646) * initial this works way better * prettier --- src/server/scripts/Outland/TempestKeep/Eye/boss_void_reaver.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/scripts/Outland/TempestKeep/Eye/boss_void_reaver.cpp b/src/server/scripts/Outland/TempestKeep/Eye/boss_void_reaver.cpp index 19c7feb76..a1d94f89f 100644 --- a/src/server/scripts/Outland/TempestKeep/Eye/boss_void_reaver.cpp +++ b/src/server/scripts/Outland/TempestKeep/Eye/boss_void_reaver.cpp @@ -95,7 +95,7 @@ struct boss_void_reaver : public BossAI context.Repeat(12100ms, 15800ms); }).Schedule(3450ms, GROUP_ARCANE_ORB, [this](TaskContext context) { - if (!DoCastRandomTarget(SPELL_ARCANE_ORB, 0, -18.0f)) + if (DoCastRandomTarget(SPELL_ARCANE_ORB, 0, -20.0f) != SPELL_CAST_OK) { DoCastRandomTarget(SPELL_ARCANE_ORB, 0, 18.0f); } From 20c4b4b463a2229c2cefdaa1957c904994c7b57c Mon Sep 17 00:00:00 2001 From: Dan <83884799+elthehablo@users.noreply.github.com> Date: Tue, 2 Apr 2024 15:12:23 +0200 Subject: [PATCH 07/30] fix(DB/TheEye): allow Kael to drop 2 non-token items (#18639) init --- data/sql/updates/pending_db_world/kael-loot.sql | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 data/sql/updates/pending_db_world/kael-loot.sql diff --git a/data/sql/updates/pending_db_world/kael-loot.sql b/data/sql/updates/pending_db_world/kael-loot.sql new file mode 100644 index 000000000..13a6a3b43 --- /dev/null +++ b/data/sql/updates/pending_db_world/kael-loot.sql @@ -0,0 +1,2 @@ +-- +UPDATE `creature_loot_template` SET `MaxCount` = 2 WHERE `Entry` = 19622 AND `Item` = 90056 AND `Reference` = 34056 AND `GroupId` = 4; From 43b51dd34ce23007c1eb1ff108128da1396144c5 Mon Sep 17 00:00:00 2001 From: Dan <83884799+elthehablo@users.noreply.github.com> Date: Tue, 2 Apr 2024 15:12:43 +0200 Subject: [PATCH 08/30] fix(DB/TheEye): remove unused reference and add Talon of the Phoenix back (#18643) * init * rip --- data/sql/updates/pending_db_world/alar-loooot.sql | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 data/sql/updates/pending_db_world/alar-loooot.sql diff --git a/data/sql/updates/pending_db_world/alar-loooot.sql b/data/sql/updates/pending_db_world/alar-loooot.sql new file mode 100644 index 000000000..be8b05ddf --- /dev/null +++ b/data/sql/updates/pending_db_world/alar-loooot.sql @@ -0,0 +1,6 @@ +-- delete old entries that are unused +DELETE FROM `reference_loot_template` WHERE `Entry` = 34377 AND `Item` IN (30448, 32944); +-- down +DELETE FROM `reference_loot_template` WHERE `Entry` = 34053 AND `Item` = 32944; +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(34053, 32944, 0, 0, 0, 1, 1, 1, 1, 'Talon of the Phoenix'); From 68857e0dc42730eb59c91c7bce5fd22c97b42de3 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 2 Apr 2024 13:15:06 +0000 Subject: [PATCH 09/30] chore(DB): import pending files Referenced commit(s): 20c4b4b463a2229c2cefdaa1957c904994c7b57c --- .../alar-loooot.sql => db_world/2024_04_02_00.sql} | 1 + .../kael-loot.sql => db_world/2024_04_02_01.sql} | 1 + 2 files changed, 2 insertions(+) rename data/sql/updates/{pending_db_world/alar-loooot.sql => db_world/2024_04_02_00.sql} (90%) rename data/sql/updates/{pending_db_world/kael-loot.sql => db_world/2024_04_02_01.sql} (75%) diff --git a/data/sql/updates/pending_db_world/alar-loooot.sql b/data/sql/updates/db_world/2024_04_02_00.sql similarity index 90% rename from data/sql/updates/pending_db_world/alar-loooot.sql rename to data/sql/updates/db_world/2024_04_02_00.sql index be8b05ddf..db6183a16 100644 --- a/data/sql/updates/pending_db_world/alar-loooot.sql +++ b/data/sql/updates/db_world/2024_04_02_00.sql @@ -1,3 +1,4 @@ +-- DB update 2024_03_31_01 -> 2024_04_02_00 -- delete old entries that are unused DELETE FROM `reference_loot_template` WHERE `Entry` = 34377 AND `Item` IN (30448, 32944); -- down diff --git a/data/sql/updates/pending_db_world/kael-loot.sql b/data/sql/updates/db_world/2024_04_02_01.sql similarity index 75% rename from data/sql/updates/pending_db_world/kael-loot.sql rename to data/sql/updates/db_world/2024_04_02_01.sql index 13a6a3b43..ad3261bd2 100644 --- a/data/sql/updates/pending_db_world/kael-loot.sql +++ b/data/sql/updates/db_world/2024_04_02_01.sql @@ -1,2 +1,3 @@ +-- DB update 2024_04_02_00 -> 2024_04_02_01 -- UPDATE `creature_loot_template` SET `MaxCount` = 2 WHERE `Entry` = 19622 AND `Item` = 90056 AND `Reference` = 34056 AND `GroupId` = 4; From 3445262b9334fdae06b083d4fd091e858c259fa6 Mon Sep 17 00:00:00 2001 From: Gultask <100873791+Gultask@users.noreply.github.com> Date: Tue, 2 Apr 2024 12:27:49 -0300 Subject: [PATCH 10/30] fix(DB/Creature): Void Reaver Movement Speed and Model Info (#18650) Create rev_1712070277049871600.sql --- data/sql/updates/pending_db_world/rev_1712070277049871600.sql | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1712070277049871600.sql diff --git a/data/sql/updates/pending_db_world/rev_1712070277049871600.sql b/data/sql/updates/pending_db_world/rev_1712070277049871600.sql new file mode 100644 index 000000000..49746e35c --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1712070277049871600.sql @@ -0,0 +1,3 @@ +-- +UPDATE `creature_template` SET `speed_walk` = 3.2, `speed_run` = 2.857142 WHERE (`entry` = 19516); +UPDATE `creature_model_info` SET `BoundingRadius` = 12.33326530456542968, `CombatReach` = 18 WHERE `DisplayID` = 18951; From 9b6e07ec2d49776f9f6c55c3535a1de3b1a13d19 Mon Sep 17 00:00:00 2001 From: Gultask <100873791+Gultask@users.noreply.github.com> Date: Tue, 2 Apr 2024 12:28:07 -0300 Subject: [PATCH 11/30] fix(Scripts/TheEye): Lord Sanguinar's Bellowing Roar timer (#18651) Update boss_kaelthas.cpp --- src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp b/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp index 77aad57b1..6bfb68416 100644 --- a/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp +++ b/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp @@ -803,9 +803,9 @@ struct npc_lord_sanguinar : public ScriptedAI { Talk(SAY_SANGUINAR_AGGRO); } - ScheduleTimedEvent(0s, [&]{ + ScheduleTimedEvent(6s, 20s, [&]{ DoCastSelf(SPELL_BELLOWING_ROAR); - }, 15s); + }, 30s, 40s); } void JustDied(Unit* /*killer*/) override From 7180065dd3bb07bea98f0c42426e8d1ba4118bff Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 2 Apr 2024 15:28:38 +0000 Subject: [PATCH 12/30] chore(DB): import pending files Referenced commit(s): 3445262b9334fdae06b083d4fd091e858c259fa6 --- .../rev_1712070277049871600.sql => db_world/2024_04_02_02.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1712070277049871600.sql => db_world/2024_04_02_02.sql} (83%) diff --git a/data/sql/updates/pending_db_world/rev_1712070277049871600.sql b/data/sql/updates/db_world/2024_04_02_02.sql similarity index 83% rename from data/sql/updates/pending_db_world/rev_1712070277049871600.sql rename to data/sql/updates/db_world/2024_04_02_02.sql index 49746e35c..7b3d43fef 100644 --- a/data/sql/updates/pending_db_world/rev_1712070277049871600.sql +++ b/data/sql/updates/db_world/2024_04_02_02.sql @@ -1,3 +1,4 @@ +-- DB update 2024_04_02_01 -> 2024_04_02_02 -- UPDATE `creature_template` SET `speed_walk` = 3.2, `speed_run` = 2.857142 WHERE (`entry` = 19516); UPDATE `creature_model_info` SET `BoundingRadius` = 12.33326530456542968, `CombatReach` = 18 WHERE `DisplayID` = 18951; From 28a64111fd81b17d900f0af7c3be2d0daddb6895 Mon Sep 17 00:00:00 2001 From: Anton Popovichenko Date: Tue, 2 Apr 2024 21:00:53 +0200 Subject: [PATCH 13/30] fix(Scripts/TheEye): Fix crash in Kaelthas. (#18653) * fix(Scripts/TheEye): Fix crash in Kaelthas. * Remove whitespace --- .../scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp b/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp index 6bfb68416..a9ba7d96e 100644 --- a/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp +++ b/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp @@ -498,8 +498,12 @@ struct boss_kaelthas : public BossAI { summons.DespawnEntry(NPC_NETHER_VAPOR); scheduler.CancelGroup(GROUP_NETHER_BEAM); - me->SetTarget(me->GetVictim()->GetGUID()); - me->GetMotionMaster()->MoveChase(me->GetVictim()); + + if (Unit* victim = me->GetVictim()) + { + me->SetTarget(victim->GetGUID()); + me->GetMotionMaster()->MoveChase(victim); + } }); me->SetTarget(); me->GetMotionMaster()->Clear(); From 961681bb9ff21764001e09e5b75a054077e80ffc Mon Sep 17 00:00:00 2001 From: sudlud Date: Tue, 2 Apr 2024 22:08:13 +0200 Subject: [PATCH 14/30] fix(DB/Gameobject): Sniffed Values for 'Forge' spawns (#18620) * fix(DB/Gameobject): Sniffed Values for 'Forge' spawns * Update rev_1711633613954464100.sql Just to trigger CI again * Update rev_1711633613954464100.sql --- .../rev_1711633613954464100.sql | 175 ++++++++++++++++++ 1 file changed, 175 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1711633613954464100.sql diff --git a/data/sql/updates/pending_db_world/rev_1711633613954464100.sql b/data/sql/updates/pending_db_world/rev_1711633613954464100.sql new file mode 100644 index 000000000..84c6cb3fd --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1711633613954464100.sql @@ -0,0 +1,175 @@ +-- Update gameobject 'Forge' with sniffed values +-- updated spawns +DELETE FROM `gameobject` WHERE (`id` IN (194468, 173063, 2575, 19902, 179924, 1749, 21679, 34571, 173095, 173064, 144133, 153459, 20738, 147285, 4090, 56897, 138317, 20986, 23304, 23305, 24745, 24746, 34572, 38491, 202392, 202393, 202391, 202394, 186556, 2728, 2727, 51949, 169969, 2573, 1797, 1896, 141838, 141841, 184617, 182056, 3223, 183818, 181716, 181990, 182117, 182278, 182860, 183121, 183148, 183345, 183347, 183408, 183484, 183757, 183758, 183759, 183760, 183782, 184286, 184922, 184923, 181884, 184146, 187112, 186139, 184687, 17190, 175144, 182270, 186138, 130668, 175851, 186141, 1685, 1743, 52175, 52176, 113754, 148960, 181130, 179886, 176509, 50831, 92490, 179863, 180913, 171716, 171717, 192020, 186654, 190495, 188452, 190765, 190524, 192831, 186433, 192583, 188250, 188257, 191346, 186486, 187256, 194487, 188607, 188354, 188356, 188624, 188651, 188396, 190457, 187388, 192062, 191287, 191288, 192572, 192573, 191508, 186653, 191237, 191505, 179844, 152034, 152042, 152045, 193126, 186231, 186630, 194128, 176895, 142078)) +AND (`guid` IN (100431, 10054, 10118, 10826, 10828, 1091, 11000, 1126, 11324, 11598, 11819, 12642, 12687, 12799, 13139, 13261, 13306, 13360, 13766, 13813, 13814, 13968, 13970, 14273, 14352, 14796, 150251, 150275, 150281, 150283, 151208, 15217, 15396, 15728, 15733, 16626, 17011, 17014, 17141, 17240, 17252, 17426, 18568, 20494, 20562, 20709, 22227, 22401, 22525, 22762, 23671, 24009, 24036, 24217, 24219, 24317, 24377, 24587, 24588, 24589, 24590, 24647, 25118, 25827, 25828, 26791, 27148, 27638, 27811, 28273, 29723, 30166, 30172, 30402, 30816, 32298, 32655, 32779, 34300, 387, 44762, 44871, 44916, 44917, 44949, 45334, 45606, 45689, 46082, 46161, 4623, 467, 47586, 47603, 48632, 49092, 49393, 49803, 5258, 5430, 55964, 56459, 56480, 56654, 56955, 57486, 57539, 57574, 57733, 58133, 58300, 59043, 59092, 59113, 59403, 59623, 59624, 60255, 60307, 60317, 60512, 61116, 61125, 61538, 61660, 62356, 63130, 63131, 63132, 63133, 63185, 65329, 65868, 65884, 66110, 66396, 66401, 6880, 6881, 6927, 6935, 71405, 7561, 7591, 77189, 82, 8821, 95, 9937)); +INSERT INTO `gameobject` (`guid`, `id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`, `Comment`) VALUES +(100431, 194468, 530, 0, 0, 1, 1, -2133.075927734375, 5371.8505859375, 53.80774307250976562, 2.286378860473632812, 0, 0, 0.909960746765136718, 0.414694398641586303, 120, 255, 1, "", 45942, NULL), +(10054, 173063, 1, 0, 0, 1, 1, 2021.614990234375, -4688.12939453125, 25.40483283996582031, 2.426007747650146484, 0, 0, 0.936672210693359375, 0.350207358598709106, 120, 255, 1, "", 45435, NULL), +(10118, 2575, 0, 0, 0, 1, 1, -14378.8134765625, 379.263885498046875, 23.31351470947265625, 4.145159721374511718, 0, 0, -0.87672615051269531, 0.48098987340927124, 120, 255, 1, "", 45572, NULL), +(10826, 19902, 0, 0, 0, 1, 1, -6763.6630859375, -3125.5087890625, 242.098419189453125, 1.343902826309204101, 0.042108535766601562, -0.03894233703613281, 0.621876716613769531, 0.781011998653411865, 120, 255, 1, "", 45613, NULL), +(10828, 179924, 0, 0, 0, 1, 1, -6670.96337890625, -2155.569580078125, 243.8922576904296875, 4.886921405792236328, 0, 0, -0.64278793334960937, 0.766044199466705322, 120, 255, 1, "", 45613, NULL), +(1091, 1749, 0, 0, 0, 1, 1, -5579.0400390625, -428.92535400390625, 397.214263916015625, 3.141592741012573242, 0, 0, -1, 0, 120, 255, 1, "", 45613, NULL), +(11000, 21679, 0, 0, 0, 1, 1, -14380.5419921875, 371.746826171875, 23.94536018371582031, 1.893682122230529785, 0, 0, 0.811573982238769531, 0.584249675273895263, 120, 255, 1, "", 45572, NULL), +(1126, 34571, 0, 0, 0, 1, 1, -5579.162109375, -435.338470458984375, 397.60888671875, 4.712389945983886718, 0, 0, -0.70710659027099609, 0.707106947898864746, 120, 255, 1, "", 45613, NULL), +(11324, 173095, 1, 0, 0, 1, 1, 2051.62890625, -4838.9736328125, 24.58019256591796875, 3.735006093978881835, 0, 0, -0.95630455017089843, 0.292372345924377441, 120, 255, 1, "", 45435, NULL), +(11598, 173064, 1, 0, 0, 1, 1, 2048.722412109375, -4812.20654296875, 22.65833473205566406, 3.735006093978881835, 0, 0, -0.95630455017089843, 0.292372345924377441, 120, 255, 1, "", 45435, NULL), +(11819, 144133, 0, 0, 0, 1, 1, -5340.11083984375, -2940.55078125, 323.762451171875, 1.823866248130798339, -0.05446863174438476, -0.08452987670898437, 0.786145210266113281, 0.609806180000305175, 120, 255, 1, "", 45613, NULL), +(12642, 153459, 0, 0, 0, 1, 1, -10894.9189453125, -3185.491455078125, 49.57025527954101562, 1.856318235397338867, 0, 0, 0.800518035888671875, 0.599308669567108154, 120, 255, 1, "", 45772, NULL), +(12687, 20738, 1, 0, 0, 1, 1, 787.8443603515625, -1821.4989013671875, 91.5555572509765625, 0.095991745591163635, 0, 0, 0.047977447509765625, 0.998848438262939453, 120, 255, 1, "", 45435, NULL), +(12799, 147285, 0, 0, 0, 1, 1, -10950.888671875, -3456.81640625, 64.95444488525390625, 2.570527553558349609, 0, 0, 0.959511756896972656, 0.28166857361793518, 120, 255, 1, "", 48632, NULL), +(13139, 4090, 530, 0, 0, 1, 1, -2976.90234375, 4027.7607421875, 1.764023303985595703, 5.619962215423583984, 0, 0, -0.32556724548339843, 0.945518851280212402, 120, 255, 1, "", 45704, NULL), +(13261, 56897, 1, 0, 0, 1, 1, -1068.0462646484375, -3534.879638671875, 64.31089019775390625, 1.247910022735595703, 0, 0, 0.584249496459960937, 0.811574101448059082, 120, 255, 1, "", 45435, NULL), +(13306, 138317, 1, 0, 0, 1, 1, -2287.17529296875, -1943.8035888671875, 95.7456817626953125, 6.073746204376220703, 0, 0, -0.10452842712402343, 0.994521915912628173, 120, 255, 1, "", 45435, NULL), +(13360, 147285, 1, 0, 0, 1, 1, -1996.5625, -3608.458984375, 21.75933074951171875, 3.630291461944580078, 0, 0, -0.97029495239257812, 0.241925001144409179, 120, 255, 1, "", 45435, NULL), +(13766, 20986, 0, 0, 0, 1, 1, -3794.984375, -862.1007080078125, 11.59808254241943359, 3.141592741012573242, 0, 0, -1, 0, 120, 255, 1, "", 46902, NULL), +(13813, 23304, 0, 0, 0, 1, 1, -8421.3154296875, 613.4404296875, 95.18099212646484375, 3.81354522705078125, 0, 0, -0.94408893585205078, 0.329690933227539062, 120, 255, 1, "", 45613, NULL), +(13814, 23305, 0, 0, 0, 1, 1, -8425.16015625, 618.067138671875, 95.38744354248046875, 3.81354522705078125, 0, 0, -0.94408893585205078, 0.329690933227539062, 120, 255, 1, "", 45613, NULL), +(13968, 24745, 0, 0, 0, 1, 1, -8420.0986328125, 633.51885986328125, 95.6527099609375, 3.81354522705078125, 0, 0, -0.94408893585205078, 0.329690933227539062, 120, 255, 1, "", 45613, NULL), +(13970, 24746, 0, 0, 0, 1, 1, -8427.1025390625, 631.1102294921875, 95.631072998046875, 2.234022140502929687, 0, 0, 0.898794174194335937, 0.438370853662490844, 120, 255, 1, "", 45613, NULL), +(14273, 34572, 0, 0, 0, 1, 1, -2603.527099609375, -2284.218017578125, 86.29964447021484375, 4.677483558654785156, 0, 0, -0.71933937072753906, 0.694658815860748291, 120, 255, 1, "", 49822, NULL), +(14352, 4090, 0, 0, 0, 1, 1, -3792.044921875, -865.609375, 9.787861824035644531, 0.741763234138488769, 0, 0, 0.362437248229980468, 0.932008147239685058, 120, 255, 1, "", 46902, NULL), +(14796, 38491, 0, 0, 0, 1, 1, -10594.263671875, -1159.22265625, 28.24942779541015625, 5.724681377410888671, 0, 0, -0.27563667297363281, 0.961261868476867675, 120, 255, 1, "", 45613, NULL), +(150251, 202392, 658, 0, 0, 3, 1, 878.23956298828125, 24.69965362548828125, 498.51959228515625, 1.553341388702392578, 0, 0, 0.700908660888671875, 0.713251054286956787, 7200, 255, 1, "", 51666, NULL), +(150275, 202393, 658, 0, 0, 3, 1, 728, -122.15625, 491.925933837890625, 1.535886883735656738, 0, 0, 0.694657325744628906, 0.719340801239013671, 7200, 255, 1, "", 51666, NULL), +(150281, 202391, 658, 0, 0, 3, 1, 855.27777099609375, 68.93402862548828125, 498.538848876953125, 1.300268411636352539, 0, 0, 0.60529327392578125, 0.796002507209777832, 7200, 255, 1, "", 51666, NULL), +(150283, 202394, 658, 0, 0, 3, 1, 661.19964599609375, -121.932289123535156, 491.615386962890625, 1.535886883735656738, 0, 0, 0.694657325744628906, 0.719340801239013671, 7200, 255, 1, "", 51666, NULL), +(151208, 186556, 571, 0, 0, 1, 1, 2426.829833984375, -5083.95849609375, 272.943023681640625, 0.270525157451629638, 0, 0, 0.134850502014160156, 0.990865945816040039, 120, 255, 1, "", 46158, NULL), +(15217, 2728, 0, 0, 0, 1, 1, -1252.359375, -2548.46875, 21.37276458740234375, 3.141592741012573242, 0, 0, -1, 0, 120, 255, 1, "", 46902, NULL), +(15396, 2727, 0, 0, 0, 1, 1, -936.98773193359375, -3482.45458984375, 51.4742889404296875, 3.141592741012573242, 0, 0, -1, 0, 120, 255, 1, "", 45572, NULL), +(15728, 51949, 1, 0, 0, 1, 1, -426.52789306640625, -3162.13427734375, 212.420684814453125, 2.923411369323730468, -0.03230953216552734, 0.025470733642578125, 0.993130683898925781, 0.109538912773132324, 120, 255, 1, "", 45435, NULL), +(15733, 169969, 1, 0, 0, 1, 1, -923.12451171875, -3686.859375, 8.161623954772949218, 4.075345039367675781, 0, 0, -0.89297866821289062, 0.450098991394042968, 120, 255, 1, "", 45435, NULL), +(16626, 147285, 530, 0, 0, 1, 1, -714.12109375, 2603.4951171875, 89.20101165771484375, 1.300268411636352539, 0, 0, 0.60529327392578125, 0.796002507209777832, 120, 255, 1, "", 45854, NULL), +(17011, 2573, 0, 0, 0, 1, 1, -574.515625, 45.43229293823242187, 49.8842926025390625, 3.141592741012573242, 0, 0, -1, 0, 120, 255, 1, "", 46368, NULL), +(17014, 1797, 0, 0, 0, 1, 1, -550.33856201171875, -1437.0208740234375, 52.44382858276367187, 3.141592741012573242, 0, 0, -1, 0, 120, 255, 1, "", 45854, NULL), +(17141, 1896, 0, 0, 0, 1, 1, -819.25152587890625, -571.79296875, 15.31679153442382812, 3.141592741012573242, 0, 0, -1, 0, 120, 255, 1, "", 45942, NULL), +(17240, 141838, 1, 0, 0, 1, 1, -7199.05419921875, -3766.189208984375, 8.659154891967773437, 2.696528911590576171, 0, 0, 0.975341796875, 0.220699742436408996, 120, 255, 1, "", 45572, NULL), +(17252, 141841, 1, 0, 0, 1, 1, -7390.02978515625, -4724.98876953125, 8.988080024719238281, 4.040439605712890625, 0, 0, -0.90069770812988281, 0.434446364641189575, 120, 255, 1, "", 45772, NULL), +(17426, 184617, 0, 0, 0, 1, 1, -160.125, -866.33380126953125, 56.50273513793945312, 2.792520999908447265, -0.03234386444091796, -0.00758171081542968, 0.984333038330078125, 0.173161461949348449, 120, 255, 1, "", 45572, NULL), +(18568, 4090, 0, 0, 0, 1, 1, -571.947265625, 39.94140625, 48.07407760620117187, 5.654868602752685546, 0, 0, -0.30901622772216796, 0.95105677843093872, 120, 255, 1, "", 46368, NULL), +(20494, 182056, 530, 0, 0, 1, 1, -1935.828125, -11912.1845703125, 48.0586395263671875, 5.907940864562988281, 0, 0, -0.1865234375, 0.982450485229492187, 120, 255, 1, "", 46158, NULL), +(20562, 3223, 1, 0, 0, 1, 1, -1886.951416015625, -1093.63720703125, 90.000457763671875, 2.740160465240478515, -0.03085994720458984, -0.02042579650878906, 0.979389190673828125, 0.198563039302825927, 120, 255, 1, "", 46368, NULL), +(20709, 183818, 530, 0, 0, 1, 1, 249.648651123046875, 6030.2138671875, 131.5974884033203125, 2.827429771423339843, 0, 0, 0.987688064575195312, 0.156436234712600708, 120, 255, 1, "", 45704, NULL), +(22227, 181716, 530, 0, 0, 1, 1, -4727.85791015625, -12387.09375, 11.0831146240234375, 3.262326002120971679, 0, 0, -0.99817848205566406, 0.060329910367727279, 120, 255, 1, "", 45942, NULL), +(22401, 181990, 530, 0, 0, 1, 1, 8677.5595703125, -6606.2431640625, 70.25475311279296875, 3.534291028976440429, 0, 0, -0.98078536987304687, 0.195089906454086303, 120, 255, 1, "", 45854, NULL), +(22525, 182117, 530, 0, 0, 1, 1, -2649.286376953125, 4441.5537109375, 36.73196029663085937, 3.351046562194824218, 0, 0, -0.99452114105224609, 0.104535527527332305, 120, 255, 1, "", 45704, NULL), +(22762, 182278, 530, 0, 0, 1, 1, -4186.52099609375, -12440.0107421875, 43.38792800903320312, 3.063024282455444335, 0, 0, 0.999228477478027343, 0.039274025708436965, 120, 255, 1, "", 45435, NULL), +(23671, 182860, 530, 0, 0, 1, 1, 173.7569427490234375, 4296.73193359375, 117.1742477416992187, 4.773476600646972656, 0, 0, -0.68518257141113281, 0.728371381759643554, 120, 255, 1, "", 48632, NULL), +(24009, 183121, 530, 0, 0, 1, 1, 216.3246612548828125, 7859.2802734375, 23.9654388427734375, 1.745326757431030273, 0, 0, 0.766043663024902343, 0.642788589000701904, 120, 255, 1, "", 45942, NULL), +(24036, 183148, 530, 0, 0, 1, 1, -1329.3367919921875, 7198.845703125, 34.24901962280273437, 3.141592741012573242, 0, 0, -1, 0, 120, 255, 1, "", 45704, NULL), +(24217, 183345, 530, 0, 0, 1, 1, 323.560760498046875, 7838.1708984375, 21.79891395568847656, 4.022988319396972656, 0, 0, -0.90445423126220703, 0.426570683717727661, 120, 255, 1, "", 45942, NULL), +(24219, 183347, 530, 0, 0, 1, 1, 189.00347900390625, 2671.132080078125, 88.7217864990234375, 2.474651098251342773, 0, 0, 0.944911956787109375, 0.327324569225311279, 120, 255, 1, "", 45704, NULL), +(24317, 183408, 530, 0, 0, 1, 1, 2544.48095703125, 6512.921875, 3.469935894012451171, 1.173768043518066406, 0, 0, 0.553769111633300781, 0.832670271396636962, 120, 255, 1, "", 45704, NULL), +(24377, 183484, 530, 0, 0, 1, 1, 2330.126708984375, 6059.69091796875, 142.1997222900390625, 1.308995485305786132, 0, 0, 0.608760833740234375, 0.793353796005249023, 120, 255, 1, "", 45704, NULL), +(24587, 183757, 530, 0, 0, 1, 1, 9846.5849609375, -7361.634765625, 19.392669677734375, 4.450565338134765625, 0, 0, -0.79336071014404296, 0.608751833438873291, 120, 255, 1, "", 45572, NULL), +(24588, 183758, 530, 0, 0, 1, 1, 9840.0341796875, -7358.28759765625, 19.392669677734375, 4.09075021743774414, 0, 0, -0.88948535919189453, 0.456963688135147094, 120, 255, 1, "", 45572, NULL), +(24589, 183759, 530, 0, 0, 1, 1, 9853.9775390625, -7361.6435546875, 19.392669677734375, 4.897896289825439453, 0, 0, -0.63857460021972656, 0.769559919834136962, 120, 255, 1, "", 45572, NULL), +(24590, 183760, 530, 0, 0, 1, 1, 9860.2431640625, -7358.53271484375, 19.392669677734375, 5.33464813232421875, 0, 0, -0.45668792724609375, 0.889626979827880859, 120, 255, 1, "", 45572, NULL), +(24647, 183782, 530, 0, 0, 1, 1, -2248.666748046875, 6225.14306640625, 43.85218429565429687, 3.62458205223083496, 0, 0, -0.97098159790039062, 0.239154160022735595, 120, 255, 1, "", 45704, NULL), +(25118, 184286, 530, 0, 0, 1, 1, -3963.257080078125, 2201.802001953125, 101.7742996215820312, 2.836158275604248046, 0, 0, 0.988361358642578125, 0.152124300599098205, 120, 255, 1, "", 45854, NULL), +(25827, 184922, 530, 0, 0, 1, 1, -4236.08984375, -11717.1201171875, -143.95550537109375, 1.744720935821533203, -0.0032806396484375, -0.00522518157958984, 0.76583099365234375, 0.643012285232543945, 120, 255, 1, "", 45942, NULL), +(25828, 184923, 530, 0, 0, 1, 1, -4242.69384765625, -11713.734375, -144.075897216796875, 0.650804519653320312, -0.00008392333984375, -0.00616931915283203, 0.319672584533691406, 0.947507977485656738, 120, 255, 1, "", 45942, NULL), +(26791, 4090, 0, 0, 0, 1, 1, -9460.033203125, 94.203125, 56.53351593017578125, 4.738570213317871093, 0, 0, -0.69779014587402343, 0.716302275657653808, 120, 255, 1, "", 45435, NULL), +(27148, 181884, 530, 0, 0, 1, 1, 7599.20751953125, -6910.67041015625, 93.76873779296875, 4.555310726165771484, 0, 0, -0.76040554046630859, 0.649448513984680175, 120, 255, 1, "", 45942, NULL), +(27638, 184146, 530, 0, 0, 1, 1, 2318.157958984375, 7256.900390625, 365.553924560546875, 0.488691210746765136, 0, 0, 0.241921424865722656, 0.970295846462249755, 120, 255, 1, "", 45942, NULL), +(27811, 187112, 530, 0, 0, 1, 1, 12667.82421875, -6982.90478515625, 14.57323360443115234, 3.124123096466064453, 0, 0, 0.99996185302734375, 0.008734640665352344, 120, 255, 1, "", 45942, NULL), +(28273, 186139, 530, 0, 0, 1, 1, 4142.79931640625, 3064.890625, 336.458526611328125, 5.742135047912597656, 0, 0, -0.26723766326904296, 0.96363067626953125, 120, 255, 1, "", 45704, NULL), +(29723, 184687, 530, 0, 0, 1, 1, -2395.927001953125, 2890.4228515625, -55.8926277160644531, 4.327290058135986328, -0.00849390029907226, 0.004799842834472656, -0.82933425903320312, 0.558667600154876708, 120, 255, 1, "", 49936, NULL), +(30166, 17190, 1, 0, 0, 1, 1, -1981.136962890625, 442.016998291015625, 133.5895843505859375, 3.150327444076538085, 0, 0, -0.99999046325683593, 0.004367320332676172, 120, 255, 1, "", 46368, NULL), +(30172, 175144, 1, 0, 0, 1, 1, 196.7274017333984375, 1173.1475830078125, 167.8319549560546875, 0.593411982059478759, 0, 0, 0.292371749877929687, 0.956304728984832763, 120, 255, 1, "", 46902, NULL), +(30402, 182270, 530, 0, 0, 1, 1, -198.95660400390625, 5483.064453125, 21.8449859619140625, 5.523968696594238281, 0, 0, -0.37055683135986328, 0.928809821605682373, 120, 255, 1, "", 45704, NULL), +(30816, 186138, 530, 0, 0, 1, 1, 2960.78125, 1799.53125, 139.0110931396484375, 0.654497027397155761, 0, 0, 0.321438789367675781, 0.946930348873138427, 120, 255, 1, "", 45704, NULL), +(32298, 130668, 0, 0, 0, 1, 1, -10651.626953125, 1106.9129638671875, 33.60646820068359375, 2.347463846206665039, 0, 0, 0.922200202941894531, 0.386712819337844848, 120, 255, 1, "", 47966, NULL), +(32655, 175851, 1, 0, 0, 1, 1, -1689.623291015625, 3082.467041015625, 32.05278396606445312, 1.562069892883300781, 0, 0, 0.704014778137207031, 0.71018528938293457, 120, 255, 1, "", 45572, NULL), +(32779, 186141, 530, 0, 0, 1, 1, 3065.7578125, 3677.720458984375, 142.3012237548828125, 4.598945140838623046, 0, 0, -0.74605655670166015, 0.665882587432861328, 120, 255, 1, "", 45704, NULL), +(34300, 38491, 0, 0, 0, 1, 1, -344.818359375, 1502.005859375, 16.99886703491210937, 3.551750659942626953, 0, 0, -0.97904491424560546, 0.203644454479217529, 120, 255, 1, "", 46248, NULL), +(387, 1685, 1, 0, 0, 1, 1, 1523.77783203125, -4368.2412109375, 18.21411514282226562, 0, 0, 0, 0, 1, 120, 255, 1, "", 45327, NULL), +(44762, 1743, 0, 0, 0, 1, 1, 2039.029541015625, 150.2760467529296875, 34.25516128540039062, 3.141669034957885742, 0.00436258316040039, -0.00872516632080078, 0.999952316284179687, 0, 120, 255, 1, "", 45572, NULL), +(44871, 38491, 0, 0, 0, 1, 1, 2230.72265625, 313.740234375, 34.91133499145507812, 5.585053920745849609, 0, 0, -0.34202003479003906, 0.939692676067352294, 120, 255, 1, "", 45435, NULL), +(44916, 52175, 0, 0, 0, 1, 1, 1392.591796875, 147.989959716796875, -62.4183311462402343, 1.928588032722473144, 0, 0, 0.821646690368652343, 0.569997072219848632, 120, 255, 1, "", 45572, NULL), +(44917, 52176, 0, 0, 0, 1, 1, 1684.68798828125, 276.8250732421875, -62.1811408996582031, 1.265363454818725585, 0, 0, 0.591309547424316406, 0.806444704532623291, 120, 255, 1, "", 45435, NULL), +(44949, 113754, 0, 0, 0, 1, 1, 1694.1341552734375, 293.993408203125, -62.1811408996582031, 2.975770950317382812, 0, 0, 0.996564865112304687, 0.082815870642662048, 120, 255, 1, "", 45435, NULL), +(45334, 148960, 0, 0, 0, 1, 1, 2979.0419921875, -1491.28125, 145.2322998046875, 4.747295856475830078, 0, 0, -0.69465827941894531, 0.719339847564697265, 120, 255, 1, "", 50664, NULL), +(45606, 181130, 0, 0, 0, 1, 1, 2261.361083984375, -5322.44970703125, 81.84270477294921875, 5.091957569122314453, 0, 0, -0.56101703643798828, 0.827804267406463623, 120, 255, 1, "", 45942, NULL), +(45689, 148960, 0, 0, 0, 1, 1, 1548.6962890625, -5387.109375, 78.22446441650390625, 5.558874130249023437, 0, 0, -0.35429096221923828, 0.935135245323181152, 120, 255, 1, "", 50664, NULL), +(46082, 179886, 0, 0, 0, 1, 1, -593.06597900390625, -4546.814453125, 8.975338935852050781, 2.111847877502441406, 0, 0, 0.870355606079101562, 0.492423713207244873, 120, 255, 1, "", 45772, NULL), +(46161, 34572, 0, 0, 0, 1, 1, 212.6529541015625, -1966.4642333984375, 140.4819793701171875, 4.703663349151611328, 0, 0, -0.71018505096435546, 0.704015016555786132, 120, 255, 1, "", 46902, NULL), +(4623, 1685, 530, 0, 0, 1, 1, 9479.353515625, -6800.869140625, 16.49356460571289062, 5.70722818374633789, 0, 0, -0.28401470184326171, 0.958819925785064697, 120, 255, 1, "", 45854, NULL), +(467, 194468, 530, 0, 0, 1, 1, -1747.6688232421875, 5648.66162109375, 128.023193359375, 4.049167633056640625, 0, 0, -0.89879322052001953, 0.438372820615768432, 120, 255, 1, "", 45942, NULL), +(47586, 176509, 1, 0, 0, 1, 1, 988.24676513671875, 1005.29302978515625, 104.6084671020507812, 2.748894453048706054, 0, 0, 0.980785369873046875, 0.195089906454086303, 120, 255, 1, "", 45435, NULL), +(47603, 50831, 1, 0, 0, 1, 1, 112.123046875, -591.829345703125, -1.67420196533203125, 4.694936752319335937, 0, 0, -0.71325016021728515, 0.700909554958343505, 120, 255, 1, "", 51943, NULL), +(48632, 92490, 1, 0, 0, 1, 1, 6542.94384765625, 434.2857666015625, 7.549087047576904296, 2.172934770584106445, 0.000201702117919921, 0.009753227233886718, 0.884927749633789062, 0.465626090764999389, 120, 255, 1, "", 46248, NULL), +(49092, 179863, 1, 0, 0, 1, 1, 6696.50341796875, -4645.01416015625, 720.94970703125, 3.359769821166992187, 0, 0, -0.99405574798583984, 0.108872212469577789, 120, 255, 1, "", 45854, NULL), +(49393, 180913, 1, 0, 0, 1, 1, -6865.65576171875, 754.037353515625, 42.65666580200195312, 3.394674062728881835, 0, 0, -0.99200439453125, 0.126203224062919616, 120, 255, 1, "", 45704, NULL), +(49803, 1685, 1, 0, 0, 1, 1, 9916.1142578125, 2308.030517578125, 1330.786376953125, 5.986480236053466796, 0, 0, -0.14780902862548828, 0.989015936851501464, 120, 255, 1, "", 46248, NULL), +(5258, 171716, 0, 0, 0, 1, 1, -4762.9716796875, -1117.1053466796875, 499.334869384765625, 2.260197162628173828, 0, 0, 0.904454231262207031, 0.426570683717727661, 120, 255, 1, "", 45435, NULL), +(5430, 171717, 0, 0, 0, 1, 1, -4807.8603515625, -1130.1844482421875, 499.49908447265625, 2.260197162628173828, 0, 0, 0.904454231262207031, 0.426570683717727661, 120, 255, 1, "", 45435, NULL), +(55964, 192020, 571, 0, 0, 1, 1, 1954.1180419921875, -6190.4912109375, 24.12676429748535156, 1.527163028717041015, 0, 0, 0.6915130615234375, 0.722363948822021484, 120, 255, 1, "", 45772, NULL), +(56459, 186654, 571, 0, 0, 1, 1, 421.713531494140625, -4648.42724609375, 246.7728118896484375, 4.799657344818115234, 0, 0, -0.67558956146240234, 0.737277925014495849, 120, 255, 1, "", 45772, NULL), +(56480, 190495, 571, 0, 0, 1, 1, 7793.19091796875, -2950.447998046875, 1257.730712890625, 0.550021290779113769, -0.00670766830444335, 0.016690254211425781, 0.271546363830566406, 0.962257266044616699, 120, 255, 1, "", 46158, NULL), +(56654, 188452, 571, 0, 0, 1, 1, 3309.210205078125, -2341.568115234375, 110.914093017578125, 4.948008537292480468, 0, 0, -0.61909389495849609, 0.785317003726959228, 120, 255, 1, "", 46158, NULL), +(56955, 190765, 571, 0, 0, 1, 1, 5246.63623046875, 4490.5849609375, -84.3280258178710937, 1.851126790046691894, -0.00239181518554687, 0.026426315307617187, 0.798467636108398437, 0.60145270824432373, 120, 255, 1, "", 45942, NULL), +(57486, 190524, 571, 0, 0, 1, 1, 6642.57666015625, -209.402786254882812, 951.870361328125, 2.932138919830322265, 0, 0, 0.994521141052246093, 0.104535527527332305, 120, 255, 1, "", 46368, NULL), +(57539, 192831, 571, 0, 0, 1, 1, 5622.48291015625, 4572.2587890625, -137.663543701171875, 2.391098499298095703, 0, 0, 0.930417060852050781, 0.366502493619918823, 120, 255, 1, "", 45942, NULL), +(57574, 186433, 571, 0, 0, 1, 1, 1401.9322509765625, -3199.857666015625, 160.9440460205078125, 4.694936752319335937, 0.012232780456542968, -0.01244735717773437, -0.71314144134521484, 0.700802862644195556, 120, 255, 1, "", 46158, NULL), +(57733, 192583, 571, 0, 0, 1, 1, 7985.84716796875, 4.990450859069824218, 961.5565185546875, 2.407231092453002929, -0.00676393508911132, 0.00738525390625, 0.933281898498535156, 0.359004944562911987, 120, 255, 1, "", 47720, NULL), +(58133, 188250, 571, 0, 0, 1, 1, 4542.96728515625, -4246.021484375, 170.49212646484375, 5.75086069107055664, 0, 0, -0.263031005859375, 0.96478736400604248, 120, 255, 1, "", 47720, NULL), +(58300, 188257, 571, 0, 0, 1, 1, 3832.708251953125, -4541.69287109375, 209.2318115234375, 3.612833499908447265, 0.01158761978149414, 0.014916419982910156, -0.97215557098388671, 0.233573809266090393, 120, 255, 1, "", 45942, NULL), +(59043, 191346, 571, 0, 0, 1, 1, 2481.087646484375, -1951.9427490234375, 10.88319873809814453, 5.410521507263183593, 0, 0, -0.42261791229248046, 0.906307935714721679, 120, 255, 1, "", 46779, NULL), +(59092, 186486, 571, 0, 0, 1, 1, 544.4949951171875, -4997.93017578125, 10.47229957580566406, 3.001969099044799804, 0.021456718444824218, -0.00587368011474609, 0.997310638427734375, 0.069832757115364074, 120, 255, 1, "", 48632, NULL), +(59113, 187256, 571, 0, 0, 1, 1, 2334.302001953125, 5269.29931640625, 7.547565937042236328, 1.954769015312194824, 0, 0, 0.829037666320800781, 0.559192776679992675, 120, 255, 1, "", 47720, NULL), +(59403, 194487, 571, 0, 0, 1, 1, 8545.7783203125, 934.6180419921875, 547.29266357421875, 3.115387916564941406, 0, 0, 0.999914169311523437, 0.013101960532367229, 120, 255, 1, "", 50129, NULL), +(59623, 1685, 571, 0, 0, 1, 1, 5924.43994140625, 715.0439453125, 642.43829345703125, 4.660029888153076171, 0, 0, -0.72537422180175781, 0.688354730606079101, 120, 255, 1, "", 45327, NULL), +(59624, 1685, 571, 0, 0, 1, 1, 2478.989990234375, -1954.662353515625, 10.88320159912109375, 4.764749526977539062, 0, 0, -0.6883544921875, 0.725374460220336914, 120, 255, 1, "", 46368, NULL), +(60255, 188607, 571, 0, 0, 1, 1, 2760.4541015625, 853.0382080078125, 6.700050830841064453, 1.649336218833923339, 0, 0, 0.734322547912597656, 0.678800702095031738, 120, 255, 1, "", 45854, NULL), +(60307, 188354, 571, 0, 0, 1, 1, 3813.7353515625, 1571.326416015625, 86.64066314697265625, 3.263772249221801757, 0, 0, -0.99813461303710937, 0.061051756143569946, 120, 255, 1, "", 45854, NULL), +(60317, 188356, 571, 0, 0, 1, 1, 3819.686767578125, 1561.798583984375, 86.58795928955078125, 4.756025314331054687, 0, 0, -0.69151210784912109, 0.722364842891693115, 120, 255, 1, "", 45854, NULL), +(60512, 188624, 571, 0, 0, 1, 1, 3417.529541015625, -2759.072998046875, 199.2813720703125, 0.968657433986663818, 0.002991676330566406, 0.003175735473632812, 0.465604782104492187, 0.884981989860534667, 120, 255, 1, "", 46158, NULL), +(61116, 188651, 571, 0, 0, 1, 1, 4131.76416015625, 5282.38818359375, 25.10947418212890625, 5.724681377410888671, 0, 0, -0.27563667297363281, 0.961261868476867675, 120, 255, 1, "", 45854, NULL), +(61125, 188396, 571, 0, 0, 1, 1, 3210.1171875, -635.60418701171875, 160.1486663818359375, 4.180065631866455078, 0, 0, -0.86819839477539062, 0.496217250823974609, 120, 255, 1, "", 45942, NULL), +(61538, 190457, 571, 0, 0, 1, 1, 5409.99462890625, -2662.455078125, 303.933135986328125, 6.025707721710205078, 0, 0, -0.12838363647460937, 0.991724610328674316, 120, 255, 1, "", 45942, NULL), +(61660, 187388, 571, 0, 0, 1, 1, 3071.33935546875, 4826.24755859375, 1.220486998558044433, 5.279621601104736328, 0, 0, -0.4809885025024414, 0.876726925373077392, 120, 255, 1, "", 45854, NULL), +(62356, 192062, 571, 0, 0, 1, 195, 6204.640625, -3.63715291023254394, 410.169921875, 2.164208889007568359, 0.002507686614990234, -0.01356697082519531, 0.88282012939453125, 0.469508498907089233, 120, 255, 1, "", 45942, NULL), +(63130, 191287, 571, 0, 0, 1, 1, 2760.498291015625, 6177.1982421875, 83.32198333740234375, 3.883358240127563476, 0, 0, -0.9320077896118164, 0.36243826150894165, 120, 255, 1, "", 45772, NULL), +(63131, 191288, 571, 0, 0, 1, 1, 2826.31787109375, 6108.43017578125, 83.32198333740234375, 4.694071292877197265, 0, 0, -0.71355342864990234, 0.700600802898406982, 120, 255, 1, "", 45772, NULL), +(63132, 192572, 571, 0, 0, 1, 1, 2757.91162109375, 6203.10693359375, 83.32198333740234375, 3.883358240127563476, 0, 0, -0.9320077896118164, 0.36243826150894165, 120, 255, 1, "", 45772, NULL), +(63133, 192573, 571, 0, 0, 1, 1, 2851.6044921875, 6105.693359375, 83.32198333740234375, 5.082666873931884765, 0, 0, -0.56485652923583984, 0.825189113616943359, 120, 255, 1, "", 45772, NULL), +(63185, 191508, 0, 0, 0, 1, 449, 2438.341064453125, -5655.60595703125, 420.542938232421875, 4.609313011169433593, 0, 0, -0.74259471893310546, 0.669741034507751464, 120, 255, 1, "", 45942, NULL), +(65329, 186653, 571, 0, 0, 1, 1, 413.211822509765625, -4655.423828125, 246.5844268798828125, 2.574358940124511718, 0, 0, 0.960049629211425781, 0.279829770326614379, 120, 255, 1, "", 45772, NULL), +(65868, 191237, 609, 0, 0, 1, 1, 2261.635498046875, -5322.5556640625, 81.92261505126953125, 5.131268978118896484, 0, 0, -0.54463863372802734, 0.838670849800109863, 120, 255, 1, "", 48632, NULL), +(65884, 191505, 609, 0, 0, 1, 231, 2453.395751953125, -5659.1181640625, 420.566162109375, 4.609313011169433593, 0, 0, -0.74259471893310546, 0.669741034507751464, 120, 255, 1, "", 48632, NULL), +(66110, 148960, 609, 0, 0, 1, 1, 1811.8017578125, -6001.63671875, 115.8481292724609375, 4.738570213317871093, 0, 0, -0.69779014587402343, 0.716302275657653808, 120, 255, 1, "", 48632, NULL), +(66396, 191505, 0, 0, 0, 1, 449, 2453.395751953125, -5659.1181640625, 420.56658935546875, 4.609313011169433593, 0, 0, -0.74259471893310546, 0.669741034507751464, 120, 255, 1, "", 45942, NULL), +(66401, 191508, 609, 0, 0, 1, 231, 2438.341064453125, -5655.60595703125, 420.54248046875, 4.609313011169433593, 0, 0, -0.74259471893310546, 0.669741034507751464, 120, 255, 1, "", 48632, NULL), +(6880, 179844, 0, 0, 0, 1, 1, -6525.9970703125, -1188.3726806640625, 309.2177734375, 2.312241077423095703, 0, 0, 0.915246963500976562, 0.402893275022506713, 120, 255, 1, "", 45772, NULL), +(6881, 152034, 0, 0, 0, 1, 1, -6831.6884765625, -1222.37109375, 240.0138702392578125, 1.780233979225158691, 0, 0, 0.7771453857421875, 0.629321098327636718, 120, 255, 1, "", 45772, NULL), +(6927, 152042, 0, 0, 0, 1, 1, -6745.45703125, -1248.993896484375, 246.7498931884765625, 1.780233979225158691, 0, 0, 0.7771453857421875, 0.629321098327636718, 120, 255, 1, "", 45772, NULL), +(6935, 152045, 0, 0, 0, 1, 1, -6686.6318359375, -1428.4888916015625, 241.3292694091796875, 0.47996494174003601, 0.030863761901855468, 0.038967132568359375, 0.236227035522460937, 0.970425546169281005, 120, 255, 1, "", 45772, NULL), +(71405, 193126, 571, 0, 0, 1, 1, 5292.3046875, 2930.510498046875, 409.157135009765625, 3.220161199569702148, 0, 0, -0.99922847747802734, 0.039274025708436965, 120, 255, 1, "", 46248, NULL), +(7561, 186231, 1, 0, 0, 1, 1, -4606.11474609375, -3212.513916015625, 34.81392288208007812, 4.022988319396972656, 0, 0, -0.90445423126220703, 0.426570683717727661, 120, 255, 1, "", 45613, NULL), +(7591, 186630, 1, 0, 0, 1, 1, -3150.38916015625, -2857.26904296875, 34.00139236450195312, 2.085667610168457031, 0, 0, 0.863835334777832031, 0.503774285316467285, 120, 255, 1, "", 45572, NULL), +(77189, 194128, 571, 0, 0, 1, 1, 6096.16845703125, -1074.0052490234375, 404.558258056640625, 0.514872133731842041, -0.0191049575805664, 0.084914207458496093, 0.253370285034179687, 0.963445961475372314, 120, 255, 1, "", 46158, NULL), +(82, 176895, 0, 0, 0, 1, 1, -8100.392578125, -1507.236083984375, 132.9344024658203125, 4.188792228698730468, 0, 0, -0.86602497100830078, 0.50000077486038208, 120, 255, 1, "", 45772, NULL), +(8821, 4090, 1, 0, 0, 1, 1, -3792.841796875, -4369.90234375, 14.97791671752929687, 6.178466320037841796, 0, 0, -0.05233573913574218, 0.998629570007324218, 120, 255, 1, "", 46902, NULL), +(95, 1685, 0, 0, 0, 1, 1, -4816.33935546875, -1250.142333984375, 501.904693603515625, 1.954769015312194824, 0, 0, 0.829037666320800781, 0.559192776679992675, 120, 255, 1, "", 45435, NULL), +(9937, 142078, 0, 0, 0, 1, 1, -12040.26953125, -1005.96307373046875, 49.4103546142578125, 2.417279243469238281, 0, 0, 0.9351348876953125, 0.354291886091232299, 120, 255, 1, "", 45572, NULL); + +-- remaining spawns (no sniffed values available) +-- (`guid` IN (66383, 66616, 31085, 42510, 76879, 44720)) + +-- two remaining spawns actually show in sniffs but with non-existend gameobject IDs +-- guid 31085, id 1745: +-- (, 405870, 0, 40, 20, 1, 1, -11042.3994140625, 1452.140625, 45.19609832763671875, 4.860743999481201171, 0.002847671508789062, 0.003304481506347656, -0.65275287628173828, 0.757558345794677734, 120, 255, 1, 53622), -- 405870 (Area: 20 - Difficulty: 0) CreateObject1 +-- guid 42510, id 2015: +-- (, 405880, 0, 44, 68, 1, 1, -9261.330078125, -2228.619873046875, 63.7667999267578125, 3.141592741012573242, 0, 0.008726119995117187, 0.99996185302734375, 0, 120, 255, 1, 53622), -- 405880 (Area: 68 - Difficulty: 0) CreateObject1 + +-- new spawns +DELETE FROM `gameobject` WHERE (`id` IN (161487, 1685, 178684, 194468, 34571, 38491)) +AND (`guid` BETWEEN 12362 AND 12368); +INSERT INTO `gameobject` (`guid`, `id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`, `Comment`) VALUES +(12362, 161487, 30, 0, 0, 3, 1, 361.09722900390625, -531.69268798828125, 71.1897735595703125, 4.127707481384277343, 0, 0, -0.880889892578125, 0.473321229219436645, 7200, 255, 1, "", 46248, NULL), +(12363, 1685, 631, 0, 0, 3, 1, -514.44793701171875, 2245.038330078125, 539.29119873046875, 0, 0, 0, 0, 1, 7200, 255, 1, "", 51666, NULL), +(12364, 178684, 30, 0, 0, 3, 1, 649.263916015625, -59.1111106872558593, 41.54756927490234375, 3.595378875732421875, 0, 0, -0.97437000274658203, 0.224951311945915222, 7200, 255, 1, "", 46248, NULL), +(12365, 194468, 530, 0, 0, 1, 1, -1892.86328125, 5669.203125, 127.458251953125, 0.785396754741668701, 0, 0, 0.38268280029296875, 0.923879802227020263, 120, 255, 1, "", 45942, NULL), +(12366, 194468, 530, 0, 0, 1, 1, -2045.0133056640625, 5568.71826171875, 53.38373565673828125, 5.096362113952636718, 0, 0, -0.55919265747070312, 0.829037725925445556, 120, 255, 1, "", 45942, NULL), +(12367, 34571, 30, 0, 0, 3, 1, -105.423355102539062, -584.35174560546875, 42.01491928100585937, 2.364918231964111328, 0, 0, 0.925539970397949218, 0.378649920225143432, 7200, 255, 1, "", 46248, NULL), +(12368, 38491, 33, 0, 0, 1, 1, -344.818359375, 2035.33984375, 16.99887275695800781, 3.551750659942626953, 0, 0, -0.97904491424560546, 0.203644454479217529, 7200, 255, 1, "", 52237, NULL); From 6fbcaf7ab1bbda0334a8f41f8a83920d38a1e8a8 Mon Sep 17 00:00:00 2001 From: Nedarion <163875108+nedarion@users.noreply.github.com> Date: Tue, 2 Apr 2024 20:08:32 +0000 Subject: [PATCH 15/30] fix: Loch Modan multiple ore spawn (#18616) * fix: Loch Modan multiple ore spawn * chore: DELETE before INSERT so it can be run multiple times --- .../rev_1711490977417590640.sql | 340 ++++++++++++++++++ 1 file changed, 340 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1711490977417590640.sql diff --git a/data/sql/updates/pending_db_world/rev_1711490977417590640.sql b/data/sql/updates/pending_db_world/rev_1711490977417590640.sql new file mode 100644 index 000000000..26ce1689b --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1711490977417590640.sql @@ -0,0 +1,340 @@ + +DELETE FROM pool_gameobject WHERE guid BETWEEN 75600 AND 75761; +DELETE FROM pool_gameobject WHERE guid BETWEEN 75765 AND 75932; +DELETE FROM pool_gameobject WHERE guid BETWEEN 75936 AND 75938; + +INSERT INTO pool_gameobject (guid, pool_entry, chance, description) VALUES +(75600, 4880, 0, 'Spawn Point 1 - Copper'), +(75601, 4880, 20, 'Spawn Point 1 - Tin'), +(75602, 4880, 20, 'Spawn Point 1 - Silver'), +(75603, 4881, 0, 'Spawn Point 2 - Copper'), +(75604, 4881, 20, 'Spawn Point 2 - Tin'), +(75605, 4881, 20, 'Spawn Point 2 - Silver'), +(75606, 4882, 0, 'Spawn Point 3 - Copper'), +(75607, 4882, 20, 'Spawn Point 3 - Tin'), +(75608, 4882, 20, 'Spawn Point 3 - Silver'), +(75609, 4883, 0, 'Spawn Point 4 - Copper'), +(75610, 4883, 20, 'Spawn Point 4 - Tin'), +(75611, 4883, 20, 'Spawn Point 4 - Silver'), +(75612, 4884, 0, 'Spawn Point 5 - Copper'), +(75613, 4884, 20, 'Spawn Point 5 - Tin'), +(75614, 4884, 20, 'Spawn Point 5 - Silver'), +(75615, 4885, 0, 'Spawn Point 6 - Copper'), +(75616, 4885, 20, 'Spawn Point 6 - Tin'), +(75617, 4885, 20, 'Spawn Point 6 - Silver'), +(75618, 4886, 0, 'Spawn Point 7 - Copper'), +(75619, 4886, 20, 'Spawn Point 7 - Tin'), +(75620, 4886, 20, 'Spawn Point 7 - Silver'), +(75621, 4887, 0, 'Spawn Point 8 - Copper'), +(75622, 4887, 20, 'Spawn Point 8 - Tin'), +(75623, 4887, 20, 'Spawn Point 8 - Silver'), +(75624, 4888, 0, 'Spawn Point 9 - Copper'), +(75625, 4888, 20, 'Spawn Point 9 - Tin'), +(75626, 4888, 20, 'Spawn Point 9 - Silver'), +(75627, 4889, 0, 'Spawn Point 10 - Copper'), +(75628, 4889, 20, 'Spawn Point 10 - Tin'), +(75629, 4889, 20, 'Spawn Point 10 - Silver'), +(75630, 4890, 0, 'Spawn Point 11 - Copper'), +(75631, 4890, 20, 'Spawn Point 11 - Tin'), +(75632, 4890, 20, 'Spawn Point 11 - Silver'), +(75633, 4891, 0, 'Spawn Point 12 - Copper'), +(75634, 4891, 20, 'Spawn Point 12 - Tin'), +(75635, 4891, 20, 'Spawn Point 12 - Silver'), +(75636, 4892, 0, 'Spawn Point 13 - Copper'), +(75637, 4892, 20, 'Spawn Point 13 - Tin'), +(75638, 4892, 20, 'Spawn Point 13 - Silver'), +(75639, 4893, 0, 'Spawn Point 14 - Copper'), +(75640, 4893, 20, 'Spawn Point 14 - Tin'), +(75641, 4893, 20, 'Spawn Point 14 - Silver'), +(75642, 4894, 0, 'Spawn Point 15 - Copper'), +(75643, 4894, 20, 'Spawn Point 15 - Tin'), +(75644, 4894, 20, 'Spawn Point 15 - Silver'), +(75645, 4895, 0, 'Spawn Point 16 - Copper'), +(75646, 4895, 20, 'Spawn Point 16 - Tin'), +(75647, 4895, 20, 'Spawn Point 16 - Silver'), +(75648, 4896, 0, 'Spawn Point 17 - Copper'), +(75649, 4896, 20, 'Spawn Point 17 - Tin'), +(75650, 4896, 20, 'Spawn Point 17 - Silver'), +(75651, 4897, 0, 'Spawn Point 18 - Copper'), +(75652, 4897, 20, 'Spawn Point 18 - Tin'), +(75653, 4897, 20, 'Spawn Point 18 - Silver'), +(75654, 4898, 0, 'Spawn Point 19 - Copper'), +(75655, 4898, 20, 'Spawn Point 19 - Tin'), +(75656, 4898, 20, 'Spawn Point 19 - Silver'), +(75657, 4899, 0, 'Spawn Point 20 - Copper'), +(75658, 4899, 20, 'Spawn Point 20 - Tin'), +(75659, 4899, 20, 'Spawn Point 20 - Silver'), +(75660, 4900, 0, 'Spawn Point 21 - Copper'), +(75661, 4900, 20, 'Spawn Point 21 - Tin'), +(75662, 4900, 20, 'Spawn Point 21 - Silver'), +(75663, 4901, 0, 'Spawn Point 22 - Copper'), +(75664, 4901, 20, 'Spawn Point 22 - Tin'), +(75665, 4901, 20, 'Spawn Point 22 - Silver'), +(75666, 4902, 0, 'Spawn Point 23 - Copper'), +(75667, 4902, 20, 'Spawn Point 23 - Tin'), +(75668, 4902, 20, 'Spawn Point 23 - Silver'), +(75669, 4903, 0, 'Spawn Point 24 - Copper'), +(75670, 4903, 20, 'Spawn Point 24 - Tin'), +(75671, 4903, 20, 'Spawn Point 24 - Silver'), +(75672, 4904, 0, 'Spawn Point 25 - Copper'), +(75673, 4904, 20, 'Spawn Point 25 - Tin'), +(75674, 4904, 20, 'Spawn Point 25 - Silver'), +(75675, 4905, 0, 'Spawn Point 26 - Copper'), +(75676, 4905, 20, 'Spawn Point 26 - Tin'), +(75677, 4905, 20, 'Spawn Point 26 - Silver'), +(75678, 4906, 0, 'Spawn Point 27 - Copper'), +(75679, 4906, 20, 'Spawn Point 27 - Tin'), +(75680, 4906, 20, 'Spawn Point 27 - Silver'), +(75681, 4907, 0, 'Spawn Point 28 - Copper'), +(75682, 4907, 20, 'Spawn Point 28 - Tin'), +(75683, 4907, 20, 'Spawn Point 28 - Silver'), +(75684, 4908, 0, 'Spawn Point 29 - Copper'), +(75685, 4908, 20, 'Spawn Point 29 - Tin'), +(75686, 4908, 20, 'Spawn Point 29 - Silver'), +(75687, 4909, 0, 'Spawn Point 30 - Copper'), +(75688, 4909, 20, 'Spawn Point 30 - Tin'), +(75689, 4909, 20, 'Spawn Point 30 - Silver'), +(75690, 4910, 0, 'Spawn Point 31 - Copper'), +(75691, 4910, 20, 'Spawn Point 31 - Tin'), +(75692, 4910, 20, 'Spawn Point 31 - Silver'), +(75693, 4911, 0, 'Spawn Point 32 - Copper'), +(75694, 4911, 20, 'Spawn Point 32 - Tin'), +(75695, 4911, 20, 'Spawn Point 32 - Silver'), +(75696, 4912, 0, 'Spawn Point 33 - Copper'), +(75697, 4912, 20, 'Spawn Point 33 - Tin'), +(75698, 4912, 20, 'Spawn Point 33 - Silver'), +(75699, 4913, 0, 'Spawn Point 34 - Copper'), +(75700, 4913, 20, 'Spawn Point 34 - Tin'), +(75701, 4913, 20, 'Spawn Point 34 - Silver'), +(75702, 4914, 0, 'Spawn Point 35 - Copper'), +(75703, 4914, 20, 'Spawn Point 35 - Tin'), +(75704, 4914, 20, 'Spawn Point 35 - Silver'), +(75705, 4915, 0, 'Spawn Point 36 - Copper'), +(75706, 4915, 20, 'Spawn Point 36 - Tin'), +(75707, 4915, 20, 'Spawn Point 36 - Silver'), +(75708, 4916, 0, 'Spawn Point 37 - Copper'), +(75709, 4916, 20, 'Spawn Point 37 - Tin'), +(75710, 4916, 20, 'Spawn Point 37 - Silver'), +(75711, 4917, 0, 'Spawn Point 38 - Copper'), +(75712, 4917, 20, 'Spawn Point 38 - Tin'), +(75713, 4917, 20, 'Spawn Point 38 - Silver'), +(75714, 4918, 0, 'Spawn Point 39 - Copper'), +(75715, 4918, 20, 'Spawn Point 39 - Tin'), +(75716, 4918, 20, 'Spawn Point 39 - Silver'), +(75717, 4919, 0, 'Spawn Point 40 - Copper'), +(75718, 4919, 20, 'Spawn Point 40 - Tin'), +(75719, 4919, 20, 'Spawn Point 40 - Silver'), +(75720, 4920, 0, 'Spawn Point 41 - Copper'), +(75721, 4920, 20, 'Spawn Point 41 - Tin'), +(75722, 4920, 20, 'Spawn Point 41 - Silver'), +(75723, 4921, 0, 'Spawn Point 42 - Copper'), +(75724, 4921, 20, 'Spawn Point 42 - Tin'), +(75725, 4921, 20, 'Spawn Point 42 - Silver'), +(75726, 4922, 0, 'Spawn Point 43 - Copper'), +(75727, 4922, 20, 'Spawn Point 43 - Tin'), +(75728, 4922, 20, 'Spawn Point 43 - Silver'), +(75729, 4923, 0, 'Spawn Point 44 - Copper'), +(75730, 4923, 20, 'Spawn Point 44 - Tin'), +(75731, 4923, 20, 'Spawn Point 44 - Silver'), +(75732, 4924, 0, 'Spawn Point 45 - Copper'), +(75733, 4924, 20, 'Spawn Point 45 - Tin'), +(75734, 4924, 20, 'Spawn Point 45 - Silver'), +(75735, 4925, 0, 'Spawn Point 46 - Copper'), +(75736, 4925, 20, 'Spawn Point 46 - Tin'), +(75737, 4925, 20, 'Spawn Point 46 - Silver'), +(75738, 4926, 0, 'Spawn Point 47 - Copper'), +(75739, 4926, 20, 'Spawn Point 47 - Tin'), +(75740, 4926, 20, 'Spawn Point 47 - Silver'), +(75741, 4927, 0, 'Spawn Point 48 - Copper'), +(75742, 4927, 20, 'Spawn Point 48 - Tin'), +(75743, 4927, 20, 'Spawn Point 48 - Silver'), +(75744, 4928, 0, 'Spawn Point 49 - Copper'), +(75745, 4928, 20, 'Spawn Point 49 - Tin'), +(75746, 4928, 20, 'Spawn Point 49 - Silver'), +(75747, 4929, 0, 'Spawn Point 50 - Copper'), +(75748, 4929, 20, 'Spawn Point 50 - Tin'), +(75749, 4929, 20, 'Spawn Point 50 - Silver'), +(75750, 4930, 0, 'Spawn Point 51 - Copper'), +(75751, 4930, 20, 'Spawn Point 51 - Tin'), +(75752, 4930, 20, 'Spawn Point 51 - Silver'), +(75753, 4931, 0, 'Spawn Point 52 - Copper'), +(75754, 4931, 20, 'Spawn Point 52 - Tin'), +(75755, 4931, 20, 'Spawn Point 52 - Silver'), +(75756, 4932, 0, 'Spawn Point 53 - Copper'), +(75757, 4932, 20, 'Spawn Point 53 - Tin'), +(75758, 4932, 20, 'Spawn Point 53 - Silver'), +(75759, 4933, 0, 'Spawn Point 54 - Copper'), +(75760, 4933, 20, 'Spawn Point 54 - Tin'), +(75761, 4933, 20, 'Spawn Point 54 - Silver'), +(75765, 4935, 0, 'Spawn Point 56 - Copper'), +(75766, 4935, 20, 'Spawn Point 56 - Tin'), +(75767, 4935, 20, 'Spawn Point 56 - Silver'), +(75768, 4936, 0, 'Spawn Point 57 - Copper'), +(75769, 4936, 20, 'Spawn Point 57 - Tin'), +(75770, 4936, 20, 'Spawn Point 57 - Silver'), +(75771, 4937, 0, 'Spawn Point 58 - Copper'), +(75772, 4937, 20, 'Spawn Point 58 - Tin'), +(75773, 4937, 20, 'Spawn Point 58 - Silver'), +(75774, 4938, 0, 'Spawn Point 59 - Copper'), +(75775, 4938, 20, 'Spawn Point 59 - Tin'), +(75776, 4938, 20, 'Spawn Point 59 - Silver'), +(75777, 4939, 0, 'Spawn Point 60 - Copper'), +(75778, 4939, 20, 'Spawn Point 60 - Tin'), +(75779, 4939, 20, 'Spawn Point 60 - Silver'), +(75780, 4940, 0, 'Spawn Point 61 - Copper'), +(75781, 4940, 20, 'Spawn Point 61 - Tin'), +(75782, 4940, 20, 'Spawn Point 61 - Silver'), +(75783, 4941, 0, 'Spawn Point 62 - Copper'), +(75784, 4941, 20, 'Spawn Point 62 - Tin'), +(75785, 4941, 20, 'Spawn Point 62 - Silver'), +(75786, 4942, 0, 'Spawn Point 63 - Copper'), +(75787, 4942, 20, 'Spawn Point 63 - Tin'), +(75788, 4942, 20, 'Spawn Point 63 - Silver'), +(75789, 4943, 0, 'Spawn Point 64 - Copper'), +(75790, 4943, 20, 'Spawn Point 64 - Tin'), +(75791, 4943, 20, 'Spawn Point 64 - Silver'), +(75792, 4944, 0, 'Spawn Point 65 - Copper'), +(75793, 4944, 20, 'Spawn Point 65 - Tin'), +(75794, 4944, 20, 'Spawn Point 65 - Silver'), +(75795, 4945, 0, 'Spawn Point 66 - Copper'), +(75796, 4945, 20, 'Spawn Point 66 - Tin'), +(75797, 4945, 20, 'Spawn Point 66 - Silver'), +(75798, 4946, 0, 'Spawn Point 67 - Copper'), +(75799, 4946, 20, 'Spawn Point 67 - Tin'), +(75800, 4946, 20, 'Spawn Point 67 - Silver'), +(75801, 4947, 0, 'Spawn Point 68 - Copper'), +(75802, 4947, 20, 'Spawn Point 68 - Tin'), +(75803, 4947, 20, 'Spawn Point 68 - Silver'), +(75804, 4948, 0, 'Spawn Point 69 - Copper'), +(75805, 4948, 20, 'Spawn Point 69 - Tin'), +(75806, 4948, 20, 'Spawn Point 69 - Silver'), +(75807, 4949, 0, 'Spawn Point 70 - Copper'), +(75808, 4949, 20, 'Spawn Point 70 - Tin'), +(75809, 4949, 20, 'Spawn Point 70 - Silver'), +(75810, 4950, 0, 'Spawn Point 71 - Copper'), +(75811, 4950, 20, 'Spawn Point 71 - Tin'), +(75812, 4950, 20, 'Spawn Point 71 - Silver'), +(75813, 4951, 0, 'Spawn Point 72 - Copper'), +(75814, 4951, 20, 'Spawn Point 72 - Tin'), +(75815, 4951, 20, 'Spawn Point 72 - Silver'), +(75816, 4952, 0, 'Spawn Point 73 - Copper'), +(75817, 4952, 20, 'Spawn Point 73 - Tin'), +(75818, 4952, 20, 'Spawn Point 73 - Silver'), +(75819, 4953, 0, 'Spawn Point 74 - Copper'), +(75820, 4953, 20, 'Spawn Point 74 - Tin'), +(75821, 4953, 20, 'Spawn Point 74 - Silver'), +(75822, 4954, 0, 'Spawn Point 75 - Copper'), +(75823, 4954, 20, 'Spawn Point 75 - Tin'), +(75824, 4954, 20, 'Spawn Point 75 - Silver'), +(75825, 4955, 0, 'Spawn Point 76 - Copper'), +(75826, 4955, 20, 'Spawn Point 76 - Tin'), +(75827, 4955, 20, 'Spawn Point 76 - Silver'), +(75828, 4956, 0, 'Spawn Point 77 - Copper'), +(75829, 4956, 20, 'Spawn Point 77 - Tin'), +(75830, 4956, 20, 'Spawn Point 77 - Silver'), +(75831, 4957, 0, 'Spawn Point 78 - Copper'), +(75832, 4957, 20, 'Spawn Point 78 - Tin'), +(75833, 4957, 20, 'Spawn Point 78 - Silver'), +(75834, 4958, 0, 'Spawn Point 79 - Copper'), +(75835, 4958, 20, 'Spawn Point 79 - Tin'), +(75836, 4958, 20, 'Spawn Point 79 - Silver'), +(75837, 4959, 0, 'Spawn Point 80 - Copper'), +(75838, 4959, 20, 'Spawn Point 80 - Tin'), +(75839, 4959, 20, 'Spawn Point 80 - Silver'), +(75840, 4960, 0, 'Spawn Point 81 - Copper'), +(75841, 4960, 20, 'Spawn Point 81 - Tin'), +(75842, 4960, 20, 'Spawn Point 81 - Silver'), +(75843, 4961, 0, 'Spawn Point 82 - Copper'), +(75844, 4961, 20, 'Spawn Point 82 - Tin'), +(75845, 4961, 20, 'Spawn Point 82 - Silver'), +(75846, 4962, 0, 'Spawn Point 83 - Copper'), +(75847, 4962, 20, 'Spawn Point 83 - Tin'), +(75848, 4962, 20, 'Spawn Point 83 - Silver'), +(75849, 4963, 0, 'Spawn Point 84 - Copper'), +(75850, 4963, 20, 'Spawn Point 84 - Tin'), +(75851, 4963, 20, 'Spawn Point 84 - Silver'), +(75852, 4964, 0, 'Spawn Point 85 - Copper'), +(75853, 4964, 20, 'Spawn Point 85 - Tin'), +(75854, 4964, 20, 'Spawn Point 85 - Silver'), +(75855, 4965, 0, 'Spawn Point 86 - Copper'), +(75856, 4965, 20, 'Spawn Point 86 - Tin'), +(75857, 4965, 20, 'Spawn Point 86 - Silver'), +(75858, 4966, 0, 'Spawn Point 87 - Copper'), +(75859, 4966, 20, 'Spawn Point 87 - Tin'), +(75860, 4966, 20, 'Spawn Point 87 - Silver'), +(75861, 4967, 0, 'Spawn Point 88 - Copper'), +(75862, 4967, 20, 'Spawn Point 88 - Tin'), +(75863, 4967, 20, 'Spawn Point 88 - Silver'), +(75864, 4968, 0, 'Spawn Point 89 - Copper'), +(75865, 4968, 20, 'Spawn Point 89 - Tin'), +(75866, 4968, 20, 'Spawn Point 89 - Silver'), +(75867, 4969, 0, 'Spawn Point 90 - Copper'), +(75868, 4969, 20, 'Spawn Point 90 - Tin'), +(75869, 4969, 20, 'Spawn Point 90 - Silver'), +(75870, 4970, 0, 'Spawn Point 91 - Copper'), +(75871, 4970, 20, 'Spawn Point 91 - Tin'), +(75872, 4970, 20, 'Spawn Point 91 - Silver'), +(75873, 4971, 0, 'Spawn Point 92 - Copper'), +(75874, 4971, 20, 'Spawn Point 92 - Tin'), +(75875, 4971, 20, 'Spawn Point 92 - Silver'), +(75876, 4972, 0, 'Spawn Point 93 - Copper'), +(75877, 4972, 20, 'Spawn Point 93 - Tin'), +(75878, 4972, 20, 'Spawn Point 93 - Silver'), +(75879, 4973, 0, 'Spawn Point 94 - Copper'), +(75880, 4973, 20, 'Spawn Point 94 - Tin'), +(75881, 4973, 20, 'Spawn Point 94 - Silver'), +(75882, 4974, 0, 'Spawn Point 95 - Copper'), +(75883, 4974, 20, 'Spawn Point 95 - Tin'), +(75884, 4974, 20, 'Spawn Point 95 - Silver'), +(75885, 4975, 0, 'Spawn Point 96 - Copper'), +(75886, 4975, 20, 'Spawn Point 96 - Tin'), +(75887, 4975, 20, 'Spawn Point 96 - Silver'), +(75888, 4976, 0, 'Spawn Point 97 - Copper'), +(75889, 4976, 20, 'Spawn Point 97 - Tin'), +(75890, 4976, 20, 'Spawn Point 97 - Silver'), +(75891, 4977, 0, 'Spawn Point 98 - Copper'), +(75892, 4977, 20, 'Spawn Point 98 - Tin'), +(75893, 4977, 20, 'Spawn Point 98 - Silver'), +(75894, 4978, 0, 'Spawn Point 99 - Copper'), +(75895, 4978, 20, 'Spawn Point 99 - Tin'), +(75896, 4978, 20, 'Spawn Point 99 - Silver'), +(75897, 4979, 0, 'Spawn Point 100 - Copper'), +(75898, 4979, 20, 'Spawn Point 100 - Tin'), +(75899, 4979, 20, 'Spawn Point 100 - Silver'), +(75900, 4980, 0, 'Spawn Point 101 - Copper'), +(75901, 4980, 20, 'Spawn Point 101 - Tin'), +(75902, 4980, 20, 'Spawn Point 101 - Silver'), +(75903, 4981, 0, 'Spawn Point 102 - Copper'), +(75904, 4981, 20, 'Spawn Point 102 - Tin'), +(75905, 4981, 20, 'Spawn Point 102 - Silver'), +(75906, 4982, 0, 'Spawn Point 103 - Copper'), +(75907, 4982, 20, 'Spawn Point 103 - Tin'), +(75908, 4982, 20, 'Spawn Point 103 - Silver'), +(75909, 4983, 0, 'Spawn Point 104 - Copper'), +(75910, 4983, 20, 'Spawn Point 104 - Tin'), +(75911, 4983, 20, 'Spawn Point 104 - Silver'), +(75912, 4984, 0, 'Spawn Point 105 - Copper'), +(75913, 4984, 20, 'Spawn Point 105 - Tin'), +(75914, 4984, 20, 'Spawn Point 105 - Silver'), +(75915, 4985, 0, 'Spawn Point 106 - Copper'), +(75916, 4985, 20, 'Spawn Point 106 - Tin'), +(75917, 4985, 20, 'Spawn Point 106 - Silver'), +(75918, 4986, 0, 'Spawn Point 107 - Copper'), +(75919, 4986, 20, 'Spawn Point 107 - Tin'), +(75920, 4986, 20, 'Spawn Point 107 - Silver'), +(75921, 4987, 0, 'Spawn Point 108 - Copper'), +(75922, 4987, 20, 'Spawn Point 108 - Tin'), +(75923, 4987, 20, 'Spawn Point 108 - Silver'), +(75924, 4988, 0, 'Spawn Point 109 - Copper'), +(75925, 4988, 20, 'Spawn Point 109 - Tin'), +(75926, 4988, 20, 'Spawn Point 109 - Silver'), +(75927, 4989, 0, 'Spawn Point 110 - Copper'), +(75928, 4989, 20, 'Spawn Point 110 - Tin'), +(75929, 4989, 20, 'Spawn Point 110 - Silver'), +(75930, 4990, 0, 'Spawn Point 111 - Copper'), +(75931, 4990, 20, 'Spawn Point 111 - Tin'), +(75932, 4990, 20, 'Spawn Point 111 - Silver'), +(75936, 4992, 0, 'Spawn Point 113 - Copper'), +(75937, 4992, 20, 'Spawn Point 113 - Tin'), +(75938, 4992, 20, 'Spawn Point 113 - Silver'); + From dc7753b2b62ac6f04133e39b2de397b8737a6e12 Mon Sep 17 00:00:00 2001 From: Gultask <100873791+Gultask@users.noreply.github.com> Date: Tue, 2 Apr 2024 17:08:51 -0300 Subject: [PATCH 16/30] fix(Scripts/BlackTemple): Rewrite Shade of Akama (#18601) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * init * akama only generators left * Update boss_shade_of_akama.cpp * Update boss_shade_of_akama.cpp * warnign * OMFG * akama generators * more for generators * done * codestyle * warnings * illidan fix Co-Authored-By: 天鹿 <18535853+pklloveyou@users.noreply.github.com> * Update rev_1711048056647652400.sql Co-Authored-By: 天鹿 <18535853+pklloveyou@users.noreply.github.com> * a Co-Authored-By: 天鹿 <18535853+pklloveyou@users.noreply.github.com> * Update instance_black_temple.cpp Co-Authored-By: 天鹿 <18535853+pklloveyou@users.noreply.github.com> * Update rev_1711048056647652400.sql Co-Authored-By: 天鹿 <18535853+pklloveyou@users.noreply.github.com> * avoid collecting trash Co-Authored-By: 天鹿 <18535853+pklloveyou@users.noreply.github.com> * Update boss_illidan.cpp Co-Authored-By: 天鹿 <18535853+pklloveyou@users.noreply.github.com> * Update boss_shade_of_akama.cpp Co-Authored-By: 天鹿 <18535853+pklloveyou@users.noreply.github.com> * crashfix? * takes too long to despawn * maybe * clear lists --------- Co-authored-by: 天鹿 <18535853+pklloveyou@users.noreply.github.com> --- .../rev_1711048056647652400.sql | 46 ++ .../Outland/BlackTemple/black_temple.h | 27 +- .../Outland/BlackTemple/boss_illidan.cpp | 63 +- .../BlackTemple/boss_shade_of_akama.cpp | 634 ++++++++---------- .../Outland/BlackTemple/illidari_council.cpp | 44 +- .../BlackTemple/instance_black_temple.cpp | 177 ++--- 6 files changed, 481 insertions(+), 510 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1711048056647652400.sql diff --git a/data/sql/updates/pending_db_world/rev_1711048056647652400.sql b/data/sql/updates/pending_db_world/rev_1711048056647652400.sql new file mode 100644 index 000000000..391553a3a --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1711048056647652400.sql @@ -0,0 +1,46 @@ +-- +UPDATE `creature_template` SET `AIName` = '', `ScriptName` = 'npc_ashtongue_channeler', `faction` = 1692 WHERE (`entry` = 23421); +UPDATE `creature_template` SET `AIName` = '', `ScriptName` = 'npc_ashtongue_sorcerer' WHERE (`entry` = 23215); +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 23215) AND (`source_type` = 0); +UPDATE `creature_template_addon` SET `auras` = '39833' WHERE (`entry` = 22841); +UPDATE `creature_template` SET `faction` = 1847 WHERE (`entry` = 23210); +UPDATE `creature_template` SET `faction` = 1813 WHERE (`entry` = 23319); + +DELETE FROM `creature_text` WHERE `CreatureID` = 23191; +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(23191, 0, 0, 'Broken of the Ashtongue tribe, your leader speaks!', 14, 0, 100, 15, 0, 0, 21342, 0, 'Akama SAY_BROKEN_FREE_0'), +(23191, 1, 0, 'The Betrayer no longer holds sway over us. His dark magic over the Ashtongue soul has been destroyed!', 14, 0, 100, 1, 0, 0, 21343, 0, 'Akama SAY_BROKEN_FREE_1'), +(23191, 2, 0, 'Come out from the shadows! I\'ve returned to lead you against our true enemy! Shed your chains and raise your weapons against your Illidari masters!', 14, 0, 100, 397, 0, 0, 21344, 0, 'Akama SAY_BROKEN_FREE_2'), +(23191, 3, 0, 'I will not last much longer!', 14, 0, 100, 0, 0, 11385, 21784, 0, 'Akama SAY_LOW_HEALTH'), +(23191, 4, 0, 'No! Not yet!', 14, 0, 100, 0, 0, 11386, 21785, 0, 'Akama SAY_DEAD'); + +UPDATE `creature` SET `spawntimesecs` = 300 WHERE `id1` = 23191 AND `map` = 564; + +DELETE FROM `creature_formations` WHERE `leaderGUID` = 148236; +INSERT INTO `creature_formations` (`memberGUID`, `leaderGUID`, `groupAI`) VALUES +(148236, 148236, 24), +(148237, 148236, 24), +(148238, 148236, 24), +(148239, 148236, 24), +(148240, 148236, 24), +(148241, 148236, 24), +(148242, 148236, 24); + +-- Delete leftover gobs +DELETE FROM `gameobject` WHERE `guid` IN (20523,20558,20559,20561,20563,20567) AND `map` = 564; + +DELETE FROM `creature_text` WHERE `CreatureID` = 23089 AND `GroupID` IN (9, 10); +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(23089, 9, 0, 'Those who\'ve defiled this temple have all been defeated. All but one!', 12, 0, 100, 1, 0, 0, 21518, 0, 'SAY_AKAMA_COUNCIL_1'), +(23089, 10, 0, 'Let us finish what we\'ve started. I will lead you to Illidan\'s abode once you\'ve recovered your strength.', 12, 0, 100, 1, 0, 0, 21520, 0, 'SAY_AKAMA_COUNCIL_2'); + +DELETE FROM `waypoint_data` WHERE `id` = 230891; +INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `move_type`) VALUES +(230891, 1, 642.5905, 305.6287, 271.6885, 1), +(230891, 2, 660.76465, 305.76627, 271.70413, 1); + +UPDATE `creature` SET `phaseMask` = 3 WHERE `guid` = 148734; +UPDATE `creature` SET `phaseMask` = 5 WHERE `guid` = 148733; + +DELETE FROM `smart_scripts` WHERE `source_type` = 2 AND `entryorguid` = 4665; +INSERT INTO `smart_scripts` VALUES (4665, 2, 0, 0, 46, 0, 100, 1, 0, 0, 0, 0, 0, 0, 45, 0, 1, 0, 0, 0, 0, 10, 148358, 22871, 0, 0, 0, 0, 0, 0, 'Area Trigger - On Trigger - Teron Gorefiend Talk'); diff --git a/src/server/scripts/Outland/BlackTemple/black_temple.h b/src/server/scripts/Outland/BlackTemple/black_temple.h index 4944e0b7e..491125714 100644 --- a/src/server/scripts/Outland/BlackTemple/black_temple.h +++ b/src/server/scripts/Outland/BlackTemple/black_temple.h @@ -40,17 +40,27 @@ enum DataTypes DATA_RELIQUARY_OF_SOULS = 5, DATA_MOTHER_SHAHRAZ = 6, DATA_ILLIDARI_COUNCIL = 7, - DATA_AKAMA_FINISHED = 8, + DATA_AKAMA_ILLIDAN = 8, DATA_ILLIDAN_STORMRAGE = 9, - MAX_ENCOUNTERS = 10 + MAX_ENCOUNTERS = 10, + + DATA_AKAMA_SHADE = 11, + DATA_GATHIOS_THE_SHATTERER = 12, + DATA_HIGH_NETHERMANCER_ZEREVOR = 13, + DATA_LADY_MALANDE = 14, + DATA_VERAS_DARKSHADOW = 15 }; enum CreatureIds { + NPC_HIGH_WARLORD_NAJENTUS = 22887, + NPC_SUPREMUS = 22898, NPC_SHADE_OF_AKAMA = 22841, NPC_AKAMA_SHADE = 23191, - NPC_STORM_FURY = 22848, + NPC_ASHTONGUE_CHANNELER = 23421, + NPC_CREATURE_GENERATOR_AKAMA = 23210, NPC_TERON_GOREFIEND = 22871, + NPC_GURTOGG_BLOODBOIL = 22948, NPC_VENGEFUL_SPIRIT = 23109, NPC_SHADOWY_CONSTRUCT = 23111, NPC_ANGERED_SOUL_FRAGMENT = 23398, @@ -58,17 +68,26 @@ enum CreatureIds NPC_SUFFERING_SOUL_FRAGMENT = 23399, NPC_RELIQUARY_OF_THE_LOST = 22856, NPC_ENSLAVED_SOUL = 23469, + NPC_MOTHER_SHAHRAZ = 22947, NPC_GATHIOS_THE_SHATTERER = 22949, NPC_HIGH_NETHERMANCER_ZEREVOR = 22950, NPC_LADY_MALANDE = 22951, NPC_VERAS_DARKSHADOW = 22952, NPC_ILLIDARI_COUNCIL = 23426, - NPC_AKAMA = 23089, + NPC_AKAMA_ILLIDAN = 23089, NPC_ILLIDAN_STORMRAGE = 22917, NPC_PARASITIC_SHADOWFIEND = 23498, NPC_BLADE_OF_AZZINOTH = 22996, NPC_FLAME_OF_AZZINOTH = 22997, + NPC_ASHTONGUE_BATTLELORD = 22844, + NPC_ASHTONGUE_MYSTIC = 22845, + NPC_ASHTONGUE_STORMCALLER = 22846, + NPC_ASHTONGUE_PRIMALIST = 22847, + NPC_ASHTONGUE_FERAL_SPIRIT = 22849, + NPC_ASHTONGUE_STALKER = 23374, + NPC_STORM_FURY = 22848, + NPC_DRAGON_TURTLE = 22885 }; diff --git a/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp b/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp index c860ef94d..698375624 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp @@ -48,6 +48,8 @@ enum Says SAY_AKAMA_ILLIDAN1 = 4, SAY_AKAMA_ILLIDAN2 = 5, SAY_AKAMA_ILLIDAN3 = 6, + SAY_AKAMA_COUNCIL_1 = 9, + SAY_AKAMA_COUNCIL_2 = 10, SAY_MAIEV_SHADOWSONG_TAUNT = 0, SAY_MAIEV_SHADOWSONG_ILLIDAN1 = 1, @@ -117,6 +119,7 @@ enum Spells enum Misc { + ACTION_ILLIDARI_COUNCIL_DONE = 0, ACTION_FIGHT_MINIONS = 1, ACTION_RETURN_BLADE = 2, ACTION_ILLIDAN_CAGED = 3, @@ -133,7 +136,9 @@ enum Misc NPC_ILLIDAN_DB_TARGET = 23070, NPC_MAIEV_SHADOWSONG = 23197, - GO_CAGE_TRAP = 185916 + GO_CAGE_TRAP = 185916, + + PATH_AKAMA_ILLIDARI_COUNCIL_1 = 230891 }; enum Events @@ -237,13 +242,13 @@ public: { BossAI::EnterEvadeMode(why); - if (Creature* akama = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_AKAMA))) + if (Creature* akama = instance->GetCreature(NPC_AKAMA_ILLIDAN)) akama->AI()->EnterEvadeMode(why); } bool CanAIAttack(Unit const* target) const override { - return target->GetEntry() != NPC_AKAMA && target->GetEntry() != NPC_MAIEV_SHADOWSONG; + return target->GetEntry() != NPC_AKAMA_ILLIDAN && target->GetEntry() != NPC_MAIEV_SHADOWSONG; } void DoAction(int32 param) override @@ -408,7 +413,7 @@ public: switch (events2.ExecuteEvent()) { case EVENT_SUMMON_MINIONS2: - if (Creature* akama = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_AKAMA))) + if (Creature* akama = instance->GetCreature(NPC_AKAMA_ILLIDAN)) akama->AI()->DoAction(ACTION_FIGHT_MINIONS); break; case EVENT_PHASE_2_EYE_BEAM_START: @@ -445,7 +450,7 @@ public: maiev->AI()->Talk(SAY_MAIEV_SHADOWSONG_ILLIDAN3); } - if (Creature* akama = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_AKAMA))) + if (Creature* akama = instance->GetCreature(NPC_AKAMA_ILLIDAN)) { akama->AI()->DoAction(ACTION_ILLIDAN_DEAD); akama->SetTarget(me->GetGUID()); @@ -754,6 +759,8 @@ enum Akama EVENT_AKAMA_HEALTH = 102 }; +Position AkamaTeleport = { 609.772f, 308.456f, 271.826f, 6.1972566f }; + class npc_akama_illidan : public CreatureScript { public: @@ -764,7 +771,7 @@ public: npc_akama_illidanAI(Creature* creature) : npc_escortAI(creature), summons(me) { instance = creature->GetInstanceScript(); - if (instance->GetBossState(DATA_AKAMA_FINISHED) == DONE) + if (instance->GetBossState(DATA_AKAMA_ILLIDAN) == DONE) { me->GetMap()->LoadGrid(751.664f, 238.933f); me->SetHomePosition(751.664f, 238.933f, 353.106f, 2.18f); @@ -789,6 +796,12 @@ public: summons.DespawnAll(); me->CombatStop(true); } + else if (param == ACTION_ILLIDARI_COUNCIL_DONE) + { + me->NearTeleportTo(AkamaTeleport); + me->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP); + me->GetMotionMaster()->MovePath(PATH_AKAMA_ILLIDARI_COUNCIL_1, false); + } } void Reset() override @@ -796,7 +809,6 @@ public: me->SetReactState(REACT_AGGRESSIVE); me->SetNpcFlag(UNIT_NPC_FLAG_GOSSIP); me->setActive(false); - me->SetVisible(instance->GetBossState(DATA_ILLIDARI_COUNCIL) == DONE && instance->GetBossState(DATA_ILLIDAN_STORMRAGE) != DONE); events.Reset(); summons.DespawnAll(); } @@ -807,7 +819,7 @@ public: me->ReplaceAllNpcFlags(UNIT_NPC_FLAG_NONE); me->setActive(true); - if (instance->GetBossState(DATA_AKAMA_FINISHED) != DONE) + if (instance->GetBossState(DATA_AKAMA_ILLIDAN) != DONE) { me->SetReactState(REACT_PASSIVE); Start(false, true); @@ -830,6 +842,22 @@ public: } } + void PathEndReached(uint32 pathId) override + { + if (pathId == PATH_AKAMA_ILLIDARI_COUNCIL_1) + { + ScheduleUniqueTimedEvent(200ms, [&] + { + Talk(SAY_AKAMA_COUNCIL_1); + }, 1); + ScheduleUniqueTimedEvent(7800ms, [&] + { + Talk(SAY_AKAMA_COUNCIL_2); + me->SetNpcFlag(UNIT_NPC_FLAG_GOSSIP); + }, 2); + } + } + void JustSummoned(Creature* summon) override { summons.Summon(summon); @@ -878,6 +906,7 @@ public: void UpdateEscortAI(uint32 diff) override { + scheduler.Update(diff); events.Update(diff); switch (events.ExecuteEvent()) { @@ -913,8 +942,8 @@ public: udalo->CastSpell(udalo, SPELL_AKAMA_DOOR_OPEN, false); break; case EVENT_AKAMA_SCENE_9: - instance->SetBossState(DATA_AKAMA_FINISHED, NOT_STARTED); - instance->SetBossState(DATA_AKAMA_FINISHED, DONE); + instance->SetBossState(DATA_AKAMA_ILLIDAN, NOT_STARTED); + instance->SetBossState(DATA_AKAMA_ILLIDAN, DONE); break; case EVENT_AKAMA_SCENE_10: Talk(SAY_AKAMA_BEWARE); @@ -923,40 +952,40 @@ public: SetEscortPaused(false); break; case EVENT_AKAMA_SCENE_20: - if (Creature* illidan = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_ILLIDAN_STORMRAGE))) + if (Creature* illidan = instance->GetCreature(DATA_ILLIDAN_STORMRAGE)) illidan->SetStandState(UNIT_STAND_STATE_STAND); break; case EVENT_AKAMA_SCENE_21: me->SetFacingTo(M_PI); break; case EVENT_AKAMA_SCENE_22: - if (Creature* illidan = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_ILLIDAN_STORMRAGE))) + if (Creature* illidan = instance->GetCreature(DATA_ILLIDAN_STORMRAGE)) illidan->AI()->Talk(SAY_ILLIDAN_AKAMA1); break; case EVENT_AKAMA_SCENE_23: Talk(SAY_AKAMA_ILLIDAN1); break; case EVENT_AKAMA_SCENE_24: - if (Creature* illidan = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_ILLIDAN_STORMRAGE))) + if (Creature* illidan = instance->GetCreature(DATA_ILLIDAN_STORMRAGE)) illidan->AI()->Talk(SAY_ILLIDAN_AKAMA2); break; case EVENT_AKAMA_SCENE_25: Talk(SAY_AKAMA_ILLIDAN2); break; case EVENT_AKAMA_SCENE_26: - if (Creature* illidan = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_ILLIDAN_STORMRAGE))) + if (Creature* illidan = instance->GetCreature(DATA_ILLIDAN_STORMRAGE)) illidan->AI()->Talk(SAY_ILLIDAN_AKAMA3); break; case EVENT_AKAMA_SCENE_27: - if (Creature* illidan = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_ILLIDAN_STORMRAGE))) + if (Creature* illidan = instance->GetCreature(DATA_ILLIDAN_STORMRAGE)) illidan->LoadEquipment(1, true); break; case EVENT_AKAMA_SCENE_28: - if (Creature* illidan = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_ILLIDAN_STORMRAGE))) + if (Creature* illidan = instance->GetCreature(DATA_ILLIDAN_STORMRAGE)) illidan->HandleEmoteCommand(EMOTE_ONESHOT_TALK_NO_SHEATHE); break; case EVENT_AKAMA_SCENE_29: - if (Creature* illidan = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_ILLIDAN_STORMRAGE))) + if (Creature* illidan = instance->GetCreature(DATA_ILLIDAN_STORMRAGE)) { illidan->SetImmuneToAll(false); illidan->SetInCombatWithZone(); diff --git a/src/server/scripts/Outland/BlackTemple/boss_shade_of_akama.cpp b/src/server/scripts/Outland/BlackTemple/boss_shade_of_akama.cpp index 691c345e0..d55c9169f 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_shade_of_akama.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_shade_of_akama.cpp @@ -25,30 +25,43 @@ enum Says SAY_BROKEN_FREE_0 = 0, SAY_BROKEN_FREE_1 = 1, SAY_BROKEN_FREE_2 = 2, + SAY_LOW_HEALTH = 3, + SAY_DEATH = 4, + SAY_BROKEN_S1 = 0, SAY_BROKEN_S2 = 1 }; enum Spells { + // Akama SPELL_STEALTH = 34189, - SPELL_AKAMA_SOUL_CHANNEL = 40447, - SPELL_SHADE_SOUL_CHANNEL = 40401, - SPELL_CHAIN_LIGHTNING = 39945, SPELL_DESTRUCTIVE_POISON = 40874, - SPELL_SHADE_OF_AKAMA_TRIGGER = 40955, - SPELL_AKAMA_SOUL_RETRIEVE = 40902, + SPELL_CHAIN_LIGHTNING = 39945, + SPELL_AKAMA_SOUL_CHANNEL = 40447, + SPELL_FIXATE = 40607, + SPELL_AKAMA_SOUL_RETRIEVE = 40902, // epilogue + SPELL_AKAMA_SOUL_EXPEL_CHANNEL = 40927, // epilogue - SPELL_ASHTONGUE_WAVE_B = 42035, - SPELL_SUMMON_ASHTONGUE_SORCERER = 40476, - SPELL_SUMMON_ASHTONGUE_DEFENDER = 40474 + // Shade & Channelers + SPELL_SHADE_SOUL_CHANNEL = 40401, + SPELL_THREAT = 41602, + SPELL_SHADE_OF_AKAMA_TRIGGER = 40955, + + // Summons + SPELL_ASHTONGUE_WAVE_A = 42073, // unused + SPELL_ASHTONGUE_WAVE_B = 42035, + SPELL_SUMMON_ASHTONGUE_SORCERER = 40476, + SPELL_SUMMON_ASHTONGUE_DEFENDER = 40474 }; enum Creatures { - NPC_ASHTONGUE_CHANNELER = 23421, - NPC_CREATURE_GENERATOR_AKAMA = 23210, NPC_ASHTONGUE_SORCERER = 23215, + NPC_ASHTONGUE_DEFENDER = 23216, + NPC_ASHTONGUE_ELEMENTAL = 23523, + NPC_ASHTONGUE_ROGUE = 23318, + NPC_ASHTONGUE_SPIRITBIND = 23524, NPC_ASHTONGUE_BROKEN = 23319 }; @@ -56,220 +69,137 @@ enum Misc { SUMMON_GROUP_BROKENS = 1, - POINT_START = 0, - POINT_CHANNEL_SOUL = 1, + POINT_ENGAGE = 0, + POINT_OUTRO = 1, - ACTION_AKAMA_DIED = 1, - ACTION_START_ENCOUNTER = 2, - ACTION_STOP_SPAWNING = 3, - ACTION_DESPAWN_ALL = 4, - ACTION_CHANNELERS_START_CHANNEL = 5, - ACTION_KILL_CHANNELERS = 6, - ACTION_NO_SORCERERS = 7, - ACTION_SHADE_DIED = 8, + ACTION_GENERATOR_START = 1, + ACTION_GENERATOR_STOP = 2, + ACTION_GENERATOR_DESPAWN_ALL = 3, - EVENT_AKAMA_START_ENCOUNTER = 1, - EVENT_AKAMA_START_CHANNEL = 2, - EVENT_SPELL_CHAIN_LIGHTNING = 4, - EVENT_SPELL_DESTRUCTIVE_POISON = 5, + COUNTER_SPAWNS_MAX = 20, // Max number of spawns for each generator, number chosen at random - EVENT_SHADE_CHECK_DISTANCE = 10, - EVENT_SHADE_RESET_ENCOUNTER = 11, - EVENT_SHADE_GATHER_NPCS = 12, + ACTION_AKAMA_START_OUTRO = 1, - EVENT_SUMMON_WAVE_B = 20, - EVENT_SUMMON_ASHTONGUE_SORCERER = 21, - EVENT_SUMMON_ASHTONGUE_DEFENDER = 22, - - EVENT_AKAMA_SCENE0 = 29, - EVENT_AKAMA_SCENE1 = 30, - EVENT_AKAMA_SCENE2 = 31, - EVENT_AKAMA_SCENE3 = 32, - EVENT_AKAMA_SCENE4 = 33, - EVENT_AKAMA_SCENE5 = 34, - EVENT_AKAMA_SCENE6 = 35, - EVENT_AKAMA_SCENE7 = 36 + FACTION_DEFAULT = 1820, + FACTION_ENGAGE = 1868 }; +Position AkamaEngage = { 517.4877f, 400.79926f, 112.77704f }; +Position AkamaOutro = { 469.0867f, 401.0793f, 118.52704f, 0.087266460061073303f }; +Position ShadeEngage = { 512.48773f, 400.8283f, 112.77704f }; + struct boss_shade_of_akama : public BossAI { - boss_shade_of_akama(Creature* creature) : BossAI(creature, DATA_SHADE_OF_AKAMA), summonsChanneler(me), summonsGenerator(me) - { - events2.ScheduleEvent(EVENT_SHADE_GATHER_NPCS, 1000); - } + boss_shade_of_akama(Creature* creature) : BossAI(creature, DATA_SHADE_OF_AKAMA) { } - SummonList summonsChanneler; - SummonList summonsGenerator; - EventMap events2; - - void ChannelersAction(int32 action) - { - for (SummonList::const_iterator i = summonsChanneler.begin(); i != summonsChanneler.end(); ++i) - if (Creature* summon = ObjectAccessor::GetCreature(*me, *i)) - { - if (action == ACTION_CHANNELERS_START_CHANNEL) - { - summon->CastSpell(me, SPELL_SHADE_SOUL_CHANNEL, true); - summon->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - } - else if (action == ACTION_START_ENCOUNTER) - { - summon->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - } - else if (action == ACTION_KILL_CHANNELERS) - { - Unit::Kill(me, summon); - } - } - } + std::list channelers; + std::list generators; void Reset() override { - BossAI::Reset(); - me->SetReactState(REACT_PASSIVE); + channelers.clear(); + generators.clear(); + me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - me->SetImmuneToAll(true); me->SetWalk(true); + me->SetReactState(REACT_DEFENSIVE); + BossAI::Reset(); } void EnterEvadeMode(EvadeReason why) override { + for (Creature* generator : generators) + generator->AI()->DoAction(ACTION_GENERATOR_DESPAWN_ALL); + + for (Creature* channeler : channelers) + channeler->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE); + BossAI::EnterEvadeMode(why); - summonsGenerator.DoAction(ACTION_DESPAWN_ALL); - events2.ScheduleEvent(EVENT_SHADE_RESET_ENCOUNTER, 20000); - me->SetVisible(false); - ChannelersAction(ACTION_KILL_CHANNELERS); } void JustDied(Unit* killer) override { BossAI::JustDied(killer); - summonsGenerator.DoAction(ACTION_DESPAWN_ALL); - summonsChanneler.DespawnAll(); me->CastSpell(me, SPELL_SHADE_OF_AKAMA_TRIGGER, true); - if (Creature* akama = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_AKAMA_SHADE))) + + for (Creature* generator : generators) + generator->AI()->DoAction(ACTION_GENERATOR_DESPAWN_ALL); + + if (Creature* akama = instance->GetCreature(DATA_AKAMA_SHADE)) + akama->AI()->DoAction(ACTION_AKAMA_START_OUTRO); + } + + void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override + { + if (spell->Id == SPELL_AKAMA_SOUL_CHANNEL) { - akama->SetHomePosition(*akama); - akama->AI()->DoAction(ACTION_SHADE_DIED); + instance->SetBossState(DATA_SHADE_OF_AKAMA, IN_PROGRESS); + + me->GetCreatureListWithEntryInGrid(channelers, NPC_ASHTONGUE_CHANNELER, 40.0f); + me->GetCreatureListWithEntryInGrid(generators, NPC_CREATURE_GENERATOR_AKAMA, 100.0f); + + for (Creature* channeler : channelers) + channeler->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); + + for (Creature* generator : generators) + generator->AI()->DoAction(ACTION_GENERATOR_START); + + ScheduleTimedEvent(1200ms, [&] + { + if (me->GetSpeed(MOVE_WALK) > 0.01f) + { + me->GetMotionMaster()->Clear(); + me->GetMotionMaster()->MovePoint(POINT_ENGAGE, ShadeEngage); + } + }, 1200ms); } } - void DoAction(int32 param) override + void MovementInform(uint32 type, uint32 point) override { - if (param == ACTION_START_ENCOUNTER) + if (type == POINT_MOTION_TYPE && point == POINT_ENGAGE) { - summonsGenerator.DoAction(ACTION_START_ENCOUNTER); - ChannelersAction(ACTION_START_ENCOUNTER); - events.ScheduleEvent(EVENT_SHADE_CHECK_DISTANCE, 1000); - } - else if (param == ACTION_AKAMA_DIED) - { - EnterEvadeMode(EVADE_REASON_OTHER); + me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); + me->RemoveAurasDueToSpell(SPELL_AKAMA_SOUL_CHANNEL); + scheduler.CancelAll(); + + for (Creature* generator : generators) + generator->AI()->DoAction(ACTION_GENERATOR_STOP); + + if (Creature* akama = instance->GetCreature(DATA_AKAMA_SHADE)) + { + akama->SetReactState(REACT_AGGRESSIVE); + akama->InterruptSpell(CURRENT_CHANNELED_SPELL); + DoCast(akama, SPELL_THREAT, true); + me->AddThreat(akama, 900000.0f); + akama->AI()->DoCast(me, SPELL_FIXATE, true); + AttackStart(akama); + } + + ScheduleTimedEvent(3500ms, [&] + { + if (Creature* akama = instance->GetCreature(DATA_AKAMA_SHADE)) + me->AddThreat(akama, 900000.0f); + }, 3500ms); } } void UpdateAI(uint32 diff) override { - events2.Update(diff); - switch (events2.ExecuteEvent()) - { - case EVENT_SHADE_GATHER_NPCS: - { - std::list ChannelerList; - me->GetCreaturesWithEntryInRange(ChannelerList, 100.0f, NPC_ASHTONGUE_CHANNELER); - for (std::list::const_iterator itr = ChannelerList.begin(); itr != ChannelerList.end(); ++itr) - summonsChanneler.Summon(*itr); - - std::list SpawnerList; - me->GetCreaturesWithEntryInRange(SpawnerList, 100.0f, NPC_CREATURE_GENERATOR_AKAMA); - for (std::list::const_iterator itr = SpawnerList.begin(); itr != SpawnerList.end(); ++itr) - summonsGenerator.Summon(*itr); - - summonsChanneler.Respawn(); - summonsGenerator.Respawn(); - ChannelersAction(ACTION_CHANNELERS_START_CHANNEL); - - if (Creature* akama = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_AKAMA_SHADE))) - akama->Respawn(true); - break; - } - case EVENT_SHADE_RESET_ENCOUNTER: - me->SetVisible(true); - summonsGenerator.Respawn(); - summonsChanneler.Respawn(); - ChannelersAction(ACTION_CHANNELERS_START_CHANNEL); - - if (Creature* akama = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_AKAMA_SHADE))) - akama->Respawn(true); - break; - } - - if (!UpdateVictim()) - return; - - events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (events.ExecuteEvent()) - { - case EVENT_SHADE_CHECK_DISTANCE: - if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() != POINT_MOTION_TYPE) - { - int32 slow = me->GetMaxNegativeAuraModifier(SPELL_AURA_MOD_DECREASE_SPEED); - if (slow > -100) - { - me->SetWalk(true); - me->GetMotionMaster()->MovePoint(POINT_START, 510.0f, 400.7993f, 112.7837f); - } - } - else - { - int32 slow = me->GetMaxNegativeAuraModifier(SPELL_AURA_MOD_DECREASE_SPEED); - if (slow < -100) - me->GetMotionMaster()->Clear(); - else if (slow == 0) - { - summonsGenerator.DoAction(ACTION_NO_SORCERERS); - me->SetWalk(false); - } - } - - if (me->IsWithinMeleeRange(me->GetVictim())) - { - me->SetReactState(REACT_AGGRESSIVE); - DoResetThreatList(); - me->GetVictim()->InterruptNonMeleeSpells(false); - me->AddThreat(me->GetVictim(), 1000000.0f); - me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - me->SetImmuneToAll(false); - summonsGenerator.DoAction(ACTION_STOP_SPAWNING); - break; - } - events.ScheduleEvent(EVENT_SHADE_CHECK_DISTANCE, 1000); - break; - } + scheduler.Update(diff); DoMeleeAttackIfReady(); } - - bool CheckEvadeIfOutOfCombatArea() const override - { - return !SelectTargetFromPlayerList(120.0f); - } }; struct npc_akama_shade : public ScriptedAI { - npc_akama_shade(Creature* creature) : ScriptedAI(creature), summons(me) + npc_akama_shade(Creature* creature) : ScriptedAI(creature) { instance = creature->GetInstanceScript(); } InstanceScript* instance; - EventMap events; - EventMap events2; - SummonList summons; void Reset() override { @@ -279,244 +209,262 @@ struct npc_akama_shade : public ScriptedAI return; } + me->SetFaction(FACTION_DEFAULT); me->SetNpcFlag(UNIT_NPC_FLAG_GOSSIP); - me->CastSpell(me, SPELL_STEALTH, true); - events.Reset(); - events2.Reset(); + DoCastSelf(SPELL_STEALTH, true); + me->SetWalk(true); + scheduler.CancelAll(); } void MovementInform(uint32 type, uint32 point) override { - if (type != POINT_MOTION_TYPE || point != POINT_CHANNEL_SOUL) - return; + if (type == POINT_MOTION_TYPE) + { + switch (point) + { + case POINT_ENGAGE: + me->SetHomePosition(me->GetPosition()); + me->SetFaction(FACTION_ENGAGE); + DoCast(me, SPELL_AKAMA_SOUL_CHANNEL, true); + break; + case POINT_OUTRO: + DoCastSelf(SPELL_AKAMA_SOUL_RETRIEVE, true); + ScheduleUniqueTimedEvent(15600ms, [&] + { + Talk(SAY_BROKEN_FREE_0); + me->SummonCreatureGroup(SUMMON_GROUP_BROKENS); + }, 1); + ScheduleUniqueTimedEvent(26550ms, [&] + { + Talk(SAY_BROKEN_FREE_1); + }, 2); + ScheduleUniqueTimedEvent(37500ms, [&] + { + Talk(SAY_BROKEN_FREE_2); + }, 3); + ScheduleUniqueTimedEvent(52000ms, [&] + { + std::list brokens; + me->GetCreatureListWithEntryInGrid(brokens, NPC_ASHTONGUE_BROKEN, 40.0f); + if (Creature* broken = GetClosestCreatureWithEntry(me, NPC_ASHTONGUE_BROKEN, 40.0f)) + broken->AI()->Talk(SAY_BROKEN_S1); - me->SetFacingTo(0.0f); - events2.ScheduleEvent(EVENT_AKAMA_SCENE1, 1000); - events2.ScheduleEvent(EVENT_AKAMA_SCENE2, 16500); - events2.ScheduleEvent(EVENT_AKAMA_SCENE3, 17500); - events2.ScheduleEvent(EVENT_AKAMA_SCENE4, 27000); - events2.ScheduleEvent(EVENT_AKAMA_SCENE5, 37000); - events2.ScheduleEvent(EVENT_AKAMA_SCENE6, 51000); - events2.ScheduleEvent(EVENT_AKAMA_SCENE7, 56000); + for (Creature* broken : brokens) + { + broken->SetStandState(UNIT_STAND_STATE_KNEEL); + broken->SetFaction(FACTION_DEFAULT); + broken->AI()->Talk(SAY_BROKEN_S2, 4800ms); + } + }, 4); + break; + } + } } void DoAction(int32 param) override { - if (param == ACTION_SHADE_DIED) - events2.ScheduleEvent(EVENT_AKAMA_SCENE0, 1000); + if (param == ACTION_AKAMA_START_OUTRO) + { + me->SetWalk(false); + me->GetMotionMaster()->MovePoint(POINT_OUTRO, AkamaOutro); + } } + void JustSummoned(Creature* summon) override + { + // In Retail they seem to me like they should move in formations of 3 to set points, this is simpler for now + ScriptedAI::JustSummoned(summon); + float x, y, z; + me->GetNearPoint(summon, x, y, z, 25.f, 0, me->GetAngle(summon)); + summon->SetWalk(true); + summon->GetMotionMaster()->MovePoint(POINT_OUTRO, x, y, z); + } + + void EnterEvadeMode(EvadeReason /*why*/) override { } + void JustDied(Unit* /*killer*/) override { - if (Creature* shade = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_SHADE_OF_AKAMA))) - shade->AI()->DoAction(ACTION_AKAMA_DIED); + if (Creature* shade = instance->GetCreature(DATA_SHADE_OF_AKAMA)) + { + shade->SetHomePosition(shade->GetHomePosition()); + shade->AI()->EnterEvadeMode(); + } + + me->DespawnOrUnsummon(); } void JustEngagedWith(Unit* /*who*/) override { - events.ScheduleEvent(EVENT_SPELL_CHAIN_LIGHTNING, 2000); - events.ScheduleEvent(EVENT_SPELL_DESTRUCTIVE_POISON, 5000); + ScheduleTimedEvent(2s, [&] + { + DoCastVictim(SPELL_CHAIN_LIGHTNING); + }, 10s, 15s); + ScheduleTimedEvent(5s, [&] + { + DoCastVictim(SPELL_DESTRUCTIVE_POISON); + }, 4s, 15s); } - void JustSummoned(Creature* summon) override + void sGossipSelect(Player* player, uint32 /*sender*/, uint32 /*action*/) override { - float dist = frand(30.0f, 32.0f); - summon->SetWalk(true); - summon->GetMotionMaster()->MovePoint(POINT_START, summon->GetPositionX() + dist * cos(summon->GetOrientation()), summon->GetPositionY() + dist * std::sin(summon->GetOrientation()), summon->GetPositionZ(), false); - summons.Summon(summon); + CloseGossipMenuFor(player); + me->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP); + me->RemoveAurasDueToSpell(SPELL_STEALTH); + me->GetMotionMaster()->MovePoint(POINT_ENGAGE, AkamaEngage); } void UpdateAI(uint32 diff) override { - events2.Update(diff); - switch (events2.ExecuteEvent()) - { - case EVENT_AKAMA_START_ENCOUNTER: - me->RemoveAura(SPELL_STEALTH); - me->SetWalk(true); - me->GetMotionMaster()->MovePoint(POINT_START, 517.4877f, 400.7993f, 112.7837f, false); - events2.ScheduleEvent(EVENT_AKAMA_START_CHANNEL, 11000); - break; - case EVENT_AKAMA_START_CHANNEL: - me->CastSpell(me, SPELL_AKAMA_SOUL_CHANNEL, false); - if (Creature* shade = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_SHADE_OF_AKAMA))) - { - shade->AI()->AttackStart(me); - shade->GetMotionMaster()->Clear(); - shade->AI()->DoAction(ACTION_START_ENCOUNTER); - } - break; - case EVENT_AKAMA_SCENE0: - me->SetWalk(true); - me->GetMotionMaster()->MovePoint(POINT_CHANNEL_SOUL, 467.0f, 400.7993f, 118.537f); - break; - case EVENT_AKAMA_SCENE1: - me->CastSpell(me, SPELL_AKAMA_SOUL_RETRIEVE, true); - break; - case EVENT_AKAMA_SCENE2: - Talk(SAY_BROKEN_FREE_0); - break; - case EVENT_AKAMA_SCENE3: - me->SummonCreatureGroup(SUMMON_GROUP_BROKENS); - break; - case EVENT_AKAMA_SCENE4: - Talk(SAY_BROKEN_FREE_1); - break; - case EVENT_AKAMA_SCENE5: - for (SummonList::const_iterator itr = summons.begin(); itr != summons.end(); ++itr) - if (Creature* broken = ObjectAccessor::GetCreature(*me, *itr)) - broken->SetStandState(UNIT_STAND_STATE_KNEEL); - Talk(SAY_BROKEN_FREE_2); - break; - case EVENT_AKAMA_SCENE6: - if (Creature* broken = summons.GetCreatureWithEntry(NPC_ASHTONGUE_BROKEN)) - broken->AI()->Talk(SAY_BROKEN_S1); - break; - case EVENT_AKAMA_SCENE7: - for (SummonList::const_iterator itr = summons.begin(); itr != summons.end(); ++itr) - if (Creature* broken = ObjectAccessor::GetCreature(*me, *itr)) - broken->AI()->Talk(SAY_BROKEN_S2); - break; - } - - if (!UpdateVictim()) - return; - - events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (events.ExecuteEvent()) - { - case EVENT_SPELL_CHAIN_LIGHTNING: - me->CastSpell(me->GetVictim(), SPELL_CHAIN_LIGHTNING, false); - events.ScheduleEvent(EVENT_SPELL_CHAIN_LIGHTNING, urand(10000, 15000)); - break; - case EVENT_SPELL_DESTRUCTIVE_POISON: - me->CastSpell(me, SPELL_DESTRUCTIVE_POISON, false); - events.ScheduleEvent(EVENT_SPELL_DESTRUCTIVE_POISON, urand(4000, 5000)); - break; - } - + scheduler.Update(diff); DoMeleeAttackIfReady(); } - - void sGossipSelect(Player* player, uint32 /*sender*/, uint32 action) override - { - if (action == 0) - { - CloseGossipMenuFor(player); - me->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP); - events2.ScheduleEvent(EVENT_AKAMA_START_ENCOUNTER, 0); - } - } }; -struct npc_creature_generator_akama : public NullCreatureAI +struct npc_creature_generator_akama : public ScriptedAI { - npc_creature_generator_akama(Creature* creature) : NullCreatureAI(creature), summons(me) + npc_creature_generator_akama(Creature* creature) : ScriptedAI(creature), summons(me) { instance = creature->GetInstanceScript(); } + uint8 spawnCounter = 0; + void Reset() override { - events.Reset(); summons.DespawnAll(); + scheduler.CancelAll(); } void JustSummoned(Creature* summon) override { - summons.Summon(summon); - if (summon->GetEntry() == NPC_ASHTONGUE_SORCERER) + spawnCounter++; + ScriptedAI::JustSummoned(summon); + + switch (summon->GetEntry()) { - std::list channelerList; - me->GetCreaturesWithEntryInRange(channelerList, 120.0f, NPC_ASHTONGUE_CHANNELER); - for (std::list::const_iterator itr = channelerList.begin(); itr != channelerList.end(); ++itr) + case NPC_ASHTONGUE_SORCERER: + if (Creature* shade = instance->GetCreature(DATA_SHADE_OF_AKAMA)) { - if ((*itr)->IsAlive() || (*itr)->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE)) - continue; - - summon->SetInCombatWithZone(); - summon->SetReactState(REACT_PASSIVE); - summon->GetMotionMaster()->MovePoint(POINT_START, **itr); - (*itr)->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - return; + float x, y, z; + shade->GetNearPoint(shade, x, y, z, 20.f, 0, shade->GetAngle(summon)); + summon->GetMotionMaster()->MovePoint(POINT_ENGAGE, x, y, z); } - } - - summon->SetInCombatWithZone(); - if (Unit* akama = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_AKAMA_SHADE))) - { - summon->AddThreat(akama, 500.0f); - summon->AI()->AttackStart(akama); + break; + default: + summon->SetInCombatWithZone(); + if (Creature* akama = instance->GetCreature(DATA_AKAMA_SHADE)) + summon->AI()->AttackStart(akama); + break; } } void SummonedCreatureDies(Creature* summon, Unit*) override { + spawnCounter--; summon->DespawnOrUnsummon(10000); summons.Despawn(summon); } void DoAction(int32 param) override { - if (param == ACTION_STOP_SPAWNING || param == ACTION_DESPAWN_ALL) + switch (param) { - events.Reset(); - for (SummonList::const_iterator itr = summons.begin(); itr != summons.end(); ++itr) + case ACTION_GENERATOR_STOP: + scheduler.CancelAll(); + break; + case ACTION_GENERATOR_START: + if (me->GetPositionY() > 400.0f) // Right Side { - if (Creature* summon = ObjectAccessor::GetCreature(*me, *itr)) + ScheduleTimedEvent(10s, [&] { - if (summon->GetEntry() != NPC_ASHTONGUE_SORCERER) - continue; - summon->InterruptNonMeleeSpells(false); - summon->GetMotionMaster()->Clear(); - summon->SetInCombatWithZone(); - } + if (spawnCounter <= COUNTER_SPAWNS_MAX) + DoCastSelf(SPELL_ASHTONGUE_WAVE_B); + }, 50s, 60s); + + ScheduleTimedEvent(2s, 5s, [&] + { + if (spawnCounter <= COUNTER_SPAWNS_MAX) + DoCastSelf(SPELL_SUMMON_ASHTONGUE_DEFENDER); + }, 30s, 40s); } - } - if (param == ACTION_DESPAWN_ALL) + + if (me->GetPositionY() < 400.0f) // Left Side + { + ScheduleTimedEvent(3s, [&] + { + if (spawnCounter <= COUNTER_SPAWNS_MAX) + DoCastSelf(SPELL_ASHTONGUE_WAVE_B); + }, 50s, 60s); + + ScheduleTimedEvent(2s, 5s, [&] + { + if (spawnCounter <= COUNTER_SPAWNS_MAX) + DoCastSelf(SPELL_SUMMON_ASHTONGUE_SORCERER); + }, 30s, 35s); + } + break; + case ACTION_GENERATOR_DESPAWN_ALL: summons.DespawnAll(); - else if (param == ACTION_NO_SORCERERS) - events.CancelEvent(EVENT_SUMMON_ASHTONGUE_SORCERER); - else if (param == ACTION_START_ENCOUNTER) - { - events.ScheduleEvent(EVENT_SUMMON_WAVE_B, 5000); - events.ScheduleEvent(EVENT_SUMMON_ASHTONGUE_DEFENDER, 20000); - events.ScheduleEvent(EVENT_SUMMON_ASHTONGUE_SORCERER, 35000); + scheduler.CancelAll(); + break; } } void UpdateAI(uint32 diff) override { - events.Update(diff); - - switch (events.ExecuteEvent()) - { - case EVENT_SUMMON_WAVE_B: - me->CastSpell(me, SPELL_ASHTONGUE_WAVE_B, true); - events.ScheduleEvent(EVENT_SUMMON_WAVE_B, 45000); - break; - case EVENT_SUMMON_ASHTONGUE_SORCERER: // left - me->CastSpell(me, SPELL_SUMMON_ASHTONGUE_SORCERER, true); - events.ScheduleEvent(EVENT_SUMMON_ASHTONGUE_SORCERER, 45000); - break; - case EVENT_SUMMON_ASHTONGUE_DEFENDER: // right - me->CastSpell(me, SPELL_SUMMON_ASHTONGUE_DEFENDER, true); - events.ScheduleEvent(EVENT_SUMMON_ASHTONGUE_DEFENDER, 45000); - break; - default: - break; - } + scheduler.Update(diff); } private: - EventMap events; SummonList summons; InstanceScript* instance; }; +struct npc_ashtongue_sorcerer : public NullCreatureAI +{ + npc_ashtongue_sorcerer(Creature* creature) : NullCreatureAI(creature) + { + instance = creature->GetInstanceScript(); + } + + void MovementInform(uint32 type, uint32 point) override + { + if (type == POINT_MOTION_TYPE && point == POINT_ENGAGE) + me->CastSpell(me, SPELL_SHADE_SOUL_CHANNEL, true); + } + +private: + InstanceScript* instance; +}; + +struct npc_ashtongue_channeler : public NullCreatureAI +{ + npc_ashtongue_channeler(Creature* creature) : NullCreatureAI(creature) + { + instance = creature->GetInstanceScript(); + } + + void Reset() override + { + scheduler.Schedule(3600ms, [this](TaskContext context) + { + if (!me->HasUnitState(UNIT_STATE_CASTING)) + me->CastSpell(me, SPELL_SHADE_SOUL_CHANNEL, true); + + context.Repeat(); + }); + } + + void UpdateAI(uint32 diff) override + { + scheduler.Update(diff); + } + +private: + InstanceScript* instance; + TaskScheduler scheduler; +}; + class spell_shade_of_akama_shade_soul_channel : public AuraScript { PrepareAuraScript(spell_shade_of_akama_shade_soul_channel); @@ -562,6 +510,8 @@ void AddSC_boss_shade_of_akama() RegisterBlackTempleCreatureAI(boss_shade_of_akama); RegisterBlackTempleCreatureAI(npc_akama_shade); RegisterBlackTempleCreatureAI(npc_creature_generator_akama); + RegisterBlackTempleCreatureAI(npc_ashtongue_channeler); + RegisterBlackTempleCreatureAI(npc_ashtongue_sorcerer); RegisterSpellScript(spell_shade_of_akama_shade_soul_channel); RegisterSpellScript(spell_shade_of_akama_akama_soul_expel); } diff --git a/src/server/scripts/Outland/BlackTemple/illidari_council.cpp b/src/server/scripts/Outland/BlackTemple/illidari_council.cpp index 247b61311..0fee4ec3b 100644 --- a/src/server/scripts/Outland/BlackTemple/illidari_council.cpp +++ b/src/server/scripts/Outland/BlackTemple/illidari_council.cpp @@ -152,15 +152,13 @@ public: { } - ObjectGuid councilGUIDs[4]; - - void Reset() override + void EnterEvadeMode(EvadeReason why) { - BossAI::Reset(); - Creature* member = nullptr; - for (uint8 i = 0; i < 4; ++i) - if ((member = ObjectAccessor::GetCreature(*me, councilGUIDs[i]))) + for (uint8 i = DATA_GATHIOS_THE_SHATTERER; i <= DATA_VERAS_DARKSHADOW; ++i) + if (Creature* member = instance->GetCreature(i)) member->AI()->EnterEvadeMode(); + + BossAI::EnterEvadeMode(why); } void AttackStart(Unit*) override { } @@ -171,15 +169,11 @@ public: if (!me->isActiveObject() && param == ACTION_START_ENCOUNTER) { me->setActive(true); - councilGUIDs[0] = instance->GetGuidData(NPC_GATHIOS_THE_SHATTERER); - councilGUIDs[1] = instance->GetGuidData(NPC_HIGH_NETHERMANCER_ZEREVOR); - councilGUIDs[2] = instance->GetGuidData(NPC_LADY_MALANDE); - councilGUIDs[3] = instance->GetGuidData(NPC_VERAS_DARKSHADOW); bool spoken = false; - for (uint8 i = 0; i < 4; ++i) + for (uint8 i = DATA_GATHIOS_THE_SHATTERER; i <= DATA_VERAS_DARKSHADOW; ++i) { - if (Creature* member = ObjectAccessor::GetCreature(*me, councilGUIDs[i])) + if (Creature* member = instance->GetCreature(i)) { if (!spoken && (roll_chance_i(33) || i == 3)) { @@ -193,17 +187,15 @@ public: } else if (param == ACTION_ENRAGE) { - Creature* member = nullptr; - for (uint8 i = 0; i < 4; ++i) - if ((member = ObjectAccessor::GetCreature(*me, councilGUIDs[i]))) + for (uint8 i = DATA_GATHIOS_THE_SHATTERER; i <= DATA_VERAS_DARKSHADOW; ++i) + if (Creature* member = instance->GetCreature(i)) member->AI()->DoAction(ACTION_ENRAGE); } else if (param == ACTION_END_ENCOUNTER) { me->setActive(false); - Creature* member = nullptr; - for (uint8 i = 0; i < 4; ++i) - if ((member = ObjectAccessor::GetCreature(*me, councilGUIDs[i]))) + for (uint8 i = DATA_GATHIOS_THE_SHATTERER; i <= DATA_VERAS_DARKSHADOW; ++i) + if (Creature* member = instance->GetCreature(i)) if (member->IsAlive()) Unit::Kill(me, member); me->KillSelf(); @@ -217,7 +209,7 @@ public: if (!SelectTargetFromPlayerList(115.0f)) { - EnterEvadeMode(); + EnterEvadeMode(EVADE_REASON_NO_HOSTILES); return; } @@ -268,13 +260,13 @@ struct boss_illidari_council_memberAI : public ScriptedAI void JustDied(Unit*) override { Talk(SAY_COUNCIL_DEATH); - if (Creature* council = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_ILLIDARI_COUNCIL))) + if (Creature* council = instance->GetCreature(DATA_ILLIDARI_COUNCIL)) council->GetAI()->DoAction(ACTION_END_ENCOUNTER); } void JustEngagedWith(Unit* /*who*/) override { - if (Creature* council = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_ILLIDARI_COUNCIL))) + if (Creature* council = instance->GetCreature(DATA_ILLIDARI_COUNCIL)) council->GetAI()->DoAction(ACTION_START_ENCOUNTER); } }; @@ -296,14 +288,14 @@ public: Creature* SelectCouncilMember() { if (roll_chance_i(50)) - return ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_LADY_MALANDE)); + return instance->GetCreature(DATA_LADY_MALANDE); if (roll_chance_i(20)) - if (Creature* veras = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_VERAS_DARKSHADOW))) + if (Creature* veras = instance->GetCreature(DATA_VERAS_DARKSHADOW)) if (!veras->HasAura(SPELL_VANISH)) return veras; - return ObjectAccessor::GetCreature(*me, instance->GetGuidData(RAND(NPC_GATHIOS_THE_SHATTERER, NPC_HIGH_NETHERMANCER_ZEREVOR))); + return instance->GetCreature(RAND(DATA_GATHIOS_THE_SHATTERER, DATA_HIGH_NETHERMANCER_ZEREVOR)); } void JustEngagedWith(Unit* who) override @@ -555,7 +547,7 @@ public: break; case EVENT_SPELL_ENRAGE: DoResetThreatList(); - if (Creature* council = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_ILLIDARI_COUNCIL))) + if (Creature* council = instance->GetCreature(DATA_ILLIDARI_COUNCIL)) council->GetAI()->DoAction(ACTION_ENRAGE); break; } diff --git a/src/server/scripts/Outland/BlackTemple/instance_black_temple.cpp b/src/server/scripts/Outland/BlackTemple/instance_black_temple.cpp index ab447cdcb..175437358 100644 --- a/src/server/scripts/Outland/BlackTemple/instance_black_temple.cpp +++ b/src/server/scripts/Outland/BlackTemple/instance_black_temple.cpp @@ -36,12 +36,37 @@ DoorData const doorData[] = { GO_MOTHER_SHAHRAZ_DOOR, DATA_MOTHER_SHAHRAZ, DOOR_TYPE_PASSAGE }, { GO_COUNCIL_DOOR_1, DATA_ILLIDARI_COUNCIL, DOOR_TYPE_ROOM }, { GO_COUNCIL_DOOR_2, DATA_ILLIDARI_COUNCIL, DOOR_TYPE_ROOM }, - { GO_ILLIDAN_GATE, DATA_AKAMA_FINISHED, DOOR_TYPE_PASSAGE }, + { GO_ILLIDAN_GATE, DATA_AKAMA_ILLIDAN, DOOR_TYPE_PASSAGE }, { GO_ILLIDAN_DOOR_L, DATA_ILLIDAN_STORMRAGE, DOOR_TYPE_ROOM }, { GO_ILLIDAN_DOOR_R, DATA_ILLIDAN_STORMRAGE, DOOR_TYPE_ROOM }, { 0, 0, DOOR_TYPE_ROOM } }; +ObjectData const creatureData[] = +{ + { NPC_HIGH_WARLORD_NAJENTUS, DATA_HIGH_WARLORD_NAJENTUS }, + { NPC_SUPREMUS, DATA_SUPREMUS }, + { NPC_SHADE_OF_AKAMA, DATA_SHADE_OF_AKAMA }, + { NPC_AKAMA_SHADE, DATA_AKAMA_SHADE }, + { NPC_TERON_GOREFIEND, DATA_TERON_GOREFIEND }, + { NPC_GURTOGG_BLOODBOIL, DATA_GURTOGG_BLOODBOIL }, + { NPC_RELIQUARY_OF_THE_LOST, DATA_RELIQUARY_OF_SOULS }, + { NPC_MOTHER_SHAHRAZ, DATA_MOTHER_SHAHRAZ }, + { NPC_ILLIDARI_COUNCIL, DATA_ILLIDARI_COUNCIL }, + { NPC_GATHIOS_THE_SHATTERER, DATA_GATHIOS_THE_SHATTERER }, + { NPC_HIGH_NETHERMANCER_ZEREVOR, DATA_HIGH_NETHERMANCER_ZEREVOR }, + { NPC_LADY_MALANDE, DATA_LADY_MALANDE }, + { NPC_VERAS_DARKSHADOW, DATA_VERAS_DARKSHADOW }, + { NPC_AKAMA_ILLIDAN, DATA_AKAMA_ILLIDAN }, + { NPC_ILLIDAN_STORMRAGE, DATA_ILLIDAN_STORMRAGE }, + { 0, 0 } +}; + +ObjectData const objectData[] = +{ + { 0, 0 } +}; + BossBoundaryData const boundaries = { { DATA_HIGH_WARLORD_NAJENTUS, new RectangleBoundary(394.0f, 479.4f, 707.8f, 859.1f) }, @@ -70,6 +95,7 @@ public: SetBossNumber(MAX_ENCOUNTERS); LoadDoorData(doorData); LoadBossBoundaries(boundaries); + LoadObjectData(creatureData, objectData); ashtongueGUIDs.clear(); } @@ -78,52 +104,19 @@ public: { switch (creature->GetEntry()) { - case NPC_SHADE_OF_AKAMA: - ShadeOfAkamaGUID = creature->GetGUID(); - break; - case NPC_AKAMA_SHADE: - AkamaShadeGUID = creature->GetGUID(); - break; - case NPC_TERON_GOREFIEND: - TeronGorefiendGUID = creature->GetGUID(); - break; - case NPC_RELIQUARY_OF_THE_LOST: - ReliquaryGUID = creature->GetGUID(); - break; - case NPC_GATHIOS_THE_SHATTERER: - GathiosTheShattererGUID = creature->GetGUID(); - break; - case NPC_HIGH_NETHERMANCER_ZEREVOR: - HighNethermancerZerevorGUID = creature->GetGUID(); - break; - case NPC_LADY_MALANDE: - LadyMalandeGUID = creature->GetGUID(); - break; - case NPC_VERAS_DARKSHADOW: - VerasDarkshadowGUID = creature->GetGUID(); - break; - case NPC_ILLIDARI_COUNCIL: - IllidariCouncilGUID = creature->GetGUID(); - break; - case NPC_AKAMA: - AkamaGUID = creature->GetGUID(); - break; - case NPC_ILLIDAN_STORMRAGE: - IllidanStormrageGUID = creature->GetGUID(); - break; case NPC_VENGEFUL_SPIRIT: case NPC_SHADOWY_CONSTRUCT: - if (Creature* teron = instance->GetCreature(TeronGorefiendGUID)) + if (Creature* teron = GetCreature(DATA_TERON_GOREFIEND)) teron->AI()->JustSummoned(creature); break; case NPC_ENSLAVED_SOUL: - if (Creature* reliquary = instance->GetCreature(ReliquaryGUID)) + if (Creature* reliquary = GetCreature(DATA_RELIQUARY_OF_SOULS)) reliquary->AI()->JustSummoned(creature); break; case NPC_PARASITIC_SHADOWFIEND: case NPC_BLADE_OF_AZZINOTH: case NPC_FLAME_OF_AZZINOTH: - if (Creature* illidan = instance->GetCreature(IllidanStormrageGUID)) + if (Creature* illidan = GetCreature(DATA_ILLIDAN_STORMRAGE)) illidan->AI()->JustSummoned(creature); break; case NPC_ANGERED_SOUL_FRAGMENT: @@ -131,85 +124,38 @@ public: case NPC_SUFFERING_SOUL_FRAGMENT: creature->SetCorpseDelay(5); break; + case NPC_ASHTONGUE_BATTLELORD: + case NPC_ASHTONGUE_MYSTIC: + case NPC_ASHTONGUE_STORMCALLER: + case NPC_ASHTONGUE_PRIMALIST: + case NPC_ASHTONGUE_FERAL_SPIRIT: + case NPC_ASHTONGUE_STALKER: + case NPC_STORM_FURY: + if (GetBossState(DATA_SHADE_OF_AKAMA) == DONE) + creature->SetFaction(FACTION_ASHTONGUE_DEATHSWORN); + else + ashtongueGUIDs.insert(creature->GetGUID()); + break; + default: + break; } - if (creature->GetName().find("Ashtongue") != std::string::npos || creature->GetEntry() == NPC_STORM_FURY) - { - ashtongueGUIDs.push_back(creature->GetGUID()); - if (GetBossState(DATA_SHADE_OF_AKAMA) == DONE) - creature->SetFaction(FACTION_ASHTONGUE_DEATHSWORN); - } + InstanceScript::OnCreatureCreate(creature); } void OnGameObjectCreate(GameObject* go) override { - switch (go->GetEntry()) + // If created after Illidari Council is done, then skip Akama's event. Used for crashes/reset + if (go->GetEntry() == GO_ILLIDAN_GATE) { - case GO_NAJENTUS_GATE: - case GO_SUPREMUS_GATE: - case GO_SHADE_OF_AKAMA_DOOR: - case GO_TERON_DOOR_1: - case GO_TERON_DOOR_2: - case GO_GURTOGG_DOOR: - case GO_TEMPLE_DOOR: - case GO_MOTHER_SHAHRAZ_DOOR: - case GO_COUNCIL_DOOR_1: - case GO_COUNCIL_DOOR_2: - case GO_ILLIDAN_GATE: - case GO_ILLIDAN_DOOR_R: - case GO_ILLIDAN_DOOR_L: - AddDoor(go); - break; - } - } - - void OnGameObjectRemove(GameObject* go) override - { - switch (go->GetEntry()) - { - case GO_NAJENTUS_GATE: - case GO_SUPREMUS_GATE: - case GO_SHADE_OF_AKAMA_DOOR: - case GO_TERON_DOOR_1: - case GO_TERON_DOOR_2: - case GO_GURTOGG_DOOR: - case GO_TEMPLE_DOOR: - case GO_MOTHER_SHAHRAZ_DOOR: - case GO_COUNCIL_DOOR_1: - case GO_COUNCIL_DOOR_2: - case GO_ILLIDAN_GATE: - case GO_ILLIDAN_DOOR_R: - case GO_ILLIDAN_DOOR_L: - RemoveDoor(go); - break; - } - } - - ObjectGuid GetGuidData(uint32 type) const override - { - switch (type) - { - case NPC_SHADE_OF_AKAMA: - return ShadeOfAkamaGUID; - case NPC_AKAMA_SHADE: - return AkamaShadeGUID; - case NPC_GATHIOS_THE_SHATTERER: - return GathiosTheShattererGUID; - case NPC_HIGH_NETHERMANCER_ZEREVOR: - return HighNethermancerZerevorGUID; - case NPC_LADY_MALANDE: - return LadyMalandeGUID; - case NPC_VERAS_DARKSHADOW: - return VerasDarkshadowGUID; - case NPC_ILLIDARI_COUNCIL: - return IllidariCouncilGUID; - case NPC_AKAMA: - return AkamaGUID; - case NPC_ILLIDAN_STORMRAGE: - return IllidanStormrageGUID; + if (GetBossState(DATA_ILLIDARI_COUNCIL) == DONE) + { + SetBossState(DATA_AKAMA_ILLIDAN, DONE); + HandleGameObject(ObjectGuid::Empty, true, go); + } } - return ObjectGuid::Empty; + InstanceScript::OnGameObjectCreate(go); } bool SetBossState(uint32 type, EncounterState state) override @@ -225,26 +171,15 @@ public: } else if (type == DATA_ILLIDARI_COUNCIL && state == DONE) { - if (Creature* akama = instance->GetCreature(AkamaGUID)) - akama->SetVisible(true); + if (Creature* akama = GetCreature(DATA_AKAMA_ILLIDAN)) + akama->AI()->DoAction(0); } return true; } protected: - ObjectGuid ShadeOfAkamaGUID; - ObjectGuid AkamaShadeGUID; - ObjectGuid TeronGorefiendGUID; - ObjectGuid ReliquaryGUID; - GuidList ashtongueGUIDs; - ObjectGuid GathiosTheShattererGUID; - ObjectGuid HighNethermancerZerevorGUID; - ObjectGuid LadyMalandeGUID; - ObjectGuid VerasDarkshadowGUID; - ObjectGuid IllidariCouncilGUID; - ObjectGuid AkamaGUID; - ObjectGuid IllidanStormrageGUID; + GuidSet ashtongueGUIDs; }; InstanceScript* GetInstanceScript(InstanceMap* map) const override From e4136639e3b1ce4e4fc73204872d988588d60aee Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 2 Apr 2024 20:09:05 +0000 Subject: [PATCH 17/30] chore(DB): import pending files Referenced commit(s): 961681bb9ff21764001e09e5b75a054077e80ffc --- .../rev_1711048056647652400.sql => db_world/2024_04_02_03.sql} | 1 + .../rev_1711490977417590640.sql => db_world/2024_04_02_04.sql} | 1 + .../rev_1711633613954464100.sql => db_world/2024_04_02_05.sql} | 1 + 3 files changed, 3 insertions(+) rename data/sql/updates/{pending_db_world/rev_1711048056647652400.sql => db_world/2024_04_02_03.sql} (98%) rename data/sql/updates/{pending_db_world/rev_1711490977417590640.sql => db_world/2024_04_02_04.sql} (99%) rename data/sql/updates/{pending_db_world/rev_1711633613954464100.sql => db_world/2024_04_02_05.sql} (99%) diff --git a/data/sql/updates/pending_db_world/rev_1711048056647652400.sql b/data/sql/updates/db_world/2024_04_02_03.sql similarity index 98% rename from data/sql/updates/pending_db_world/rev_1711048056647652400.sql rename to data/sql/updates/db_world/2024_04_02_03.sql index 391553a3a..f31602dbd 100644 --- a/data/sql/updates/pending_db_world/rev_1711048056647652400.sql +++ b/data/sql/updates/db_world/2024_04_02_03.sql @@ -1,3 +1,4 @@ +-- DB update 2024_04_02_02 -> 2024_04_02_03 -- UPDATE `creature_template` SET `AIName` = '', `ScriptName` = 'npc_ashtongue_channeler', `faction` = 1692 WHERE (`entry` = 23421); UPDATE `creature_template` SET `AIName` = '', `ScriptName` = 'npc_ashtongue_sorcerer' WHERE (`entry` = 23215); diff --git a/data/sql/updates/pending_db_world/rev_1711490977417590640.sql b/data/sql/updates/db_world/2024_04_02_04.sql similarity index 99% rename from data/sql/updates/pending_db_world/rev_1711490977417590640.sql rename to data/sql/updates/db_world/2024_04_02_04.sql index 26ce1689b..f62b89d5d 100644 --- a/data/sql/updates/pending_db_world/rev_1711490977417590640.sql +++ b/data/sql/updates/db_world/2024_04_02_04.sql @@ -1,3 +1,4 @@ +-- DB update 2024_04_02_03 -> 2024_04_02_04 DELETE FROM pool_gameobject WHERE guid BETWEEN 75600 AND 75761; DELETE FROM pool_gameobject WHERE guid BETWEEN 75765 AND 75932; diff --git a/data/sql/updates/pending_db_world/rev_1711633613954464100.sql b/data/sql/updates/db_world/2024_04_02_05.sql similarity index 99% rename from data/sql/updates/pending_db_world/rev_1711633613954464100.sql rename to data/sql/updates/db_world/2024_04_02_05.sql index 84c6cb3fd..49bbc31bc 100644 --- a/data/sql/updates/pending_db_world/rev_1711633613954464100.sql +++ b/data/sql/updates/db_world/2024_04_02_05.sql @@ -1,3 +1,4 @@ +-- DB update 2024_04_02_04 -> 2024_04_02_05 -- Update gameobject 'Forge' with sniffed values -- updated spawns DELETE FROM `gameobject` WHERE (`id` IN (194468, 173063, 2575, 19902, 179924, 1749, 21679, 34571, 173095, 173064, 144133, 153459, 20738, 147285, 4090, 56897, 138317, 20986, 23304, 23305, 24745, 24746, 34572, 38491, 202392, 202393, 202391, 202394, 186556, 2728, 2727, 51949, 169969, 2573, 1797, 1896, 141838, 141841, 184617, 182056, 3223, 183818, 181716, 181990, 182117, 182278, 182860, 183121, 183148, 183345, 183347, 183408, 183484, 183757, 183758, 183759, 183760, 183782, 184286, 184922, 184923, 181884, 184146, 187112, 186139, 184687, 17190, 175144, 182270, 186138, 130668, 175851, 186141, 1685, 1743, 52175, 52176, 113754, 148960, 181130, 179886, 176509, 50831, 92490, 179863, 180913, 171716, 171717, 192020, 186654, 190495, 188452, 190765, 190524, 192831, 186433, 192583, 188250, 188257, 191346, 186486, 187256, 194487, 188607, 188354, 188356, 188624, 188651, 188396, 190457, 187388, 192062, 191287, 191288, 192572, 192573, 191508, 186653, 191237, 191505, 179844, 152034, 152042, 152045, 193126, 186231, 186630, 194128, 176895, 142078)) From 171011e506694cfeb8ac0f884ea2c9d1c7cba3cd Mon Sep 17 00:00:00 2001 From: sudlud Date: Wed, 3 Apr 2024 14:01:37 +0200 Subject: [PATCH 18/30] fix(DB/Gameobject): remove duplicate 'Door' spawns in Black Temple (#18656) - this is due to a 'collision' of the Black Temple rework PR and my general 'Door' update PR which was merged later --- data/sql/updates/pending_db_world/rev_1712085690434398700.sql | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1712085690434398700.sql diff --git a/data/sql/updates/pending_db_world/rev_1712085690434398700.sql b/data/sql/updates/pending_db_world/rev_1712085690434398700.sql new file mode 100644 index 000000000..bd4f91038 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1712085690434398700.sql @@ -0,0 +1,2 @@ +-- remove duplicate 'Door' spawns from Black Temple +DELETE from `gameobject` WHERE (`id` IN (185482, 185892, 185479, 185478, 185481, 185480)) AND (`guid` IN (20567, 20523, 20559, 20558, 20563, 20561)); From 40bbba64d95f617137c256a56c0462a89b7444a6 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 3 Apr 2024 12:02:29 +0000 Subject: [PATCH 19/30] chore(DB): import pending files Referenced commit(s): 171011e506694cfeb8ac0f884ea2c9d1c7cba3cd --- .../rev_1712085690434398700.sql => db_world/2024_04_03_00.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1712085690434398700.sql => db_world/2024_04_03_00.sql} (82%) diff --git a/data/sql/updates/pending_db_world/rev_1712085690434398700.sql b/data/sql/updates/db_world/2024_04_03_00.sql similarity index 82% rename from data/sql/updates/pending_db_world/rev_1712085690434398700.sql rename to data/sql/updates/db_world/2024_04_03_00.sql index bd4f91038..6da6147b7 100644 --- a/data/sql/updates/pending_db_world/rev_1712085690434398700.sql +++ b/data/sql/updates/db_world/2024_04_03_00.sql @@ -1,2 +1,3 @@ +-- DB update 2024_04_02_05 -> 2024_04_03_00 -- remove duplicate 'Door' spawns from Black Temple DELETE from `gameobject` WHERE (`id` IN (185482, 185892, 185479, 185478, 185481, 185480)) AND (`guid` IN (20567, 20523, 20559, 20558, 20563, 20561)); From 94ea1098581786499a0995657178acfc868a4fe5 Mon Sep 17 00:00:00 2001 From: Gultask <100873791+Gultask@users.noreply.github.com> Date: Wed, 3 Apr 2024 16:30:41 -0300 Subject: [PATCH 20/30] fix(Scripts/BlackTemple): Illidan not accessing Akama's guid (#18665) init --- .../pending_db_world/rev_1712171769662178600.sql | 2 ++ .../scripts/Outland/BlackTemple/boss_illidan.cpp | 10 +++++----- 2 files changed, 7 insertions(+), 5 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1712171769662178600.sql diff --git a/data/sql/updates/pending_db_world/rev_1712171769662178600.sql b/data/sql/updates/pending_db_world/rev_1712171769662178600.sql new file mode 100644 index 000000000..583e9a344 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1712171769662178600.sql @@ -0,0 +1,2 @@ +-- +UPDATE `creature` SET `spawntimesecs` = 60 WHERE `guid` = 148735 AND `id1` = 23089; diff --git a/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp b/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp index 698375624..ebc2d0589 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp @@ -240,10 +240,10 @@ public: void EnterEvadeMode(EvadeReason why) override { - BossAI::EnterEvadeMode(why); + if (Creature* akama = instance->GetCreature(DATA_AKAMA_ILLIDAN)) + akama->DespawnOrUnsummon(); - if (Creature* akama = instance->GetCreature(NPC_AKAMA_ILLIDAN)) - akama->AI()->EnterEvadeMode(why); + BossAI::EnterEvadeMode(why); } bool CanAIAttack(Unit const* target) const override @@ -413,7 +413,7 @@ public: switch (events2.ExecuteEvent()) { case EVENT_SUMMON_MINIONS2: - if (Creature* akama = instance->GetCreature(NPC_AKAMA_ILLIDAN)) + if (Creature* akama = instance->GetCreature(DATA_AKAMA_ILLIDAN)) akama->AI()->DoAction(ACTION_FIGHT_MINIONS); break; case EVENT_PHASE_2_EYE_BEAM_START: @@ -450,7 +450,7 @@ public: maiev->AI()->Talk(SAY_MAIEV_SHADOWSONG_ILLIDAN3); } - if (Creature* akama = instance->GetCreature(NPC_AKAMA_ILLIDAN)) + if (Creature* akama = instance->GetCreature(DATA_AKAMA_ILLIDAN)) { akama->AI()->DoAction(ACTION_ILLIDAN_DEAD); akama->SetTarget(me->GetGUID()); From e863873d4c808fabac48a4132c6ba97802c6dd79 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 3 Apr 2024 19:36:53 +0000 Subject: [PATCH 21/30] chore(DB): import pending files Referenced commit(s): 94ea1098581786499a0995657178acfc868a4fe5 --- .../rev_1712171769662178600.sql => db_world/2024_04_03_01.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1712171769662178600.sql => db_world/2024_04_03_01.sql} (66%) diff --git a/data/sql/updates/pending_db_world/rev_1712171769662178600.sql b/data/sql/updates/db_world/2024_04_03_01.sql similarity index 66% rename from data/sql/updates/pending_db_world/rev_1712171769662178600.sql rename to data/sql/updates/db_world/2024_04_03_01.sql index 583e9a344..81a4e0ea9 100644 --- a/data/sql/updates/pending_db_world/rev_1712171769662178600.sql +++ b/data/sql/updates/db_world/2024_04_03_01.sql @@ -1,2 +1,3 @@ +-- DB update 2024_04_03_00 -> 2024_04_03_01 -- UPDATE `creature` SET `spawntimesecs` = 60 WHERE `guid` = 148735 AND `id1` = 23089; From 94df67b1c27c06017d2ff309d90ee589a60e24f0 Mon Sep 17 00:00:00 2001 From: sudlud Date: Thu, 4 Apr 2024 23:29:34 +0200 Subject: [PATCH 22/30] fix(Core/Battleground): correctly limit Eye of the Storm max points to 1600 (#18669) - before the max points could exceed 1600 on winning which e.g. resulted in the achievement 'The Perfect Storm' not beeing triggered correctly --- src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp index 1b3fe32c8..226bcf709 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp @@ -113,6 +113,8 @@ void BattlegroundEY::AddPoints(TeamId teamId, uint32 points) { uint8 honorRewards = uint8(m_TeamScores[teamId] / _honorTics); m_TeamScores[teamId] += points; + if (m_TeamScores[teamId] > BG_EY_MAX_TEAM_SCORE) + m_TeamScores[teamId] = BG_EY_MAX_TEAM_SCORE; for (; honorRewards < uint8(m_TeamScores[teamId] / _honorTics); ++honorRewards) RewardHonorToTeam(GetBonusHonorFromKill(1), teamId); From 1f640c98729ddfd5e3aba885fd0fcb6bc8740000 Mon Sep 17 00:00:00 2001 From: Anton Popovichenko Date: Fri, 5 Apr 2024 08:03:11 +0200 Subject: [PATCH 23/30] feat(Core/Optimization): Optimize build of units update object by leveraging cache (#18637) * feat(Core/Optimization): Optimize build of units update object by leveraging cache. * Remove whitespaces. * Add alternative hooks to handle transmog and other similar things. * Fix build on some compilers. * Fix codestyle * Fix build again. * Take into account updateType. --- src/server/game/Entities/Corpse/Corpse.cpp | 2 +- src/server/game/Entities/Corpse/Corpse.h | 2 +- .../game/Entities/GameObject/GameObject.cpp | 2 +- .../game/Entities/GameObject/GameObject.h | 2 +- .../game/Entities/Item/Container/Bag.cpp | 2 +- src/server/game/Entities/Item/Container/Bag.h | 2 +- src/server/game/Entities/Object/Object.cpp | 8 +- src/server/game/Entities/Object/Object.h | 8 +- src/server/game/Entities/Player/Player.cpp | 2 +- src/server/game/Entities/Player/Player.h | 2 +- src/server/game/Entities/Unit/Unit.cpp | 340 +++++++++++------- src/server/game/Entities/Unit/Unit.h | 64 +++- .../Scripting/ScriptDefines/UnitScript.cpp | 14 +- .../game/Scripting/ScriptDefines/UnitScript.h | 5 +- src/server/game/Scripting/ScriptMgr.h | 3 +- 15 files changed, 302 insertions(+), 156 deletions(-) diff --git a/src/server/game/Entities/Corpse/Corpse.cpp b/src/server/game/Entities/Corpse/Corpse.cpp index b2304cb18..ab0b84dca 100644 --- a/src/server/game/Entities/Corpse/Corpse.cpp +++ b/src/server/game/Entities/Corpse/Corpse.cpp @@ -198,7 +198,7 @@ void Corpse::ResetGhostTime() m_time = GameTime::GetGameTime().count(); } -void Corpse::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* target) const +void Corpse::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* target) { if (!target) return; diff --git a/src/server/game/Entities/Corpse/Corpse.h b/src/server/game/Entities/Corpse/Corpse.h index 6d1dedcf0..e74f2c943 100644 --- a/src/server/game/Entities/Corpse/Corpse.h +++ b/src/server/game/Entities/Corpse/Corpse.h @@ -54,7 +54,7 @@ public: void AddToWorld() override; void RemoveFromWorld() override; - void BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* target) const override; + void BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* target) override; bool Create(ObjectGuid::LowType guidlow); bool Create(ObjectGuid::LowType guidlow, Player* owner); diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 7f9886aa4..83f21ac4c 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -2738,7 +2738,7 @@ GameObject* GameObject::GetLinkedTrap() return ObjectAccessor::GetGameObject(*this, m_linkedTrap); } -void GameObject::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* target) const +void GameObject::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* target) { if (!target) return; diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h index a2e352ea8..ed47aa084 100644 --- a/src/server/game/Entities/GameObject/GameObject.h +++ b/src/server/game/Entities/GameObject/GameObject.h @@ -124,7 +124,7 @@ public: explicit GameObject(); ~GameObject() override; - void BuildValuesUpdate(uint8 updatetype, ByteBuffer* data, Player* target) const override; + void BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* target) override; void AddToWorld() override; void RemoveFromWorld() override; diff --git a/src/server/game/Entities/Item/Container/Bag.cpp b/src/server/game/Entities/Item/Container/Bag.cpp index ad7164c56..100df4604 100644 --- a/src/server/game/Entities/Item/Container/Bag.cpp +++ b/src/server/game/Entities/Item/Container/Bag.cpp @@ -166,7 +166,7 @@ void Bag::StoreItem(uint8 slot, Item* pItem, bool /*update*/) } } -void Bag::BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target) const +void Bag::BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target) { Item::BuildCreateUpdateBlockForPlayer(data, target); diff --git a/src/server/game/Entities/Item/Container/Bag.h b/src/server/game/Entities/Item/Container/Bag.h index dfe7654f8..071f4d902 100644 --- a/src/server/game/Entities/Item/Container/Bag.h +++ b/src/server/game/Entities/Item/Container/Bag.h @@ -55,7 +55,7 @@ public: // overwrite virtual Item::DeleteFromDB void DeleteFromDB(CharacterDatabaseTransaction trans) override; - void BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target) const override; + void BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target) override; std::string GetDebugInfo() const override; diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index a831a0804..5f505655d 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -186,7 +186,7 @@ void Object::BuildMovementUpdateBlock(UpdateData* data, uint32 flags) const data->AddUpdateBlock(buf); } -void Object::BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target) const +void Object::BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target) { if (!target) return; @@ -254,7 +254,7 @@ void Object::SendUpdateToPlayer(Player* player) player->GetSession()->SendPacket(&packet); } -void Object::BuildValuesUpdateBlockForPlayer(UpdateData* data, Player* target) const +void Object::BuildValuesUpdateBlockForPlayer(UpdateData* data, Player* target) { ByteBuffer buf(500); @@ -494,7 +494,7 @@ void Object::BuildMovementUpdate(ByteBuffer* data, uint16 flags) const } } -void Object::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* target) const +void Object::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* target) { if (!target) return; @@ -542,7 +542,7 @@ void Object::ClearUpdateMask(bool remove) } } -void Object::BuildFieldsUpdate(Player* player, UpdateDataMapType& data_map) const +void Object::BuildFieldsUpdate(Player* player, UpdateDataMapType& data_map) { UpdateDataMapType::iterator iter = data_map.find(player); diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index 3547b36ce..f9a9ac69c 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -121,10 +121,10 @@ public: [[nodiscard]] TypeID GetTypeId() const { return m_objectTypeId; } [[nodiscard]] bool isType(uint16 mask) const { return (mask & m_objectType); } - virtual void BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target) const; + virtual void BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target); void SendUpdateToPlayer(Player* player); - void BuildValuesUpdateBlockForPlayer(UpdateData* data, Player* target) const; + void BuildValuesUpdateBlockForPlayer(UpdateData* data, Player* target); void BuildOutOfRangeUpdateBlock(UpdateData* data) const; void BuildMovementUpdateBlock(UpdateData* data, uint32 flags = 0) const; @@ -183,7 +183,7 @@ public: [[nodiscard]] virtual bool hasQuest(uint32 /* quest_id */) const { return false; } [[nodiscard]] virtual bool hasInvolvedQuest(uint32 /* quest_id */) const { return false; } virtual void BuildUpdate(UpdateDataMapType&, UpdatePlayerSet&) {} - void BuildFieldsUpdate(Player*, UpdateDataMapType&) const; + void BuildFieldsUpdate(Player*, UpdateDataMapType&); void SetFieldNotifyFlag(uint16 flag) { _fieldNotifyFlags |= flag; } void RemoveFieldNotifyFlag(uint16 flag) { _fieldNotifyFlags &= ~flag; } @@ -223,7 +223,7 @@ protected: uint32 GetUpdateFieldData(Player const* target, uint32*& flags) const; void BuildMovementUpdate(ByteBuffer* data, uint16 flags) const; - virtual void BuildValuesUpdate(uint8 updatetype, ByteBuffer* data, Player* target) const; + virtual void BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* target); uint16 m_objectType; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index fd173a16b..bde2d0a92 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -3791,7 +3791,7 @@ Mail* Player::GetMail(uint32 id) return nullptr; } -void Player::BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target) const +void Player::BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target) { if (target == this) { diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 70bd05ba9..f10be00ed 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -1974,7 +1974,7 @@ public: [[nodiscard]] WorldSession* GetSession() const { return m_session; } void SetSession(WorldSession* sess) { m_session = sess; } - void BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target) const override; + void BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target) override; void DestroyForPlayer(Player* target, bool onDeath = false) const override; void SendLogXPGain(uint32 GivenXP, Unit* victim, uint32 BonusXP, bool recruitAFriend = false, float group_rate = 1.0f); diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index f89793acd..9cdb7343c 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -534,6 +534,8 @@ void Unit::Update(uint32 p_time) UpdateSplineMovement(p_time); GetMotionMaster()->UpdateMotion(p_time); + + InvalidateValuesUpdateCache(); } bool Unit::haveOffhandWeapon() const @@ -21034,16 +21036,11 @@ void Unit::SendMovementHover(Player* sendTo) sendTo->SendDirectMessage(&data); } -void Unit::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* target) const +void Unit::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* target) { if (!target) return; - ByteBuffer fieldBuffer; - - UpdateMask updateMask; - updateMask.SetCount(m_valuesCount); - uint32* flags = UnitUpdateFieldFlags; uint32 visibleFlag = UF_FLAG_PUBLIC; @@ -21061,7 +21058,30 @@ void Unit::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* target) if (plr && plr->IsInSameRaidWith(target)) visibleFlag |= UF_FLAG_PARTY_MEMBER; - Creature const* creature = ToCreature(); + uint64 cacheKey = static_cast(visibleFlag) << 8 | updateType; + + auto cacheIt = _valuesUpdateCache.find(cacheKey); + if (cacheIt != _valuesUpdateCache.end()) + { + int32 cachePos = static_cast(data->wpos()); + data->append(cacheIt->second.buffer); + + BuildValuesCachePosPointers dataAdjustedPos = cacheIt->second.posPointers; + if (cachePos) + dataAdjustedPos.ApplyOffset(cachePos); + + PatchValuesUpdate(*data, dataAdjustedPos, target); + + return; + } + + BuildValuesCachedBuffer cacheValue(500); + + ByteBuffer fieldBuffer(400); + + UpdateMask updateMask; + updateMask.SetCount(m_valuesCount); + for (uint16 index = 0; index < m_valuesCount; ++index) { if (_fieldNotifyFlags & flags[index] || @@ -21073,37 +21093,13 @@ void Unit::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* target) if (index == UNIT_NPC_FLAGS) { - uint32 appendValue = m_uint32Values[UNIT_NPC_FLAGS]; - - if (creature) - { - if (sWorld->getIntConfig(CONFIG_INSTANT_TAXI) == 2 && appendValue & UNIT_NPC_FLAG_FLIGHTMASTER) - { - appendValue |= UNIT_NPC_FLAG_GOSSIP; // flight masters need NPC gossip flag to show instant flight toggle option - } - - if (!target->CanSeeSpellClickOn(creature)) - { - appendValue &= ~UNIT_NPC_FLAG_SPELLCLICK; - } - - if (!target->CanSeeVendor(creature)) - { - appendValue &= ~UNIT_NPC_FLAG_VENDOR_MASK; - } - - if (!creature->IsValidTrainerForPlayer(target, &appendValue)) - { - appendValue &= ~UNIT_NPC_FLAG_TRAINER; - } - } - - fieldBuffer << uint32(appendValue); + cacheValue.posPointers.UnitNPCFlagsPos = int32(fieldBuffer.wpos()); + fieldBuffer << m_uint32Values[UNIT_NPC_FLAGS]; } else if (index == UNIT_FIELD_AURASTATE) { - // Check per caster aura states to not enable using a spell in client if specified aura is not by target - fieldBuffer << BuildAuraStateUpdateForTarget(target); + cacheValue.posPointers.UnitFieldAuraStatePos = int32(fieldBuffer.wpos()); + fieldBuffer << uint32(0); // Fill in later. } // FIXME: Some values at server stored in float format but must be sent to client in uint32 format else if (index >= UNIT_FIELD_BASEATTACKTIME && index <= UNIT_FIELD_RANGEDATTACKTIME) @@ -21122,115 +21118,35 @@ void Unit::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* target) // Gamemasters should be always able to select units - remove not selectable flag else if (index == UNIT_FIELD_FLAGS) { - uint32 appendValue = m_uint32Values[UNIT_FIELD_FLAGS]; - if (target->IsGameMaster() && target->GetSession()->IsGMAccount()) - appendValue &= ~UNIT_FLAG_NOT_SELECTABLE; - - fieldBuffer << uint32(appendValue); + cacheValue.posPointers.UnitFieldFlagsPos = int32(fieldBuffer.wpos()); + fieldBuffer << m_uint32Values[UNIT_FIELD_FLAGS]; } // use modelid_a if not gm, _h if gm for CREATURE_FLAG_EXTRA_TRIGGER creatures else if (index == UNIT_FIELD_DISPLAYID) { - uint32 displayId = m_uint32Values[UNIT_FIELD_DISPLAYID]; - if (creature) - { - CreatureTemplate const* cinfo = creature->GetCreatureTemplate(); - - // this also applies for transform auras - if (SpellInfo const* transform = sSpellMgr->GetSpellInfo(getTransForm())) - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) - if (transform->Effects[i].IsAura(SPELL_AURA_TRANSFORM)) - if (CreatureTemplate const* transformInfo = sObjectMgr->GetCreatureTemplate(transform->Effects[i].MiscValue)) - { - cinfo = transformInfo; - break; - } - - if (cinfo->flags_extra & CREATURE_FLAG_EXTRA_TRIGGER) - { - if (target->IsGameMaster() && target->GetSession()->IsGMAccount()) - { - if (cinfo->Modelid1) - displayId = cinfo->Modelid1; // Modelid1 is a visible model for gms - else - displayId = 17519; // world visible trigger's model - } - else - { - if (cinfo->Modelid2) - displayId = cinfo->Modelid2; // Modelid2 is an invisible model for players - else - displayId = 11686; // world invisible trigger's model - } - } - } - - fieldBuffer << uint32(displayId); + cacheValue.posPointers.UnitFieldDisplayPos = int32(fieldBuffer.wpos()); + fieldBuffer << m_uint32Values[UNIT_FIELD_DISPLAYID]; } - // hide lootable animation for unallowed players else if (index == UNIT_DYNAMIC_FLAGS) { + cacheValue.posPointers.UnitDynamicFlagsPos = int32(fieldBuffer.wpos()); uint32 dynamicFlags = m_uint32Values[UNIT_DYNAMIC_FLAGS] & ~(UNIT_DYNFLAG_TAPPED | UNIT_DYNFLAG_TAPPED_BY_PLAYER); - - if (creature) - { - if (creature->hasLootRecipient()) - { - dynamicFlags |= UNIT_DYNFLAG_TAPPED; - if (creature->isTappedBy(target)) - dynamicFlags |= UNIT_DYNFLAG_TAPPED_BY_PLAYER; - } - - if (!target->isAllowedToLoot(creature)) - dynamicFlags &= ~UNIT_DYNFLAG_LOOTABLE; - } - - // unit UNIT_DYNFLAG_TRACK_UNIT should only be sent to caster of SPELL_AURA_MOD_STALKED auras - if (dynamicFlags & UNIT_DYNFLAG_TRACK_UNIT) - if (!HasAuraTypeWithCaster(SPELL_AURA_MOD_STALKED, target->GetGUID())) - dynamicFlags &= ~UNIT_DYNFLAG_TRACK_UNIT; - fieldBuffer << dynamicFlags; } - // FG: pretend that OTHER players in own group are friendly ("blue") - else if (index == UNIT_FIELD_BYTES_2 || index == UNIT_FIELD_FACTIONTEMPLATE) + else if (index == UNIT_FIELD_BYTES_2) { - if (IsControlledByPlayer() && target != this && sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP) && IsInRaidWith(target)) - { - FactionTemplateEntry const* ft1 = GetFactionTemplateEntry(); - FactionTemplateEntry const* ft2 = target->GetFactionTemplateEntry(); - if (ft1 && ft2 && !ft1->IsFriendlyTo(*ft2)) - { - if (index == UNIT_FIELD_BYTES_2) - // Allow targetting opposite faction in party when enabled in config - fieldBuffer << (m_uint32Values[UNIT_FIELD_BYTES_2] & ((UNIT_BYTE2_FLAG_SANCTUARY /*| UNIT_BYTE2_FLAG_AURAS | UNIT_BYTE2_FLAG_UNK5*/) << 8)); // this flag is at uint8 offset 1 !! - else - // pretend that all other HOSTILE players have own faction, to allow follow, heal, rezz (trade wont work) - fieldBuffer << uint32(target->GetFaction()); - } - else - fieldBuffer << m_uint32Values[index]; - }// pussywizard / Callmephil - else if (target->IsSpectator() && target->FindMap() && target->FindMap()->IsBattleArena() && - (this->GetTypeId() == TYPEID_PLAYER || this->GetTypeId() == TYPEID_UNIT || this->GetTypeId() == TYPEID_DYNAMICOBJECT)) - { - if (index == UNIT_FIELD_BYTES_2) - fieldBuffer << (m_uint32Values[index] & 0xFFFFF2FF); // clear UNIT_BYTE2_FLAG_PVP, UNIT_BYTE2_FLAG_FFA_PVP, UNIT_BYTE2_FLAG_SANCTUARY - else - fieldBuffer << (uint32)target->GetFaction(); - } - else - if (!sScriptMgr->IsCustomBuildValuesUpdate(this, updateType, fieldBuffer, target, index)) - { - fieldBuffer << m_uint32Values[index]; - } + cacheValue.posPointers.UnitFieldBytes2Pos = int32(fieldBuffer.wpos()); + fieldBuffer << m_uint32Values[index]; + } + else if (index == UNIT_FIELD_FACTIONTEMPLATE) + { + cacheValue.posPointers.UnitFieldFactionTemplatePos = int32(fieldBuffer.wpos()); + fieldBuffer << m_uint32Values[index]; } else { - if (sScriptMgr->OnBuildValuesUpdate(this, updateType, fieldBuffer, target, index)) - { - continue; - } + if (sScriptMgr->ShouldTrackValuesUpdatePosByIndex(this, updateType, index)) + cacheValue.posPointers.other[index] = static_cast(fieldBuffer.wpos()); // send in current format (float as float, uint32 as uint32) fieldBuffer << m_uint32Values[index]; @@ -21238,9 +21154,167 @@ void Unit::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* target) } } - *data << uint8(updateMask.GetBlockCount()); - updateMask.AppendToPacket(data); - data->append(fieldBuffer); + cacheValue.buffer << uint8(updateMask.GetBlockCount()); + updateMask.AppendToPacket(&cacheValue.buffer); + int32 fieldBufferPos = static_cast(cacheValue.buffer.wpos()); + cacheValue.buffer.append(fieldBuffer); + cacheValue.posPointers.ApplyOffset(fieldBufferPos); + + int32 cachePos = static_cast(data->wpos()); + data->append(cacheValue.buffer); + + BuildValuesCachePosPointers dataAdjustedPos = cacheValue.posPointers; + if (cachePos) + dataAdjustedPos.ApplyOffset(cachePos); + + PatchValuesUpdate(*data, dataAdjustedPos, target); + + _valuesUpdateCache.insert(std::pair(cacheKey, std::move(cacheValue))); +} + +void Unit::PatchValuesUpdate(ByteBuffer& valuesUpdateBuf, BuildValuesCachePosPointers& posPointers, Player* target) +{ + Creature const* creature = ToCreature(); + + // UNIT_NPC_FLAGS + if (creature && posPointers.UnitNPCFlagsPos >= 0) + { + uint32 appendValue = m_uint32Values[UNIT_NPC_FLAGS]; + + if (sWorld->getIntConfig(CONFIG_INSTANT_TAXI) == 2 && appendValue & UNIT_NPC_FLAG_FLIGHTMASTER) + appendValue |= UNIT_NPC_FLAG_GOSSIP; // flight masters need NPC gossip flag to show instant flight toggle option + + if (!target->CanSeeSpellClickOn(creature)) + appendValue &= ~UNIT_NPC_FLAG_SPELLCLICK; + + if (!target->CanSeeVendor(creature)) + appendValue &= ~UNIT_NPC_FLAG_VENDOR_MASK; + + if (!creature->IsValidTrainerForPlayer(target, &appendValue)) + appendValue &= ~UNIT_NPC_FLAG_TRAINER; + + valuesUpdateBuf.put(posPointers.UnitNPCFlagsPos, appendValue); + } + + // UNIT_FIELD_AURASTATE + if (posPointers.UnitFieldAuraStatePos >= 0) + valuesUpdateBuf.put(posPointers.UnitFieldAuraStatePos, uint32(BuildAuraStateUpdateForTarget(target))); + + // UNIT_FIELD_FLAGS + if (posPointers.UnitFieldFlagsPos >= 0) + { + uint32 appendValue = m_uint32Values[UNIT_FIELD_FLAGS]; + if (target->IsGameMaster() && target->GetSession()->IsGMAccount()) + appendValue &= ~UNIT_FLAG_NOT_SELECTABLE; + + valuesUpdateBuf.put(posPointers.UnitFieldFlagsPos, appendValue); + } + + // UNIT_FIELD_DISPLAYID + // Use modelid_a if not gm, _h if gm for CREATURE_FLAG_EXTRA_TRIGGER creatures. + if (posPointers.UnitFieldDisplayPos >= 0) + { + uint32 displayId = m_uint32Values[UNIT_FIELD_DISPLAYID]; + if (creature) + { + CreatureTemplate const* cinfo = creature->GetCreatureTemplate(); + + // this also applies for transform auras + if (SpellInfo const* transform = sSpellMgr->GetSpellInfo(getTransForm())) + for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + if (transform->Effects[i].IsAura(SPELL_AURA_TRANSFORM)) + if (CreatureTemplate const* transformInfo = sObjectMgr->GetCreatureTemplate(transform->Effects[i].MiscValue)) + { + cinfo = transformInfo; + break; + } + + if (cinfo->flags_extra & CREATURE_FLAG_EXTRA_TRIGGER) + { + if (target->IsGameMaster() && target->GetSession()->IsGMAccount()) + { + if (cinfo->Modelid1) + displayId = cinfo->Modelid1; // Modelid1 is a visible model for gms + else + displayId = 17519; // world visible trigger's model + } + else + { + if (cinfo->Modelid2) + displayId = cinfo->Modelid2; // Modelid2 is an invisible model for players + else + displayId = 11686; // world invisible trigger's model + } + } + } + + valuesUpdateBuf.put(posPointers.UnitFieldDisplayPos, uint32(displayId)); + } + + // UNIT_DYNAMIC_FLAGS + // Hide lootable animation for unallowed players. + if (posPointers.UnitDynamicFlagsPos >= 0) + { + uint32 dynamicFlags = m_uint32Values[UNIT_DYNAMIC_FLAGS] & ~(UNIT_DYNFLAG_TAPPED | UNIT_DYNFLAG_TAPPED_BY_PLAYER); + + if (creature) + { + if (creature->hasLootRecipient()) + { + dynamicFlags |= UNIT_DYNFLAG_TAPPED; + if (creature->isTappedBy(target)) + dynamicFlags |= UNIT_DYNFLAG_TAPPED_BY_PLAYER; + } + + if (!target->isAllowedToLoot(creature)) + dynamicFlags &= ~UNIT_DYNFLAG_LOOTABLE; + } + + // unit UNIT_DYNFLAG_TRACK_UNIT should only be sent to caster of SPELL_AURA_MOD_STALKED auras + if (dynamicFlags & UNIT_DYNFLAG_TRACK_UNIT) + if (!HasAuraTypeWithCaster(SPELL_AURA_MOD_STALKED, target->GetGUID())) + dynamicFlags &= ~UNIT_DYNFLAG_TRACK_UNIT; + + valuesUpdateBuf.put(posPointers.UnitDynamicFlagsPos, dynamicFlags); + } + + // UNIT_FIELD_BYTES_2 + if (posPointers.UnitFieldBytes2Pos >= 0) + { + if (IsControlledByPlayer() && target != this && sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP) && IsInRaidWith(target)) + { + FactionTemplateEntry const* ft1 = GetFactionTemplateEntry(); + FactionTemplateEntry const* ft2 = target->GetFactionTemplateEntry(); + if (ft1 && ft2 && !ft1->IsFriendlyTo(*ft2)) + // Allow targetting opposite faction in party when enabled in config + valuesUpdateBuf.put(posPointers.UnitFieldBytes2Pos, (m_uint32Values[UNIT_FIELD_BYTES_2] & ((UNIT_BYTE2_FLAG_SANCTUARY /*| UNIT_BYTE2_FLAG_AURAS | UNIT_BYTE2_FLAG_UNK5*/) << 8))); // this flag is at uint8 offset 1 !! + }// pussywizard / Callmephil + else if (target->IsSpectator() && target->FindMap() && target->FindMap()->IsBattleArena() && + (this->GetTypeId() == TYPEID_PLAYER || this->GetTypeId() == TYPEID_UNIT || this->GetTypeId() == TYPEID_DYNAMICOBJECT)) + { + valuesUpdateBuf.put(posPointers.UnitFieldBytes2Pos, (m_uint32Values[UNIT_FIELD_BYTES_2] & 0xFFFFF2FF)); // clear UNIT_BYTE2_FLAG_PVP, UNIT_BYTE2_FLAG_FFA_PVP, UNIT_BYTE2_FLAG_SANCTUARY + } + } + + // UNIT_FIELD_FACTIONTEMPLATE + if (posPointers.UnitFieldFactionTemplatePos >= 0) + { + if (IsControlledByPlayer() && target != this && sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP) && IsInRaidWith(target)) + { + FactionTemplateEntry const* ft1 = GetFactionTemplateEntry(); + FactionTemplateEntry const* ft2 = target->GetFactionTemplateEntry(); + if (ft1 && ft2 && !ft1->IsFriendlyTo(*ft2)) + // pretend that all other HOSTILE players have own faction, to allow follow, heal, rezz (trade wont work) + valuesUpdateBuf.put(posPointers.UnitFieldFactionTemplatePos, uint32(target->GetFaction())); + }// pussywizard / Callmephil + else if (target->IsSpectator() && target->FindMap() && target->FindMap()->IsBattleArena() && + (this->GetTypeId() == TYPEID_PLAYER || this->GetTypeId() == TYPEID_UNIT || this->GetTypeId() == TYPEID_DYNAMICOBJECT)) + { + valuesUpdateBuf.put(posPointers.UnitFieldFactionTemplatePos, uint32(target->GetFaction())); + } + } + + sScriptMgr->OnPatchValuesUpdate(this, valuesUpdateBuf, posPointers, target); } void Unit::BuildCooldownPacket(WorldPacket& data, uint8 flags, uint32 spellId, uint32 cooldown) diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index b4e5cc699..3fb0e55ab 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -1321,6 +1321,62 @@ private: Unit* defaultValue; }; +// BuildValuesCachePosPointers is marks of the position of some data inside of BuildValue cache. +struct BuildValuesCachePosPointers +{ + BuildValuesCachePosPointers() : + UnitNPCFlagsPos(-1), UnitFieldAuraStatePos(-1), UnitFieldFlagsPos(-1), UnitFieldDisplayPos(-1), + UnitDynamicFlagsPos(-1), UnitFieldBytes2Pos(-1), UnitFieldFactionTemplatePos(-1) {} + + void ApplyOffset(uint32 offset) + { + if (UnitNPCFlagsPos >= 0) + UnitNPCFlagsPos += offset; + + if (UnitFieldAuraStatePos >= 0) + UnitFieldAuraStatePos += offset; + + if (UnitFieldFlagsPos >= 0) + UnitFieldFlagsPos += offset; + + if (UnitFieldDisplayPos >= 0) + UnitFieldDisplayPos += offset; + + if (UnitDynamicFlagsPos >= 0) + UnitDynamicFlagsPos += offset; + + if (UnitFieldBytes2Pos >= 0) + UnitFieldBytes2Pos += offset; + + if (UnitFieldFactionTemplatePos >= 0) + UnitFieldFactionTemplatePos += offset; + + for (auto it = other.begin(); it != other.end(); ++it) + it->second += offset; + } + + int32 UnitNPCFlagsPos; + int32 UnitFieldAuraStatePos; + int32 UnitFieldFlagsPos; + int32 UnitFieldDisplayPos; + int32 UnitDynamicFlagsPos; + int32 UnitFieldBytes2Pos; + int32 UnitFieldFactionTemplatePos; + + std::unordered_map other; +}; + +// BuildValuesCachedBuffer cache for calculated BuildValue. +struct BuildValuesCachedBuffer +{ + BuildValuesCachedBuffer(uint32 bufferSize) : + buffer(bufferSize), posPointers() {} + + ByteBuffer buffer; + + BuildValuesCachePosPointers posPointers; +}; + class Unit : public WorldObject { public: @@ -2505,7 +2561,7 @@ public: protected: explicit Unit (bool isWorldObject); - void BuildValuesUpdate(uint8 updatetype, ByteBuffer* data, Player* target) const override; + void BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* target) override; UnitAI* i_AI, *i_disabledAI; @@ -2598,6 +2654,9 @@ private: [[nodiscard]] float GetCombatRatingReduction(CombatRating cr) const; [[nodiscard]] uint32 GetCombatRatingDamageReduction(CombatRating cr, float rate, float cap, uint32 damage) const; + void PatchValuesUpdate(ByteBuffer& valuesUpdateBuf, BuildValuesCachePosPointers& posPointers, Player* target); + void InvalidateValuesUpdateCache() { _valuesUpdateCache.clear(); } + protected: void SetFeared(bool apply, Unit* fearedBy = nullptr, bool isFear = false); void SetConfused(bool apply); @@ -2635,6 +2694,9 @@ private: uint32 _lastExtraAttackSpell; std::unordered_map extraAttacksTargets; ObjectGuid _lastDamagedTargetGuid; + + typedef std::unordered_map ValuesUpdateCache; + ValuesUpdateCache _valuesUpdateCache; }; namespace Acore diff --git a/src/server/game/Scripting/ScriptDefines/UnitScript.cpp b/src/server/game/Scripting/ScriptDefines/UnitScript.cpp index eb070a6cf..f493b5166 100644 --- a/src/server/game/Scripting/ScriptDefines/UnitScript.cpp +++ b/src/server/game/Scripting/ScriptDefines/UnitScript.cpp @@ -192,18 +192,24 @@ bool ScriptMgr::IsCustomBuildValuesUpdate(Unit const* unit, uint8 updateType, By return false; } -bool ScriptMgr::OnBuildValuesUpdate(Unit const* unit, uint8 updateType, ByteBuffer& fieldBuffer, Player* target, uint16 index) +bool ScriptMgr::ShouldTrackValuesUpdatePosByIndex(Unit const* unit, uint8 updateType, uint16 index) { - auto ret = IsValidBoolScript([&](UnitScript* script) { return script->OnBuildValuesUpdate(unit, updateType, fieldBuffer, target, index); }); + auto ret = IsValidBoolScript([&](UnitScript* script) { return script->ShouldTrackValuesUpdatePosByIndex(unit, updateType, index); }); if (ret && *ret) - { return true; - } return false; } +void ScriptMgr::OnPatchValuesUpdate(Unit const* unit, ByteBuffer& valuesUpdateBuf, BuildValuesCachePosPointers& posPointers, Player* target) +{ + ExecuteScript([&](UnitScript* script) + { + script->OnPatchValuesUpdate(unit, valuesUpdateBuf, posPointers, target); + }); +} + void ScriptMgr::OnUnitUpdate(Unit* unit, uint32 diff) { ExecuteScript([&](UnitScript* script) diff --git a/src/server/game/Scripting/ScriptDefines/UnitScript.h b/src/server/game/Scripting/ScriptDefines/UnitScript.h index 3b44ca03d..f0341909c 100644 --- a/src/server/game/Scripting/ScriptDefines/UnitScript.h +++ b/src/server/game/Scripting/ScriptDefines/UnitScript.h @@ -22,6 +22,7 @@ enum ReputationRank : uint8; class ByteBuffer; +struct BuildValuesCachePosPointers; class UnitScript : public ScriptObject { @@ -69,7 +70,9 @@ public: [[nodiscard]] virtual bool IsCustomBuildValuesUpdate(Unit const* /*unit*/, uint8 /*updateType*/, ByteBuffer& /*fieldBuffer*/, Player const* /*target*/, uint16 /*index*/) { return false; } - [[nodiscard]] virtual bool OnBuildValuesUpdate(Unit const* /*unit*/, uint8 /*updateType*/, ByteBuffer& /*fieldBuffer*/, Player* /*target*/, uint16 /*index*/) { return false; } + [[nodiscard]] virtual bool ShouldTrackValuesUpdatePosByIndex(Unit const* /*unit*/, uint8 /*updateType*/, uint16 /*index*/) { return false; } + + virtual void OnPatchValuesUpdate(Unit const* /*unit*/, ByteBuffer& /*valuesUpdateBuf*/, BuildValuesCachePosPointers& /*posPointers*/, Player* /*target*/) { } /** * @brief This hook runs in Unit::Update diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h index 0bb977fb9..a2f1cf5f5 100644 --- a/src/server/game/Scripting/ScriptMgr.h +++ b/src/server/game/Scripting/ScriptMgr.h @@ -548,7 +548,8 @@ public: /* UnitScript */ bool IsNeedModHealPercent(Unit const* unit, AuraEffect* auraEff, float& doneTotalMod, SpellInfo const* spellProto); bool CanSetPhaseMask(Unit const* unit, uint32 newPhaseMask, bool update); bool IsCustomBuildValuesUpdate(Unit const* unit, uint8 updateType, ByteBuffer& fieldBuffer, Player const* target, uint16 index); - bool OnBuildValuesUpdate(Unit const* unit, uint8 updateType, ByteBuffer& fieldBuffer, Player* target, uint16 index); + bool ShouldTrackValuesUpdatePosByIndex(Unit const* unit, uint8 updateType, uint16 index); + void OnPatchValuesUpdate(Unit const* unit, ByteBuffer& valuesUpdateBuf, BuildValuesCachePosPointers& posPointers, Player* target); void OnUnitUpdate(Unit* unit, uint32 diff); void OnDisplayIdChange(Unit* unit, uint32 displayId); void OnUnitEnterEvadeMode(Unit* unit, uint8 why); From f7f1952f4b6c894e01fc275cdc6a0254936f71d0 Mon Sep 17 00:00:00 2001 From: Anton Popovichenko Date: Fri, 5 Apr 2024 12:04:55 +0200 Subject: [PATCH 24/30] fix(Core/Player): Fix memory leak. (#18671) --- src/server/game/Entities/Player/Player.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index bde2d0a92..10140ff94 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -444,6 +444,7 @@ Player::~Player() delete m_runes; delete m_achievementMgr; delete m_reputationMgr; + delete _cinematicMgr; sWorld->DecreasePlayerCount(); From 90cef46e6c243f5fffbebe4d15612905acbc5ed5 Mon Sep 17 00:00:00 2001 From: Mike Delago <32778141+michaeldelago@users.noreply.github.com> Date: Fri, 5 Apr 2024 11:38:11 -0400 Subject: [PATCH 25/30] fix(CI): Don't cache pch builds (#18674) --- .github/actions/linux-build/action.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/actions/linux-build/action.yml b/.github/actions/linux-build/action.yml index 3a8fefd77..9a7ca0612 100644 --- a/.github/actions/linux-build/action.yml +++ b/.github/actions/linux-build/action.yml @@ -26,6 +26,7 @@ runs: steps: - name: Cache uses: actions/cache@v3 + if: inputs.pch != 'true' with: path: ${{ github.workspace }}/var/ccache # format @@ -102,7 +103,7 @@ runs: -DBUILD_TESTING="ON" \ -DUSE_SCRIPTPCH=${{ inputs.pch == 'true' && 'ON' || '' }} \ -DUSE_COREPCH=${{ inputs.pch == 'true' && 'ON' || '' }} \ - ${{ !inputs.pch && '-DNOPCH=true' || '' }} + ${{ inputs.pch == 'true' && '' || '-DNOPCH=true' }} - name: build shell: bash From 21e0803508fa7136c55b4bbedffbc6310b603164 Mon Sep 17 00:00:00 2001 From: Walter Pagani Date: Fri, 5 Apr 2024 12:54:40 -0300 Subject: [PATCH 26/30] fix(Script/BlackTemple): Add override in EnterEvadeMode (#18673) fix(Script/illidari_council.cpp). Add override to the method EnterEvadeMode --- src/server/scripts/Outland/BlackTemple/illidari_council.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/server/scripts/Outland/BlackTemple/illidari_council.cpp b/src/server/scripts/Outland/BlackTemple/illidari_council.cpp index 0fee4ec3b..44d4cae96 100644 --- a/src/server/scripts/Outland/BlackTemple/illidari_council.cpp +++ b/src/server/scripts/Outland/BlackTemple/illidari_council.cpp @@ -148,11 +148,9 @@ public: struct boss_illidari_councilAI : public BossAI { - boss_illidari_councilAI(Creature* creature) : BossAI(creature, DATA_ILLIDARI_COUNCIL) - { - } + boss_illidari_councilAI(Creature* creature) : BossAI(creature, DATA_ILLIDARI_COUNCIL) { } - void EnterEvadeMode(EvadeReason why) + void EnterEvadeMode(EvadeReason why) override { for (uint8 i = DATA_GATHIOS_THE_SHATTERER; i <= DATA_VERAS_DARKSHADOW; ++i) if (Creature* member = instance->GetCreature(i)) From 146f5a64ad8685876dcf11dd9c894145207bec45 Mon Sep 17 00:00:00 2001 From: BAUXA <77631148+bauxa@users.noreply.github.com> Date: Sat, 6 Apr 2024 14:16:54 +0200 Subject: [PATCH 27/30] fix(Scripts/Commands): "go xyz" command crash (#18676) go xyz fix crash --- src/server/scripts/Commands/cs_go.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/scripts/Commands/cs_go.cpp b/src/server/scripts/Commands/cs_go.cpp index 6780b042c..4169428fe 100644 --- a/src/server/scripts/Commands/cs_go.cpp +++ b/src/server/scripts/Commands/cs_go.cpp @@ -352,7 +352,7 @@ public: float x = locationValues[0]; float y = locationValues[1]; - if (!sMapStore.LookupEntry(mapId)) + if (!sMapStore.LookupEntry(mapId) || !MapMgr::IsValidMapCoord(mapId, x, y)) { handler->SendErrorMessage(LANG_INVALID_TARGET_COORD, x, y, mapId); return false; From c80ad3d779da28f8d324e4d5e519d4fff6084835 Mon Sep 17 00:00:00 2001 From: Johaine <32821455+Johaine@users.noreply.github.com> Date: Sat, 6 Apr 2024 14:19:14 +0200 Subject: [PATCH 28/30] fix(Scripts/TempleOfAhnQiraj): Fix Vem enrage (#18652) Fix Vem enrage Vem should enrage when it is the last bug alive (Regression from last refactor) --- .../scripts/Kalimdor/TempleOfAhnQiraj/boss_bug_trio.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_bug_trio.cpp b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_bug_trio.cpp index 323d4af42..d4b5e39ec 100644 --- a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_bug_trio.cpp +++ b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_bug_trio.cpp @@ -390,6 +390,14 @@ struct boss_vem : public boss_bug_trio { DoCastVictim(SPELL_KNOCKDOWN); context.Repeat(); + }) + .Schedule(1s, [this](TaskContext context) + { + if (instance->GetData(DATA_BUG_TRIO_DEATH) == 2 && !me->HasAura(SPELL_VENGEANCE)) // Vem is the only one left. + { + DoCastSelf(SPELL_VENGEANCE, true); + } + context.Repeat(1s); }); } }; From 3a93ae1af1158f552838375f454c9dff6d3bc95b Mon Sep 17 00:00:00 2001 From: Johaine <32821455+Johaine@users.noreply.github.com> Date: Sat, 6 Apr 2024 15:22:32 +0200 Subject: [PATCH 29/30] feat(Core/Optimization): Correctly document sendBuffer size and optimize it. (#18647) * Fix comment documenting WorldSocket The buffer is constructed with 4096 bytes but later resized in WorldSocketThread::SocketAdded() according to the configuration setting Network.OutUBuff (currently 65536 bytes) * Reuse calculated packet size Instead of recalculating the current packet size three times at worst, calculate it once and reuse it when required. * Reduce reserved buffer size per WorldSocket Don't reserve 64kB of memory for every WorldSocket's output buffer. Instead, start with a 4kB baseline for every WorldSocket and grow the buffer size dynamically when we have single packets that do not fit the current buffer. --- .../apps/worldserver/worldserver.conf.dist | 8 +++---- src/server/game/Server/WorldSocket.cpp | 23 ++++++++++++------- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/src/server/apps/worldserver/worldserver.conf.dist b/src/server/apps/worldserver/worldserver.conf.dist index 05ffeb6fd..34a734331 100644 --- a/src/server/apps/worldserver/worldserver.conf.dist +++ b/src/server/apps/worldserver/worldserver.conf.dist @@ -364,11 +364,11 @@ Network.OutKBuff = -1 # # Network.OutUBuff -# Description: Amount of memory (in bytes) reserved in the user space per connection for -# output buffering. -# Default: 65536 +# Description: Amount of memory (in bytes) reserved initially in the user space per +# connection for output buffering. +# Default: 4096 -Network.OutUBuff = 65536 +Network.OutUBuff = 4096 # # Network.TcpNoDelay: diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp index 2b44a26ee..a2e8e5dcd 100644 --- a/src/server/game/Server/WorldSocket.cpp +++ b/src/server/game/Server/WorldSocket.cpp @@ -165,6 +165,7 @@ bool WorldSocket::Update() { // Allocate buffer only when it's needed but not on every Update() call. MessageBuffer buffer(_sendBufferSize); + std::size_t currentPacketSize; do { queued->CompressIfNeeded(); @@ -172,26 +173,32 @@ bool WorldSocket::Update() if (queued->NeedsEncryption()) _authCrypt.EncryptSend(header.header, header.getHeaderLength()); - if (buffer.GetRemainingSpace() < queued->size() + header.getHeaderLength()) + currentPacketSize = queued->size() + header.getHeaderLength(); + + if (buffer.GetRemainingSpace() < currentPacketSize) { QueuePacket(std::move(buffer)); buffer.Resize(_sendBufferSize); } - if (buffer.GetRemainingSpace() >= queued->size() + header.getHeaderLength()) + if (buffer.GetRemainingSpace() >= currentPacketSize) { buffer.Write(header.header, header.getHeaderLength()); if (!queued->empty()) buffer.Write(queued->contents(), queued->size()); } - else // single packet larger than 4096 bytes + else // Single packet larger than current buffer size { - MessageBuffer packetBuffer(queued->size() + header.getHeaderLength()); - packetBuffer.Write(header.header, header.getHeaderLength()); - if (!queued->empty()) - packetBuffer.Write(queued->contents(), queued->size()); + // Resize buffer to fit current packet + buffer.Resize(currentPacketSize); - QueuePacket(std::move(packetBuffer)); + // Grow future buffers to current packet size if still below limit + if (currentPacketSize <= 65536) + _sendBufferSize = currentPacketSize; + + buffer.Write(header.header, header.getHeaderLength()); + if (!queued->empty()) + buffer.Write(queued->contents(), queued->size()); } delete queued; From 8ef8ddad24b8d85c66549692143a8110caa8eae0 Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Sat, 6 Apr 2024 14:14:55 -0300 Subject: [PATCH 30/30] =?UTF-8?q?fix(Scripts/TheEye):=20Fix=20Alar=20not?= =?UTF-8?q?=20using=20abilities=20if=20no=20target=20is=20in=20=E2=80=A6?= =?UTF-8?q?=20(#18678)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix(Scripts/TheEye): Fix Alar not using abilities if no target is in range --- .../Outland/TempestKeep/Eye/boss_alar.cpp | 41 +++++++++++++++---- 1 file changed, 32 insertions(+), 9 deletions(-) diff --git a/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp b/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp index 21594b256..198abc879 100644 --- a/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp +++ b/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp @@ -102,15 +102,6 @@ struct boss_alar : public BossAI }); } - void JustReachedHome() override - { - BossAI::JustReachedHome(); - if (me->IsEngaged()) - { - ConstructWaypointsAndMove(); - } - } - void Reset() override { BossAI::Reset(); @@ -129,6 +120,15 @@ struct boss_alar : public BossAI ConstructWaypointsAndMove(); } + void JustReachedHome() override + { + BossAI::JustReachedHome(); + if (me->IsEngaged()) + { + ConstructWaypointsAndMove(); + } + } + void JustEngagedWith(Unit* who) override { BossAI::JustEngagedWith(who); @@ -158,6 +158,29 @@ struct boss_alar : public BossAI ScheduleMainSpellAttack(0s); } + bool CanAIAttack(Unit const* victim) const override + { + if (me->isMoving()) + return true; + + return me->IsWithinMeleeRange(victim); + } + + void EnterEvadeMode(EvadeReason why) override + { + if (why == EVADE_REASON_BOUNDARY) + { + BossAI::EnterEvadeMode(why); + } + else + { + if (me->GetThreatMgr().GetThreatList().empty()) + { + BossAI::EnterEvadeMode(why); + } + } + } + void JustDied(Unit* killer) override { BossAI::JustDied(killer);