From 60be029e4c85079218082d21a7bee655cb9fe89a Mon Sep 17 00:00:00 2001 From: sudlud Date: Wed, 3 Jul 2024 19:54:45 +0200 Subject: [PATCH 01/68] fix(Core/Scripting): fix OnBeforeCreateInstanceScript hook (#19252) - to me this hook should obviously provide an option to overwrite the InstanceScript pointer - this is e.g. beeing used by mod-eluna (but currently broken) --- src/server/game/Maps/Map.cpp | 2 +- src/server/game/Scripting/ScriptDefines/AllMapScript.cpp | 2 +- src/server/game/Scripting/ScriptDefines/AllMapScript.h | 2 +- src/server/game/Scripting/ScriptMgr.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index b2cdbddaf..4900bd377 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -3063,7 +3063,7 @@ void InstanceMap::CreateInstanceScript(bool load, std::string data, uint32 compl bool isOtherAI = false; - sScriptMgr->OnBeforeCreateInstanceScript(this, instance_data, load, data, completedEncounterMask); + sScriptMgr->OnBeforeCreateInstanceScript(this, &instance_data, load, data, completedEncounterMask); if (instance_data) isOtherAI = true; diff --git a/src/server/game/Scripting/ScriptDefines/AllMapScript.cpp b/src/server/game/Scripting/ScriptDefines/AllMapScript.cpp index e35700a12..c778b8fff 100644 --- a/src/server/game/Scripting/ScriptDefines/AllMapScript.cpp +++ b/src/server/game/Scripting/ScriptDefines/AllMapScript.cpp @@ -279,7 +279,7 @@ void ScriptMgr::OnMapUpdate(Map* map, uint32 diff) }); } -void ScriptMgr::OnBeforeCreateInstanceScript(InstanceMap* instanceMap, InstanceScript* instanceData, bool load, std::string data, uint32 completedEncounterMask) +void ScriptMgr::OnBeforeCreateInstanceScript(InstanceMap* instanceMap, InstanceScript** instanceData, bool load, std::string data, uint32 completedEncounterMask) { ExecuteScript([&](AllMapScript* script) { diff --git a/src/server/game/Scripting/ScriptDefines/AllMapScript.h b/src/server/game/Scripting/ScriptDefines/AllMapScript.h index f97198866..77479fc1b 100644 --- a/src/server/game/Scripting/ScriptDefines/AllMapScript.h +++ b/src/server/game/Scripting/ScriptDefines/AllMapScript.h @@ -51,7 +51,7 @@ public: * @param data Contains information about the instance save data * @param completedEncounterMask Contains information about the completed encouter mask */ - virtual void OnBeforeCreateInstanceScript(InstanceMap* /*instanceMap*/, InstanceScript* /*instanceData*/, bool /*load*/, std::string /*data*/, uint32 /*completedEncounterMask*/) { } + virtual void OnBeforeCreateInstanceScript(InstanceMap* /*instanceMap*/, InstanceScript** /*instanceData*/, bool /*load*/, std::string /*data*/, uint32 /*completedEncounterMask*/) { } /** * @brief This hook called before destroy instance diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h index b767487a2..15fb7d4fa 100644 --- a/src/server/game/Scripting/ScriptMgr.h +++ b/src/server/game/Scripting/ScriptMgr.h @@ -572,7 +572,7 @@ public: /* AllGameobjectScript */ void OnGameObjectSaveToDB(GameObject* go); public: /* AllMapScript */ - void OnBeforeCreateInstanceScript(InstanceMap* instanceMap, InstanceScript* instanceData, bool load, std::string data, uint32 completedEncounterMask); + void OnBeforeCreateInstanceScript(InstanceMap* instanceMap, InstanceScript** instanceData, bool load, std::string data, uint32 completedEncounterMask); void OnDestroyInstance(MapInstanced* mapInstanced, Map* map); public: /* BGScript */ From fa8680746ea2e314313919c645cc4b616e26374a Mon Sep 17 00:00:00 2001 From: thomasjteachey <81936627+thomasjteachey@users.noreply.github.com> Date: Thu, 4 Jul 2024 07:42:36 -0400 Subject: [PATCH 02/68] =?UTF-8?q?fix(Core/Arena):=20Check=20to=20see=20if?= =?UTF-8?q?=20other=20members=20in=20your=20arena=20team=20are=20queued=20?= =?UTF-8?q?or=20in=20a=20r=E2=80=A6=20(#18808)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Check to see if other members in your arena team are queued or in a rated arena already and, if so, do not allow queue to go through * Accidentally put team party check inside the for loop * some basic logic efficiency changes * minor syntax issue --- src/server/game/Groups/Group.cpp | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp index 8db5f3740..630856b7a 100644 --- a/src/server/game/Groups/Group.cpp +++ b/src/server/game/Groups/Group.cpp @@ -41,6 +41,8 @@ #include "World.h" #include "WorldPacket.h" #include "WorldSession.h" +#include "ArenaTeam.h" +#include "ArenaTeamMgr.h" Roll::Roll(ObjectGuid _guid, LootItem const& li) : itemGUID(_guid), itemid(li.itemid), itemRandomPropId(li.randomPropertyId), itemRandomSuffix(li.randomSuffix), itemCount(li.count), @@ -1996,6 +1998,35 @@ GroupJoinBattlegroundResult Group::CanJoinBattlegroundQueue(Battleground const* if (bgTemplate->isArena() && memberscount != MinPlayerCount) return ERR_ARENA_TEAM_PARTY_SIZE; + //check against other arena team members + if (isRated) + { + ArenaTeam* arenaTeam = sArenaTeamMgr->GetArenaTeamById(arenaTeamId); + for (auto const& itr : arenaTeam->GetMembers()) + { + Player* teamMember = ObjectAccessor::FindConnectedPlayer(itr.Guid); + //are they online and not a member of this current group? + if (teamMember && !IsMember(teamMember->GetGUID())) + { + //are they already in queue for a rated arena? + if (teamMember->InBattlegroundQueueForBattlegroundQueueType(bgQueueTypeId)) + { + GroupQueueInfo ginfo; + BattlegroundQueue& queue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId); + if (queue.GetPlayerGroupInfoData(teamMember->GetGUID(), &ginfo)) + { + if (ginfo.IsRated) + return ERR_BATTLEGROUND_JOIN_FAILED; + } + } + //are they currently in an arena match? + Battleground* bg = teamMember->GetBattleground(false); + if (bg && bg->isRated() && bg->GetMinPlayersPerTeam() == MinPlayerCount) + return ERR_BATTLEGROUND_JOIN_FAILED; + } + } + } + return GroupJoinBattlegroundResult(bgTemplate->GetBgTypeID()); } From e41080468f8c79199ce4aed5aa613886b8365e4a Mon Sep 17 00:00:00 2001 From: Benjamin Jackson <38561765+heyitsbench@users.noreply.github.com> Date: Thu, 4 Jul 2024 08:26:23 -0400 Subject: [PATCH 03/68] fix(Scripts/TheEye): Kael'thas adjustments. (#19213) * Init. * Update advisor phase timer. --- .../Outland/TempestKeep/Eye/boss_kaelthas.cpp | 24 ++----------------- 1 file changed, 2 insertions(+), 22 deletions(-) diff --git a/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp b/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp index b1f07c880..cce6acefd 100644 --- a/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp +++ b/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp @@ -392,34 +392,14 @@ struct boss_kaelthas : public BossAI } } }); - scheduler.Schedule(2min, GROUP_PROGRESS_PHASE, [this](TaskContext) + scheduler.Schedule(90s, GROUP_PROGRESS_PHASE, [this](TaskContext) { PhaseAllAdvisorsExecute(); }); }, EVENT_PREFIGHT_PHASE52); break; case ACTION_PROGRESS_PHASE_CHECK: - if (_phase == PHASE_WEAPONS) - { - bool aliveWeapon = false; - summons.DoForAllSummons([&aliveWeapon](WorldObject* summon) - { - if (Creature* summonedCreature = summon->ToCreature()) - { - if (summonedCreature->IsAlive()) - { - if (summonedCreature->GetEntry() >= NPC_NETHERSTRAND_LONGBOW && summonedCreature->GetEntry() <= NPC_STAFF_OF_DISINTEGRATION) - { - aliveWeapon = true; - return; - } - } - } - }); - if (!aliveWeapon) - PhaseAllAdvisorsExecute(); - } - else if (_phase == PHASE_ALL_ADVISORS) + if (_phase == PHASE_ALL_ADVISORS) { bool advisorAlive = false; summons.DoForAllSummons([&advisorAlive](WorldObject* summon) From d5ba5e0168401a698bd4eb398850ca9c1c9c274e Mon Sep 17 00:00:00 2001 From: Kitzunu <24550914+Kitzunu@users.noreply.github.com> Date: Thu, 4 Jul 2024 14:41:53 +0200 Subject: [PATCH 04/68] fix(Core/Quest): typo in RewardQuest makes LFG quests not reward if dead (#19271) fix(Core/Quest): typo in RewardQuest * Allow LFG quests to be rewarded even when dead --- src/server/game/Entities/Player/PlayerQuest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/game/Entities/Player/PlayerQuest.cpp b/src/server/game/Entities/Player/PlayerQuest.cpp index 13e08dab6..e5626dc5e 100644 --- a/src/server/game/Entities/Player/PlayerQuest.cpp +++ b/src/server/game/Entities/Player/PlayerQuest.cpp @@ -753,7 +753,7 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver, else { sScriptMgr->OnGivePlayerXP(this, XP, nullptr, isLFGReward ? PlayerXPSource::XPSOURCE_QUEST_DF : PlayerXPSource::XPSOURCE_QUEST); - GiveXP(XP, nullptr, isLFGReward); + GiveXP(XP, nullptr, 1.0f, isLFGReward); } // Give player extra money if GetRewOrReqMoney > 0 and get ReqMoney if negative From e66f4f99a7137fabd26d85767dc0feb2652d7686 Mon Sep 17 00:00:00 2001 From: Benjamin Jackson <38561765+heyitsbench@users.noreply.github.com> Date: Thu, 4 Jul 2024 09:41:14 -0400 Subject: [PATCH 05/68] fix(DB/Gameobject): Move Karazhan chess chest. (#19273) Init. --- data/sql/updates/pending_db_world/kara-chest-pos.sql | 1 + 1 file changed, 1 insertion(+) create mode 100644 data/sql/updates/pending_db_world/kara-chest-pos.sql diff --git a/data/sql/updates/pending_db_world/kara-chest-pos.sql b/data/sql/updates/pending_db_world/kara-chest-pos.sql new file mode 100644 index 000000000..58148d78c --- /dev/null +++ b/data/sql/updates/pending_db_world/kara-chest-pos.sql @@ -0,0 +1 @@ +UPDATE `gameobject` SET `position_x` = -11102.743, `position_y` = -1848.9752, `position_z` = 221.06969, `orientation` = 5.393069, `rotation2` = -0.43051052, `rotation3` = 0.90258557 WHERE `guid` = 56429 AND `id` = 185119; From 8180841163e43960b1ef6a741beb9e94c0ace27e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 4 Jul 2024 13:42:06 +0000 Subject: [PATCH 06/68] chore(DB): import pending files Referenced commit(s): e66f4f99a7137fabd26d85767dc0feb2652d7686 --- .../kara-chest-pos.sql => db_world/2024_07_04_00.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/kara-chest-pos.sql => db_world/2024_07_04_00.sql} (83%) diff --git a/data/sql/updates/pending_db_world/kara-chest-pos.sql b/data/sql/updates/db_world/2024_07_04_00.sql similarity index 83% rename from data/sql/updates/pending_db_world/kara-chest-pos.sql rename to data/sql/updates/db_world/2024_07_04_00.sql index 58148d78c..fd521f81e 100644 --- a/data/sql/updates/pending_db_world/kara-chest-pos.sql +++ b/data/sql/updates/db_world/2024_07_04_00.sql @@ -1 +1,2 @@ +-- DB update 2024_07_02_00 -> 2024_07_04_00 UPDATE `gameobject` SET `position_x` = -11102.743, `position_y` = -1848.9752, `position_z` = 221.06969, `orientation` = 5.393069, `rotation2` = -0.43051052, `rotation3` = 0.90258557 WHERE `guid` = 56429 AND `id` = 185119; From f84a4f14082ee6b53789b9ce9bc6c010c9c4ca1d Mon Sep 17 00:00:00 2001 From: avarishd <46330494+avarishd@users.noreply.github.com> Date: Thu, 4 Jul 2024 19:50:45 +0300 Subject: [PATCH 07/68] fix(Scripts/TK): Kael'thas mind control should reset threat (#19264) * fix(Scripts/TK): Kael'thas mind control should reset threat * lol * -2 lines Co-authored-by: Kitzunu <24550914+Kitzunu@users.noreply.github.com> --------- Co-authored-by: Kitzunu <24550914+Kitzunu@users.noreply.github.com> --- .../scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp b/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp index cce6acefd..62818e025 100644 --- a/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp +++ b/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp @@ -1143,9 +1143,19 @@ class spell_kaelthas_mind_control : public SpellScript targets.remove_if(Acore::ObjectTypeIdCheck(TYPEID_PLAYER, false)); } + void HandleEffect(SpellEffIndex /*effIndex*/) + { + if (!GetCaster() || !GetHitPlayer()) + return; + + if (Player* player = GetHitPlayer()) + GetCaster()->GetThreatMgr().ResetThreat(player); + } + void Register() override { OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_kaelthas_mind_control::SelectTarget, EFFECT_ALL, TARGET_UNIT_SRC_AREA_ENEMY); + OnEffectHitTarget += SpellEffectFn(spell_kaelthas_mind_control::HandleEffect, EFFECT_ALL, SPELL_AURA_ANY); } }; From cf1185551d2a9e70bfb01da7cde5a7eeb664d2bf Mon Sep 17 00:00:00 2001 From: Jelle Meeus Date: Thu, 4 Jul 2024 19:20:24 +0200 Subject: [PATCH 08/68] fix(Core/Pet): prevent LoadPetFromDB to trigger a fake summon spell cast in most cases (#19277) * add CategoryRecoveryTime check * add RecoveryTime check --- src/server/game/Entities/Pet/Pet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp index a998afa57..de53dfa7b 100644 --- a/src/server/game/Entities/Pet/Pet.cpp +++ b/src/server/game/Entities/Pet/Pet.cpp @@ -394,7 +394,7 @@ bool Pet::LoadPetFromDB(Player* owner, uint32 petEntry, uint32 petnumber, bool c // Send fake summon spell cast - this is needed for correct cooldown application for spells // Example: 46584 - without this cooldown (which should be set always when pet is loaded) isn't set clientside /// @todo pets should be summoned from real cast instead of just faking it? - if (petInfo->CreatedBySpellId) + if (petInfo->CreatedBySpellId && spellInfo && (spellInfo->CategoryRecoveryTime > 0 || spellInfo->RecoveryTime > 0)) { WorldPacket data(SMSG_SPELL_GO, (8 + 8 + 4 + 4 + 2)); data << owner->GetPackGUID(); From e878cedb7f20719f9911198d57e961270847ceff Mon Sep 17 00:00:00 2001 From: Kitzunu <24550914+Kitzunu@users.noreply.github.com> Date: Thu, 4 Jul 2024 19:20:41 +0200 Subject: [PATCH 09/68] =?UTF-8?q?feat(Core/SAI):=20implement=20new=20remov?= =?UTF-8?q?eObjectFromWorld=20param=20for=20SMART=5FA=E2=80=A6=20(#19275)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit feat(Core/SAI): implement new removeObjectFromWorld param for SMART_ACTION_FORCE_DESPAWN --- .../game/AI/SmartScripts/SmartScript.cpp | 33 +++++++++++-------- .../game/AI/SmartScripts/SmartScriptMgr.h | 1 + 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index cabedbe4a..f7f31fd40 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -1272,22 +1272,29 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u { for (WorldObject* target : targets) { - Milliseconds despawnDelay(e.action.forceDespawn.delay); + if (e.action.forceDespawn.removeObjectFromWorld) + { + if (e.action.forceDespawn.delay || e.action.forceDespawn.forceRespawnTimer) + LOG_ERROR("sql.sql", "SmartScript: SMART_ACTION_FORCE_DESPAWN has removeObjectFromWorld set. delay and forceRespawnTimer ignored."); - // Wait at least one world update tick before despawn, so it doesn't break linked actions. - if (despawnDelay <= 0ms) - { - despawnDelay = 1ms; + if (Creature* creature = target->ToCreature()) + creature->AddObjectToRemoveList(); + else if (GameObject* go = target->ToGameObject()) + go->AddObjectToRemoveList(); } + else + { + Milliseconds despawnDelay(e.action.forceDespawn.delay); - Seconds forceRespawnTimer(e.action.forceDespawn.forceRespawnTimer); - if (Creature* creature = target->ToCreature()) - { - creature->DespawnOrUnsummon(despawnDelay, forceRespawnTimer); - } - else if (GameObject* go = target->ToGameObject()) - { - go->DespawnOrUnsummon(despawnDelay, forceRespawnTimer); + // Wait at least one world update tick before despawn, so it doesn't break linked actions. + if (despawnDelay <= 0ms) + despawnDelay = 1ms; + + Seconds forceRespawnTimer(e.action.forceDespawn.forceRespawnTimer); + if (Creature* creature = target->ToCreature()) + creature->DespawnOrUnsummon(despawnDelay, forceRespawnTimer); + else if (GameObject* go = target->ToGameObject()) + go->DespawnOrUnsummon(despawnDelay, forceRespawnTimer); } } diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h index 66d0deaa9..554863690 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h @@ -978,6 +978,7 @@ struct SmartAction { uint32 delay; uint32 forceRespawnTimer; + SAIBool removeObjectFromWorld; } forceDespawn; struct From 8745ac9c2e5448b9866b63e7f22121cb58690a2c Mon Sep 17 00:00:00 2001 From: Kitzunu <24550914+Kitzunu@users.noreply.github.com> Date: Thu, 4 Jul 2024 19:21:00 +0200 Subject: [PATCH 10/68] =?UTF-8?q?fix(Core/Loot):=20implement=20automatic?= =?UTF-8?q?=20pass=20in=20group=20loot=20for=20items=20that=E2=80=A6=20(#1?= =?UTF-8?q?9272)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(Core/Loot): implement automatic pass in group loot for items that cannot be looted * cherry-pick commit (https://github.com/TrinityCore/TrinityCore/commit/00fdf6e99a2516095889e13d4638efa049782ce5) * closes https://github.com/chromiecraft/chromiecraft/issues/4523 Co-Authored-By: Wyrserth <43747507+Wyrserth@users.noreply.github.com> * whoopise --------- Co-authored-by: Wyrserth <43747507+Wyrserth@users.noreply.github.com> --- src/server/game/Groups/Group.cpp | 114 +++++++++++++++++++------------ src/server/game/Groups/Group.h | 2 +- 2 files changed, 73 insertions(+), 43 deletions(-) diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp index 630856b7a..c9e8a5896 100644 --- a/src/server/game/Groups/Group.cpp +++ b/src/server/game/Groups/Group.cpp @@ -898,7 +898,7 @@ void Group::SendLootStartRollToPlayer(uint32 countDown, uint32 mapId, Player* p, p->GetSession()->SendPacket(&data); } -void Group::SendLootRoll(ObjectGuid sourceGuid, ObjectGuid targetGuid, uint8 rollNumber, uint8 rollType, Roll const& roll) +void Group::SendLootRoll(ObjectGuid sourceGuid, ObjectGuid targetGuid, uint8 rollNumber, uint8 rollType, Roll const& roll, bool autoPass) { WorldPacket data(SMSG_LOOT_ROLL, (8 + 4 + 8 + 4 + 4 + 4 + 1 + 1 + 1)); data << sourceGuid; // guid of the item rolled @@ -909,7 +909,7 @@ void Group::SendLootRoll(ObjectGuid sourceGuid, ObjectGuid targetGuid, uint8 rol data << uint32(roll.itemRandomPropId); // Item random property ID data << uint8(rollNumber); // 0: "Need for: [item name]" > 127: "you passed on: [item name]" Roll number data << uint8(rollType); // 0: "Need for: [item name]" 0: "You have selected need for [item name] 1: need roll 2: greed roll - data << uint8(0); // 1: "You automatically passed on: %s because you cannot loot that item." - Possibly used in need befor greed + data << uint8(autoPass); // 1: "You automatically passed on: %s because you cannot loot that item." for (Roll::PlayerVote::const_iterator itr = roll.playerVote.begin(); itr != roll.playerVote.end(); ++itr) { @@ -986,6 +986,23 @@ void Group::SendLooter(Creature* creature, Player* groupLooter) BroadcastPacket(&data, false); } +bool CanRollOnItem(LootItem const& item, Player const* player, Loot* loot) +{ + // Players can't roll on unique items if they already reached the maximum quantity of that item + ItemTemplate const* proto = sObjectMgr->GetItemTemplate(item.itemid); + if (!proto) + return false; + + uint32 itemCount = player->GetItemCount(item.itemid); + if ((proto->MaxCount > 0 && static_cast(itemCount) >= proto->MaxCount) || (player->CanEquipUniqueItem(proto) != EQUIP_ERR_OK)) + return false; + + if (!item.AllowedForPlayer(player, loot->sourceWorldObjectGUID)) + return false; + + return true; +} + void Group::GroupLoot(Loot* loot, WorldObject* pLootedObject) { std::vector::iterator i; @@ -1013,23 +1030,20 @@ void Group::GroupLoot(Loot* loot, WorldObject* pLootedObject) for (GroupReference* itr = GetFirstMember(); itr != nullptr; itr = itr->next()) { Player* member = itr->GetSource(); - if (!member) + if (!member || !member->GetSession()) continue; if (member->IsAtLootRewardDistance(pLootedObject)) { - if (i->AllowedForPlayer(member, loot->sourceWorldObjectGUID)) - { - r->totalPlayersRolling++; + r->totalPlayersRolling++; - if (member->GetPassOnGroupLoot()) - { - r->playerVote[member->GetGUID()] = PASS; - r->totalPass++; - // can't broadcast the pass now. need to wait until all rolling players are known. - } - else - r->playerVote[member->GetGUID()] = NOT_EMITED_YET; + RollVote vote = member->GetPassOnGroupLoot() ? PASS : NOT_EMITED_YET; + if (!CanRollOnItem(*i, member, loot)) + { + vote = PASS; + ++r->totalPass; } + + r->playerVote[member->GetGUID()] = vote; } } @@ -1052,23 +1066,28 @@ void Group::GroupLoot(Loot* loot, WorldObject* pLootedObject) continue; if (itr->second == PASS) - SendLootRoll(newitemGUID, p->GetGUID(), 128, ROLL_PASS, *r); + SendLootRoll(newitemGUID, p->GetGUID(), 128, ROLL_PASS, *r, true); } } - SendLootStartRoll(60000, pLootedObject->GetMapId(), *r); - - RollId.push_back(r); - - if (Creature* creature = pLootedObject->ToCreature()) + if (r->totalPass == r->totalPlayersRolling) + delete r; + else { - creature->m_groupLootTimer = 60000; - creature->lootingGroupLowGUID = GetGUID().GetCounter(); - } - else if (GameObject* go = pLootedObject->ToGameObject()) - { - go->m_groupLootTimer = 60000; - go->lootingGroupLowGUID = GetGUID().GetCounter(); + SendLootStartRoll(60000, pLootedObject->GetMapId(), *r); + + RollId.push_back(r); + + if (Creature* creature = pLootedObject->ToCreature()) + { + creature->m_groupLootTimer = 60000; + creature->lootingGroupLowGUID = GetGUID().GetCounter(); + } + else if (GameObject* go = pLootedObject->ToGameObject()) + { + go->m_groupLootTimer = 60000; + go->lootingGroupLowGUID = GetGUID().GetCounter(); + } } } else @@ -1096,16 +1115,18 @@ void Group::GroupLoot(Loot* loot, WorldObject* pLootedObject) for (GroupReference* itr = GetFirstMember(); itr != nullptr; itr = itr->next()) { Player* member = itr->GetSource(); - if (!member) + if (!member || !member->GetSession()) continue; if (member->IsAtLootRewardDistance(pLootedObject)) { - if (i->AllowedForPlayer(member, loot->sourceWorldObjectGUID)) + RollVote vote = NOT_EMITED_YET; + if (!CanRollOnItem(*i, member, loot)) { - r->totalPlayersRolling++; - r->playerVote[member->GetGUID()] = NOT_EMITED_YET; + vote = PASS; + ++r->totalPass; } + r->playerVote[member->GetGUID()] = vote; } } @@ -1156,20 +1177,21 @@ void Group::NeedBeforeGreed(Loot* loot, WorldObject* lootedObject) for (GroupReference* itr = GetFirstMember(); itr != nullptr; itr = itr->next()) { Player* playerToRoll = itr->GetSource(); - if (!playerToRoll) + if (!playerToRoll || !playerToRoll->GetSession()) continue; - if (i->AllowedForPlayer(playerToRoll, loot->sourceWorldObjectGUID) && playerToRoll->IsAtLootRewardDistance(lootedObject)) + if (playerToRoll->IsAtGroupRewardDistance(lootedObject)) { r->totalPlayersRolling++; - if (playerToRoll->GetPassOnGroupLoot()) + + RollVote vote = playerToRoll->GetPassOnGroupLoot() ? PASS : NOT_EMITED_YET; + if (!CanRollOnItem(*i, playerToRoll, loot)) { - r->playerVote[playerToRoll->GetGUID()] = PASS; - r->totalPass++; - // can't broadcast the pass now. need to wait until all rolling players are known. + vote = PASS; + r->totalPass++; // Can't broadcast the pass now. need to wait until all rolling players are known } - else - r->playerVote[playerToRoll->GetGUID()] = NOT_EMITED_YET; + + r->playerVote[playerToRoll->GetGUID()] = vote; } } @@ -1230,13 +1252,21 @@ void Group::NeedBeforeGreed(Loot* loot, WorldObject* lootedObject) for (GroupReference* itr = GetFirstMember(); itr != nullptr; itr = itr->next()) { Player* playerToRoll = itr->GetSource(); - if (!playerToRoll) + if (!playerToRoll || !playerToRoll->GetSession()) continue; - if (i->AllowedForPlayer(playerToRoll, loot->sourceWorldObjectGUID) && playerToRoll->IsAtLootRewardDistance(lootedObject)) + if (playerToRoll->IsAtGroupRewardDistance(lootedObject)) { r->totalPlayersRolling++; - r->playerVote[playerToRoll->GetGUID()] = NOT_EMITED_YET; + + RollVote vote = playerToRoll->GetPassOnGroupLoot() ? PASS : NOT_EMITED_YET; + if (!CanRollOnItem(*i, playerToRoll, loot)) + { + vote = PASS; + r->totalPass++; // Can't broadcast the pass now. need to wait until all rolling players are known + } + + r->playerVote[playerToRoll->GetGUID()] = vote; } } diff --git a/src/server/game/Groups/Group.h b/src/server/game/Groups/Group.h index 87317f376..f4afabf6f 100644 --- a/src/server/game/Groups/Group.h +++ b/src/server/game/Groups/Group.h @@ -286,7 +286,7 @@ public: bool isRollLootActive() const; void SendLootStartRoll(uint32 CountDown, uint32 mapid, const Roll& r); void SendLootStartRollToPlayer(uint32 countDown, uint32 mapId, Player* p, bool canNeed, Roll const& r); - void SendLootRoll(ObjectGuid SourceGuid, ObjectGuid TargetGuid, uint8 RollNumber, uint8 RollType, const Roll& r); + void SendLootRoll(ObjectGuid SourceGuid, ObjectGuid TargetGuid, uint8 RollNumber, uint8 RollType, const Roll& r, bool autoPass = false); void SendLootRollWon(ObjectGuid SourceGuid, ObjectGuid TargetGuid, uint8 RollNumber, uint8 RollType, const Roll& r); void SendLootAllPassed(Roll const& roll); void SendLooter(Creature* creature, Player* pLooter); From 193e906a84cb47090b8c95046b42251265f6cc97 Mon Sep 17 00:00:00 2001 From: Kitzunu <24550914+Kitzunu@users.noreply.github.com> Date: Thu, 4 Jul 2024 19:21:33 +0200 Subject: [PATCH 11/68] =?UTF-8?q?fix(Core/Spells):=20Shapeshift=20should?= =?UTF-8?q?=20show=20in=20Old=20Hillsbrad=20Foothills=20a=E2=80=A6=20(#192?= =?UTF-8?q?74)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix(Core/Spells): Shapeshift should show in Old Hillsbrad Foothills as horde --- src/server/game/Spells/Auras/SpellAuraEffects.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 3c7f16d7a..24f932fe9 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -2011,7 +2011,7 @@ void AuraEffect::HandleAuraModShapeshift(AuraApplication const* aurApp, uint8 mo if (modelid > 0) { bool allow = true; - if (target->getTransForm()) + if (target->getTransForm() && !target->GetMapId() == 560 /*The Escape From Durnholde*/) if (SpellInfo const* transformSpellInfo = sSpellMgr->GetSpellInfo(target->getTransForm())) if (transformSpellInfo->HasAttribute(SPELL_ATTR0_NO_IMMUNITIES) || !transformSpellInfo->IsPositive()) allow = false; From 385d7fd515c998f6420912e966aa65af4318e49a Mon Sep 17 00:00:00 2001 From: Kitzunu <24550914+Kitzunu@users.noreply.github.com> Date: Thu, 4 Jul 2024 19:23:25 +0200 Subject: [PATCH 12/68] chore(Core/DBC): define unused unknown dbc fields (#19262) * chore(Core/DBC): define unused unknown dbc fields * Name unused unknown dbc fields using WDBX and wowdev.wiki * rename SpellShapeshiftEntry to SpellShapeshiftFormEntry to properly match the DBC used * rename sSpellShapeshiftStore to sSpellShapeshiftFormStore to properly match the DBC used * Comment out unused field for GlyphPropertiesEntry * Comment out unused field for MapEntry * forgot one * SpellShapeshiftfmt to SpellShapeshiftFormfmt * SpellShapeshiftFormEntryfmt --- src/server/game/DataStores/DBCStores.cpp | 4 +- src/server/game/DataStores/DBCStores.h | 4 +- src/server/game/Entities/Player/Player.cpp | 2 +- src/server/game/Entities/Unit/Unit.cpp | 6 +- .../game/Spells/Auras/SpellAuraEffects.cpp | 2 +- src/server/game/Spells/Spell.cpp | 2 +- src/server/game/Spells/SpellInfo.cpp | 6 +- src/server/shared/DataStores/DBCStructure.h | 166 +++++++++--------- src/server/shared/DataStores/DBCfmt.h | 6 +- 9 files changed, 100 insertions(+), 98 deletions(-) diff --git a/src/server/game/DataStores/DBCStores.cpp b/src/server/game/DataStores/DBCStores.cpp index 33cb2ace1..72a852244 100644 --- a/src/server/game/DataStores/DBCStores.cpp +++ b/src/server/game/DataStores/DBCStores.cpp @@ -160,7 +160,7 @@ DBCStorage sSpellFocusObjectStore(SpellFocusObjectfmt); DBCStorage sSpellRadiusStore(SpellRadiusfmt); DBCStorage sSpellRangeStore(SpellRangefmt); DBCStorage sSpellRuneCostStore(SpellRuneCostfmt); -DBCStorage sSpellShapeshiftStore(SpellShapeshiftfmt); +DBCStorage sSpellShapeshiftFormStore(SpellShapeshiftFormEntryfmt); DBCStorage sSpellVisualStore(SpellVisualfmt); DBCStorage sStableSlotPricesStore(StableSlotPricesfmt); DBCStorage sSummonPropertiesStore(SummonPropertiesfmt); @@ -363,7 +363,7 @@ void LoadDBCStores(const std::string& dataPath) LOAD_DBC(sSpellRadiusStore, "SpellRadius.dbc", "spellradius_dbc"); LOAD_DBC(sSpellRangeStore, "SpellRange.dbc", "spellrange_dbc"); LOAD_DBC(sSpellRuneCostStore, "SpellRuneCost.dbc", "spellrunecost_dbc"); - LOAD_DBC(sSpellShapeshiftStore, "SpellShapeshiftForm.dbc", "spellshapeshiftform_dbc"); + LOAD_DBC(sSpellShapeshiftFormStore, "SpellShapeshiftForm.dbc", "spellshapeshiftform_dbc"); LOAD_DBC(sSpellVisualStore, "SpellVisual.dbc", "spellvisual_dbc"); LOAD_DBC(sStableSlotPricesStore, "StableSlotPrices.dbc", "stableslotprices_dbc"); LOAD_DBC(sSummonPropertiesStore, "SummonProperties.dbc", "summonproperties_dbc"); diff --git a/src/server/game/DataStores/DBCStores.h b/src/server/game/DataStores/DBCStores.h index 9bc8090e2..0f71e25fd 100644 --- a/src/server/game/DataStores/DBCStores.h +++ b/src/server/game/DataStores/DBCStores.h @@ -134,7 +134,7 @@ extern DBCStorage sItemLimitCategoryStore; extern DBCStorage sItemRandomPropertiesStore; extern DBCStorage sItemRandomSuffixStore; extern DBCStorage sItemSetStore; -extern DBCStorage sLFGDungeonStore; +extern DBCStorage sLFGDungeonStore; extern DBCStorage sLiquidTypeStore; extern DBCStorage sLockStore; extern DBCStorage sMailTemplateStore; @@ -170,7 +170,7 @@ extern std::unordered_set sPetTalentSpells; extern DBCStorage sSpellRadiusStore; extern DBCStorage sSpellRangeStore; extern DBCStorage sSpellRuneCostStore; -extern DBCStorage sSpellShapeshiftStore; +extern DBCStorage sSpellShapeshiftFormStore; extern DBCStorage sSpellStore; extern DBCStorage sSpellVisualStore; extern DBCStorage sStableSlotPricesStore; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index e4cc9ee28..89ce0d76d 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -10519,7 +10519,7 @@ void Player::InitDataForForm(bool reapplyMods) { ShapeshiftForm form = GetShapeshiftForm(); - SpellShapeshiftEntry const* ssEntry = sSpellShapeshiftStore.LookupEntry(form); + SpellShapeshiftFormEntry const* ssEntry = sSpellShapeshiftFormStore.LookupEntry(form); if (ssEntry && ssEntry->attackSpeed) { SetAttackTime(BASE_ATTACK, ssEntry->attackSpeed); diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index d384219a0..0cbdf05aa 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -15173,7 +15173,7 @@ uint32 Unit::GetCreatureType() const if (GetTypeId() == TYPEID_PLAYER) { ShapeshiftForm form = GetShapeshiftForm(); - SpellShapeshiftEntry const* ssEntry = sSpellShapeshiftStore.LookupEntry(form); + SpellShapeshiftFormEntry const* ssEntry = sSpellShapeshiftFormStore.LookupEntry(form); if (ssEntry && ssEntry->creatureType > 0) return ssEntry->creatureType; else @@ -19646,7 +19646,7 @@ uint32 Unit::GetModelForForm(ShapeshiftForm form, uint32 spellId) const } uint32 modelid = 0; - SpellShapeshiftEntry const* formEntry = sSpellShapeshiftStore.LookupEntry(form); + SpellShapeshiftFormEntry const* formEntry = sSpellShapeshiftFormStore.LookupEntry(form); if (formEntry && formEntry->modelID_A) { // Take the alliance modelid as default @@ -21582,7 +21582,7 @@ bool Unit::IsInDisallowedMountForm() const if (ShapeshiftForm form = GetShapeshiftForm()) { - SpellShapeshiftEntry const* shapeshift = sSpellShapeshiftStore.LookupEntry(form); + SpellShapeshiftFormEntry const* shapeshift = sSpellShapeshiftFormStore.LookupEntry(form); if (!shapeshift) { return true; diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 24f932fe9..85b2a5995 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -2143,7 +2143,7 @@ void AuraEffect::HandleAuraModShapeshift(AuraApplication const* aurApp, uint8 mo if (target->GetTypeId() == TYPEID_PLAYER) { - SpellShapeshiftEntry const* shapeInfo = sSpellShapeshiftStore.LookupEntry(form); + SpellShapeshiftFormEntry const* shapeInfo = sSpellShapeshiftFormStore.LookupEntry(form); // Learn spells for shapeshift form - no need to send action bars or add spells to spellbook for (uint8 i = 0; i < MAX_SHAPESHIFT_SPELLS; ++i) { diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 24b0b81ad..c37093e2d 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -5799,7 +5799,7 @@ SpellCastResult Spell::CheckCast(bool strict) SpellEffectInfo const* effInfo = &m_spellInfo->Effects[effIndex]; if (effInfo->ApplyAuraName == SPELL_AURA_MOD_SHAPESHIFT) { - SpellShapeshiftEntry const* shapeShiftEntry = sSpellShapeshiftStore.LookupEntry(effInfo->MiscValue); + SpellShapeshiftFormEntry const* shapeShiftEntry = sSpellShapeshiftFormStore.LookupEntry(effInfo->MiscValue); if (shapeShiftEntry && (shapeShiftEntry->flags1 & 1) == 0) // unk flag checkMask |= VEHICLE_SEAT_FLAG_UNCONTROLLED; break; diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index c90f3a9c4..42455c958 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -1435,10 +1435,10 @@ SpellCastResult SpellInfo::CheckShapeshift(uint32 form) const return SPELL_CAST_OK; bool actAsShifted = false; - SpellShapeshiftEntry const* shapeInfo = nullptr; + SpellShapeshiftFormEntry const* shapeInfo = nullptr; if (form > 0) { - shapeInfo = sSpellShapeshiftStore.LookupEntry(form); + shapeInfo = sSpellShapeshiftFormStore.LookupEntry(form); if (!shapeInfo) { LOG_ERROR("spells", "GetErrorAtShapeshiftedCast: unknown shapeshift {}", form); @@ -2437,7 +2437,7 @@ int32 SpellInfo::CalcPowerCost(Unit const* caster, SpellSchoolMask schoolMask, S if (AttributesEx4 & SPELL_ATTR4_WEAPON_SPEED_COST_SCALING) { uint32 speed = 0; - if (SpellShapeshiftEntry const* ss = sSpellShapeshiftStore.LookupEntry(caster->GetShapeshiftForm())) + if (SpellShapeshiftFormEntry const* ss = sSpellShapeshiftFormStore.LookupEntry(caster->GetShapeshiftForm())) speed = ss->attackSpeed; else { diff --git a/src/server/shared/DataStores/DBCStructure.h b/src/server/shared/DataStores/DBCStructure.h index 30307e17f..db61bb0af 100644 --- a/src/server/shared/DataStores/DBCStructure.h +++ b/src/server/shared/DataStores/DBCStructure.h @@ -590,11 +590,11 @@ struct BarberShopStyleEntry { uint32 Id; // 0 uint32 type; // 1 value 0 -> hair, value 2 -> facialhair - //char const* name[16]; // 2-17 name of hair style - //uint32 name_flags; // 18 - //uint32 unk_name[16]; // 19-34, all empty - //uint32 unk_flags; // 35 - //float CostMultiplier; // 36 values 1 and 0.75 + //char const* displayNameLang[16]; // 2-17 name of hair style + //char const* displayNameLangMask; // 18 + //char const* descriptionLang[16]; // 19-34, all empty + //char const* descriptionLangMask; // 35 + //float costModifier; // 36 values 1 and 0.75 uint32 race; // 37 race uint32 gender; // 38 0 -> male, 1 -> female uint32 hair_id; // 39 real ID to hair/facial hair @@ -618,11 +618,11 @@ struct BattlemasterListEntry struct CharStartOutfitEntry { - //uint32 Id; // 0 + //uint32 ID; // 0 uint8 Race; // 1 uint8 Class; // 2 uint8 Gender; // 3 - //uint8 Unused; // 4 + //uint8 outfitID; // 4 unused int32 ItemId[MAX_OUTFIT_ITEMS]; // 5-28 //int32 ItemDisplayId[MAX_OUTFIT_ITEMS]; // 29-52 not required at server side //int32 ItemInventorySlot[MAX_OUTFIT_ITEMS]; // 53-76 not required at server side @@ -631,11 +631,11 @@ struct CharStartOutfitEntry struct CharTitlesEntry { uint32 ID; // 0, title ids, for example in Quest::GetCharTitleId() - //uint32 unk1; // 1 flags? + //uint32 conditionID; // 1 Never used by the client. Should be used serverside? char const* nameMale[16]; // 2-17 - // 18 string flag, unused + //uint32 nameLangMask // 18 string flag, unused char const* nameFemale[16]; // 19-34 - // 35 string flag, unused + //uint32 nameLang1Mask // 35 string flag, unused uint32 bit_index; // 36 used in PLAYER_CHOSEN_TITLE and 1< RankID; // 4-8 - // 9-12 not used, always 0, maybe not used high ranks - uint32 DependsOn; // 13 index in Talent.dbc (TalentEntry) - // 14-15 not used - uint32 DependsOnRank; // 16 - // 17-18 not used + // uint32 spellRank [4] // 9-12 not used, always 0, maybe not used high ranks + uint32 DependsOn; // 13 preReqTalent1 index in Talent.dbc (TalentEntry) + // uint32 preReqTalent[2] // 14-15 not used + uint32 DependsOnRank; // 16 preReqRank1 + // uint32 preReqRank[2] // 17-18 not used uint32 addToSpellBook; // 19 also need disable higest ranks on reset talent tree - //uint32 unk2; // 20, all 0 - //uint64 allowForPet; // 21-22 its a 64 bit mask for pet 1< Date: Thu, 4 Jul 2024 19:25:28 +0200 Subject: [PATCH 13/68] =?UTF-8?q?chore(Core/Conf):=20Show=20better=20loggi?= =?UTF-8?q?ng=20when=20fatal=20config=20options=20are=20m=E2=80=A6=20(#192?= =?UTF-8?q?36)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit chore(Core/Conf): Show better logging when fatal config options are missing * Show better log when the server halts due to missing fatal config option * Change error to warning for missing config options. As they are not errors * Update output when autoupdater is disabled for all databases --- src/common/Configuration/Config.cpp | 36 +++++++++++++++++-- .../database/Database/DatabaseLoader.cpp | 2 +- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/src/common/Configuration/Config.cpp b/src/common/Configuration/Config.cpp index 742777b18..d8665593c 100644 --- a/src/common/Configuration/Config.cpp +++ b/src/common/Configuration/Config.cpp @@ -35,6 +35,14 @@ namespace std::unordered_map _envVarCache; std::mutex _configLock; + std::vector _fatalConfigOptions = + { + { "RealmID" }, + { "LoginDatabaseInfo" }, + { "WorldDatabaseInfo" }, + { "CharacterDatabaseInfo" }, + }; + // Check system configs like *server.conf* bool IsAppConfig(std::string_view fileName) { @@ -388,6 +396,7 @@ T ConfigMgr::GetValueDefault(std::string const& name, T const& def, bool showLog std::string strValue; auto const& itr = _configOptions.find(name); + bool fatalConfig = false; bool notFound = itr == _configOptions.end(); auto envVarName = GetEnvVarName(name); Optional envVar = GetEnvFromCache(name, envVarName); @@ -406,7 +415,18 @@ T ConfigMgr::GetValueDefault(std::string const& name, T const& def, bool showLog { if (showLogs) { - LOG_ERROR("server.loading", "> Config: Missing property {} in config file {}, add \"{} = {}\" to this file or define '{}' as an environment variable.", + for (std::string s : _fatalConfigOptions) + if (s == name) + { + fatalConfig = true; + break; + } + + if (fatalConfig) + LOG_FATAL("server.loading", "> Config:\n\nFATAL ERROR: Missing property {} in config file {}, add \"{} = {}\" to this file or define '{}' as an environment variable\n\nYour server cannot start without this option!", + name, _filename, name, Acore::ToString(def), envVarName); + else + LOG_WARN("server.loading", "> Config: Missing property {} in config file {}, add \"{} = {}\" to this file or define '{}' as an environment variable.", name, _filename, name, Acore::ToString(def), envVarName); } return def; @@ -435,6 +455,7 @@ template<> std::string ConfigMgr::GetValueDefault(std::string const& name, std::string const& def, bool showLogs /*= true*/) const { auto const& itr = _configOptions.find(name); + bool fatalConfig = false; bool notFound = itr == _configOptions.end(); auto envVarName = GetEnvVarName(name); Optional envVar = GetEnvFromCache(name, envVarName); @@ -453,7 +474,18 @@ std::string ConfigMgr::GetValueDefault(std::string const& name, std { if (showLogs) { - LOG_ERROR("server.loading", "> Config: Missing property {} in config file {}, add \"{} = {}\" to this file or define '{}' as an environment variable.", + for (std::string s : _fatalConfigOptions) + if (s == name) + { + fatalConfig = true; + break; + } + + if (fatalConfig) + LOG_FATAL("server.loading", "> Config:\n\nFATAL ERROR: Missing property {} in config file {}, add \"{} = {}\" to this file or define '{}' as an environment variable.\n\nYour server cannot start without this option!", + name, _filename, name, def, envVarName); + else + LOG_WARN("server.loading", "> Config: Missing property {} in config file {}, add \"{} = {}\" to this file or define '{}' as an environment variable.", name, _filename, name, def, envVarName); } diff --git a/src/server/database/Database/DatabaseLoader.cpp b/src/server/database/Database/DatabaseLoader.cpp index cfd0d6f0f..5ad77d35d 100644 --- a/src/server/database/Database/DatabaseLoader.cpp +++ b/src/server/database/Database/DatabaseLoader.cpp @@ -154,7 +154,7 @@ DatabaseLoader& DatabaseLoader::AddDatabase(DatabaseWorkerPool& pool, std::st bool DatabaseLoader::Load() { if (!_updateFlags) - LOG_INFO("sql.updates", "Automatic database updates are disabled for all databases!"); + LOG_WARN("sql.updates", "> AUTOUPDATER: Automatic database updates are disabled for all databases in the config! This is not recommended!"); if (!OpenDatabases()) return false; From e8f7d70ee086f3a7efac454076cb80e53d2ea559 Mon Sep 17 00:00:00 2001 From: Kitzunu <24550914+Kitzunu@users.noreply.github.com> Date: Thu, 4 Jul 2024 19:28:10 +0200 Subject: [PATCH 14/68] refactor(Script/Dalaran): Minigob Manabonk (#19244) * refactor(Script/Dalaran): Minigob Manabonk * closes https://github.com/azerothcore/azerothcore-wotlk/issues/16841 * Update src/server/scripts/Northrend/zone_dalaran.cpp --- src/server/scripts/Northrend/zone_dalaran.cpp | 182 +++++++++--------- 1 file changed, 93 insertions(+), 89 deletions(-) diff --git a/src/server/scripts/Northrend/zone_dalaran.cpp b/src/server/scripts/Northrend/zone_dalaran.cpp index 9085eeeb3..274748225 100644 --- a/src/server/scripts/Northrend/zone_dalaran.cpp +++ b/src/server/scripts/Northrend/zone_dalaran.cpp @@ -20,6 +20,7 @@ #include "Player.h" #include "ScriptedCreature.h" #include "ScriptedGossip.h" +#include "TaskScheduler.h" #include "World.h" // Ours @@ -506,108 +507,113 @@ enum MinigobData SPELL_IMPROVED_BLINK = 61995, EVENT_SELECT_TARGET = 1, - EVENT_BLINK = 2, - EVENT_DESPAWN_VISUAL = 3, - EVENT_DESPAWN = 4, + EVENT_POLYMORPH = 2, + EVENT_LAUGH = 3, + EVENT_MOVE = 4, + EVENT_DESPAWN_VISUAL = 5, + EVENT_DESPAWN = 6, MAIL_MINIGOB_ENTRY = 264, MAIL_DELIVER_DELAY_MIN = 5 * MINUTE, MAIL_DELIVER_DELAY_MAX = 15 * MINUTE }; -class npc_minigob_manabonk : public CreatureScript +struct npc_minigob_manabonk : public ScriptedAI { -public: - npc_minigob_manabonk() : CreatureScript("npc_minigob_manabonk") {} - - struct npc_minigob_manabonkAI : public ScriptedAI + npc_minigob_manabonk(Creature* creature) : ScriptedAI(creature) { - npc_minigob_manabonkAI(Creature* creature) : ScriptedAI(creature) - { - me->setActive(true); - } + me->setActive(true); + } - void Reset() override - { - me->SetVisible(false); - events.ScheduleEvent(EVENT_SELECT_TARGET, IN_MILLISECONDS); - } + void Reset() override + { + me->SetVisible(false); + events.ScheduleEvent(EVENT_SELECT_TARGET, 1s); + } - Player* SelectTargetInDalaran() - { - std::list PlayerInDalaranList; - PlayerInDalaranList.clear(); + Player* SelectTargetInDalaran() + { + std::list playerInDalaranList; + playerInDalaranList.clear(); - Map::PlayerList const& players = me->GetMap()->GetPlayers(); - for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) - if (Player* player = itr->GetSource()->ToPlayer()) - if (player->GetZoneId() == ZONE_DALARAN && !player->IsFlying() && !player->IsMounted() && !player->IsGameMaster()) - PlayerInDalaranList.push_back(player); - - if (PlayerInDalaranList.empty()) - return nullptr; - return Acore::Containers::SelectRandomContainerElement(PlayerInDalaranList); - } - - void SendMailToPlayer(Player* player) - { - CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction(); - int16 deliverDelay = irand(MAIL_DELIVER_DELAY_MIN, MAIL_DELIVER_DELAY_MAX); - MailDraft(MAIL_MINIGOB_ENTRY, true).SendMailTo(trans, MailReceiver(player), MailSender(MAIL_CREATURE, me->GetEntry()), MAIL_CHECK_MASK_NONE, deliverDelay); - CharacterDatabase.CommitTransaction(trans); - } - - void UpdateAI(uint32 diff) override - { - if (!sWorld->getBoolConfig(CONFIG_MINIGOB_MANABONK)) - return; - - events.Update(diff); - - while (uint32 eventId = events.ExecuteEvent()) + me->GetMap()->DoForAllPlayers([&](Player* player) { - switch (eventId) - { - case EVENT_SELECT_TARGET: - me->SetVisible(true); - DoCast(me, SPELL_TELEPORT_VISUAL); - if (Player* player = SelectTargetInDalaran()) - { - me->NearTeleportTo(player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), 0.0f); - DoCast(player, SPELL_MANABONKED); - SendMailToPlayer(player); - } - events.ScheduleEvent(EVENT_BLINK, 3ms); - break; - case EVENT_BLINK: - { - DoCast(me, SPELL_IMPROVED_BLINK); - Position pos = me->GetRandomNearPosition((urand(15, 40))); - me->GetMotionMaster()->MovePoint(0, pos.m_positionX, pos.m_positionY, pos.m_positionZ); - events.ScheduleEvent(EVENT_DESPAWN, 3ms); - events.ScheduleEvent(EVENT_DESPAWN_VISUAL, 3ms); - break; - } - case EVENT_DESPAWN_VISUAL: - DoCast(me, SPELL_TELEPORT_VISUAL); - break; - case EVENT_DESPAWN: + if (player->GetZoneId() == ZONE_DALARAN && !player->IsFlying() && !player->IsMounted() && !player->IsGameMaster()) + playerInDalaranList.push_back(player); + }); + + if (playerInDalaranList.empty()) + return nullptr; + return Acore::Containers::SelectRandomContainerElement(playerInDalaranList); + } + + void SendMailToPlayer(Player* player) + { + CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction(); + int16 deliverDelay = irand(MAIL_DELIVER_DELAY_MIN, MAIL_DELIVER_DELAY_MAX); + MailDraft(MAIL_MINIGOB_ENTRY, true).SendMailTo(trans, MailReceiver(player), MailSender(MAIL_CREATURE, me->GetEntry()), MAIL_CHECK_MASK_NONE, deliverDelay); + CharacterDatabase.CommitTransaction(trans); + } + + void UpdateAI(uint32 diff) override + { + if (!sWorld->getBoolConfig(CONFIG_MINIGOB_MANABONK)) + return; + + events.Update(diff); + + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_SELECT_TARGET: + me->SetVisible(true); + DoCastSelf(SPELL_TELEPORT_VISUAL); + if (Player* player = SelectTargetInDalaran()) + { + playerGUID = player->GetGUID(); + Position pos = player->GetPosition(); + me->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation()); + me->GetMotionMaster()->MoveRandom(10); + } + events.ScheduleEvent(EVENT_POLYMORPH, 30s); + break; + case EVENT_POLYMORPH: + if (Player* player = ObjectAccessor::GetPlayer(*me, playerGUID)) + { + DoCast(player, SPELL_MANABONKED); + SendMailToPlayer(player); + } + else me->DespawnOrUnsummon(); - break; - default: - break; - } + events.ScheduleEvent(EVENT_LAUGH, 2s); + break; + case EVENT_LAUGH: + me->GetMotionMaster()->MoveIdle(); + me->HandleEmoteCommand(EMOTE_ONESHOT_LAUGH_NO_SHEATHE); + events.ScheduleEvent(EVENT_MOVE, 4s); + break; + case EVENT_MOVE: + { + Position pos = me->GetRandomNearPosition((urand(15, 40))); + me->GetMotionMaster()->MovePoint(0, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), true); + } + events.ScheduleEvent(EVENT_DESPAWN_VISUAL, 3s); + events.ScheduleEvent(EVENT_DESPAWN, 4s); + break; + case EVENT_DESPAWN_VISUAL: + DoCastSelf(SPELL_IMPROVED_BLINK); + break; + case EVENT_DESPAWN: + me->DespawnOrUnsummon(); + break; + default: + break; } } - - private: - EventMap events; - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_minigob_manabonkAI(creature); } +private: + ObjectGuid playerGUID; }; class npc_dalaran_mage : public CreatureScript @@ -861,8 +867,6 @@ void AddSC_dalaran() new npc_dalaran_mage(); new npc_dalaran_warrior(); RegisterCreatureAI(npc_cosmetic_toy_plane); - - // theirs new npc_mageguard_dalaran(); - new npc_minigob_manabonk(); + RegisterCreatureAI(npc_minigob_manabonk); } From aebb99ecdac9d398495806384bad233cadaab637 Mon Sep 17 00:00:00 2001 From: Kitzunu <24550914+Kitzunu@users.noreply.github.com> Date: Thu, 4 Jul 2024 19:30:25 +0200 Subject: [PATCH 15/68] =?UTF-8?q?fix(Core/Character):=20TeleportTo()=20in?= =?UTF-8?q?=20HandlePlayerLoginFromDB()=20causes=E2=80=A6=20(#19237)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix(Core/Character): TeleportTo() in HandlePlayerLoginFromDB() causes breakdown in the network communication * closes https://github.com/azerothcore/azerothcore-wotlk/issues/16307 --- src/server/game/Handlers/CharacterHandler.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index 4520f96a6..ad8ddbbce 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -893,6 +893,9 @@ void WorldSession::HandlePlayerLoginFromDB(LoginQueryHolder const& holder) pCurrChar->TeleportTo(at->target_mapId, at->target_X, at->target_Y, at->target_Z, pCurrChar->GetOrientation()); else pCurrChar->TeleportTo(pCurrChar->m_homebindMapId, pCurrChar->m_homebindX, pCurrChar->m_homebindY, pCurrChar->m_homebindZ, pCurrChar->GetOrientation()); + + // Probably a hackfix, but currently the best workaround to prevent character names showing as Unknown after teleport out from instances at login. + pCurrChar->GetSession()->SendNameQueryOpcode(pCurrChar->GetGUID()); } pCurrChar->SendInitialPacketsAfterAddToMap(); From bd29e9e1b37380bf5207d3e280dfa40ec3a692c9 Mon Sep 17 00:00:00 2001 From: Kitzunu <24550914+Kitzunu@users.noreply.github.com> Date: Thu, 4 Jul 2024 19:30:59 +0200 Subject: [PATCH 16/68] fix(Core/Spell): Implement SPELL_ATTR1_AURA_STAYS_AFTER_COMBAT (#19254) feat(Core/Spell): Implement SPELL_ATTR1_AURA_STAYS_AFTER_COMBAT * closes https://github.com/azerothcore/azerothcore-wotlk/issues/19248 --- src/common/Logging/enuminfo_LogCommon.cpp | 2 +- src/server/game/Entities/Item/enuminfo_Item.cpp | 2 +- src/server/game/Entities/Unit/Unit.cpp | 11 +++++++---- src/server/game/Entities/Unit/enuminfo_Unit.cpp | 2 +- src/server/game/Quests/enuminfo_QuestDef.cpp | 2 +- src/server/game/Warden/enuminfo_WardenCheckMgr.cpp | 2 +- src/server/shared/SharedDefines.h | 2 +- src/server/shared/enuminfo_SharedDefines.cpp | 4 ++-- 8 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/common/Logging/enuminfo_LogCommon.cpp b/src/common/Logging/enuminfo_LogCommon.cpp index e1750cb3f..2e4265563 100644 --- a/src/common/Logging/enuminfo_LogCommon.cpp +++ b/src/common/Logging/enuminfo_LogCommon.cpp @@ -15,8 +15,8 @@ * with this program. If not, see . */ -#include "Define.h" #include "LogCommon.h" +#include "Define.h" #include "SmartEnum.h" #include diff --git a/src/server/game/Entities/Item/enuminfo_Item.cpp b/src/server/game/Entities/Item/enuminfo_Item.cpp index d43ff6470..a7b1ecc35 100644 --- a/src/server/game/Entities/Item/enuminfo_Item.cpp +++ b/src/server/game/Entities/Item/enuminfo_Item.cpp @@ -15,8 +15,8 @@ * with this program. If not, see . */ -#include "Define.h" #include "Item.h" +#include "Define.h" #include "SmartEnum.h" #include diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 0cbdf05aa..a53d70545 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -3453,7 +3453,8 @@ SpellMissInfo Unit::SpellHitResult(Unit* victim, SpellInfo const* spell, bool Ca return SPELL_MISS_NONE; // Return evade for units in evade mode - if (victim->GetTypeId() == TYPEID_UNIT && victim->ToCreature()->IsEvadingAttacks() && !spell->HasAura(SPELL_AURA_CONTROL_VEHICLE) && !spell->HasAttribute(SPELL_ATTR0_CU_IGNORE_EVADE)) + if (victim->GetTypeId() == TYPEID_UNIT && victim->ToCreature()->IsEvadingAttacks() && !spell->HasAura(SPELL_AURA_CONTROL_VEHICLE) + && !spell->HasAttribute(SPELL_ATTR0_CU_IGNORE_EVADE) && !spell->HasAttribute(SPELL_ATTR1_AURA_STAYS_AFTER_COMBAT)) return SPELL_MISS_EVADE; // Try victim reflect spell @@ -3528,7 +3529,7 @@ SpellMissInfo Unit::SpellHitResult(Unit* victim, Spell const* spell, bool CanRef // Return evade for units in evade mode if (victim->GetTypeId() == TYPEID_UNIT && victim->ToCreature()->IsEvadingAttacks() && !spellInfo->HasAura(SPELL_AURA_CONTROL_VEHICLE) && - !spellInfo->HasAttribute(SPELL_ATTR0_CU_IGNORE_EVADE)) + !spellInfo->HasAttribute(SPELL_ATTR0_CU_IGNORE_EVADE) && !spellInfo->HasAttribute(SPELL_ATTR1_AURA_STAYS_AFTER_COMBAT)) { return SPELL_MISS_EVADE; } @@ -5384,7 +5385,8 @@ void Unit::RemoveEvadeAuras() { Aura const* aura = iter->second->GetBase(); SpellInfo const* spellInfo = aura->GetSpellInfo(); - if (spellInfo->HasAttribute(SPELL_ATTR0_CU_IGNORE_EVADE) || spellInfo->HasAura(SPELL_AURA_CONTROL_VEHICLE) || spellInfo->HasAura(SPELL_AURA_CLONE_CASTER) || (aura->IsPassive() && GetOwnerGUID().IsPlayer())) + if (spellInfo->HasAttribute(SPELL_ATTR0_CU_IGNORE_EVADE) || spellInfo->HasAttribute(SPELL_ATTR1_AURA_STAYS_AFTER_COMBAT) || spellInfo->HasAura(SPELL_AURA_CONTROL_VEHICLE) + || spellInfo->HasAura(SPELL_AURA_CLONE_CASTER) || (aura->IsPassive() && GetOwnerGUID().IsPlayer())) ++iter; else _UnapplyAura(iter, AURA_REMOVE_BY_DEFAULT); @@ -5394,7 +5396,8 @@ void Unit::RemoveEvadeAuras() { Aura* aura = iter->second; SpellInfo const* spellInfo = aura->GetSpellInfo(); - if (spellInfo->HasAttribute(SPELL_ATTR0_CU_IGNORE_EVADE) || spellInfo->HasAura(SPELL_AURA_CONTROL_VEHICLE) || spellInfo->HasAura(SPELL_AURA_CLONE_CASTER) || (aura->IsPassive() && GetOwnerGUID().IsPlayer())) + if (spellInfo->HasAttribute(SPELL_ATTR0_CU_IGNORE_EVADE) || spellInfo->HasAttribute(SPELL_ATTR1_AURA_STAYS_AFTER_COMBAT) || spellInfo->HasAura(SPELL_AURA_CONTROL_VEHICLE) + || spellInfo->HasAura(SPELL_AURA_CLONE_CASTER) || (aura->IsPassive() && GetOwnerGUID().IsPlayer())) ++iter; else RemoveOwnedAura(iter, AURA_REMOVE_BY_DEFAULT); diff --git a/src/server/game/Entities/Unit/enuminfo_Unit.cpp b/src/server/game/Entities/Unit/enuminfo_Unit.cpp index bd16ebd35..a3c4938c6 100644 --- a/src/server/game/Entities/Unit/enuminfo_Unit.cpp +++ b/src/server/game/Entities/Unit/enuminfo_Unit.cpp @@ -15,9 +15,9 @@ * with this program. If not, see . */ +#include "Unit.h" #include "Define.h" #include "SmartEnum.h" -#include "Unit.h" #include namespace Acore::Impl::EnumUtilsImpl diff --git a/src/server/game/Quests/enuminfo_QuestDef.cpp b/src/server/game/Quests/enuminfo_QuestDef.cpp index cf4651adc..aec7b5de3 100644 --- a/src/server/game/Quests/enuminfo_QuestDef.cpp +++ b/src/server/game/Quests/enuminfo_QuestDef.cpp @@ -15,8 +15,8 @@ * with this program. If not, see . */ -#include "Define.h" #include "QuestDef.h" +#include "Define.h" #include "SmartEnum.h" #include diff --git a/src/server/game/Warden/enuminfo_WardenCheckMgr.cpp b/src/server/game/Warden/enuminfo_WardenCheckMgr.cpp index f4d906b69..f76872a82 100644 --- a/src/server/game/Warden/enuminfo_WardenCheckMgr.cpp +++ b/src/server/game/Warden/enuminfo_WardenCheckMgr.cpp @@ -15,9 +15,9 @@ * with this program. If not, see . */ +#include "WardenCheckMgr.h" #include "Define.h" #include "SmartEnum.h" -#include "WardenCheckMgr.h" #include namespace Acore::Impl::EnumUtilsImpl diff --git a/src/server/shared/SharedDefines.h b/src/server/shared/SharedDefines.h index 02729cc1b..11e1711b6 100644 --- a/src/server/shared/SharedDefines.h +++ b/src/server/shared/SharedDefines.h @@ -441,7 +441,7 @@ enum SpellAttr1 : uint32 SPELL_ATTR1_FINISHING_MOVE_DURATION = 0x00400000, // TITLE Requires combo points (type 2) SPELL_ATTR1_IGNORE_OWNERS_DEATH = 0x00800000, // TITLE Unknwon attribute 23@Attr1 SPELL_ATTR1_SPECIAL_SKILLUP = 0x01000000, // TITLE Fishing (client only) - SPELL_ATTR1_AURA_STAYS_AFTER_COMBAT = 0x02000000, // TITLE Unknown attribute 25@Attr1 + SPELL_ATTR1_AURA_STAYS_AFTER_COMBAT = 0x02000000, // TITLE Aura stays after combat DESCRIPTION Aura will not be removed when the unit leaves combat SPELL_ATTR1_REQUIRE_ALL_TARGETS = 0x04000000, // TITLE Unknown attribute 26@Attr1 DESCRIPTION Related to [target=focus] and [target=mouseover] macros? SPELL_ATTR1_DISCOUNT_POWER_ON_MISS = 0x08000000, // TITLE Unknown attribute 27@Attr1 DESCRIPTION Melee spell? SPELL_ATTR1_NO_AURA_ICON = 0x10000000, // TITLE Hide in aura bar (client only) diff --git a/src/server/shared/enuminfo_SharedDefines.cpp b/src/server/shared/enuminfo_SharedDefines.cpp index 0c13b3f0d..cbeccaf65 100644 --- a/src/server/shared/enuminfo_SharedDefines.cpp +++ b/src/server/shared/enuminfo_SharedDefines.cpp @@ -15,8 +15,8 @@ * with this program. If not, see . */ -#include "Define.h" #include "SharedDefines.h" +#include "Define.h" #include "SmartEnum.h" #include @@ -311,7 +311,7 @@ AC_API_EXPORT EnumText EnumUtils::ToString(SpellAttr1 value) case SPELL_ATTR1_FINISHING_MOVE_DURATION: return { "SPELL_ATTR1_FINISHING_MOVE_DURATION", "Requires combo points (type 2)", "" }; case SPELL_ATTR1_IGNORE_OWNERS_DEATH: return { "SPELL_ATTR1_IGNORE_OWNERS_DEATH", "Unknwon attribute 23@Attr1", "" }; case SPELL_ATTR1_SPECIAL_SKILLUP: return { "SPELL_ATTR1_SPECIAL_SKILLUP", "Fishing (client only)", "" }; - case SPELL_ATTR1_AURA_STAYS_AFTER_COMBAT: return { "SPELL_ATTR1_AURA_STAYS_AFTER_COMBAT", "Unknown attribute 25@Attr1", "" }; + case SPELL_ATTR1_AURA_STAYS_AFTER_COMBAT: return { "SPELL_ATTR1_AURA_STAYS_AFTER_COMBAT", "Aura stays after combat", "Aura will not be removed when the unit leaves combat" }; case SPELL_ATTR1_REQUIRE_ALL_TARGETS: return { "SPELL_ATTR1_REQUIRE_ALL_TARGETS", "Unknown attribute 26@Attr1", "Related to [target=focus] and [target=mouseover] macros?" }; case SPELL_ATTR1_DISCOUNT_POWER_ON_MISS: return { "SPELL_ATTR1_DISCOUNT_POWER_ON_MISS", "Unknown attribute 27@Attr1", "Melee spell?" }; case SPELL_ATTR1_NO_AURA_ICON: return { "SPELL_ATTR1_NO_AURA_ICON", "Hide in aura bar (client only)", "" }; From c3e22c0fe221e7cb16bd316ac875de7f25973508 Mon Sep 17 00:00:00 2001 From: Benjamin Jackson <38561765+heyitsbench@users.noreply.github.com> Date: Thu, 4 Jul 2024 13:31:22 -0400 Subject: [PATCH 17/68] fix(Scripts/HyjalSummit): Couple Archimonde adjustments. (#19193) * Init. Co-Authored-By: cyberium Co-Authored-By: killerwife * Corrections. * Adjust fear timer. * Wrong spell. * Whitespace. * Use the much cooler and more hip scheduler. * Correct teleport timers. Matches up with sniffed 3.4.3 data. * Swap magic number for constant. Co-Authored-By: killerwife * Adjust notation. * Public. Co-authored-by: Kitzunu <24550914+Kitzunu@users.noreply.github.com> * Kitzunu's fault. Co-authored-by: Kitzunu <24550914+Kitzunu@users.noreply.github.com> --------- Co-authored-by: cyberium Co-authored-by: killerwife Co-authored-by: Kitzunu <24550914+Kitzunu@users.noreply.github.com> --- .../BattleForMountHyjal/boss_archimonde.cpp | 43 +++++++++---------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp index cdf4fc11a..eea967559 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp @@ -143,35 +143,37 @@ struct npc_doomfire_spirit : public ScriptedAI { npc_doomfire_spirit(Creature* creature) : ScriptedAI(creature){ } + float const turnConstant = 0.785402f; + float fAngle = urand(0, M_PI * 2); + void Reset() override { scheduler.CancelAll(); ScheduleTimedEvent(0s, [&] { - me->GetMotionMaster()->MovePoint(NEAR_POINT, DoomfireMovement(me->GetPosition())); - }, 1500ms); + float nextOrientation = Position::NormalizeOrientation(me->GetOrientation() + irand(-1, 1) * turnConstant); + Position pos = GetFirstRandomAngleCollisionPosition(8.f, nextOrientation); // both orientation and distance verified with sniffs + me->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), nextOrientation); + }, 1600ms); + + fAngle = urand(0, M_PI * 2); } - Position DoomfireMovement(Position mePos) + Position GetFirstRandomAngleCollisionPosition(float dist, float angle) { - float angle = mePos.GetOrientation(); - float distance = 100.0f; - float newAngle = angle + ((rand() % 181) - 90) * M_PI / 180; - float x = mePos.GetPositionX() + distance * cos(newAngle); - float y = mePos.GetPositionY() + distance * sin(newAngle); - - Position targetPos = Position(x, y, me->GetPositionZ()); - return targetPos; + Position pos; + for (uint32 i = 0; i < 10; ++i) + { + pos = me->WorldObject::GetFirstCollisionPosition(dist, angle); + if (me->GetDistance(pos) > dist * 0.8f) // if at least 80% distance, good enough + break; + angle += (M_PI / 5); // else try slightly different angle + } + return pos; } void UpdateAI(uint32 diff) override { scheduler.Update(diff); - - if (!UpdateVictim()) - return; - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; } }; @@ -313,7 +315,7 @@ struct boss_archimonde : public BossAI DoCastVictim(SPELL_RED_SKY_EFFECT); DoCastVictim(SPELL_HAND_OF_DEATH); }, 3s); - scheduler.Schedule(25s, 35s, GROUP_FEAR, [this](TaskContext context) + scheduler.Schedule(40s, GROUP_FEAR, [this](TaskContext context) { DoCastAOE(SPELL_FEAR); context.Repeat(42s); @@ -381,11 +383,6 @@ struct boss_archimonde : public BossAI summoned->CastSpell(summoned, SPELL_DOOMFIRE_SPAWN); summoned->CastSpell(summoned, SPELL_DOOMFIRE, true, 0, 0, me->GetGUID()); } - else if (summoned->GetEntry() == CREATURE_DOOMFIRE_SPIRIT) - { - Position randomPosition = summoned->GetRandomNearPosition(40.0f); - summoned->GetMotionMaster()->MovePoint(0, randomPosition); - } else { summoned->SetFaction(me->GetFaction()); //remove? From d2e6eee205a8abb2e2f5129b0ee52150f701e9da Mon Sep 17 00:00:00 2001 From: Jelle Meeus Date: Thu, 4 Jul 2024 19:32:56 +0200 Subject: [PATCH 18/68] fix(DB/Creature): set Idol Room Spawner no longer visible (#19276) --- data/sql/updates/pending_db_world/rev_1720109494288604410.sql | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1720109494288604410.sql diff --git a/data/sql/updates/pending_db_world/rev_1720109494288604410.sql b/data/sql/updates/pending_db_world/rev_1720109494288604410.sql new file mode 100644 index 000000000..37da3b1cf --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1720109494288604410.sql @@ -0,0 +1,2 @@ +-- +UPDATE `creature_template` SET `flags_extra` = `flags_extra` | 128 WHERE `entry` = 8611; From 96e94cd95dd497f97fbc74f57b35bb464602c258 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 4 Jul 2024 17:34:01 +0000 Subject: [PATCH 19/68] chore(DB): import pending files Referenced commit(s): d2e6eee205a8abb2e2f5129b0ee52150f701e9da --- .../rev_1720109494288604410.sql => db_world/2024_07_04_01.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1720109494288604410.sql => db_world/2024_07_04_01.sql} (67%) diff --git a/data/sql/updates/pending_db_world/rev_1720109494288604410.sql b/data/sql/updates/db_world/2024_07_04_01.sql similarity index 67% rename from data/sql/updates/pending_db_world/rev_1720109494288604410.sql rename to data/sql/updates/db_world/2024_07_04_01.sql index 37da3b1cf..863d045ca 100644 --- a/data/sql/updates/pending_db_world/rev_1720109494288604410.sql +++ b/data/sql/updates/db_world/2024_07_04_01.sql @@ -1,2 +1,3 @@ +-- DB update 2024_07_04_00 -> 2024_07_04_01 -- UPDATE `creature_template` SET `flags_extra` = `flags_extra` | 128 WHERE `entry` = 8611; From 8bca8a45edf85a73fe77ee28b6d7a9009e2ebd25 Mon Sep 17 00:00:00 2001 From: Kitzunu <24550914+Kitzunu@users.noreply.github.com> Date: Thu, 4 Jul 2024 19:47:36 +0200 Subject: [PATCH 20/68] chore(Core/Spells): Fix compile warning (#19278) * chore(Core/Spells): Fix compile warning * s --- src/server/game/Spells/Auras/SpellAuraEffects.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 85b2a5995..63af8f62b 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -2011,7 +2011,7 @@ void AuraEffect::HandleAuraModShapeshift(AuraApplication const* aurApp, uint8 mo if (modelid > 0) { bool allow = true; - if (target->getTransForm() && !target->GetMapId() == 560 /*The Escape From Durnholde*/) + if (target->getTransForm() && !(target->GetMapId() == 560 /*The Escape From Durnholde*/)) if (SpellInfo const* transformSpellInfo = sSpellMgr->GetSpellInfo(target->getTransForm())) if (transformSpellInfo->HasAttribute(SPELL_ATTR0_NO_IMMUNITIES) || !transformSpellInfo->IsPositive()) allow = false; From 9de2178eb500ddf1a20eafddf25ad34f5bad6c54 Mon Sep 17 00:00:00 2001 From: Jelle Meeus Date: Thu, 4 Jul 2024 19:59:53 +0200 Subject: [PATCH 21/68] fix(Scripts/Naxxramas): Razuvious' Death Knight Understudy RP (#19183) --- .../rev_1715986644313348181.sql | 13 ++ .../Northrend/Naxxramas/boss_razuvious.cpp | 195 ++++++++++++++++-- .../Naxxramas/instance_naxxramas.cpp | 16 ++ .../scripts/Northrend/Naxxramas/naxxramas.h | 44 ++-- 4 files changed, 234 insertions(+), 34 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1715986644313348181.sql diff --git a/data/sql/updates/pending_db_world/rev_1715986644313348181.sql b/data/sql/updates/pending_db_world/rev_1715986644313348181.sql new file mode 100644 index 000000000..466919755 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1715986644313348181.sql @@ -0,0 +1,13 @@ +-- +-- Razuvious +DELETE FROM `creature_text` WHERE `CreatureID` = 16061 AND `GroupID` IN (4, 5); +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(16061, 4, 0, 'Pathetic...', 12, 0, 100, 5, 0, 0, 27865, 0, 'Razuvious SAY_PATHETIC'), +(16061, 5, 0, 'Start doing something before I replace that target dummy with you and begin a warm up session of my own!', 12, 0, 100, 5, 0, 0, 13136, 0, 'Razuvious SAY_TARGET_DUMMY'); + +-- Death Knight Understudy +DELETE FROM `creature_text` WHERE `CreatureID` = 16803; +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(16803, 0, 0, 'Sir, student requests that you beat him for his lack of understanding!', 12, 0, 100, 1, 0, 0, 13140, 0, 'Death Knight Understudy SAY_BEAT_ME'), +(16803, 0, 1, 'I am unworthy, master!', 12, 0, 100, 1, 0, 0, 13138, 0, 'Death Knight Understudy SAY_UNWORTHY'), +(16803, 0, 2, 'Student is worthless, master! Student apologizes for his deficiency!', 12, 0, 100, 1, 0, 0, 13137, 0, 'Death Knight Understudy SAY_WORTHLESS'); diff --git a/src/server/scripts/Northrend/Naxxramas/boss_razuvious.cpp b/src/server/scripts/Northrend/Naxxramas/boss_razuvious.cpp index 9264e851f..eed3cd6cf 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_razuvious.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_razuvious.cpp @@ -24,7 +24,10 @@ enum Says SAY_AGGRO = 0, SAY_SLAY = 1, SAY_TAUNTED = 2, - SAY_DEATH = 3 + SAY_DEATH = 3, + SAY_PATHETIC = 4, + SAY_TARGET_DUMMY = 5, + SAY_DEATH_KNIGHT_UNDERSTUDY = 0, }; enum Spells @@ -34,7 +37,6 @@ enum Spells SPELL_DISRUPTING_SHOUT_25 = 29107, SPELL_JAGGED_KNIFE = 55550, SPELL_HOPELESS = 29125, - SPELL_TAUNT = 29060 }; @@ -45,10 +47,25 @@ enum Events EVENT_JAGGED_KNIFE = 3 }; -enum Misc +enum NPCs { NPC_DEATH_KNIGHT_UNDERSTUDY = 16803, - NPC_RAZUVIOUS = 16061 + NPC_TARGET_DUMMY = 16211, +}; + +enum Actions +{ + ACTION_FACE_ME = 0, + ACTION_TALK = 1, + ACTION_EMOTE = 2, + ACTION_SALUTE = 3, + ACTION_BACK_TO_TRAINING = 4, +}; + +enum Misc +{ + GROUP_OOC_RP = 0, + POINT_DEATH_KNIGHT = 0, }; class boss_razuvious : public CreatureScript @@ -94,6 +111,99 @@ public: summons.DespawnAll(); events.Reset(); SpawnHelpers(); + ScheduleRP(); + } + + void ScheduleInteractWithDeathKnight() + { + if (_rpBuddyGUID) + if (Creature* understudy = ObjectAccessor::GetCreature(*me, _rpBuddyGUID)) + me->SetFacingToObject(understudy); + + scheduler.Schedule(2s, GROUP_OOC_RP, [this](TaskContext /*context*/) + { + if (roll_chance_i(75)) + { + bool longText = roll_chance_i(50); + Talk(longText ? SAY_TARGET_DUMMY : SAY_PATHETIC); + scheduler.Schedule(4s, GROUP_OOC_RP, [this](TaskContext /*context*/) + { + if (_rpBuddyGUID) + if (Creature* understudy = ObjectAccessor::GetCreature(*me, _rpBuddyGUID)) + understudy->AI()->DoAction(ACTION_TALK); + }); + if (longText) + scheduler.DelayGroup(GROUP_OOC_RP, 5s); + } + else + { + me->HandleEmoteCommand(EMOTE_ONESHOT_EXCLAMATION); + scheduler.Schedule(4s, GROUP_OOC_RP, [this](TaskContext /*context*/) + { + if (_rpBuddyGUID) + if (Creature* understudy = ObjectAccessor::GetCreature(*me, _rpBuddyGUID)) + { + if (roll_chance_i(25)) + understudy->AI()->DoAction(ACTION_EMOTE); + else + understudy->AI()->DoAction(ACTION_TALK); + } + }); + } + }).Schedule(4s, GROUP_OOC_RP, [this](TaskContext /*context*/) + { + if (_rpBuddyGUID) + if (Creature* understudy = ObjectAccessor::GetCreature(*me, _rpBuddyGUID)) + understudy->AI()->DoAction(ACTION_FACE_ME); + }).Schedule(10s, GROUP_OOC_RP, [this](TaskContext /*context*/) + { + if (_rpBuddyGUID) + if (Creature* understudy = ObjectAccessor::GetCreature(*me, _rpBuddyGUID)) + understudy->AI()->DoAction(ACTION_SALUTE); + }).Schedule(13s, GROUP_OOC_RP, [this](TaskContext /*context*/) + { + me->ResumeMovement(); + }).Schedule(16s, GROUP_OOC_RP, [this](TaskContext /*context*/) + { + if (_rpBuddyGUID) + if (Creature* understudy = ObjectAccessor::GetCreature(*me, _rpBuddyGUID)) + understudy->AI()->DoAction(ACTION_BACK_TO_TRAINING); + ScheduleRP(); + }); + } + + void MovementInform(uint32 type, uint32 id) override + { + if (type == POINT_MOTION_TYPE && id == POINT_DEATH_KNIGHT) + { + ScheduleInteractWithDeathKnight(); + } + } + + void ScheduleRP() + { + _rpBuddyGUID = Acore::Containers::SelectRandomContainerElement(summons); + scheduler.Schedule(60s, 80s, GROUP_OOC_RP, [this](TaskContext context) + { + if (_rpBuddyGUID) + { + if (Creature* understudy = ObjectAccessor::GetCreature(*me, _rpBuddyGUID)) + { + if (me->GetDistance2d(understudy) <= 6.0f) + { + me->PauseMovement(); + scheduler.Schedule(500ms, GROUP_OOC_RP, [this](TaskContext /*context*/) + { + if (_rpBuddyGUID) + if (Creature* understudy = ObjectAccessor::GetCreature(*me, _rpBuddyGUID)) + me->GetMotionMaster()->MovePoint(POINT_DEATH_KNIGHT, understudy->GetNearPosition(3.2f, understudy->GetRelativeAngle(me))); + }); + return; + } + } + } + context.Repeat(2s); + }); } void KilledUnit(Unit* who) override @@ -135,6 +245,7 @@ public: void JustEngagedWith(Unit* who) override { BossAI::JustEngagedWith(who); + scheduler.CancelGroup(GROUP_OOC_RP); Talk(SAY_AGGRO); events.ScheduleEvent(EVENT_UNBALANCING_STRIKE, 20s); events.ScheduleEvent(EVENT_DISRUPTING_SHOUT, 15s); @@ -144,6 +255,9 @@ public: void UpdateAI(uint32 diff) override { + if (!me->IsInCombat()) + scheduler.Update(diff); + if (!UpdateVictim()) return; @@ -171,6 +285,9 @@ public: } DoMeleeAttackIfReady(); } + + private: + ObjectGuid _rpBuddyGUID; }; }; @@ -179,20 +296,65 @@ class boss_razuvious_minion : public CreatureScript public: boss_razuvious_minion() : CreatureScript("boss_razuvious_minion") { } - CreatureAI* GetAI(Creature* pCreature) const override + CreatureAI* GetAI(Creature* creature) const override { - return GetNaxxramasAI(pCreature); + return GetNaxxramasAI(creature); } struct boss_razuvious_minionAI : public ScriptedAI { - explicit boss_razuvious_minionAI(Creature* c) : ScriptedAI(c) { } - - EventMap events; + explicit boss_razuvious_minionAI(Creature* creature) : ScriptedAI(creature) { } void Reset() override { - events.Reset(); + scheduler.CancelAll(); + ScheduleAttackDummy(); + } + + void ScheduleAttackDummy() + { + me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_READY1H); + if (Creature* targetDummy = me->FindNearestCreature(NPC_TARGET_DUMMY, 10.0f)) + { + me->SetFacingToObject(targetDummy); + } + scheduler.Schedule(6s, 9s, GROUP_OOC_RP, [this](TaskContext context) + { + me->HandleEmoteCommand(EMOTE_ONESHOT_ATTACK1H); + context.Repeat(6s, 9s); + }); + } + + void DoAction(int32 action) override + { + switch (action) + { + case ACTION_FACE_ME: + scheduler.CancelGroup(GROUP_OOC_RP); + me->SetSheath(SHEATH_STATE_UNARMED); + me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_NONE); + if (InstanceScript* instance = me->GetInstanceScript()) + { + if (Creature* creature = instance->GetCreature(DATA_RAZUVIOUS)) + { + me->SetFacingToObject(creature); + } + } + break; + case ACTION_TALK: + Talk(SAY_DEATH_KNIGHT_UNDERSTUDY); + break; + case ACTION_EMOTE: + me->HandleEmoteCommand(EMOTE_ONESHOT_TALK); + break; + case ACTION_SALUTE: + me->HandleEmoteCommand(EMOTE_ONESHOT_SALUTE); + break; + case ACTION_BACK_TO_TRAINING: + me->SetSheath(SHEATH_STATE_MELEE); + ScheduleAttackDummy(); + break; + } } void KilledUnit(Unit* who) override @@ -205,18 +367,23 @@ public: void JustEngagedWith(Unit* who) override { - if (Creature* cr = me->FindNearestCreature(NPC_RAZUVIOUS, 100.0f)) + scheduler.CancelGroup(GROUP_OOC_RP); + if (InstanceScript* instance = me->GetInstanceScript()) { - cr->SetInCombatWithZone(); - cr->AI()->AttackStart(who); + if (Creature* creature = instance->GetCreature(DATA_RAZUVIOUS)) + { + creature->SetInCombatWithZone(); + creature->AI()->AttackStart(who); + } } } void UpdateAI(uint32 diff) override { + scheduler.Update(diff); + if (UpdateVictim()) { - events.Update(diff); if (!me->HasUnitState(UNIT_STATE_CASTING) || !me->IsCharmed()) { DoMeleeAttackIfReady(); diff --git a/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp b/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp index 2f45192b7..431e5ae55 100644 --- a/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp +++ b/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp @@ -52,6 +52,17 @@ inline uint8 GetEruptionSection(float x, float y) return 3; } +ObjectData const creatureData[] = +{ + { NPC_RAZUVIOUS, DATA_RAZUVIOUS }, + { 0, 0 } +}; + +ObjectData const gameObjectData[] = +{ + { 0, 0 } +}; + class instance_naxxramas : public InstanceMapScript { public: @@ -68,6 +79,7 @@ public: { SetHeaders(DataHeader); SetBossNumber(MAX_ENCOUNTERS); + LoadObjectData(creatureData, gameObjectData); for (auto& i : HeiganEruption) i.clear(); @@ -253,6 +265,8 @@ public: _lichkingGUID = creature->GetGUID(); return; } + + InstanceScript::OnCreatureCreate(creature); } void OnGameObjectCreate(GameObject* pGo) override @@ -498,6 +512,8 @@ public: } break; } + + InstanceScript::OnGameObjectCreate(pGo); } void OnGameObjectRemove(GameObject* pGo) override diff --git a/src/server/scripts/Northrend/Naxxramas/naxxramas.h b/src/server/scripts/Northrend/Naxxramas/naxxramas.h index 256ca8633..5c237d784 100644 --- a/src/server/scripts/Northrend/Naxxramas/naxxramas.h +++ b/src/server/scripts/Northrend/Naxxramas/naxxramas.h @@ -58,26 +58,27 @@ enum NXData DATA_STALAGG_BOSS = 108, DATA_FEUGEN_BOSS = 109, DATA_THADDIUS_GATE = 110, - DATA_GOTHIK_BOSS = 111, - DATA_GOTHIK_ENTER_GATE = 112, - DATA_GOTHIK_INNER_GATE = 113, - DATA_GOTHIK_EXIT_GATE = 114, - DATA_HORSEMEN_GATE = 115, - DATA_LICH_KING_BOSS = 116, - DATA_KELTHUZAD_FLOOR = 117, - DATA_ABOMINATION_KILLED = 118, - DATA_FRENZY_REMOVED = 119, - DATA_CHARGES_CROSSED = 120, - DATA_SPORE_KILLED = 121, - DATA_HUNDRED_CLUB = 122, - DATA_DANCE_FAIL = 123, - DATA_IMMORTAL_FAIL = 124, - DATA_KELTHUZAD_GATE = 125, - DATA_HAD_THADDIUS_GREET = 126, - DATA_KELTHUZAD_PORTAL_1 = 127, - DATA_KELTHUZAD_PORTAL_2 = 128, - DATA_KELTHUZAD_PORTAL_3 = 129, - DATA_KELTHUZAD_PORTAL_4 = 130 + DATA_RAZUVIOUS = 111, + DATA_GOTHIK_BOSS = 112, + DATA_GOTHIK_ENTER_GATE = 113, + DATA_GOTHIK_INNER_GATE = 114, + DATA_GOTHIK_EXIT_GATE = 115, + DATA_HORSEMEN_GATE = 116, + DATA_LICH_KING_BOSS = 117, + DATA_KELTHUZAD_FLOOR = 118, + DATA_ABOMINATION_KILLED = 119, + DATA_FRENZY_REMOVED = 120, + DATA_CHARGES_CROSSED = 121, + DATA_SPORE_KILLED = 122, + DATA_HUNDRED_CLUB = 123, + DATA_DANCE_FAIL = 124, + DATA_IMMORTAL_FAIL = 125, + DATA_KELTHUZAD_GATE = 126, + DATA_HAD_THADDIUS_GREET = 127, + DATA_KELTHUZAD_PORTAL_1 = 128, + DATA_KELTHUZAD_PORTAL_2 = 129, + DATA_KELTHUZAD_PORTAL_3 = 130, + DATA_KELTHUZAD_PORTAL_4 = 131 }; enum NXGOs @@ -137,6 +138,9 @@ enum NXNPCs NPC_STALAGG = 15929, NPC_FEUGEN = 15930, + // Razuvious + NPC_RAZUVIOUS = 16061, + // Four horseman NPC_BARON_RIVENDARE = 30549, NPC_SIR_ZELIEK = 16063, From 90974332bb4adf372e904a676999f7b786c12d00 Mon Sep 17 00:00:00 2001 From: daobashun <49193927+fangshun2004@users.noreply.github.com> Date: Fri, 5 Jul 2024 02:13:13 +0800 Subject: [PATCH 22/68] fix(DB/SAI): Added healing options for the Silver Dawn Healer in the Eastern Plaguelands (#18852) * add sai * Remove duplicates * Gossip Menu 2 may only appear if Silver Dawn has reached Friendly or higher (being able to confirm that neutrality is none) --- .../rev_1714139994033487600.sql | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1714139994033487600.sql diff --git a/data/sql/updates/pending_db_world/rev_1714139994033487600.sql b/data/sql/updates/pending_db_world/rev_1714139994033487600.sql new file mode 100644 index 000000000..1ff745f8c --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1714139994033487600.sql @@ -0,0 +1,32 @@ +DELETE FROM `gossip_menu` WHERE `MenuID` = 7175; +INSERT INTO `gossip_menu` (`MenuID`, `TextID`) VALUES +(7175, 8454), +(7175, 8455); +DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 14) AND (`SourceGroup` IN (7175)); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `Comment`) VALUES +(14, 7175, 8455, 0, 0, 5, 0, 529, 240, 0, 0, 'Player for which gossip text is shown has at least reputation Friendly, Honored, Revered, Exalted to faction 529'); + +DELETE FROM `gossip_menu_option` WHERE `MenuID` = 7175; +INSERT INTO `gossip_menu_option` (`MenuID`, `OptionID`, `OptionIcon`, `OptionText`, `OptionBroadcastTextID`, `OptionType`, `OptionNpcFlag`, `ActionMenuID`, `ActionPoiID`, `BoxCoded`, `BoxMoney`, `BoxText`, `BoxBroadcastTextID`, `VerifiedBuild`) VALUES +(7175, 0, 0, 'I am diseased. Please cure me, medic.', 12154, 1, 1, 0, 0, 0, 0, NULL, 0, 0); + +DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 15) AND (`SourceGroup` IN (7175)); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `Comment`) VALUES +(15, 7175, 0, 0, 0, 1, 0, 12541, 0, 0, 0, 'Player for which gossip text is shown has aura of spell Ghoul Rot (Ghoul Rot12541), effect EFFECT_0'), +(15, 7175, 0, 0, 1, 1, 0, 3427, 0, 0, 0, 'Player for which gossip text is shown has aura of spell Infected Wound (3427), effect EFFECT_0'), +(15, 7175, 0, 0, 2, 1, 0, 16449, 0, 0, 0, 'Player for which gossip text is shown has aura of spell Maggot Slime (16449), effect EFFECT_0'); + +-- Argent Medic smart ai +SET @ENTRY := 16284; +UPDATE `creature_template` SET `AIName` = 'SmartAI', `ScriptName` = '' WHERE `entry` = @ENTRY; +DELETE FROM `smart_scripts` WHERE `source_type` = 0 AND `entryOrGuid` = @ENTRY; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(@ENTRY, 0, 0, 0, 2, 0, 100, 1, 0, 15, 0, 0, 25, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'Argent Medic - Self: Flee for assist'), +(@ENTRY, 0, 1, 0, 25, 0, 100, 0, 0, 0, 0, 0, 22, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'Argent Medic - On reset - Set event phase to phase 1'), +(@ENTRY, 0, 2, 0, 62, 0, 100, 512, 7175, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 'Player - On gossip action 0 from menu 7175 selected - Gossip player: Close gossip'), +(@ENTRY, 0, 3, 4, 62, 1, 100, 512, 7175, 0, 0, 0, 22, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'Player - On gossip action 0 from menu 7175 selected - Set event phase to phase 2'), +(@ENTRY, 0, 4, 0, 61, 0, 100, 0, 0, 0, 0, 0, 11, 28133, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 'Player - On gossip action 0 from menu 7175 selected - Self: Cast spell Cure Disease (28133) on Gossip player'), +(@ENTRY, 0, 5, 0, 31, 0, 100, 0, 28133, 0, 0, 0, 22, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'Argent Medic - On spell Cure Disease (28133) hit a target - Set event phase to phase 1'); + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` = 22 AND `SourceEntry` = 16284 AND `SourceId` = 0; + From 65eb900c550686260e86cbcf4f9117181ec30458 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 4 Jul 2024 18:13:33 +0000 Subject: [PATCH 23/68] chore(DB): import pending files Referenced commit(s): 9de2178eb500ddf1a20eafddf25ad34f5bad6c54 --- .../rev_1714139994033487600.sql => db_world/2024_07_04_02.sql} | 1 + .../rev_1715986644313348181.sql => db_world/2024_07_04_03.sql} | 1 + 2 files changed, 2 insertions(+) rename data/sql/updates/{pending_db_world/rev_1714139994033487600.sql => db_world/2024_07_04_02.sql} (98%) rename data/sql/updates/{pending_db_world/rev_1715986644313348181.sql => db_world/2024_07_04_03.sql} (96%) diff --git a/data/sql/updates/pending_db_world/rev_1714139994033487600.sql b/data/sql/updates/db_world/2024_07_04_02.sql similarity index 98% rename from data/sql/updates/pending_db_world/rev_1714139994033487600.sql rename to data/sql/updates/db_world/2024_07_04_02.sql index 1ff745f8c..7c27ae5bd 100644 --- a/data/sql/updates/pending_db_world/rev_1714139994033487600.sql +++ b/data/sql/updates/db_world/2024_07_04_02.sql @@ -1,3 +1,4 @@ +-- DB update 2024_07_04_01 -> 2024_07_04_02 DELETE FROM `gossip_menu` WHERE `MenuID` = 7175; INSERT INTO `gossip_menu` (`MenuID`, `TextID`) VALUES (7175, 8454), diff --git a/data/sql/updates/pending_db_world/rev_1715986644313348181.sql b/data/sql/updates/db_world/2024_07_04_03.sql similarity index 96% rename from data/sql/updates/pending_db_world/rev_1715986644313348181.sql rename to data/sql/updates/db_world/2024_07_04_03.sql index 466919755..1ef76fb66 100644 --- a/data/sql/updates/pending_db_world/rev_1715986644313348181.sql +++ b/data/sql/updates/db_world/2024_07_04_03.sql @@ -1,3 +1,4 @@ +-- DB update 2024_07_04_02 -> 2024_07_04_03 -- -- Razuvious DELETE FROM `creature_text` WHERE `CreatureID` = 16061 AND `GroupID` IN (4, 5); From b959d5cc87e262efdebf1fc079a3637b41af3df2 Mon Sep 17 00:00:00 2001 From: Dan <83884799+elthehablo@users.noreply.github.com> Date: Thu, 4 Jul 2024 20:13:41 +0200 Subject: [PATCH 24/68] refactor(Scripts/ZulAman): Nalorakk refactored (#19010) * init * update movement * updates and debug * stuck :/ scheduler doesn't seem to update when at the end of wp movement??? * fix wps and implement fight * finalise * unused * Update boss_nalorakk.cpp * keep oprientation * ran_intro --- .../updates/pending_db_world/waypoints.sql | 14 + .../EasternKingdoms/ZulAman/boss_nalorakk.cpp | 642 ++++++++---------- .../ZulAman/instance_zulaman.cpp | 4 +- .../scripts/EasternKingdoms/ZulAman/zulaman.h | 6 +- 4 files changed, 286 insertions(+), 380 deletions(-) create mode 100644 data/sql/updates/pending_db_world/waypoints.sql diff --git a/data/sql/updates/pending_db_world/waypoints.sql b/data/sql/updates/pending_db_world/waypoints.sql new file mode 100644 index 000000000..f36912184 --- /dev/null +++ b/data/sql/updates/pending_db_world/waypoints.sql @@ -0,0 +1,14 @@ +-- +DELETE FROM `waypoint_data` WHERE `id` IN (2357601, 2357602, 2357603); +INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `orientation`, `delay`, `move_type`, `action`, `action_chance`, `wpguid`) VALUES +(2357601, 1, -52.642, 1419.357, 27.31, NULL, 0, 1, 0, 100, 0), +(2357602, 1, -69.908, 1419.721, 27.31, NULL, 0, 1, 0, 100, 0), +(2357602, 2, -79.929, 1395.958, 27.31, NULL, 0, 1, 0, 100, 0), +(2357602, 3, -80.072, 1374.555, 40.87, NULL, 0, 1, 0, 100, 0), +(2357603, 1, -80.072, 1314.398, 40.87, NULL, 0, 1, 0, 100, 0), +(2357603, 2, -80.072, 1295.775, 48.60, NULL, 0, 1, 0, 100, 0); + +DELETE FROM `creature_text` WHERE `CreatureID` = 23576 AND `GroupID` IN (14, 15); +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(23576, 14, 0, 'Mua-ha-ha!', 14, 0, 100, 0, 0, 0, 22145, 1, 'Nalorakk - RUN AWAY'), +(23576, 15, 0, '%s transforms into a bear!', 16, 0, 100, 0, 0, 0, 24263, 1, 'Nalorakk - EMOTE BEAR'); diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_nalorakk.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_nalorakk.cpp index 5631b5edc..af0e1e19d 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/boss_nalorakk.cpp +++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_nalorakk.cpp @@ -46,19 +46,6 @@ enum Spells SPELL_DEAFENINGROAR = 42398 }; -// Trash Waves -float NalorakkWay[8][3] = -{ - { 18.569f, 1414.512f, 11.42f}, // waypoint 1 - {-17.264f, 1419.551f, 12.62f}, - {-52.642f, 1419.357f, 27.31f}, // waypoint 2 - {-69.908f, 1419.721f, 27.31f}, - {-79.929f, 1395.958f, 27.31f}, - {-80.072f, 1374.555f, 40.87f}, // waypoint 3 - {-80.072f, 1314.398f, 40.87f}, - {-80.072f, 1295.775f, 48.60f} // waypoint 4 -}; - enum Talks { SAY_WAVE1 = 0, @@ -74,399 +61,300 @@ enum Talks SAY_KILL_TWO, SAY_DEATH, SAY_NALORAKK_EVENT1, // Not implemented - SAY_NALORAKK_EVENT2 // Not implemented + SAY_NALORAKK_EVENT2, // Not implemented + SAY_RUN_AWAY, + EMOTE_BEAR }; -class boss_nalorakk : public CreatureScript +enum Phases { -public: - boss_nalorakk() - : CreatureScript("boss_nalorakk") + PHASE_SEND_GUARDS_1 = 0, + PHASE_SEND_GUARDS_2 = 1, + PHASE_SEND_GUARDS_3 = 2, + PHASE_SEND_GUARDS_4 = 3, + PHASE_SEND_GUARDS_5 = 4, + PHASE_START_COMBAT = 5 +}; + +enum NalorakkGroups +{ + GROUP_CHECK_DEAD = 1, + GROUP_MOVE = 2, + GROUP_BERSERK = 3, + GROUP_HUMAN = 4, + GROUP_BEAR = 5 +}; + +struct boss_nalorakk : public BossAI +{ + boss_nalorakk(Creature* creature) : BossAI(creature, DATA_NALORAKKEVENT) { + _ranIntro = false; + _active = true; + creature->SetReactState(REACT_PASSIVE); + me->SetImmuneToAll(true); } - struct boss_nalorakkAI : public ScriptedAI + void Reset() override { - boss_nalorakkAI(Creature* creature) : ScriptedAI(creature) + BossAI::Reset(); + _waveList.clear(); + _introScheduler.CancelAll(); + if (_bearForm) { - MoveEvent = true; - MovePhase = 0; - instance = creature->GetInstanceScript(); + me->RemoveAurasDueToSpell(SPELL_BEARFORM); + _bearForm = false; } - - InstanceScript* instance; - - uint32 BrutalSwipe_Timer; - uint32 Mangle_Timer; - uint32 Surge_Timer; - - uint32 LaceratingSlash_Timer; - uint32 RendFlesh_Timer; - uint32 DeafeningRoar_Timer; - - uint32 ShapeShift_Timer; - uint32 Berserk_Timer; - - bool inBearForm; - bool MoveEvent; - bool inMove; - uint32 MovePhase; - uint32 waitTimer; - - void Reset() override + if (_ranIntro) { - if (MoveEvent) - { - me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE); - inMove = false; - waitTimer = 0; - me->SetSpeed(MOVE_RUN, 2); - me->SetWalk(false); - ResetMobs(); - } - else - { - (*me).GetMotionMaster()->MovePoint(0, NalorakkWay[7][0], NalorakkWay[7][1], NalorakkWay[7][2]); - } + _phase = PHASE_START_COMBAT; + me->SetReactState(REACT_AGGRESSIVE); + _active = false; - if (instance) - { - instance->SetData(DATA_NALORAKKEVENT, NOT_STARTED); - } - - Surge_Timer = urand(15000, 20000); - BrutalSwipe_Timer = urand(7000, 12000); - Mangle_Timer = urand(10000, 15000); - ShapeShift_Timer = urand(45000, 50000); - Berserk_Timer = 600000; - - inBearForm = false; - // me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, 5122); /// @todo find the correct equipment id } + } - void ResetMobs() + void MoveInLineOfSight(Unit* who) override + { + if (who->IsPlayer() && _phase < PHASE_START_COMBAT && _active) { - std::list templist; - float x, y, z; - me->GetPosition(x, y, z); - + _active = false; + switch (_phase) { - CellCoord pair(Acore::ComputeCellCoord(x, y)); - Cell cell(pair); - cell.SetNoCreate(); - - Acore::AllFriendlyCreaturesInGrid check(me); - Acore::CreatureListSearcher searcher(me, templist, check); - - TypeContainerVisitor, GridTypeMapContainer> cSearcher(searcher); - - cell.Visit(pair, cSearcher, *(me->GetMap()), *me, me->GetGridActivationRange()); - } - - if (templist.empty()) - return; - - for (std::list::const_iterator i = templist.begin(); i != templist.end(); ++i) - if ((*i) && me->GetGUID() != (*i)->GetGUID() && me->IsWithinDistInMap((*i), 25)) - (*i)->AI()->Reset(); - } - - void SendAttacker(Unit* target) - { - std::list templist; - float x, y, z; - me->GetPosition(x, y, z); - - { - CellCoord pair(Acore::ComputeCellCoord(x, y)); - Cell cell(pair); - cell.SetNoCreate(); - - Acore::AllFriendlyCreaturesInGrid check(me); - Acore::CreatureListSearcher searcher(me, templist, check); - - TypeContainerVisitor, GridTypeMapContainer> cSearcher(searcher); - - cell.Visit(pair, cSearcher, *(me->GetMap()), *me, me->GetGridActivationRange()); - } - - if (templist.empty()) - return; - - for (std::list::const_iterator i = templist.begin(); i != templist.end(); ++i) - { - if ((*i) && me->IsWithinDistInMap((*i), 25)) - { - (*i)->SetNoCallAssistance(true); - (*i)->AI()->AttackStart(target); - } - } - } - - void AttackStart(Unit* who) override - { - if (!MoveEvent) - ScriptedAI::AttackStart(who); - } - - void MoveInLineOfSight(Unit* who) override - - { - if (!MoveEvent) - { - ScriptedAI::MoveInLineOfSight(who); - } - else - { - if (me->IsHostileTo(who)) - { - if (!inMove) + case PHASE_SEND_GUARDS_1: + me->GetCreaturesWithEntryInRange(_waveList, 10.0f, NPC_AMANISHI_AXE_THROWER); + me->GetCreaturesWithEntryInRange(_waveList, 10.0f, NPC_AMANISHI_TRIBESMAN); + GroupedAttack(_waveList); + Talk(SAY_WAVE1); + _introScheduler.Schedule(5s, GROUP_CHECK_DEAD, [this](TaskContext context) { - switch (MovePhase) + if (CheckFullyDeadGroup(_waveList)) { - case 0: - if (me->IsWithinDistInMap(who, 50)) + if (_phase == PHASE_SEND_GUARDS_1) + { + _introScheduler.CancelGroup(GROUP_CHECK_DEAD); + _waveList.clear(); + me->GetMotionMaster()->MovePath(me->GetEntry()*100+1, false); + Talk(SAY_RUN_AWAY); + _introScheduler.Schedule(5s, [this](TaskContext) { - Talk(SAY_WAVE1); - - (*me).GetMotionMaster()->MovePoint(1, NalorakkWay[1][0], NalorakkWay[1][1], NalorakkWay[1][2]); - MovePhase ++; - inMove = true; - - SendAttacker(who); - } - break; - case 2: - if (me->IsWithinDistInMap(who, 40)) - { - Talk(SAY_WAVE2); - - (*me).GetMotionMaster()->MovePoint(3, NalorakkWay[3][0], NalorakkWay[3][1], NalorakkWay[3][2]); - MovePhase ++; - inMove = true; - - SendAttacker(who); - } - break; - case 5: - if (me->IsWithinDistInMap(who, 40)) - { - Talk(SAY_WAVE3); - - (*me).GetMotionMaster()->MovePoint(6, NalorakkWay[6][0], NalorakkWay[6][1], NalorakkWay[6][2]); - MovePhase ++; - inMove = true; - - SendAttacker(who); - } - break; - case 7: - if (me->IsWithinDistInMap(who, 50)) - { - SendAttacker(who); - - Talk(SAY_WAVE4); - - me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE); - - MoveEvent = false; - } - break; + me->SetFacingTo(6.25f); + _active = true; + }); + _phase = PHASE_SEND_GUARDS_2; + } } - } - } - } - } - - void JustEngagedWith(Unit* /*who*/) override - { - if (instance) - instance->SetData(DATA_NALORAKKEVENT, IN_PROGRESS); - - Talk(SAY_AGGRO); - DoZoneInCombat(); - } - - void JustDied(Unit* /*killer*/) override - { - ResetMobs(); - - if (instance) - instance->SetData(DATA_NALORAKKEVENT, DONE); - - Talk(SAY_DEATH); - } - - void KilledUnit(Unit* /*victim*/) override - { - switch (urand(0, 1)) - { - case 0: - Talk(SAY_KILL_ONE); + context.Repeat(5s); + }); break; - case 1: - Talk(SAY_KILL_TWO); - break; - } - } - - void MovementInform(uint32 type, uint32 id) override - { - if (MoveEvent) - { - if (type != POINT_MOTION_TYPE) - return; - - if (!inMove) - return; - - if (MovePhase != id) - return; - - switch (MovePhase) - { - case 2: - me->SetOrientation(3.1415f * 2); - inMove = false; - return; - case 1: - case 3: - case 4: - case 6: - MovePhase ++; - waitTimer = 1; - inMove = true; - return; - case 5: - me->SetOrientation(3.1415f * 0.5f); - inMove = false; - return; - case 7: - me->SetOrientation(3.1415f * 0.5f); - inMove = false; - return; - } - } - } - - void UpdateAI(uint32 diff) override - { - if (waitTimer && inMove) - { - if (waitTimer <= diff) - { - (*me).GetMotionMaster()->MovementExpired(); - (*me).GetMotionMaster()->MovePoint(MovePhase, NalorakkWay[MovePhase][0], NalorakkWay[MovePhase][1], NalorakkWay[MovePhase][2]); - waitTimer = 0; - } - else waitTimer -= diff; - } - - if (!UpdateVictim()) - return; - - if (Berserk_Timer <= diff) - { - DoCast(me, SPELL_BERSERK, true); - Talk(SAY_BERSERK); - Berserk_Timer = 600000; - } - else Berserk_Timer -= diff; - - if (ShapeShift_Timer <= diff) - { - if (inBearForm) - { - // me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, 5122); - Talk(SAY_SHIFTEDTOTROLL); - me->RemoveAurasDueToSpell(SPELL_BEARFORM); - Surge_Timer = urand(15000, 20000); - BrutalSwipe_Timer = urand(7000, 12000); - Mangle_Timer = urand(10000, 15000); - ShapeShift_Timer = urand(45000, 50000); - inBearForm = false; - } - else - { - // me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, 0); - Talk(SAY_SHIFTEDTOBEAR); - DoCast(me, SPELL_BEARFORM, true); - LaceratingSlash_Timer = 2000; // dur 18s - RendFlesh_Timer = 3000; // dur 5s - DeafeningRoar_Timer = urand(5000, 10000); // dur 2s - ShapeShift_Timer = urand(20000, 25000); // dur 30s - inBearForm = true; - } - } - else ShapeShift_Timer -= diff; - - if (!inBearForm) - { - if (BrutalSwipe_Timer <= diff) - { - DoCastVictim(SPELL_BRUTALSWIPE); - BrutalSwipe_Timer = urand(7000, 12000); - } - else BrutalSwipe_Timer -= diff; - - if (Mangle_Timer <= diff) - { - if (me->GetVictim() && !me->GetVictim()->HasAura(SPELL_MANGLEEFFECT)) + case PHASE_SEND_GUARDS_2: + me->GetCreaturesWithEntryInRange(_waveList, 10.0f, NPC_AMANISHI_AXE_THROWER); + me->GetCreaturesWithEntryInRange(_waveList, 10.0f, NPC_AMANISHI_TRIBESMAN); + me->GetCreaturesWithEntryInRange(_waveList, 10.0f, NPC_AMANISHI_MEDICINE_MAN); + GroupedAttack(_waveList); + Talk(SAY_WAVE2); + _introScheduler.Schedule(5s, GROUP_CHECK_DEAD, [this](TaskContext context) { - DoCastVictim(SPELL_MANGLE); - Mangle_Timer = 1000; - } - else Mangle_Timer = urand(10000, 15000); - } - else Mangle_Timer -= diff; + if (CheckFullyDeadGroup(_waveList)) + { + if (_phase == PHASE_SEND_GUARDS_2) + { + _introScheduler.CancelGroup(GROUP_CHECK_DEAD); + _waveList.clear(); + Talk(SAY_RUN_AWAY); + me->GetMotionMaster()->MovePath(me->GetEntry()*100+2, false); + _introScheduler.Schedule(6s, [this](TaskContext) + { + me->SetFacingTo(1.54f); + _active = true; + }); + _phase = PHASE_SEND_GUARDS_3; + } - if (Surge_Timer <= diff) - { - Talk(SAY_SURGE); - Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 45, true); - if (target) - DoCast(target, SPELL_SURGE); - Surge_Timer = urand(15000, 20000); - } - else Surge_Timer -= diff; + } + context.Repeat(5s); + }); + break; + case PHASE_SEND_GUARDS_3: + me->GetCreaturesWithEntryInRange(_waveList, 10.0f, NPC_AMANISHI_WARBRINGER); + GroupedAttack(_waveList); + Talk(SAY_WAVE3); + _introScheduler.Schedule(5s, GROUP_CHECK_DEAD, [this](TaskContext context) + { + if (CheckFullyDeadGroup(_waveList)) + { + if (_phase == PHASE_SEND_GUARDS_3) + { + _introScheduler.CancelGroup(GROUP_CHECK_DEAD); + _waveList.clear(); + Talk(SAY_RUN_AWAY); + me->GetMotionMaster()->MovePath(me->GetEntry()*100+3, false); + _introScheduler.Schedule(6s, [this](TaskContext) + { + me->SetFacingTo(1.54f); + _active = true; + }); + _phase = PHASE_SEND_GUARDS_4; + } + } + context.Repeat(5s); + }); + break; + case PHASE_SEND_GUARDS_4: + me->GetCreaturesWithEntryInRange(_waveList, 25.0f, NPC_AMANISHI_WARBRINGER); + me->GetCreaturesWithEntryInRange(_waveList, 25.0f, NPC_AMANISHI_MEDICINE_MAN); + GroupedAttack(_waveList); + Talk(SAY_WAVE4); + _introScheduler.Schedule(5s, GROUP_CHECK_DEAD, [this](TaskContext context) + { + if (CheckFullyDeadGroup(_waveList)) + { + if (_phase == PHASE_SEND_GUARDS_4) + { + _introScheduler.CancelGroup(GROUP_CHECK_DEAD); + me->SetHomePosition(me->GetPosition()); + me->SetImmuneToAll(false); + me->SetReactState(REACT_AGGRESSIVE); + me->SetInCombatWithZone(); + _waveList.clear(); + _phase = PHASE_START_COMBAT; + _ranIntro = true; + } + } + context.Repeat(5s); + }); + break; + } + } + BossAI::MoveInLineOfSight(who); + } + + void JustEngagedWith(Unit* who) override + { + BossAI::JustEngagedWith(who); + Talk(SAY_AGGRO); + scheduler.Schedule(15s, 20s, GROUP_HUMAN, [this](TaskContext context) + { + Talk(SAY_SURGE); + DoCastRandomTarget(SPELL_SURGE, 0, 45.0f, false, false, false); + context.Repeat(); + }).Schedule(7s, 12s, GROUP_HUMAN, [this](TaskContext context) + { + DoCastVictim(SPELL_BRUTALSWIPE); + context.Repeat(); + }).Schedule(10s, 15s, GROUP_HUMAN, [this](TaskContext context) + { + if (!me->GetVictim()->HasAura(SPELL_MANGLEEFFECT)) + { + DoCastVictim(SPELL_MANGLE); + context.Repeat(1s); } else { - if (LaceratingSlash_Timer <= diff) - { - DoCastVictim(SPELL_LACERATINGSLASH); - LaceratingSlash_Timer = urand(18000, 23000); - } - else LaceratingSlash_Timer -= diff; - - if (RendFlesh_Timer <= diff) - { - DoCastVictim(SPELL_RENDFLESH); - RendFlesh_Timer = urand(5000, 10000); - } - else RendFlesh_Timer -= diff; - - if (DeafeningRoar_Timer <= diff) - { - DoCastVictim(SPELL_DEAFENINGROAR); - DeafeningRoar_Timer = urand(15000, 20000); - } - else DeafeningRoar_Timer -= diff; + context.Repeat(); } - - DoMeleeAttackIfReady(); - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetZulAmanAI(creature); + }).Schedule(10min, GROUP_BERSERK, [this](TaskContext) + { + Talk(SAY_BERSERK); + DoCastSelf(SPELL_BERSERK, true); + }).Schedule(45s, 50s, GROUP_HUMAN, [this](TaskContext) + { + ShapeShift(_bearForm); + }); } + + void ShapeShift(bool currentlyInBearForm) + { + if (currentlyInBearForm) + { + Talk(SAY_SHIFTEDTOTROLL); + me->RemoveAurasDueToSpell(SPELL_BEARFORM); + scheduler.CancelGroup(GROUP_BEAR); + _bearForm = false; + scheduler.Schedule(15s, 20s, GROUP_HUMAN, [this](TaskContext context) + { + Talk(SAY_SURGE); + DoCastRandomTarget(SPELL_SURGE, 0, 45.0f, false, false, false); + context.Repeat(); + }).Schedule(7s, 12s, GROUP_HUMAN, [this](TaskContext context) + { + DoCastVictim(SPELL_BRUTALSWIPE); + context.Repeat(); + }).Schedule(10s, 15s, GROUP_HUMAN, [this](TaskContext context) + { + DoCastVictim(SPELL_MANGLE); + context.Repeat(); + }).Schedule(10min, GROUP_BERSERK, [this](TaskContext) + { + Talk(SAY_BERSERK); + DoCastSelf(SPELL_BERSERK, true); + }).Schedule(45s, 50s, GROUP_HUMAN, [this](TaskContext) + { + ShapeShift(_bearForm); + }); + } + else + { + Talk(SAY_SHIFTEDTOBEAR); + Talk(EMOTE_BEAR); + DoCastSelf(SPELL_BEARFORM, true); + scheduler.CancelGroup(GROUP_HUMAN); + _bearForm = true; + scheduler.Schedule(2s, GROUP_BEAR, [this](TaskContext context) + { + DoCastVictim(SPELL_LACERATINGSLASH); + context.Repeat(18s, 23s); + }).Schedule(3s, GROUP_BEAR, [this](TaskContext context) + { + DoCastVictim(SPELL_RENDFLESH); + context.Repeat(5s, 10s); + }).Schedule(5s, 10s, GROUP_BEAR, [this](TaskContext context) + { + DoCastSelf(SPELL_DEAFENINGROAR); + context.Repeat(15s, 20s); + }).Schedule(25s, 30s, GROUP_BEAR, [this](TaskContext context) + { + ShapeShift(_bearForm); + context.Repeat(); + }); + } + } + + void GroupedAttack(std::list attackerList) + { + for (Creature* attacker : attackerList) + { + attacker->SetInCombatWithZone(); + } + } + + void UpdateAI(uint32 diff) override + { + _introScheduler.Update(diff); + BossAI::UpdateAI(diff); + } + + bool CheckFullyDeadGroup(std::list groupToCheck) + { + for (Creature* member : groupToCheck) + { + if (member->IsAlive()) + { + return false; + } + } + return true; + } +private: + uint8 _phase; + bool _ranIntro; + bool _active; + bool _bearForm; + TaskScheduler _introScheduler; + std::list _waveList; }; void AddSC_boss_nalorakk() { - new boss_nalorakk(); + RegisterZulAmanCreatureAI(boss_nalorakk); } diff --git a/src/server/scripts/EasternKingdoms/ZulAman/instance_zulaman.cpp b/src/server/scripts/EasternKingdoms/ZulAman/instance_zulaman.cpp index baa83f557..ffb1b771b 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/instance_zulaman.cpp +++ b/src/server/scripts/EasternKingdoms/ZulAman/instance_zulaman.cpp @@ -57,8 +57,8 @@ Position const HarrisonJonesLoc = {120.687f, 1674.0f, 42.0217f, 1.59044f}; ObjectData const creatureData[] = { - { NPC_SPIRIT_LYNX, DATA_SPIRIT_LYNX }, - { 0, 0 } + { NPC_SPIRIT_LYNX, DATA_SPIRIT_LYNX }, + { 0, 0 } }; ObjectData const gameObjectData[] = diff --git a/src/server/scripts/EasternKingdoms/ZulAman/zulaman.h b/src/server/scripts/EasternKingdoms/ZulAman/zulaman.h index 4ca81145b..caf94bfc2 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/zulaman.h +++ b/src/server/scripts/EasternKingdoms/ZulAman/zulaman.h @@ -46,7 +46,11 @@ enum CreatureIds NPC_HEXLORD = 24239, NPC_HALAZZI = 23577, NPC_NALORAKK = 23576, - NPC_SPIRIT_LYNX = 24143 + NPC_SPIRIT_LYNX = 24143, + NPC_AMANISHI_WARBRINGER = 23580, + NPC_AMANISHI_TRIBESMAN = 23582, + NPC_AMANISHI_MEDICINE_MAN = 23581, + NPC_AMANISHI_AXE_THROWER = 23542 }; enum GameobjectIds From ee3763392a2813ba2d8daa5d4256dbc7278b7c4c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 4 Jul 2024 18:14:33 +0000 Subject: [PATCH 25/68] chore(DB): import pending files Referenced commit(s): 65eb900c550686260e86cbcf4f9117181ec30458 --- .../waypoints.sql => db_world/2024_07_04_04.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/waypoints.sql => db_world/2024_07_04_04.sql} (96%) diff --git a/data/sql/updates/pending_db_world/waypoints.sql b/data/sql/updates/db_world/2024_07_04_04.sql similarity index 96% rename from data/sql/updates/pending_db_world/waypoints.sql rename to data/sql/updates/db_world/2024_07_04_04.sql index f36912184..aded22c2c 100644 --- a/data/sql/updates/pending_db_world/waypoints.sql +++ b/data/sql/updates/db_world/2024_07_04_04.sql @@ -1,3 +1,4 @@ +-- DB update 2024_07_04_03 -> 2024_07_04_04 -- DELETE FROM `waypoint_data` WHERE `id` IN (2357601, 2357602, 2357603); INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `orientation`, `delay`, `move_type`, `action`, `action_chance`, `wpguid`) VALUES From 7cf25c94ab41ff35d74be40a825877fc8fcf3b6c Mon Sep 17 00:00:00 2001 From: avarishd <46330494+avarishd@users.noreply.github.com> Date: Thu, 4 Jul 2024 21:50:11 +0300 Subject: [PATCH 26/68] fix(Scripts/Shattrath): Daily Dungeon quests holograms (#19233) * fix(Scripts/Shattrath): Daily Dungeon quests holographs * Move to single script + doaction SAI * ocd * use NEAR_PLAYER * use only Wind Trader as SAI * use creature_guid target * rename action * cleanup * zzz * Update zone_shattrath_city.cpp --- .../rev_1719691851180437100.sql | 10 ++ .../scripts/Outland/zone_shattrath_city.cpp | 158 ++++++++++++++++++ 2 files changed, 168 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1719691851180437100.sql diff --git a/data/sql/updates/pending_db_world/rev_1719691851180437100.sql b/data/sql/updates/pending_db_world/rev_1719691851180437100.sql new file mode 100644 index 000000000..b30a4e119 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1719691851180437100.sql @@ -0,0 +1,10 @@ +-- Shattrath Daily Normal/Heroic holograms +UPDATE `creature_template` SET `ScriptName` = 'npc_shattrath_daily_quest' WHERE `entry` IN (24410,24854); + +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 24369; +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 24369); +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 +(24369, 0, 0, 1, 1, 0, 100, 1, 0, 0, 0, 0, 0, 0, 223, 1, 0, 0, 0, 0, 0, 10, 79464, 24854, 0, 0, 0, 0, 0, 0, 'Wind Trader Zhareem - Out of Combat - Do Action ID 1 (No Repeat)'), +(24369, 0, 1, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 223, 1, 0, 0, 0, 0, 0, 10, 79462, 24410, 0, 0, 0, 0, 0, 0, 'Wind Trader Zhareem - Out of Combat - Do Action ID 1 (No Repeat)'), +(24369, 0, 2, 3, 101, 0, 100, 0, 1, 30, 60000, 60000, 60000, 0, 223, 1, 0, 0, 0, 0, 0, 10, 79464, 24854, 0, 0, 0, 0, 0, 0, 'Wind Trader Zhareem - On 1 or More Players in Range - Do Action ID 1'), +(24369, 0, 3, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 223, 1, 0, 0, 0, 0, 0, 10, 79462, 24410, 0, 0, 0, 0, 0, 0, 'Wind Trader Zhareem - On 1 or More Players in Range - Do Action ID 1'); diff --git a/src/server/scripts/Outland/zone_shattrath_city.cpp b/src/server/scripts/Outland/zone_shattrath_city.cpp index 34ca2c9e0..bccd14d26 100644 --- a/src/server/scripts/Outland/zone_shattrath_city.cpp +++ b/src/server/scripts/Outland/zone_shattrath_city.cpp @@ -16,6 +16,7 @@ */ #include "CreatureScript.h" +#include "PassiveAI.h" #include "Player.h" #include "ScriptedCreature.h" #include "ScriptedEscortAI.h" @@ -253,9 +254,166 @@ public: }; }; +enum ShattrathQuests +{ + // QuestID : Creature Template ID + // Heroic Daily Quests + QUEST_H_NAZZAN = 11354, // 24410 + QUEST_H_KELIDAN = 11362, // 24413 + QUEST_H_BLADEFIST = 11363, // 24414 + QUEST_H_QUAG = 11368, // 24419 + QUEST_H_BLACKSTALKER = 11369, // 24420 + QUEST_H_WARLORD = 11370, // 24421 + QUEST_H_IKISS = 11372, // 24422 + QUEST_H_SHAFFAR = 11373, // 24423 + QUEST_H_EXARCH = 11374, // 24424 + QUEST_H_MURMUR = 11375, // 24425 + QUEST_H_EPOCH = 11378, // 24427 + QUEST_H_AEONUS = 11382, // 24428 + QUEST_H_WARP = 11384, // 24431 + QUEST_H_CALCULATOR = 11386, // 21504 + QUEST_H_SKYRISS = 11388, // 24435 + QUEST_H_KAEL = 11499, // 24855 + // Normal Daily Quests + QUEST_N_CENTURIONS = 11364, // 24411 + QUEST_N_MYRMIDONS = 11371, // 24415 + QUEST_N_INSTRUCTORS = 11376, // 24426 + QUEST_N_LORDS = 11383, // 24429 + QUEST_N_CHANNELERS = 11385, // 24430 + QUEST_N_DESTROYERS = 11387, // 24432 + QUEST_N_SENTINELS = 11389, // 24434 + QUEST_N_SISTERS = 11500, // 24854 + + ACTION_UPDATE_QUEST_STATUS = 1, + + POOL_SHATTRATH_DAILY_H = 356, + POOL_SHATTRATH_DAILY_N = 357, + + // Image NPCs + NPC_SHATTRATH_DAILY_H = 24854, + NPC_SHATTRATH_DAILY_N = 24410 +}; + +struct npc_shattrath_daily_quest : public NullCreatureAI +{ + npc_shattrath_daily_quest(Creature* c) : NullCreatureAI(c) {} + + void DoAction(int32 action) override + { + if (action == ACTION_UPDATE_QUEST_STATUS) + { + uint32 creature = me->GetEntry(); + QueryResult result = CharacterDatabase.Query("SELECT `quest_id` FROM `pool_quest_save` WHERE `pool_id` = '{}'", creature == NPC_SHATTRATH_DAILY_H ? POOL_SHATTRATH_DAILY_H : POOL_SHATTRATH_DAILY_N); + if (result) + { + Field *fields = result->Fetch(); + int quest_id = fields[0].Get(); + uint32 templateID; + + if (creature == NPC_SHATTRATH_DAILY_H) + { + switch (quest_id) + { + case QUEST_H_NAZZAN: + templateID = 24410; + break; + case QUEST_H_KELIDAN: + templateID = 24413; + break; + case QUEST_H_BLADEFIST: + templateID = 24414; + break; + case QUEST_H_QUAG: + templateID = 24419; + break; + case QUEST_H_BLACKSTALKER: + templateID = 24420; + break; + case QUEST_H_WARLORD: + templateID = 24421; + break; + case QUEST_H_IKISS: + templateID = 24422; + break; + case QUEST_H_SHAFFAR: + templateID = 24423; + break; + case QUEST_H_EXARCH: + templateID = 24424; + break; + case QUEST_H_MURMUR: + templateID = 24425; + break; + case QUEST_H_EPOCH: + templateID = 24427; + break; + case QUEST_H_AEONUS: + templateID = 24428; + break; + case QUEST_H_WARP: + templateID = 24431; + break; + case QUEST_H_CALCULATOR: + templateID = 21504; + break; + case QUEST_H_SKYRISS: + templateID = 24435; + break; + case QUEST_H_KAEL: + templateID = 24855; + break; + default: + break; + } + } + + if (creature == NPC_SHATTRATH_DAILY_N) + { + switch (quest_id) + { + case QUEST_N_CENTURIONS: + templateID = 24411; + break; + case QUEST_N_MYRMIDONS: + templateID = 24415; + break; + case QUEST_N_INSTRUCTORS: + templateID = 24426; + break; + case QUEST_N_LORDS: + templateID = 24429; + break; + case QUEST_N_CHANNELERS: + templateID = 24430; + break; + case QUEST_N_DESTROYERS: + templateID = 24432; + break; + case QUEST_N_SENTINELS: + templateID = 24434; + break; + case QUEST_N_SISTERS: + templateID = 24854; + break; + default: + break; + } + } + + if (CreatureTemplate const* ci = sObjectMgr->GetCreatureTemplate(templateID)) + { + CreatureModel const* model = ObjectMgr::ChooseDisplayId(ci); + me->SetDisplayId(model->CreatureDisplayID, model->DisplayScale); + } + } + } + } +}; + void AddSC_shattrath_city() { new npc_shattrathflaskvendors(); new npc_zephyr(); new npc_kservant(); + RegisterCreatureAI(npc_shattrath_daily_quest); } From 2cfe665a530176c6a0a596f28e8aa95039bbefd4 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 4 Jul 2024 18:51:11 +0000 Subject: [PATCH 27/68] chore(DB): import pending files Referenced commit(s): 7cf25c94ab41ff35d74be40a825877fc8fcf3b6c --- .../rev_1719691851180437100.sql => db_world/2024_07_04_05.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1719691851180437100.sql => db_world/2024_07_04_05.sql} (97%) diff --git a/data/sql/updates/pending_db_world/rev_1719691851180437100.sql b/data/sql/updates/db_world/2024_07_04_05.sql similarity index 97% rename from data/sql/updates/pending_db_world/rev_1719691851180437100.sql rename to data/sql/updates/db_world/2024_07_04_05.sql index b30a4e119..f34250d85 100644 --- a/data/sql/updates/pending_db_world/rev_1719691851180437100.sql +++ b/data/sql/updates/db_world/2024_07_04_05.sql @@ -1,3 +1,4 @@ +-- DB update 2024_07_04_04 -> 2024_07_04_05 -- Shattrath Daily Normal/Heroic holograms UPDATE `creature_template` SET `ScriptName` = 'npc_shattrath_daily_quest' WHERE `entry` IN (24410,24854); From 37431cd7a6a2fb54fada2f637651c06ec32a44e3 Mon Sep 17 00:00:00 2001 From: Jelle Meeus Date: Thu, 4 Jul 2024 21:34:14 +0200 Subject: [PATCH 28/68] fix(Core/Pets): Correct Pet size for bigger pets 2 (#18867) * scale displayInfo, cap scale to maxScale * prevent scaling with displayInfo if scale is already increasing the size --- src/server/game/Entities/Pet/Pet.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp index de53dfa7b..0f77f0c97 100644 --- a/src/server/game/Entities/Pet/Pet.cpp +++ b/src/server/game/Entities/Pet/Pet.cpp @@ -2499,11 +2499,6 @@ float Pet::GetNativeObjectScale() const { uint8 ctFamily = GetCreatureTemplate()->family; - // hackfix: Edge case where DBC scale values for DEVILSAUR pets make them too small. - // Therefore we take data from spirit beast instead. - if (ctFamily && ctFamily == CREATURE_FAMILY_DEVILSAUR) - ctFamily = CREATURE_FAMILY_SPIRIT_BEAST; - CreatureFamilyEntry const* creatureFamily = sCreatureFamilyStore.LookupEntry(ctFamily); if (creatureFamily && creatureFamily->minScale > 0.0f && getPetType() & HUNTER_PET) { @@ -2520,6 +2515,13 @@ float Pet::GetNativeObjectScale() const float scale = (creatureFamily->maxScale - creatureFamily->minScale) * scaleMod + creatureFamily->minScale; + scale = std::min(scale, creatureFamily->maxScale); + + if (CreatureDisplayInfoEntry const* displayInfo = sCreatureDisplayInfoStore.LookupEntry(GetNativeDisplayId())) + { + if (scale < 1.f && displayInfo->scale > 1.f) + scale *= displayInfo->scale; + } return scale; } From 48e35501a8fc6abed4adfc80125f6b35fa5eb1eb Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Thu, 4 Jul 2024 19:23:01 -0300 Subject: [PATCH 29/68] =?UTF-8?q?fix(DB/Spells):=20Allow=20Sablemane's=20S?= =?UTF-8?q?leeping=20Powder=20to=20bypass=20stun=20immu=E2=80=A6=20(#19280?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix(DB/Spells): Allow Sablemane's Sleeping Powder to bypass stun immunity --- data/sql/updates/pending_db_world/rev_1720131063062734900.sql | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1720131063062734900.sql diff --git a/data/sql/updates/pending_db_world/rev_1720131063062734900.sql b/data/sql/updates/pending_db_world/rev_1720131063062734900.sql new file mode 100644 index 000000000..21d620d15 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1720131063062734900.sql @@ -0,0 +1,4 @@ +-- +DELETE FROM `spell_custom_attr` WHERE `spell_id` = 38510; +INSERT INTO `spell_custom_attr` (`spell_id`, `attributes`) VALUES +(38510, 2147483648); From a40387cd4c06d6bf7fc3ff3945d420cb2e9b14fd Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 4 Jul 2024 22:23:57 +0000 Subject: [PATCH 30/68] chore(DB): import pending files Referenced commit(s): 48e35501a8fc6abed4adfc80125f6b35fa5eb1eb --- .../rev_1720131063062734900.sql => db_world/2024_07_04_06.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1720131063062734900.sql => db_world/2024_07_04_06.sql} (77%) diff --git a/data/sql/updates/pending_db_world/rev_1720131063062734900.sql b/data/sql/updates/db_world/2024_07_04_06.sql similarity index 77% rename from data/sql/updates/pending_db_world/rev_1720131063062734900.sql rename to data/sql/updates/db_world/2024_07_04_06.sql index 21d620d15..c67e8bc1e 100644 --- a/data/sql/updates/pending_db_world/rev_1720131063062734900.sql +++ b/data/sql/updates/db_world/2024_07_04_06.sql @@ -1,3 +1,4 @@ +-- DB update 2024_07_04_05 -> 2024_07_04_06 -- DELETE FROM `spell_custom_attr` WHERE `spell_id` = 38510; INSERT INTO `spell_custom_attr` (`spell_id`, `attributes`) VALUES From d9f4ba5e1d4cc762ed766eb3afd7975385933fcf Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Fri, 5 Jul 2024 06:32:33 -0300 Subject: [PATCH 31/68] =?UTF-8?q?fix(Scripts/Item):=20Fix=20Fel=20Mana=20P?= =?UTF-8?q?otion=20not=20benefiting=20from=20Alchemist'=E2=80=A6=20(#19281?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix(Scripts/Item): Fix Fel Mana Potion not benefiting from Alchemist's Stone --- .../rev_1720136214539685800.sql | 4 +++ src/server/scripts/Spells/spell_item.cpp | 33 +++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1720136214539685800.sql diff --git a/data/sql/updates/pending_db_world/rev_1720136214539685800.sql b/data/sql/updates/pending_db_world/rev_1720136214539685800.sql new file mode 100644 index 000000000..bbdea5293 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1720136214539685800.sql @@ -0,0 +1,4 @@ +-- +DELETE FROM `spell_script_names` WHERE `spell_id` = 38929; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(38929, 'spell_item_fel_mana_potion'); diff --git a/src/server/scripts/Spells/spell_item.cpp b/src/server/scripts/Spells/spell_item.cpp index 654d14a63..9eb2652ab 100644 --- a/src/server/scripts/Spells/spell_item.cpp +++ b/src/server/scripts/Spells/spell_item.cpp @@ -3990,6 +3990,38 @@ class spell_item_eye_of_grillok_aura : public AuraScript } }; +enum FelManaPotion +{ + SPELL_FEL_MANA_POTION = 38929, + SPELL_ALCHEMIST_STONE = 17619, + SPELL_ALCHEMIST_STONE_ENERGIZE = 21400 +}; + +class spell_item_fel_mana_potion : public AuraScript +{ + PrepareAuraScript(spell_item_fel_mana_potion) + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_ALCHEMIST_STONE, SPELL_ALCHEMIST_STONE_ENERGIZE }); + } + + void OnPeriodic(AuraEffect const* aurEff) + { + if (Unit* caster = GetCaster()) + if (caster->HasAura(SPELL_ALCHEMIST_STONE)) + { + uint32 val = GetSpellInfo()->Effects[EFFECT_0].BasePoints * 0.4f; + caster->CastCustomSpell(SPELL_ALCHEMIST_STONE_ENERGIZE, SPELLVALUE_BASE_POINT0, val, caster, true); + } + } + + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_item_fel_mana_potion::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_ENERGIZE); + } +}; + void AddSC_item_spell_scripts() { RegisterSpellScript(spell_item_massive_seaforium_charge); @@ -4112,5 +4144,6 @@ void AddSC_item_spell_scripts() RegisterSpellScript(spell_item_venomhide_feed); RegisterSpellScript(spell_item_scroll_of_retribution); RegisterSpellAndAuraScriptPair(spell_item_eye_of_grillok, spell_item_eye_of_grillok_aura); + RegisterSpellScript(spell_item_fel_mana_potion); } From 932433d23550609066eab17e489c4def75a199c2 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 5 Jul 2024 09:33:31 +0000 Subject: [PATCH 32/68] chore(DB): import pending files Referenced commit(s): d9f4ba5e1d4cc762ed766eb3afd7975385933fcf --- .../rev_1720136214539685800.sql => db_world/2024_07_05_00.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1720136214539685800.sql => db_world/2024_07_05_00.sql} (79%) diff --git a/data/sql/updates/pending_db_world/rev_1720136214539685800.sql b/data/sql/updates/db_world/2024_07_05_00.sql similarity index 79% rename from data/sql/updates/pending_db_world/rev_1720136214539685800.sql rename to data/sql/updates/db_world/2024_07_05_00.sql index bbdea5293..b917c5e87 100644 --- a/data/sql/updates/pending_db_world/rev_1720136214539685800.sql +++ b/data/sql/updates/db_world/2024_07_05_00.sql @@ -1,3 +1,4 @@ +-- DB update 2024_07_04_06 -> 2024_07_05_00 -- DELETE FROM `spell_script_names` WHERE `spell_id` = 38929; INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES From 620c40b01072dc38f894f5da6fe968fd35d08dde Mon Sep 17 00:00:00 2001 From: Benjamin Jackson <38561765+heyitsbench@users.noreply.github.com> Date: Fri, 5 Jul 2024 06:45:26 -0400 Subject: [PATCH 33/68] fix(Core/Handlers): Adjust start swing handler. (#19267) * Init. * Flesh out packet info. https: //github.com/TrinityCore/TrinityCore/commit/af6d207addfef177fb5ac3e7fa61ec93ced83d16 Co-Authored-By: ForesterDev <11771800+ForesterDev@users.noreply.github.com> --------- Co-authored-by: ForesterDev <11771800+ForesterDev@users.noreply.github.com> --- src/server/game/Handlers/CombatHandler.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/server/game/Handlers/CombatHandler.cpp b/src/server/game/Handlers/CombatHandler.cpp index 0150c83e4..6a92526de 100644 --- a/src/server/game/Handlers/CombatHandler.cpp +++ b/src/server/game/Handlers/CombatHandler.cpp @@ -84,9 +84,12 @@ void WorldSession::HandleSetSheathedOpcode(WorldPackets::Combat::SetSheathed& pa void WorldSession::SendAttackStop(Unit const* enemy) { - WorldPacket data(SMSG_ATTACKSTOP, (8 + 8 + 4)); // we guess size + WorldPacket data(SMSG_ATTACKSTOP, (8 + 8 + 4)); // we guess size data << GetPlayer()->GetPackGUID(); - data << (enemy ? enemy->GetPackGUID() : PackedGuid()); // must be packed guid - data << uint32(0); // unk, can be 1 also + if (enemy) + { + data << enemy->GetPackGUID(); // must be packed guid + data << enemy->isDead(); + } SendPacket(&data); } From 34edcefc8be3fbcd165847084430f4e5e94a237a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=A9=E9=B9=BF?= <18535853+PkllonG@users.noreply.github.com> Date: Fri, 5 Jul 2024 18:45:58 +0800 Subject: [PATCH 34/68] fix(Core/dbc): GlyphPropertiesfmt ERROR (#19284) Add files via upload --- src/server/shared/DataStores/DBCStructure.h | 2 +- src/server/shared/DataStores/DBCfmt.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/server/shared/DataStores/DBCStructure.h b/src/server/shared/DataStores/DBCStructure.h index db61bb0af..b3d08a949 100644 --- a/src/server/shared/DataStores/DBCStructure.h +++ b/src/server/shared/DataStores/DBCStructure.h @@ -1019,7 +1019,7 @@ struct GemPropertiesEntry struct GlyphPropertiesEntry { - //uint32 Id; + uint32 Id; uint32 SpellId; uint32 TypeFlags; //uint32 spellIconID; // GlyphIconId (SpellIcon.dbc) diff --git a/src/server/shared/DataStores/DBCfmt.h b/src/server/shared/DataStores/DBCfmt.h index 14d123866..d17da2dd9 100644 --- a/src/server/shared/DataStores/DBCfmt.h +++ b/src/server/shared/DataStores/DBCfmt.h @@ -53,7 +53,7 @@ char constexpr FactionTemplateEntryfmt[] = "niiiiiiiiiiiii"; char constexpr GameObjectArtKitfmt[] = "nxxxxxxx"; char constexpr GameObjectDisplayInfofmt[] = "nsxxxxxxxxxxffffffx"; char constexpr GemPropertiesEntryfmt[] = "nixxi"; -char constexpr GlyphPropertiesfmt[] = "xiix"; +char constexpr GlyphPropertiesfmt[] = "niix"; char constexpr GlyphSlotfmt[] = "nii"; char constexpr GtBarberShopCostBasefmt[] = "df"; char constexpr GtCombatRatingsfmt[] = "df"; From e7f9fb9f76e9bb26d8d58f3d48fd89801f25b355 Mon Sep 17 00:00:00 2001 From: mpfans Date: Sat, 6 Jul 2024 01:18:19 +0800 Subject: [PATCH 35/68] fix(DB/Misc): Migrate SQL files to the correct folder (#19282) * Create rev_1719945200692175000.sql Migrate to the correct folder * Delete data/sql/updates/pending_db_character directory https://github.com/azerothcore/azerothcore-wotlk/commit/f96d4c86706ac1befca0719d1cc99f8f82863ac0 The SQL file was placed in the wrong folder --- .../rev_1719945200692175000.sql | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename data/sql/updates/{pending_db_character => pending_db_characters}/rev_1719945200692175000.sql (100%) diff --git a/data/sql/updates/pending_db_character/rev_1719945200692175000.sql b/data/sql/updates/pending_db_characters/rev_1719945200692175000.sql similarity index 100% rename from data/sql/updates/pending_db_character/rev_1719945200692175000.sql rename to data/sql/updates/pending_db_characters/rev_1719945200692175000.sql From 163d454491f24ab7f07815fbc2e9b092f93113a9 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 5 Jul 2024 17:19:16 +0000 Subject: [PATCH 36/68] chore(DB): import pending files Referenced commit(s): e7f9fb9f76e9bb26d8d58f3d48fd89801f25b355 --- .../2024_07_05_00.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_characters/rev_1719945200692175000.sql => db_characters/2024_07_05_00.sql} (56%) diff --git a/data/sql/updates/pending_db_characters/rev_1719945200692175000.sql b/data/sql/updates/db_characters/2024_07_05_00.sql similarity index 56% rename from data/sql/updates/pending_db_characters/rev_1719945200692175000.sql rename to data/sql/updates/db_characters/2024_07_05_00.sql index 93b01738b..4a7e9e03c 100644 --- a/data/sql/updates/pending_db_characters/rev_1719945200692175000.sql +++ b/data/sql/updates/db_characters/2024_07_05_00.sql @@ -1,3 +1,4 @@ +-- DB update 2024_01_20_00 -> 2024_07_05_00 -- ALTER TABLE `character_homebind` From 172f73db921414f47975d9e3b25ef4e182a37e95 Mon Sep 17 00:00:00 2001 From: Kitzunu <24550914+Kitzunu@users.noreply.github.com> Date: Fri, 5 Jul 2024 20:06:03 +0200 Subject: [PATCH 37/68] fix(Core/Misc): unused param (#19286) --- src/server/scripts/Spells/spell_item.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/server/scripts/Spells/spell_item.cpp b/src/server/scripts/Spells/spell_item.cpp index 9eb2652ab..2a69287c2 100644 --- a/src/server/scripts/Spells/spell_item.cpp +++ b/src/server/scripts/Spells/spell_item.cpp @@ -3992,7 +3992,6 @@ class spell_item_eye_of_grillok_aura : public AuraScript enum FelManaPotion { - SPELL_FEL_MANA_POTION = 38929, SPELL_ALCHEMIST_STONE = 17619, SPELL_ALCHEMIST_STONE_ENERGIZE = 21400 }; @@ -4006,7 +4005,7 @@ class spell_item_fel_mana_potion : public AuraScript return ValidateSpellInfo({ SPELL_ALCHEMIST_STONE, SPELL_ALCHEMIST_STONE_ENERGIZE }); } - void OnPeriodic(AuraEffect const* aurEff) + void OnPeriodic(AuraEffect const* /*aurEff*/) { if (Unit* caster = GetCaster()) if (caster->HasAura(SPELL_ALCHEMIST_STONE)) From 89a6996628243beecb7c4e1165d8020d53fe4ca9 Mon Sep 17 00:00:00 2001 From: Gultask <100873791+Gultask@users.noreply.github.com> Date: Fri, 5 Jul 2024 15:07:56 -0300 Subject: [PATCH 38/68] fix(Scripts/SmartAI): Rewrite ACTION_MOVE_TO_POS (#19190) * init * Update SmartScript.cpp * combatReach * Update SmartScript.cpp --- .../rev_1719454050542680700.sql | 25 ++++++ .../game/AI/SmartScripts/SmartScript.cpp | 85 ++++++++++--------- .../game/AI/SmartScripts/SmartScriptMgr.h | 1 + 3 files changed, 69 insertions(+), 42 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1719454050542680700.sql diff --git a/data/sql/updates/pending_db_world/rev_1719454050542680700.sql b/data/sql/updates/pending_db_world/rev_1719454050542680700.sql new file mode 100644 index 000000000..4e09cdec6 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1719454050542680700.sql @@ -0,0 +1,25 @@ +-- +UPDATE `smart_scripts` SET `target_type` = 8 WHERE `entryorguid` = 1367 AND `source_type` = 0 AND `id` = 1; +UPDATE `smart_scripts` SET `target_type` = 8 WHERE `entryorguid` = 1367 AND `source_type` = 0 AND `id` = 3; +UPDATE `smart_scripts` SET `target_type` = 8 WHERE `entryorguid` = 1367 AND `source_type` = 0 AND `id` = 5; +UPDATE `smart_scripts` SET `target_type` = 8 WHERE `entryorguid` = 1368 AND `source_type` = 0 AND `id` = 1; +UPDATE `smart_scripts` SET `target_type` = 8 WHERE `entryorguid` = 1368 AND `source_type` = 0 AND `id` = 3; +UPDATE `smart_scripts` SET `target_type` = 8 WHERE `entryorguid` = 1371 AND `source_type` = 0 AND `id` = 2; +UPDATE `smart_scripts` SET `target_type` = 8 WHERE `entryorguid` = 1371 AND `source_type` = 0 AND `id` = 4; +UPDATE `smart_scripts` SET `target_type` = 8 WHERE `entryorguid` = 1414 AND `source_type` = 0 AND `id` = 4; +UPDATE `smart_scripts` SET `target_type` = 8 WHERE `entryorguid` = 1415 AND `source_type` = 0 AND `id` = 3; +UPDATE `smart_scripts` SET `target_type` = 8 WHERE `entryorguid` = 2470 AND `source_type` = 0 AND `id` = 0; +UPDATE `smart_scripts` SET `target_type` = 8 WHERE `entryorguid` = 137300 AND `source_type` = 9 AND `id` = 20; +UPDATE `smart_scripts` SET `target_type` = 8 WHERE `entryorguid` = 137300 AND `source_type` = 9 AND `id` = 19; +UPDATE `smart_scripts` SET `target_type` = 8 WHERE `entryorguid` = 1043900 AND `source_type` = 9 AND `id` = 2; +UPDATE `smart_scripts` SET `target_type` = 8 WHERE `entryorguid` = 2129100 AND `source_type` = 9 AND `id` = 1; +UPDATE `smart_scripts` SET `target_type` = 8 WHERE `entryorguid` = 2129100 AND `source_type` = 9 AND `id` = 13; +UPDATE `smart_scripts` SET `target_type` = 8 WHERE `entryorguid` = 2711300 AND `source_type` = 9 AND `id` = 1; +UPDATE `smart_scripts` SET `target_type` = 8 WHERE `entryorguid` = 2711300 AND `source_type` = 9 AND `id` = 3; +UPDATE `smart_scripts` SET `target_type` = 8 WHERE `entryorguid` = 2711400 AND `source_type` = 9 AND `id` = 1; +UPDATE `smart_scripts` SET `target_type` = 8 WHERE `entryorguid` = 2711400 AND `source_type` = 9 AND `id` = 3; +UPDATE `smart_scripts` SET `target_type` = 8 WHERE `entryorguid` = 2711500 AND `source_type` = 9 AND `id` = 1; +UPDATE `smart_scripts` SET `target_type` = 8 WHERE `entryorguid` = 2711500 AND `source_type` = 9 AND `id` = 3; +UPDATE `smart_scripts` SET `target_type` = 8 WHERE `entryorguid` = 2731600 AND `source_type` = 9 AND `id` = 2; +UPDATE `smart_scripts` SET `target_type` = 8 WHERE `entryorguid` = 2731600 AND `source_type` = 9 AND `id` = 3; +UPDATE `smart_scripts` SET `target_type` = 8 WHERE `entryorguid` = 3019000 AND `source_type` = 9 AND `id` = 13; diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index f7f31fd40..3102b37bf 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -1744,60 +1744,61 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u WorldObject* target = nullptr; - if (e.GetTargetType() == SMART_TARGET_RANDOM_POINT) + switch (e.GetTargetType()) { + case SMART_TARGET_POSITION: + { + G3D::Vector3 dest(e.target.x, e.target.y, e.target.z); + if (e.action.moveToPos.transport) + if (TransportBase* trans = me->GetDirectTransport()) + trans->CalculatePassengerPosition(dest.x, dest.y, dest.z); + + me->GetMotionMaster()->MovePoint(e.action.moveToPos.pointId, dest.x, dest.y, dest.z, true, true, + isControlled ? MOTION_SLOT_CONTROLLED : MOTION_SLOT_ACTIVE, e.target.o); + + break; + } + case SMART_TARGET_RANDOM_POINT: if (me) { float range = (float)e.target.randomPoint.range; Position srcPos = { e.target.x, e.target.y, e.target.z, e.target.o }; Position randomPoint = me->GetRandomPoint(srcPos, range); me->GetMotionMaster()->MovePoint( - e.action.moveToPos.pointId, - randomPoint.m_positionX, - randomPoint.m_positionY, - randomPoint.m_positionZ, - true, - true, - isControlled ? MOTION_SLOT_CONTROLLED : MOTION_SLOT_ACTIVE + e.action.moveToPos.pointId, + randomPoint.m_positionX, + randomPoint.m_positionY, + randomPoint.m_positionZ, + true, + true, + isControlled ? MOTION_SLOT_CONTROLLED : MOTION_SLOT_ACTIVE ); + + break; } - - break; - } - - /*if (e.GetTargetType() == SMART_TARGET_CREATURE_RANGE || e.GetTargetType() == SMART_TARGET_CREATURE_GUID || - e.GetTargetType() == SMART_TARGET_CREATURE_DISTANCE || e.GetTargetType() == SMART_TARGET_GAMEOBJECT_RANGE || - e.GetTargetType() == SMART_TARGET_GAMEOBJECT_GUID || e.GetTargetType() == SMART_TARGET_GAMEOBJECT_DISTANCE || - e.GetTargetType() == SMART_TARGET_CLOSEST_CREATURE || e.GetTargetType() == SMART_TARGET_CLOSEST_GAMEOBJECT || - e.GetTargetType() == SMART_TARGET_OWNER_OR_SUMMONER || e.GetTargetType() == SMART_TARGET_ACTION_INVOKER || - e.GetTargetType() == SMART_TARGET_CLOSEST_ENEMY || e.GetTargetType() == SMART_TARGET_CLOSEST_FRIENDLY || - e.GetTargetType() == SMART_TARGET_SELF || e.GetTargetType() == SMART_TARGET_STORED)) */ - { - // we want to move to random element - if (!targets.empty()) - target = Acore::Containers::SelectRandomContainerElement(targets); - } - - if (!target) - { - G3D::Vector3 dest(e.target.x, e.target.y, e.target.z); - if (e.action.moveToPos.transport) - if (TransportBase* trans = me->GetDirectTransport()) - trans->CalculatePassengerPosition(dest.x, dest.y, dest.z); - - me->GetMotionMaster()->MovePoint(e.action.moveToPos.pointId, dest.x, dest.y, dest.z, true, true, - isControlled ? MOTION_SLOT_CONTROLLED : MOTION_SLOT_ACTIVE, e.target.o); - } - else // Xinef: we can use dest.x, dest.y, dest.z to make offset - { - float x, y, z; - target->GetPosition(x, y, z); - if (e.action.moveToPos.ContactDistance > 0) + // Can use target floats as offset + default: { - target->GetNearPoint(me, x, y, z, e.action.moveToPos.ContactDistance, 0, target->GetAngle(me)); + // we want to move to random element + if (targets.empty()) + return; + else + target = Acore::Containers::SelectRandomContainerElement(targets); + + float x, y, z; + target->GetPosition(x, y, z); + + if (e.action.moveToPos.combatReach) + target->GetNearPoint(me, x, y, z, target->GetCombatReach() + e.action.moveToPos.ContactDistance, 0, target->GetAngle(me)); + else if (e.action.moveToPos.ContactDistance) + target->GetNearPoint(me, x, y, z, e.action.moveToPos.ContactDistance, 0, target->GetAngle(me)); + + me->GetMotionMaster()->MovePoint(e.action.moveToPos.pointId, x + e.target.x, y + e.target.y, z + e.target.z, true, true, isControlled ? MOTION_SLOT_CONTROLLED : MOTION_SLOT_ACTIVE); + + break; } - me->GetMotionMaster()->MovePoint(e.action.moveToPos.pointId, x + e.target.x, y + e.target.y, z + e.target.z, true, true, isControlled ? MOTION_SLOT_CONTROLLED : MOTION_SLOT_ACTIVE); } + break; } case SMART_ACTION_MOVE_TO_POS_TARGET: diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h index 554863690..1d65711e3 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h @@ -1202,6 +1202,7 @@ struct SmartAction SAIBool transport; uint32 controlled; uint32 ContactDistance; + uint32 combatReach; } moveToPos; struct From 9453bfbad2d001ac69abc3a48b77516da9b58858 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 5 Jul 2024 18:08:47 +0000 Subject: [PATCH 39/68] chore(DB): import pending files Referenced commit(s): 89a6996628243beecb7c4e1165d8020d53fe4ca9 --- .../rev_1719454050542680700.sql => db_world/2024_07_05_01.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1719454050542680700.sql => db_world/2024_07_05_01.sql} (98%) diff --git a/data/sql/updates/pending_db_world/rev_1719454050542680700.sql b/data/sql/updates/db_world/2024_07_05_01.sql similarity index 98% rename from data/sql/updates/pending_db_world/rev_1719454050542680700.sql rename to data/sql/updates/db_world/2024_07_05_01.sql index 4e09cdec6..a05420758 100644 --- a/data/sql/updates/pending_db_world/rev_1719454050542680700.sql +++ b/data/sql/updates/db_world/2024_07_05_01.sql @@ -1,3 +1,4 @@ +-- DB update 2024_07_05_00 -> 2024_07_05_01 -- UPDATE `smart_scripts` SET `target_type` = 8 WHERE `entryorguid` = 1367 AND `source_type` = 0 AND `id` = 1; UPDATE `smart_scripts` SET `target_type` = 8 WHERE `entryorguid` = 1367 AND `source_type` = 0 AND `id` = 3; From 04acfd96a044a84bd471481ce123e7a2cba9ad26 Mon Sep 17 00:00:00 2001 From: Anton Popovichenko Date: Fri, 5 Jul 2024 20:42:22 +0200 Subject: [PATCH 40/68] fix(Core/Unit): Invalidate update object cache when changing health in the same world update tick. (#19287) * fix(Core/Unit): Invalidate update object cache when changing health in the same world update tick. Should fix an issue when the client sees dead NPCs when they are not. * Fix styling * Another codestyle fix --- src/server/game/Entities/Unit/Unit.cpp | 14 ++++++++++++++ src/server/game/Entities/Unit/Unit.h | 2 ++ 2 files changed, 16 insertions(+) diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index a53d70545..57d770907 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -21628,6 +21628,20 @@ bool Unit::IsInDisallowedMountForm() const return false; } +void Unit::SetUInt32Value(uint16 index, uint32 value) +{ + Object::SetUInt32Value(index, value); + + switch (index) + { + // Invalidating the cache on health change should fix an issue where the client sees dead NPCs when they are not. + // We might also need to invalidate the cache for some other fields as well. + case UNIT_FIELD_HEALTH: + InvalidateValuesUpdateCache(); + break; + } +} + std::string Unit::GetDebugInfo() const { std::stringstream sstr; diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 16dc4f605..106a35eed 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -1571,6 +1571,8 @@ public: void ApplyAttackTimePercentMod(WeaponAttackType att, float val, bool apply); void ApplyCastTimePercentMod(float val, bool apply); + void SetUInt32Value(uint16 index, uint32 value); + UnitFlags GetUnitFlags() const { return UnitFlags(GetUInt32Value(UNIT_FIELD_FLAGS)); } bool HasUnitFlag(UnitFlags flags) const { return HasFlag(UNIT_FIELD_FLAGS, flags); } void SetUnitFlag(UnitFlags flags) { SetFlag(UNIT_FIELD_FLAGS, flags); } From 8acdbc44390ddf56f1f666b7c694c2e58d1d3da7 Mon Sep 17 00:00:00 2001 From: Gultask <100873791+Gultask@users.noreply.github.com> Date: Fri, 5 Jul 2024 19:36:55 -0300 Subject: [PATCH 41/68] fix(DB/Creature): Rewrite Voidshrieker AI (#19290) Create rev_1720211249204769700.sql --- .../rev_1720211249204769700.sql | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1720211249204769700.sql diff --git a/data/sql/updates/pending_db_world/rev_1720211249204769700.sql b/data/sql/updates/pending_db_world/rev_1720211249204769700.sql new file mode 100644 index 000000000..2121c7b80 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1720211249204769700.sql @@ -0,0 +1,40 @@ +-- +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 18870); +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 +(18870, 0, 0, 0, 25, 0, 100, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Voidshrieker - On Reset - Set Event Phase 0'), +(18870, 0, 1, 0, 11, 0, 100, 0, 0, 0, 0, 0, 0, 0, 11, 34302, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Voidshrieker - On Respawn - Cast \'Coalesce\''), +(18870, 0, 2, 0, 4, 0, 100, 0, 0, 0, 0, 0, 0, 0, 22, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Voidshrieker - On Aggro - Set Event Phase 1'), +(18870, 0, 3, 4, 8, 1, 100, 0, 0, 2, 0, 0, 0, 0, 11, 34336, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Voidshrieker - On Spellhit \'Holy\' - Cast \'Damage Reduction: Holy\' (Phase 1)'), +(18870, 0, 4, 5, 61, 1, 100, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Voidshrieker - On Spellhit \'Holy\' - Say Line 1 (Phase 1)'), +(18870, 0, 5, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 22, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Voidshrieker - On Spellhit \'Holy\' - Set Event Phase 2 (Phase 1)'), +(18870, 0, 6, 7, 8, 1, 100, 0, 0, 4, 0, 0, 0, 0, 11, 34333, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Voidshrieker - On Spellhit \'Fire\' - Cast \'Damage Reduction: Fire\' (Phase 1)'), +(18870, 0, 7, 8, 61, 1, 100, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Voidshrieker - On Spellhit \'Fire\' - Say Line 2 (Phase 1)'), +(18870, 0, 8, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 22, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Voidshrieker - On Spellhit \'Fire\' - Set Event Phase 3 (Phase 1)'), +(18870, 0, 9, 10, 8, 1, 100, 0, 0, 8, 0, 0, 0, 0, 11, 34335, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Voidshrieker - On Spellhit \'Nature\' - Cast \'Damage Reduction: Nature\' (Phase 1)'), +(18870, 0, 10, 11, 61, 1, 100, 0, 0, 0, 0, 0, 0, 0, 1, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Voidshrieker - On Spellhit \'Nature\' - Say Line 3 (Phase 1)'), +(18870, 0, 11, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 22, 4, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Voidshrieker - On Spellhit \'Nature\' - Set Event Phase 4 (Phase 1)'), +(18870, 0, 12, 13, 8, 1, 100, 0, 0, 16, 0, 0, 0, 0, 11, 34334, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Voidshrieker - On Spellhit \'Frost\' - Cast \'Damage Reduction: Frost\' (Phase 1)'), +(18870, 0, 13, 14, 61, 1, 100, 0, 0, 0, 0, 0, 0, 0, 1, 4, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Voidshrieker - On Spellhit \'Frost\' - Say Line 4 (Phase 1)'), +(18870, 0, 14, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 22, 5, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Voidshrieker - On Spellhit \'Frost\' - Set Event Phase 5 (Phase 1)'), +(18870, 0, 15, 16, 8, 1, 100, 0, 0, 32, 0, 0, 0, 0, 11, 34338, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Voidshrieker - On Spellhit \'Shadow\' - Cast \'Damage Reduction: Shadow\' (Phase 1)'), +(18870, 0, 16, 17, 61, 1, 100, 0, 0, 0, 0, 0, 0, 0, 1, 5, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Voidshrieker - On Spellhit \'Shadow\' - Say Line 5 (Phase 1)'), +(18870, 0, 17, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Voidshrieker - On Spellhit \'Shadow\' - Set Event Phase 6 (Phase 1)'), +(18870, 0, 18, 19, 8, 1, 100, 0, 0, 64, 0, 0, 0, 0, 11, 34331, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Voidshrieker - On Spellhit \'Arcane\' - Cast \'Damage Reduction: Arcane\' (Phase 1)'), +(18870, 0, 19, 20, 61, 1, 100, 0, 0, 0, 0, 0, 0, 0, 1, 6, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Voidshrieker - On Spellhit \'Arcane\' - Say Line 6 (Phase 1)'), +(18870, 0, 20, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 22, 7, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Voidshrieker - On Spellhit \'Arcane\' - Set Event Phase 7 (Phase 1)'), +(18870, 0, 21, 0, 106, 0, 100, 0, 9000, 13000, 14000, 18000, 0, 8, 11, 22884, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Voidshrieker - On Hostile in Range - Cast \'Psychic Scream\''), +(18870, 0, 22, 0, 0, 33, 100, 0, 0, 1000, 3000, 3500, 0, 0, 11, 12471, 64, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Voidshrieker - In Combat - Cast \'Shadow Bolt\' (Phases 1 & 6)'), +(18870, 0, 23, 0, 0, 2, 100, 0, 0, 1000, 2500, 3000, 0, 0, 11, 15498, 64, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Voidshrieker - In Combat - Cast \'Holy Smite\' (Phase 2)'), +(18870, 0, 24, 0, 0, 4, 100, 0, 0, 1000, 3000, 3500, 0, 0, 11, 14034, 64, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Voidshrieker - In Combat - Cast \'Fireball\' (Phase 3)'), +(18870, 0, 25, 0, 0, 8, 100, 0, 0, 1000, 3000, 3500, 0, 0, 11, 12167, 64, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Voidshrieker - In Combat - Cast \'Lightning Bolt\' (Phase 4)'), +(18870, 0, 26, 0, 0, 16, 100, 0, 0, 1000, 3000, 3500, 0, 0, 11, 15497, 64, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Voidshrieker - In Combat - Cast \'Frostbolt\' (Phase 5)'), +(18870, 0, 27, 0, 0, 64, 100, 0, 0, 1000, 5000, 6000, 0, 0, 11, 38204, 64, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Voidshrieker - In Combat - Cast \'Arcane Bolt\' (Phase 7)'); + +DELETE FROM `creature_text` WHERE (`CreatureID` = 18870); +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(18870, 1, 0, '%s absorbs the holy energy of the attack.', 16, 0, 0, 0, 0, 0, 17110, 0, 'Voidshrieker'), +(18870, 2, 0, '%s absorbs the fire energy of the attack.', 16, 0, 0, 0, 0, 0, 17105, 0, 'Voidshrieker'), +(18870, 3, 0, '%s absorbs the nature energy of the attack.', 16, 0, 0, 0, 0, 0, 17107, 0, 'Voidshrieker'), +(18870, 4, 0, '%s absorbs the frost energy of the attack.', 16, 0, 0, 0, 0, 0, 17106, 0, 'Voidshrieker'), +(18870, 5, 0, '%s absorbs the shadow energy of the attack.', 16, 0, 0, 0, 0, 0, 17108, 0, 'Voidshrieker'), +(18870, 6, 0, '%s absorbs the arcane energy of the attack.', 16, 0, 0, 0, 0, 0, 17109, 0, 'Voidshrieker'); From 0d668fb43e3c534740111336a71e3f6209a5a5d4 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 5 Jul 2024 22:37:46 +0000 Subject: [PATCH 42/68] chore(DB): import pending files Referenced commit(s): 8acdbc44390ddf56f1f666b7c694c2e58d1d3da7 --- .../rev_1720211249204769700.sql => db_world/2024_07_05_02.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1720211249204769700.sql => db_world/2024_07_05_02.sql} (99%) diff --git a/data/sql/updates/pending_db_world/rev_1720211249204769700.sql b/data/sql/updates/db_world/2024_07_05_02.sql similarity index 99% rename from data/sql/updates/pending_db_world/rev_1720211249204769700.sql rename to data/sql/updates/db_world/2024_07_05_02.sql index 2121c7b80..2b8ab129c 100644 --- a/data/sql/updates/pending_db_world/rev_1720211249204769700.sql +++ b/data/sql/updates/db_world/2024_07_05_02.sql @@ -1,3 +1,4 @@ +-- DB update 2024_07_05_01 -> 2024_07_05_02 -- DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 18870); 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 From fc8b67bbe49e7bf9be17c77baba12ee1fda48380 Mon Sep 17 00:00:00 2001 From: Kitzunu <24550914+Kitzunu@users.noreply.github.com> Date: Sat, 6 Jul 2024 01:18:38 +0200 Subject: [PATCH 43/68] chore(Scripts/Commands): QOL server debug (#19297) * chore(Scripts/Commands): QOL server debug * England * might as well do updatetime while we are at it. Consistency right? * Hey let's sneak this ENGLAND in --- src/server/game/Conditions/ConditionMgr.cpp | 4 +- src/server/game/Time/UpdateTime.cpp | 9 +- src/server/scripts/Commands/cs_reload.cpp | 184 ++++++++++---------- src/server/scripts/Commands/cs_server.cpp | 12 +- 4 files changed, 105 insertions(+), 104 deletions(-) diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp index 8b98e0b8b..805fcd06d 100644 --- a/src/server/game/Conditions/ConditionMgr.cpp +++ b/src/server/game/Conditions/ConditionMgr.cpp @@ -1054,10 +1054,10 @@ void ConditionMgr::LoadConditions(bool isReload) LootTemplates_Spell.ResetConditions(); LootTemplates_Player.ResetConditions(); - LOG_INFO("server.loading", "Re-Loading `gossip_menu` Table for Conditions!"); + LOG_INFO("server.loading", "Reloading `gossip_menu` Table for Conditions!"); sObjectMgr->LoadGossipMenu(); - LOG_INFO("server.loading", "Re-Loading `gossip_menu_option` Table for Conditions!"); + LOG_INFO("server.loading", "Reloading `gossip_menu_option` Table for Conditions!"); sObjectMgr->LoadGossipMenuItems(); sSpellMgr->UnloadSpellInfoImplicitTargetConditionLists(); } diff --git a/src/server/game/Time/UpdateTime.cpp b/src/server/game/Time/UpdateTime.cpp index 8aa9592b7..182323ab0 100644 --- a/src/server/game/Time/UpdateTime.cpp +++ b/src/server/game/Time/UpdateTime.cpp @@ -165,10 +165,11 @@ void WorldUpdateTime::RecordUpdateTime(Milliseconds gameTimeMs, uint32 diff, uin { if (GetMSTimeDiff(_lastRecordTime, gameTimeMs) > _recordUpdateTimeInverval) { - LOG_INFO("time.update", "Last {} diffs summary with {} players online:", GetDatasetSize(), sessionCount); - LOG_INFO("time.update", " - Mean: {};", GetAverageUpdateTime()); - LOG_INFO("time.update", " - Median: {};", GetPercentile(50)); - LOG_INFO("time.update", " - Percentiles (95, 99, max): {}, {}, {}.", GetPercentile(95), GetPercentile(99), GetPercentile(100)); + LOG_INFO("time.update", "Update time diff: {} with {} players online", GetLastUpdateTime(), sessionCount); + LOG_INFO("time.update", "Last {} diffs summary:", GetDatasetSize()); + LOG_INFO("time.update", "|- Mean: {}", GetAverageUpdateTime()); + LOG_INFO("time.update", "|- Median: {}", GetPercentile(50)); + LOG_INFO("time.update", "|- Percentiles (95, 99, max): {}, {}, {}", GetPercentile(95), GetPercentile(99), GetPercentile(100)); _lastRecordTime = gameTimeMs; } } diff --git a/src/server/scripts/Commands/cs_reload.cpp b/src/server/scripts/Commands/cs_reload.cpp index 1cd1e0a23..9ea10809b 100644 --- a/src/server/scripts/Commands/cs_reload.cpp +++ b/src/server/scripts/Commands/cs_reload.cpp @@ -223,7 +223,7 @@ public: static bool HandleReloadBattlegroundTemplate(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Battleground Templates..."); + LOG_INFO("server.loading", "Reloading Battleground Templates..."); sBattlegroundMgr->LoadBattlegroundTemplates(); handler->SendGlobalGMSysMessage("DB table `battleground_template` reloaded."); return true; @@ -247,7 +247,7 @@ public: static bool HandleReloadAllLootCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Loot Tables..."); + LOG_INFO("server.loading", "Reloading Loot Tables..."); LoadLootTables(); handler->SendGlobalGMSysMessage("DB tables `*_loot_template` reloaded."); sConditionMgr->LoadConditions(true); @@ -271,7 +271,7 @@ public: HandleReloadQuestTemplateCommand(handler); HandleReloadLocalesQuestGreetingCommand(handler); - LOG_INFO("server.loading", "Re-Loading Quests Relations..."); + LOG_INFO("server.loading", "Reloading Quests Relations..."); sObjectMgr->LoadQuestStartersAndEnders(); handler->SendGlobalGMSysMessage("DB tables `*_queststarter` and `*_questender` reloaded."); return true; @@ -285,7 +285,7 @@ public: return false; } - LOG_INFO("server.loading", "Re-Loading Scripts..."); + LOG_INFO("server.loading", "Reloading Scripts..."); HandleReloadEventScriptsCommand(handler); HandleReloadSpellScriptsCommand(handler); handler->SendGlobalGMSysMessage("DB tables `*_scripts` reloaded."); @@ -346,7 +346,7 @@ public: static bool HandleReloadConfigCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading config settings..."); + LOG_INFO("server.loading", "Reloading config settings..."); sWorld->LoadConfigSettings(true); sMapMgr->InitializeVisibilityDistanceInfo(); handler->SendGlobalGMSysMessage("World config settings reloaded."); @@ -355,7 +355,7 @@ public: static bool HandleReloadDungeonAccessCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Dungeon Access Requirement definitions..."); + LOG_INFO("server.loading", "Reloading Dungeon Access Requirement definitions..."); sObjectMgr->LoadAccessRequirements(); handler->SendGlobalGMSysMessage("DB tables `dungeon_access_template` AND `dungeon_access_requirements` reloaded."); return true; @@ -363,7 +363,7 @@ public: static bool HandleReloadAchievementCriteriaDataCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Additional Achievement Criteria Data..."); + LOG_INFO("server.loading", "Reloading Additional Achievement Criteria Data..."); sAchievementMgr->LoadAchievementCriteriaData(); handler->SendGlobalGMSysMessage("DB table `achievement_criteria_data` reloaded."); return true; @@ -371,7 +371,7 @@ public: static bool HandleReloadAchievementRewardCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Achievement Reward Data..."); + LOG_INFO("server.loading", "Reloading Achievement Reward Data..."); sAchievementMgr->LoadRewards(); handler->SendGlobalGMSysMessage("DB table `achievement_reward` reloaded."); return true; @@ -379,7 +379,7 @@ public: static bool HandleReloadAreaTriggerTavernCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Tavern Area Triggers..."); + LOG_INFO("server.loading", "Reloading Tavern Area Triggers..."); sObjectMgr->LoadTavernAreaTriggers(); handler->SendGlobalGMSysMessage("DB table `areatrigger_tavern` reloaded."); return true; @@ -387,7 +387,7 @@ public: static bool HandleReloadAreaTriggerCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Area Trigger definitions..."); + LOG_INFO("server.loading", "Reloading Area Trigger definitions..."); sObjectMgr->LoadAreaTriggers(); handler->SendGlobalGMSysMessage("DB table `areatrigger` reloaded."); return true; @@ -395,7 +395,7 @@ public: static bool HandleReloadAreaTriggerTeleportCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Area Trigger teleport definitions..."); + LOG_INFO("server.loading", "Reloading Area Trigger teleport definitions..."); sObjectMgr->LoadAreaTriggerTeleports(); handler->SendGlobalGMSysMessage("DB table `areatrigger_teleport` reloaded."); return true; @@ -403,7 +403,7 @@ public: static bool HandleReloadAutobroadcastCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Autobroadcasts..."); + LOG_INFO("server.loading", "Reloading Autobroadcasts..."); sAutobroadcastMgr->LoadAutobroadcasts(); handler->SendGlobalGMSysMessage("DB table `autobroadcast` reloaded."); return true; @@ -411,7 +411,7 @@ public: static bool HandleReloadMotdCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Motd..."); + LOG_INFO("server.loading", "Reloading Motd..."); sMotdMgr->LoadMotd(); handler->SendGlobalGMSysMessage("DB table `motd` reloaded."); handler->SendGlobalSysMessage(sMotdMgr->GetMotd()); @@ -420,7 +420,7 @@ public: static bool HandleReloadBroadcastTextCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Broadcast texts..."); + LOG_INFO("server.loading", "Reloading Broadcast texts..."); sObjectMgr->LoadBroadcastTexts(); sObjectMgr->LoadBroadcastTextLocales(); handler->SendGlobalGMSysMessage("DB table `broadcast_text` reloaded."); @@ -440,7 +440,7 @@ public: static bool HandleReloadOnKillReputationCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading creature award reputation definitions..."); + LOG_INFO("server.loading", "Reloading creature award reputation definitions..."); sObjectMgr->LoadReputationOnKill(); handler->SendGlobalGMSysMessage("DB table `creature_onkill_reputation` reloaded."); return true; @@ -510,7 +510,7 @@ public: static bool HandleReloadGossipMenuCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading `gossip_menu` Table!"); + LOG_INFO("server.loading", "Reloading `gossip_menu` Table!"); sObjectMgr->LoadGossipMenu(); handler->SendGlobalGMSysMessage("DB table `gossip_menu` reloaded."); sConditionMgr->LoadConditions(true); @@ -519,7 +519,7 @@ public: static bool HandleReloadGossipMenuOptionCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading `gossip_menu_option` Table!"); + LOG_INFO("server.loading", "Reloading `gossip_menu_option` Table!"); sObjectMgr->LoadGossipMenuItems(); handler->SendGlobalGMSysMessage("DB table `gossip_menu_option` reloaded."); sConditionMgr->LoadConditions(true); @@ -544,7 +544,7 @@ public: static bool HandleReloadQuestAreaTriggersCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Quest Area Triggers..."); + LOG_INFO("server.loading", "Reloading Quest Area Triggers..."); sObjectMgr->LoadQuestAreaTriggers(); handler->SendGlobalGMSysMessage("DB table `areatrigger_involvedrelation` (quest area triggers) reloaded."); return true; @@ -552,7 +552,7 @@ public: static bool HandleReloadQuestGreetingCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Quest Greeting ..."); + LOG_INFO("server.loading", "Reloading Quest Greeting ..."); sObjectMgr->LoadQuestGreetings(); handler->SendGlobalGMSysMessage("DB table `quest_greeting` reloaded."); return true; @@ -560,7 +560,7 @@ public: static bool HandleReloadLocalesQuestGreetingCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Quest Greeting locales..."); + LOG_INFO("server.loading", "Reloading Quest Greeting locales..."); sObjectMgr->LoadQuestGreetingsLocales(); handler->SendGlobalGMSysMessage("DB table `quest_greeting_locale` reloaded."); return true; @@ -568,12 +568,12 @@ public: static bool HandleReloadQuestTemplateCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Quest Templates..."); + LOG_INFO("server.loading", "Reloading Quest Templates..."); sObjectMgr->LoadQuests(); handler->SendGlobalGMSysMessage("DB table `quest_template` (quest definitions) reloaded."); /// dependent also from `gameobject` but this table not reloaded anyway - LOG_INFO("server.loading", "Re-Loading GameObjects for quests..."); + LOG_INFO("server.loading", "Reloading GameObjects for quests..."); sObjectMgr->LoadGameObjectForQuests(); handler->SendGlobalGMSysMessage("Data GameObjects for quests reloaded."); return true; @@ -581,7 +581,7 @@ public: static bool HandleReloadLootTemplatesCreatureCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Loot Tables... (`creature_loot_template`)"); + LOG_INFO("server.loading", "Reloading Loot Tables... (`creature_loot_template`)"); LoadLootTemplates_Creature(); LootTemplates_Creature.CheckLootRefs(); handler->SendGlobalGMSysMessage("DB table `creature_loot_template` reloaded."); @@ -591,7 +591,7 @@ public: static bool HandleReloadCreatureMovementOverrideCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Creature movement overrides..."); + LOG_INFO("server.loading", "Reloading Creature movement overrides..."); sObjectMgr->LoadCreatureMovementOverrides(); handler->SendGlobalGMSysMessage("DB table `creature_movement_override` reloaded."); return true; @@ -599,7 +599,7 @@ public: static bool HandleReloadLootTemplatesDisenchantCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Loot Tables... (`disenchant_loot_template`)"); + LOG_INFO("server.loading", "Reloading Loot Tables... (`disenchant_loot_template`)"); LoadLootTemplates_Disenchant(); LootTemplates_Disenchant.CheckLootRefs(); handler->SendGlobalGMSysMessage("DB table `disenchant_loot_template` reloaded."); @@ -609,7 +609,7 @@ public: static bool HandleReloadLootTemplatesFishingCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Loot Tables... (`fishing_loot_template`)"); + LOG_INFO("server.loading", "Reloading Loot Tables... (`fishing_loot_template`)"); LoadLootTemplates_Fishing(); LootTemplates_Fishing.CheckLootRefs(); handler->SendGlobalGMSysMessage("DB table `fishing_loot_template` reloaded."); @@ -619,7 +619,7 @@ public: static bool HandleReloadLootTemplatesGameobjectCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Loot Tables... (`gameobject_loot_template`)"); + LOG_INFO("server.loading", "Reloading Loot Tables... (`gameobject_loot_template`)"); LoadLootTemplates_Gameobject(); LootTemplates_Gameobject.CheckLootRefs(); handler->SendGlobalGMSysMessage("DB table `gameobject_loot_template` reloaded."); @@ -629,7 +629,7 @@ public: static bool HandleReloadLootTemplatesItemCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Loot Tables... (`item_loot_template`)"); + LOG_INFO("server.loading", "Reloading Loot Tables... (`item_loot_template`)"); LoadLootTemplates_Item(); LootTemplates_Item.CheckLootRefs(); handler->SendGlobalGMSysMessage("DB table `item_loot_template` reloaded."); @@ -639,7 +639,7 @@ public: static bool HandleReloadLootTemplatesMillingCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Loot Tables... (`milling_loot_template`)"); + LOG_INFO("server.loading", "Reloading Loot Tables... (`milling_loot_template`)"); LoadLootTemplates_Milling(); LootTemplates_Milling.CheckLootRefs(); handler->SendGlobalGMSysMessage("DB table `milling_loot_template` reloaded."); @@ -649,7 +649,7 @@ public: static bool HandleReloadLootTemplatesPickpocketingCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Loot Tables... (`pickpocketing_loot_template`)"); + LOG_INFO("server.loading", "Reloading Loot Tables... (`pickpocketing_loot_template`)"); LoadLootTemplates_Pickpocketing(); LootTemplates_Pickpocketing.CheckLootRefs(); handler->SendGlobalGMSysMessage("DB table `pickpocketing_loot_template` reloaded."); @@ -659,7 +659,7 @@ public: static bool HandleReloadLootTemplatesProspectingCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Loot Tables... (`prospecting_loot_template`)"); + LOG_INFO("server.loading", "Reloading Loot Tables... (`prospecting_loot_template`)"); LoadLootTemplates_Prospecting(); LootTemplates_Prospecting.CheckLootRefs(); handler->SendGlobalGMSysMessage("DB table `prospecting_loot_template` reloaded."); @@ -669,7 +669,7 @@ public: static bool HandleReloadLootTemplatesMailCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Loot Tables... (`mail_loot_template`)"); + LOG_INFO("server.loading", "Reloading Loot Tables... (`mail_loot_template`)"); LoadLootTemplates_Mail(); LootTemplates_Mail.CheckLootRefs(); handler->SendGlobalGMSysMessage("DB table `mail_loot_template` reloaded."); @@ -679,7 +679,7 @@ public: static bool HandleReloadLootTemplatesReferenceCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Loot Tables... (`reference_loot_template`)"); + LOG_INFO("server.loading", "Reloading Loot Tables... (`reference_loot_template`)"); LoadLootTemplates_Reference(); handler->SendGlobalGMSysMessage("DB table `reference_loot_template` reloaded."); sConditionMgr->LoadConditions(true); @@ -688,7 +688,7 @@ public: static bool HandleReloadLootTemplatesSkinningCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Loot Tables... (`skinning_loot_template`)"); + LOG_INFO("server.loading", "Reloading Loot Tables... (`skinning_loot_template`)"); LoadLootTemplates_Skinning(); LootTemplates_Skinning.CheckLootRefs(); handler->SendGlobalGMSysMessage("DB table `skinning_loot_template` reloaded."); @@ -698,7 +698,7 @@ public: static bool HandleReloadLootTemplatesSpellCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Loot Tables... (`spell_loot_template`)"); + LOG_INFO("server.loading", "Reloading Loot Tables... (`spell_loot_template`)"); LoadLootTemplates_Spell(); LootTemplates_Spell.CheckLootRefs(); handler->SendGlobalGMSysMessage("DB table `spell_loot_template` reloaded."); @@ -708,7 +708,7 @@ public: static bool HandleReloadLootTemplatesPlayerCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Loot Tables... (`player_loot_template`)"); + LOG_INFO("server.loading", "Reloading Loot Tables... (`player_loot_template`)"); LoadLootTemplates_Player(); LootTemplates_Player.CheckLootRefs(); handler->SendGlobalGMSysMessage("DB table `player_loot_template` reloaded."); @@ -718,7 +718,7 @@ public: static bool HandleReloadAcoreStringCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading acore_string Table!"); + LOG_INFO("server.loading", "Reloading acore_string Table!"); sObjectMgr->LoadAcoreStrings(); handler->SendGlobalGMSysMessage("DB table `acore_string` reloaded."); return true; @@ -732,7 +732,7 @@ public: return false; } - LOG_INFO("server.loading", "Re-Loading warden_action Table!"); + LOG_INFO("server.loading", "Reloading warden_action Table!"); sWardenCheckMgr->LoadWardenOverrides(); handler->SendGlobalGMSysMessage("DB table `warden_action` reloaded."); return true; @@ -740,7 +740,7 @@ public: static bool HandleReloadNpcTrainerCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading `npc_trainer` Table!"); + LOG_INFO("server.loading", "Reloading `npc_trainer` Table!"); sObjectMgr->LoadTrainerSpell(); handler->SendGlobalGMSysMessage("DB table `npc_trainer` reloaded."); return true; @@ -748,7 +748,7 @@ public: static bool HandleReloadNpcVendorCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading `npc_vendor` Table!"); + LOG_INFO("server.loading", "Reloading `npc_vendor` Table!"); sObjectMgr->LoadVendors(); handler->SendGlobalGMSysMessage("DB table `npc_vendor` reloaded."); return true; @@ -756,7 +756,7 @@ public: static bool HandleReloadPointsOfInterestCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading `points_of_interest` Table!"); + LOG_INFO("server.loading", "Reloading `points_of_interest` Table!"); sObjectMgr->LoadPointsOfInterest(); handler->SendGlobalGMSysMessage("DB table `points_of_interest` reloaded."); return true; @@ -764,7 +764,7 @@ public: static bool HandleReloadQuestPOICommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Quest POI ..." ); + LOG_INFO("server.loading", "Reloading Quest POI ..." ); sObjectMgr->LoadQuestPOI(); handler->SendGlobalGMSysMessage("DB Table `quest_poi` and `quest_poi_points` reloaded."); return true; @@ -772,7 +772,7 @@ public: static bool HandleReloadSpellClickSpellsCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading `npc_spellclick_spells` Table!"); + LOG_INFO("server.loading", "Reloading `npc_spellclick_spells` Table!"); sObjectMgr->LoadNPCSpellClickSpells(); handler->SendGlobalGMSysMessage("DB table `npc_spellclick_spells` reloaded."); return true; @@ -780,7 +780,7 @@ public: static bool HandleReloadReservedNameCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Reserved Names!"); + LOG_INFO("server.loading", "Reloading Reserved Names!"); sObjectMgr->LoadReservedPlayerNamesDB(); sObjectMgr->LoadReservedPlayerNamesDBC(); // Needed because we clear the store in LoadReservedPlayerNamesDB() handler->SendGlobalGMSysMessage("Reserved Names reloaded."); @@ -789,7 +789,7 @@ public: static bool HandleReloadProfanityNameCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Profanity Names!"); + LOG_INFO("server.loading", "Reloading Profanity Names!"); sObjectMgr->LoadProfanityNamesFromDB(); sObjectMgr->LoadProfanityNamesFromDBC(); // Needed because we clear the store in LoadProfanityNamesFromDB() handler->SendGlobalGMSysMessage("Profanity Names reloaded."); @@ -798,7 +798,7 @@ public: static bool HandleReloadReputationRewardRateCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading `reputation_reward_rate` Table!" ); + LOG_INFO("server.loading", "Reloading `reputation_reward_rate` Table!" ); sObjectMgr->LoadReputationRewardRate(); handler->SendGlobalSysMessage("DB table `reputation_reward_rate` reloaded."); return true; @@ -806,7 +806,7 @@ public: static bool HandleReloadReputationSpilloverTemplateCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading `reputation_spillover_template` Table!" ); + LOG_INFO("server.loading", "Reloading `reputation_spillover_template` Table!" ); sObjectMgr->LoadReputationSpilloverTemplate(); handler->SendGlobalSysMessage("DB table `reputation_spillover_template` reloaded."); return true; @@ -814,7 +814,7 @@ public: static bool HandleReloadSkillDiscoveryTemplateCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Skill Discovery Table..."); + LOG_INFO("server.loading", "Reloading Skill Discovery Table..."); LoadSkillDiscoveryTable(); handler->SendGlobalGMSysMessage("DB table `skill_discovery_template` (recipes discovered at crafting) reloaded."); return true; @@ -823,7 +823,7 @@ public: static bool HandleReloadSkillPerfectItemTemplateCommand(ChatHandler* handler) { // latched onto HandleReloadSkillExtraItemTemplateCommand as it's part of that table group (and i don't want to chance all the command IDs) - LOG_INFO("server.loading", "Re-Loading Skill Perfection Data Table..."); + LOG_INFO("server.loading", "Reloading Skill Perfection Data Table..."); LoadSkillPerfectItemTable(); handler->SendGlobalGMSysMessage("DB table `skill_perfect_item_template` (perfect item procs when crafting) reloaded."); return true; @@ -831,7 +831,7 @@ public: static bool HandleReloadSkillExtraItemTemplateCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Skill Extra Item Table..."); + LOG_INFO("server.loading", "Reloading Skill Extra Item Table..."); LoadSkillExtraItemTable(); handler->SendGlobalGMSysMessage("DB table `skill_extra_item_template` (extra item creation when crafting) reloaded."); return HandleReloadSkillPerfectItemTemplateCommand(handler); @@ -839,7 +839,7 @@ public: static bool HandleReloadSkillFishingBaseLevelCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Skill Fishing base level requirements..."); + LOG_INFO("server.loading", "Reloading Skill Fishing base level requirements..."); sObjectMgr->LoadFishingBaseSkillLevel(); handler->SendGlobalGMSysMessage("DB table `skill_fishing_base_level` (fishing base level for zone/subzone) reloaded."); return true; @@ -847,7 +847,7 @@ public: static bool HandleReloadSpellAreaCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading SpellArea Data..."); + LOG_INFO("server.loading", "Reloading SpellArea Data..."); sSpellMgr->LoadSpellAreas(); handler->SendGlobalGMSysMessage("DB table `spell_area` (spell dependences from area/quest/auras state) reloaded."); return true; @@ -855,7 +855,7 @@ public: static bool HandleReloadSpellRequiredCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Spell Required Data... "); + LOG_INFO("server.loading", "Reloading Spell Required Data... "); sSpellMgr->LoadSpellRequired(); handler->SendGlobalGMSysMessage("DB table `spell_required` reloaded."); return true; @@ -863,7 +863,7 @@ public: static bool HandleReloadSpellGroupsCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Spell Groups..."); + LOG_INFO("server.loading", "Reloading Spell Groups..."); sSpellMgr->LoadSpellGroups(); handler->SendGlobalGMSysMessage("DB table `spell_group` (spell groups) reloaded."); return true; @@ -871,7 +871,7 @@ public: static bool HandleReloadSpellLinkedSpellCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Spell Linked Spells..."); + LOG_INFO("server.loading", "Reloading Spell Linked Spells..."); sSpellMgr->LoadSpellLinked(); handler->SendGlobalGMSysMessage("DB table `spell_linked_spell` reloaded."); return true; @@ -879,7 +879,7 @@ public: static bool HandleReloadSpellProcEventCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Spell Proc Event conditions..."); + LOG_INFO("server.loading", "Reloading Spell Proc Event conditions..."); sSpellMgr->LoadSpellProcEvents(); handler->SendGlobalGMSysMessage("DB table `spell_proc_event` (spell proc trigger requirements) reloaded."); return true; @@ -887,7 +887,7 @@ public: static bool HandleReloadSpellProcsCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Spell Proc conditions and data..."); + LOG_INFO("server.loading", "Reloading Spell Proc conditions and data..."); sSpellMgr->LoadSpellProcs(); handler->SendGlobalGMSysMessage("DB table `spell_proc` (spell proc conditions and data) reloaded."); return true; @@ -895,7 +895,7 @@ public: static bool HandleReloadSpellBonusesCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Spell Bonus Data..."); + LOG_INFO("server.loading", "Reloading Spell Bonus Data..."); sSpellMgr->LoadSpellBonuses(); handler->SendGlobalGMSysMessage("DB table `spell_bonus_data` (spell damage/healing coefficients) reloaded."); return true; @@ -903,7 +903,7 @@ public: static bool HandleReloadSpellTargetPositionCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Spell target coordinates..."); + LOG_INFO("server.loading", "Reloading Spell target coordinates..."); sSpellMgr->LoadSpellTargetPositions(); handler->SendGlobalGMSysMessage("DB table `spell_target_position` (destination coordinates for spell targets) reloaded."); return true; @@ -911,7 +911,7 @@ public: static bool HandleReloadSpellThreatsCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Aggro Spells Definitions..."); + LOG_INFO("server.loading", "Reloading Aggro Spells Definitions..."); sSpellMgr->LoadSpellThreats(); handler->SendGlobalGMSysMessage("DB table `spell_threat` (spell aggro definitions) reloaded."); return true; @@ -919,7 +919,7 @@ public: static bool HandleReloadSpellGroupStackRulesCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Spell Group Stack Rules..."); + LOG_INFO("server.loading", "Reloading Spell Group Stack Rules..."); sSpellMgr->LoadSpellGroupStackRules(); handler->SendGlobalGMSysMessage("DB table `spell_group_stack_rules` (spell stacking definitions) reloaded."); return true; @@ -927,7 +927,7 @@ public: static bool HandleReloadSpellPetAurasCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Spell pet auras..."); + LOG_INFO("server.loading", "Reloading Spell pet auras..."); sSpellMgr->LoadSpellPetAuras(); handler->SendGlobalGMSysMessage("DB table `spell_pet_auras` reloaded."); return true; @@ -935,7 +935,7 @@ public: static bool HandleReloadPageTextsCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Page Texts..."); + LOG_INFO("server.loading", "Reloading Page Texts..."); sObjectMgr->LoadPageTexts(); handler->SendGlobalGMSysMessage("DB table `page_texts` reloaded."); handler->SendGlobalGMSysMessage("You need to delete your client cache or change the cache number in config in order for your players see the changes."); @@ -944,7 +944,7 @@ public: static bool HandleReloadItemEnchantementsCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Item Random Enchantments Table..."); + LOG_INFO("server.loading", "Reloading Item Random Enchantments Table..."); LoadRandomEnchantmentsTable(); handler->SendGlobalGMSysMessage("DB table `item_enchantment_template` reloaded."); return true; @@ -952,7 +952,7 @@ public: static bool HandleReloadItemSetNamesCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Item set names..."); + LOG_INFO("server.loading", "Reloading Item set names..."); sObjectMgr->LoadItemSetNames(); handler->SendGlobalGMSysMessage("DB table `item_set_names` reloaded."); return true; @@ -966,7 +966,7 @@ public: return false; } - LOG_INFO("server.loading", "Re-Loading Scripts from `event_scripts`..."); + LOG_INFO("server.loading", "Reloading Scripts from `event_scripts`..."); sObjectMgr->LoadEventScripts(); @@ -983,7 +983,7 @@ public: return false; } - LOG_INFO("server.loading", "Re-Loading Scripts from `waypoint_scripts`..."); + LOG_INFO("server.loading", "Reloading Scripts from `waypoint_scripts`..."); sObjectMgr->LoadWaypointScripts(); @@ -994,7 +994,7 @@ public: static bool HandleReloadWpCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Waypoints data from 'waypoints_data'"); + LOG_INFO("server.loading", "Reloading Waypoints data from 'waypoints_data'"); sWaypointMgr->Load(); handler->SendGlobalGMSysMessage("DB Table 'waypoint_data' reloaded."); @@ -1009,7 +1009,7 @@ public: return false; } - LOG_INFO("server.loading", "Re-Loading Scripts from `spell_scripts`..."); + LOG_INFO("server.loading", "Reloading Scripts from `spell_scripts`..."); sObjectMgr->LoadSpellScripts(); @@ -1020,7 +1020,7 @@ public: static bool HandleReloadGameGraveyardZoneCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Graveyard-zone links..."); + LOG_INFO("server.loading", "Reloading Graveyard-zone links..."); sGraveyard->LoadGraveyardZones(); @@ -1031,7 +1031,7 @@ public: static bool HandleReloadGameTeleCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Game Tele coordinates..."); + LOG_INFO("server.loading", "Reloading Game Tele coordinates..."); sObjectMgr->LoadGameTele(); @@ -1042,7 +1042,7 @@ public: static bool HandleReloadDisablesCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading disables table..."); + LOG_INFO("server.loading", "Reloading disables table..."); DisableMgr::LoadDisables(); LOG_INFO("server.loading", "Checking quest disables..."); DisableMgr::CheckQuestDisables(); @@ -1052,7 +1052,7 @@ public: static bool HandleReloadLocalesAchievementRewardCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Achievement Reward Data Locale..."); + LOG_INFO("server.loading", "Reloading Achievement Reward Data Locale..."); sAchievementMgr->LoadRewardLocales(); handler->SendGlobalGMSysMessage("DB table `achievement_reward_locale` reloaded."); return true; @@ -1060,7 +1060,7 @@ public: static bool HandleReloadLfgRewardsCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading lfg dungeon rewards..."); + LOG_INFO("server.loading", "Reloading lfg dungeon rewards..."); sLFGMgr->LoadRewards(); handler->SendGlobalGMSysMessage("DB table `lfg_dungeon_rewards` reloaded."); return true; @@ -1068,7 +1068,7 @@ public: static bool HandleReloadLocalesCreatureCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Creature Template Locale..."); + LOG_INFO("server.loading", "Reloading Creature Template Locale..."); sObjectMgr->LoadCreatureLocales(); handler->SendGlobalGMSysMessage("DB table `creature_template_locale` reloaded."); return true; @@ -1076,7 +1076,7 @@ public: static bool HandleReloadLocalesCreatureTextCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Creature Texts Locale..."); + LOG_INFO("server.loading", "Reloading Creature Texts Locale..."); sCreatureTextMgr->LoadCreatureTextLocales(); handler->SendGlobalGMSysMessage("DB table `creature_text_locale` reloaded."); return true; @@ -1084,7 +1084,7 @@ public: static bool HandleReloadLocalesGameobjectCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Gameobject Template Locale ... "); + LOG_INFO("server.loading", "Reloading Gameobject Template Locale ... "); sObjectMgr->LoadGameObjectLocales(); handler->SendGlobalGMSysMessage("DB table `gameobject_template_locale` reloaded."); return true; @@ -1092,7 +1092,7 @@ public: static bool HandleReloadLocalesGossipMenuOptionCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Gossip Menu Option Locale ... "); + LOG_INFO("server.loading", "Reloading Gossip Menu Option Locale ... "); sObjectMgr->LoadGossipMenuItemsLocales(); handler->SendGlobalGMSysMessage("DB table `gossip_menu_option_locale` reloaded."); return true; @@ -1100,7 +1100,7 @@ public: static bool HandleReloadLocalesItemCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Item Template Locale ... "); + LOG_INFO("server.loading", "Reloading Item Template Locale ... "); sObjectMgr->LoadItemLocales(); handler->SendGlobalGMSysMessage("DB table `item_template_locale` reloaded."); return true; @@ -1108,7 +1108,7 @@ public: static bool HandleReloadLocalesItemSetNameCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Item set name Locale... "); + LOG_INFO("server.loading", "Reloading Item set name Locale... "); sObjectMgr->LoadItemSetNameLocales(); handler->SendGlobalGMSysMessage("DB table `item_set_name_locale` reloaded."); return true; @@ -1116,7 +1116,7 @@ public: static bool HandleReloadLocalesNpcTextCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading NPC Text Locale ... "); + LOG_INFO("server.loading", "Reloading NPC Text Locale ... "); sObjectMgr->LoadNpcTextLocales(); handler->SendGlobalGMSysMessage("DB table `npc_text_locale` reloaded."); return true; @@ -1124,7 +1124,7 @@ public: static bool HandleReloadLocalesPageTextCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Page Text Locale ... "); + LOG_INFO("server.loading", "Reloading Page Text Locale ... "); sObjectMgr->LoadPageTextLocales(); handler->SendGlobalGMSysMessage("DB table `page_text_locale` reloaded."); handler->SendGlobalGMSysMessage("You need to delete your client cache or change the cache number in config in order for your players see the changes."); @@ -1133,7 +1133,7 @@ public: static bool HandleReloadLocalesPointsOfInterestCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Points Of Interest Locale ... "); + LOG_INFO("server.loading", "Reloading Points Of Interest Locale ... "); sObjectMgr->LoadPointOfInterestLocales(); handler->SendGlobalGMSysMessage("DB table `points_of_interest_locale` reloaded."); return true; @@ -1141,7 +1141,7 @@ public: static bool HandleReloadLocalesQuestCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Locales Quest ... "); + LOG_INFO("server.loading", "Reloading Locales Quest ... "); sObjectMgr->LoadQuestLocales(); handler->SendGlobalGMSysMessage("DB table `quest_template_locale` reloaded."); return true; @@ -1149,7 +1149,7 @@ public: static bool HandleReloadLocalesQuestOfferRewardCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Quest Offer Reward Locale... "); + LOG_INFO("server.loading", "Reloading Quest Offer Reward Locale... "); sObjectMgr->LoadQuestOfferRewardLocale(); handler->SendGlobalGMSysMessage("DB table `quest_offer_reward_locale` reloaded."); return true; @@ -1157,7 +1157,7 @@ public: static bool HandleReloadLocalesQuestRequestItemsCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Quest Request Item Locale... "); + LOG_INFO("server.loading", "Reloading Quest Request Item Locale... "); sObjectMgr->LoadQuestRequestItemsLocale(); handler->SendGlobalGMSysMessage("DB table `quest_request_item_locale` reloaded."); return true; @@ -1165,7 +1165,7 @@ public: static bool HandleReloadMailLevelRewardCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Player level dependent mail rewards..."); + LOG_INFO("server.loading", "Reloading Player level dependent mail rewards..."); sObjectMgr->LoadMailLevelRewards(); handler->SendGlobalGMSysMessage("DB table `mail_level_reward` reloaded."); return true; @@ -1173,7 +1173,7 @@ public: static bool HandleReloadMailServerTemplateCommand(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading `server_mail_template` table"); + LOG_INFO("server.loading", "Reloading `server_mail_template` table"); sObjectMgr->LoadMailServerTemplates(); handler->SendGlobalGMSysMessage("DB table `server_mail_template` reloaded."); return true; @@ -1182,7 +1182,7 @@ public: static bool HandleReloadAuctionsCommand(ChatHandler* handler) { ///- Reload dynamic data tables from the database - LOG_INFO("server.loading", "Re-Loading Auctions..."); + LOG_INFO("server.loading", "Reloading Auctions..."); sAuctionMgr->LoadAuctionItems(); sAuctionMgr->LoadAuctions(); handler->SendGlobalGMSysMessage("Auctions reloaded."); @@ -1191,7 +1191,7 @@ public: static bool HandleReloadConditions(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Conditions..."); + LOG_INFO("server.loading", "Reloading Conditions..."); sConditionMgr->LoadConditions(true); handler->SendGlobalGMSysMessage("Conditions reloaded."); return true; @@ -1199,7 +1199,7 @@ public: static bool HandleReloadCreatureText(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Creature Texts..."); + LOG_INFO("server.loading", "Reloading Creature Texts..."); sCreatureTextMgr->LoadCreatureTexts(); handler->SendGlobalGMSysMessage("Creature Texts reloaded."); return true; @@ -1207,7 +1207,7 @@ public: static bool HandleReloadSmartScripts(ChatHandler* handler) { - LOG_INFO("server.loading", "Re-Loading Smart Scripts..."); + LOG_INFO("server.loading", "Reloading Smart Scripts..."); sSmartScriptMgr->LoadSmartAIFromDB(); handler->SendGlobalGMSysMessage("Smart Scripts reloaded."); return true; diff --git a/src/server/scripts/Commands/cs_server.cpp b/src/server/scripts/Commands/cs_server.cpp index a6a20c108..d004420b4 100644 --- a/src/server/scripts/Commands/cs_server.cpp +++ b/src/server/scripts/Commands/cs_server.cpp @@ -243,13 +243,13 @@ public: handler->PSendSysMessage("WorldDatabase queue size: %zu", WorldDatabase.QueueSize()); if (Acore::Module::GetEnableModulesList().empty()) - handler->SendSysMessage("No modules enabled"); + handler->SendSysMessage("No modules are enabled"); else - handler->SendSysMessage("> List enable modules:"); + handler->SendSysMessage("List of enabled modules:"); for (auto const& modName : Acore::Module::GetEnableModulesList()) { - handler->SendSysMessage(Acore::StringFormatFmt("- {}", modName)); + handler->SendSysMessage(Acore::StringFormatFmt("|- {}", modName)); } return true; @@ -272,9 +272,9 @@ public: handler->PSendSysMessage("Connection peak: %u.", connPeak); handler->PSendSysMessage(LANG_UPTIME, secsToTimeString(GameTime::GetUptime().count()).c_str()); handler->PSendSysMessage("Update time diff: %ums. Last %d diffs summary:", sWorldUpdateTime.GetLastUpdateTime(), sWorldUpdateTime.GetDatasetSize()); - handler->PSendSysMessage("- Mean: %ums", sWorldUpdateTime.GetAverageUpdateTime()); - handler->PSendSysMessage("- Median: %ums", sWorldUpdateTime.GetPercentile(50)); - handler->PSendSysMessage("- Percentiles (95, 99, max): %ums, %ums, %ums", + handler->PSendSysMessage("|- Mean: %ums", sWorldUpdateTime.GetAverageUpdateTime()); + handler->PSendSysMessage("|- Median: %ums", sWorldUpdateTime.GetPercentile(50)); + handler->PSendSysMessage("|- Percentiles (95, 99, max): %ums, %ums, %ums", sWorldUpdateTime.GetPercentile(95), sWorldUpdateTime.GetPercentile(99), sWorldUpdateTime.GetPercentile(100)); From f83660ca8680cd971d119d0ff010041c5e10afa8 Mon Sep 17 00:00:00 2001 From: Gultask <100873791+Gultask@users.noreply.github.com> Date: Fri, 5 Jul 2024 21:15:46 -0300 Subject: [PATCH 44/68] chore(DB/Loot): Remove Metzen's Letters and Notes from creature loot tables (#19299) Create rev_1720224478854376400.sql --- data/sql/updates/pending_db_world/rev_1720224478854376400.sql | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1720224478854376400.sql diff --git a/data/sql/updates/pending_db_world/rev_1720224478854376400.sql b/data/sql/updates/pending_db_world/rev_1720224478854376400.sql new file mode 100644 index 000000000..b5717ff34 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1720224478854376400.sql @@ -0,0 +1,2 @@ +-- +DELETE FROM `creature_loot_template` WHERE `Item` = 21314; From b357e8e2c4a181c24a82ac1bf710afe027bc04f9 Mon Sep 17 00:00:00 2001 From: Gultask <100873791+Gultask@users.noreply.github.com> Date: Fri, 5 Jul 2024 21:16:03 -0300 Subject: [PATCH 45/68] fix(DB/Creature): Add AI to Affray Challenger (#19298) Create rev_1720223739574037500.sql --- .../rev_1720223739574037500.sql | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1720223739574037500.sql diff --git a/data/sql/updates/pending_db_world/rev_1720223739574037500.sql b/data/sql/updates/pending_db_world/rev_1720223739574037500.sql new file mode 100644 index 000000000..a253cc343 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1720223739574037500.sql @@ -0,0 +1,17 @@ +-- +DELETE FROM `creature_text` WHERE (`CreatureID` = 6240); +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(6240, 0, 0, '%s is demoralized and runs!', 16, 0, 100, 0, 0, 0, 2356, 0, 'Affray Challenger'); + +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 6240; + +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 6240); +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 +(6240, 0, 1, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Affray Challenger - On Spellhit \'Demoralizing Shout\' - Emote'), +(6240, 0, 2, 1, 8, 0, 100, 0, 1160, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Affray Challenger - On Spellhit \'Demoralizing Shout\' - Flee For Assist'), +(6240, 0, 3, 1, 8, 0, 100, 0, 6190, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Affray Challenger - On Spellhit \'Demoralizing Shout\' - Flee For Assist'), +(6240, 0, 4, 1, 8, 0, 100, 0, 11554, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Affray Challenger - On Spellhit \'Demoralizing Shout\' - Flee For Assist'), +(6240, 0, 5, 1, 8, 0, 100, 0, 11555, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Affray Challenger - On Spellhit \'Demoralizing Shout\' - Flee For Assist'), +(6240, 0, 6, 1, 8, 0, 100, 0, 11556, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Affray Challenger - On Spellhit \'Demoralizing Shout\' - Flee For Assist'), +(6240, 0, 7, 1, 8, 0, 100, 0, 25202, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Affray Challenger - On Spellhit \'Demoralizing Shout\' - Flee For Assist'), +(6240, 0, 8, 1, 8, 0, 100, 0, 25203, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Affray Challenger - On Spellhit \'Demoralizing Shout\' - Flee For Assist'); From 4a06256bb735a8663ecca68f9f3be106d36807d9 Mon Sep 17 00:00:00 2001 From: Gultask <100873791+Gultask@users.noreply.github.com> Date: Fri, 5 Jul 2024 21:16:20 -0300 Subject: [PATCH 46/68] fix(DB/Condition): Fix condition type for restoring Scale of the Sands exalted ring (#19291) * Create rev_1720214274816211200.sql * Update rev_1720214274816211200.sql --- .../updates/pending_db_world/rev_1720214274816211200.sql | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1720214274816211200.sql diff --git a/data/sql/updates/pending_db_world/rev_1720214274816211200.sql b/data/sql/updates/pending_db_world/rev_1720214274816211200.sql new file mode 100644 index 000000000..8da4d6495 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1720214274816211200.sql @@ -0,0 +1,9 @@ +-- +UPDATE `conditions` SET `ConditionTypeOrReference` = 8 WHERE `SourceGroup` = 8234 AND `SourceTypeOrReferenceId` = 15 AND `ConditionTypeOrReference` = 9; + +DELETE FROM `gossip_menu_option` WHERE (`MenuID` = 8234); +INSERT INTO `gossip_menu_option` (`MenuID`, `OptionID`, `OptionIcon`, `OptionText`, `OptionBroadcastTextID`, `OptionType`, `OptionNpcFlag`, `ActionMenuID`, `ActionPoiID`, `BoxCoded`, `BoxMoney`, `BoxText`, `BoxBroadcastTextID`, `VerifiedBuild`) VALUES +(8234, 0, 0, 'I seem to have misplaced my ring.', 21813, 1, 1, 0, 0, 0, 0, '', 0, 55056), +(8234, 1, 0, 'I seem to have misplaced my ring.', 21813, 1, 1, 0, 0, 0, 0, '', 0, 55056), +(8234, 2, 0, 'I seem to have misplaced my ring.', 21813, 1, 1, 0, 0, 0, 0, '', 0, 55056), +(8234, 3, 0, 'I seem to have misplaced my ring.', 21813, 1, 1, 0, 0, 0, 0, '', 0, 55056); From 76b6da1b3ff18b84097c4487a2e146fa5b04bab2 Mon Sep 17 00:00:00 2001 From: Gultask <100873791+Gultask@users.noreply.github.com> Date: Fri, 5 Jul 2024 21:16:41 -0300 Subject: [PATCH 47/68] fix(Scripts/BlackTemple): Move Teron Gorefiend to scheduler and add Berserk (#19288) Update boss_teron_gorefiend.cpp --- .../BlackTemple/boss_teron_gorefiend.cpp | 133 +++++++++--------- 1 file changed, 68 insertions(+), 65 deletions(-) diff --git a/src/server/scripts/Outland/BlackTemple/boss_teron_gorefiend.cpp b/src/server/scripts/Outland/BlackTemple/boss_teron_gorefiend.cpp index 00034a60f..8c0e5d9cb 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_teron_gorefiend.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_teron_gorefiend.cpp @@ -46,6 +46,7 @@ enum Spells SPELL_POSSESS_SPIRIT_IMMUNE = 40282, SPELL_SPIRITUAL_VENGEANCE = 40268, SPELL_BRIEF_STUN = 41421, + SPELL_BERSERK = 45078, SPELL_SPIRIT_LANCE = 40157, SPELL_SPIRIT_CHAINS = 40175, @@ -54,13 +55,7 @@ enum Spells enum Misc { - SET_DATA_INTRO = 1, - - EVENT_SPELL_INCINERATE = 1, - EVENT_SPELL_DOOM_BLOSSOM = 2, - EVENT_SPELL_CRUSHING_SHADOWS = 3, - EVENT_SPELL_SHADOW_OF_DEATH = 4, - EVENT_TALK_KILL = 10 + SET_DATA_INTRO = 1 }; struct ShadowOfDeathSelector @@ -73,9 +68,11 @@ struct ShadowOfDeathSelector struct boss_teron_gorefiend : public BossAI { - boss_teron_gorefiend(Creature* creature) : BossAI(creature, DATA_TERON_GOREFIEND), intro(false) { } - - bool intro; + boss_teron_gorefiend(Creature* creature) : BossAI(creature, DATA_TERON_GOREFIEND) + { + _recentlySpoken = false; + _intro = false; + } void Reset() override { @@ -83,36 +80,72 @@ struct boss_teron_gorefiend : public BossAI me->CastSpell(me, SPELL_SHADOW_OF_DEATH_REMOVE, true); } + void JustEngagedWith(Unit* who) override + { + ScheduleTimedEvent(20s, 30s, [&] + { + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0)) + { + if (roll_chance_i(50)) + Talk(SAY_INCINERATE); + me->CastSpell(target, SPELL_INCINERATE, false); + } + }, 20s, 50s); + + ScheduleTimedEvent(5s, 10s, [&] + { + if (roll_chance_i(50)) + Talk(SAY_BLOSSOM); + me->CastSpell(me, SPELL_SUMMON_DOOM_BLOSSOM, false); + }, 35s); + + ScheduleTimedEvent(17s, 22s, [&] + { + if (roll_chance_i(20)) + Talk(SAY_CRUSHING); + me->CastCustomSpell(SPELL_CRUSHING_SHADOWS, SPELLVALUE_MAX_TARGETS, 5, me, false); + }, 10s, 26s); + + ScheduleTimedEvent(10s, [&] + { + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, ShadowOfDeathSelector())) + me->CastSpell(target, SPELL_SHADOW_OF_DEATH, false); + }, 30s, 50s); + + ScheduleTimedEvent(10min, [&] + { + DoCastSelf(SPELL_BERSERK); + }, 5min); + + BossAI::JustEngagedWith(who); + } + + void KilledUnit(Unit* victim) override + { + if (!_recentlySpoken && victim->IsPlayer()) + { + Talk(SAY_SLAY); + _recentlySpoken = true; + + ScheduleUniqueTimedEvent(6s, [&] + { + _recentlySpoken = false; + }, 1); + } + } + void SetData(uint32 type, uint32 id) override { if (type || !me->IsAlive()) return; - if (id == SET_DATA_INTRO && !intro) + if (id == SET_DATA_INTRO && !_intro) { - intro = true; + _intro = true; Talk(SAY_INTRO); } } - void JustEngagedWith(Unit* who) override - { - BossAI::JustEngagedWith(who); - events.ScheduleEvent(EVENT_SPELL_INCINERATE, 24000); - events.ScheduleEvent(EVENT_SPELL_DOOM_BLOSSOM, 10000); - events.ScheduleEvent(EVENT_SPELL_CRUSHING_SHADOWS, 17000); - events.ScheduleEvent(EVENT_SPELL_SHADOW_OF_DEATH, 20000); - } - - void KilledUnit(Unit* /*victim*/) override - { - if (events.GetNextEventTime(EVENT_TALK_KILL) == 0) - { - Talk(SAY_SLAY); - events.ScheduleEvent(EVENT_TALK_KILL, 6000); - } - } - void JustSummoned(Creature* summon) override { summons.Summon(summon); @@ -130,43 +163,13 @@ struct boss_teron_gorefiend : public BossAI if (!UpdateVictim()) return; - events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (events.ExecuteEvent()) - { - case EVENT_SPELL_INCINERATE: - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0)) - { - if (roll_chance_i(50)) - Talk(SAY_INCINERATE); - me->CastSpell(target, SPELL_INCINERATE, false); - } - events.ScheduleEvent(EVENT_SPELL_INCINERATE, 25000); - break; - case EVENT_SPELL_DOOM_BLOSSOM: - if (roll_chance_i(50)) - Talk(SAY_BLOSSOM); - - me->CastSpell(me, SPELL_SUMMON_DOOM_BLOSSOM, false); - events.ScheduleEvent(EVENT_SPELL_DOOM_BLOSSOM, 40000); - break; - case EVENT_SPELL_CRUSHING_SHADOWS: - if (roll_chance_i(20)) - Talk(SAY_CRUSHING); - me->CastCustomSpell(SPELL_CRUSHING_SHADOWS, SPELLVALUE_MAX_TARGETS, 5, me, false); - events.ScheduleEvent(EVENT_SPELL_CRUSHING_SHADOWS, 15000); - break; - case EVENT_SPELL_SHADOW_OF_DEATH: - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, ShadowOfDeathSelector())) - me->CastSpell(target, SPELL_SHADOW_OF_DEATH, false); - events.ScheduleEvent(EVENT_SPELL_SHADOW_OF_DEATH, 30000); - break; - } - + scheduler.Update(diff); DoMeleeAttackIfReady(); } + + private: + bool _recentlySpoken; + bool _intro; }; class spell_teron_gorefiend_shadow_of_death : public AuraScript From 9011e034ff5660f9efeb4f82b5f682dd0b6773e7 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 6 Jul 2024 00:16:59 +0000 Subject: [PATCH 48/68] chore(DB): import pending files Referenced commit(s): b357e8e2c4a181c24a82ac1bf710afe027bc04f9 --- .../rev_1720214274816211200.sql => db_world/2024_07_06_00.sql} | 1 + .../rev_1720223739574037500.sql => db_world/2024_07_06_01.sql} | 1 + .../rev_1720224478854376400.sql => db_world/2024_07_06_02.sql} | 1 + 3 files changed, 3 insertions(+) rename data/sql/updates/{pending_db_world/rev_1720214274816211200.sql => db_world/2024_07_06_00.sql} (94%) rename data/sql/updates/{pending_db_world/rev_1720223739574037500.sql => db_world/2024_07_06_01.sql} (98%) rename data/sql/updates/{pending_db_world/rev_1720224478854376400.sql => db_world/2024_07_06_02.sql} (58%) diff --git a/data/sql/updates/pending_db_world/rev_1720214274816211200.sql b/data/sql/updates/db_world/2024_07_06_00.sql similarity index 94% rename from data/sql/updates/pending_db_world/rev_1720214274816211200.sql rename to data/sql/updates/db_world/2024_07_06_00.sql index 8da4d6495..3b65178a3 100644 --- a/data/sql/updates/pending_db_world/rev_1720214274816211200.sql +++ b/data/sql/updates/db_world/2024_07_06_00.sql @@ -1,3 +1,4 @@ +-- DB update 2024_07_05_02 -> 2024_07_06_00 -- UPDATE `conditions` SET `ConditionTypeOrReference` = 8 WHERE `SourceGroup` = 8234 AND `SourceTypeOrReferenceId` = 15 AND `ConditionTypeOrReference` = 9; diff --git a/data/sql/updates/pending_db_world/rev_1720223739574037500.sql b/data/sql/updates/db_world/2024_07_06_01.sql similarity index 98% rename from data/sql/updates/pending_db_world/rev_1720223739574037500.sql rename to data/sql/updates/db_world/2024_07_06_01.sql index a253cc343..1fd815d2d 100644 --- a/data/sql/updates/pending_db_world/rev_1720223739574037500.sql +++ b/data/sql/updates/db_world/2024_07_06_01.sql @@ -1,3 +1,4 @@ +-- DB update 2024_07_06_00 -> 2024_07_06_01 -- DELETE FROM `creature_text` WHERE (`CreatureID` = 6240); INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES diff --git a/data/sql/updates/pending_db_world/rev_1720224478854376400.sql b/data/sql/updates/db_world/2024_07_06_02.sql similarity index 58% rename from data/sql/updates/pending_db_world/rev_1720224478854376400.sql rename to data/sql/updates/db_world/2024_07_06_02.sql index b5717ff34..1c568b645 100644 --- a/data/sql/updates/pending_db_world/rev_1720224478854376400.sql +++ b/data/sql/updates/db_world/2024_07_06_02.sql @@ -1,2 +1,3 @@ +-- DB update 2024_07_06_01 -> 2024_07_06_02 -- DELETE FROM `creature_loot_template` WHERE `Item` = 21314; From 0cdeef7980dbb529b5ef2aa49999c91913b7a781 Mon Sep 17 00:00:00 2001 From: Gultask <100873791+Gultask@users.noreply.github.com> Date: Fri, 5 Jul 2024 21:42:36 -0300 Subject: [PATCH 49/68] fix(DB/Creature): Skyguard Prisoner shoul spawn with ReactState Passive (#19300) Create rev_1720225685784761500.sql --- data/sql/updates/pending_db_world/rev_1720225685784761500.sql | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1720225685784761500.sql diff --git a/data/sql/updates/pending_db_world/rev_1720225685784761500.sql b/data/sql/updates/pending_db_world/rev_1720225685784761500.sql new file mode 100644 index 000000000..1c804a72e --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1720225685784761500.sql @@ -0,0 +1,4 @@ +-- +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 23383) AND (`source_type` = 0) AND (`id` IN (7)); +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 +(23383, 0, 7, 0, 11, 0, 100, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Skyguard Prisoner - On Respawn - Set Reactstate Passive'); From a71293ef480280092833c1a01842a3e16272996e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 6 Jul 2024 00:43:31 +0000 Subject: [PATCH 50/68] chore(DB): import pending files Referenced commit(s): 0cdeef7980dbb529b5ef2aa49999c91913b7a781 --- .../rev_1720225685784761500.sql => db_world/2024_07_06_03.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1720225685784761500.sql => db_world/2024_07_06_03.sql} (94%) diff --git a/data/sql/updates/pending_db_world/rev_1720225685784761500.sql b/data/sql/updates/db_world/2024_07_06_03.sql similarity index 94% rename from data/sql/updates/pending_db_world/rev_1720225685784761500.sql rename to data/sql/updates/db_world/2024_07_06_03.sql index 1c804a72e..02801d8b2 100644 --- a/data/sql/updates/pending_db_world/rev_1720225685784761500.sql +++ b/data/sql/updates/db_world/2024_07_06_03.sql @@ -1,3 +1,4 @@ +-- DB update 2024_07_06_02 -> 2024_07_06_03 -- DELETE FROM `smart_scripts` WHERE (`entryorguid` = 23383) AND (`source_type` = 0) AND (`id` IN (7)); 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 From 7d71affd62c25ee35f78e2c170608ce77ae96aa4 Mon Sep 17 00:00:00 2001 From: Gultask <100873791+Gultask@users.noreply.github.com> Date: Fri, 5 Jul 2024 22:32:53 -0300 Subject: [PATCH 51/68] fix(DB/Quests): Marks of Kil'Jaeden and Firewing Signets quests should be available at Neutral 0 (#19301) * Create rev_1720226619555284700.sql * no likey comments on end --- data/sql/updates/pending_db_world/rev_1720226619555284700.sql | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1720226619555284700.sql diff --git a/data/sql/updates/pending_db_world/rev_1720226619555284700.sql b/data/sql/updates/pending_db_world/rev_1720226619555284700.sql new file mode 100644 index 000000000..ee006a32b --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1720226619555284700.sql @@ -0,0 +1,2 @@ +-- RequiredMinRepValue was set to 1 +UPDATE `quest_template_addon` SET `RequiredMinRepValue` = 0 WHERE (`ID` IN (10412, 10414, 10415, 10325, 10326, 10327)); From b87407907271ad8fefaa81f513de729eba3fe8d2 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 6 Jul 2024 01:33:49 +0000 Subject: [PATCH 52/68] chore(DB): import pending files Referenced commit(s): 7d71affd62c25ee35f78e2c170608ce77ae96aa4 --- .../rev_1720226619555284700.sql => db_world/2024_07_06_04.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1720226619555284700.sql => db_world/2024_07_06_04.sql} (78%) diff --git a/data/sql/updates/pending_db_world/rev_1720226619555284700.sql b/data/sql/updates/db_world/2024_07_06_04.sql similarity index 78% rename from data/sql/updates/pending_db_world/rev_1720226619555284700.sql rename to data/sql/updates/db_world/2024_07_06_04.sql index ee006a32b..c6fe8b15d 100644 --- a/data/sql/updates/pending_db_world/rev_1720226619555284700.sql +++ b/data/sql/updates/db_world/2024_07_06_04.sql @@ -1,2 +1,3 @@ +-- DB update 2024_07_06_03 -> 2024_07_06_04 -- RequiredMinRepValue was set to 1 UPDATE `quest_template_addon` SET `RequiredMinRepValue` = 0 WHERE (`ID` IN (10412, 10414, 10415, 10325, 10326, 10327)); From 9e6eca979bc9fb7f5489ef541fe0eb9fa964483f Mon Sep 17 00:00:00 2001 From: Kitzunu <24550914+Kitzunu@users.noreply.github.com> Date: Sat, 6 Jul 2024 11:22:13 +0200 Subject: [PATCH 53/68] fix(Scripts/ShadeOfAran): Make immune to Mind-numbing and Cure of Tongue (#19309) * closes https://github.com/chromiecraft/chromiecraft/issues/6900 --- .../EasternKingdoms/Karazhan/boss_shade_of_aran.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/server/scripts/EasternKingdoms/Karazhan/boss_shade_of_aran.cpp b/src/server/scripts/EasternKingdoms/Karazhan/boss_shade_of_aran.cpp index c63797afa..e586d9ecf 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/boss_shade_of_aran.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/boss_shade_of_aran.cpp @@ -73,7 +73,11 @@ enum Spells SPELL_SHADOW_PYRO = 29978, - SPELL_ATIESH_VISUAL = 31796 + SPELL_ATIESH_VISUAL = 31796, + + SPELL_CURSE_OF_TONGUE_RANK1 = 1714, + SPELL_CURSE_OF_TONGUE_RANK2 = 11719, + SPELL_MIND_NUMBING_POISON = 5760 }; enum Creatures @@ -100,6 +104,8 @@ enum Misc Position const roomCenter = {-11158.f, -1920.f}; +std::vector immuneSpells = { SPELL_CURSE_OF_TONGUE_RANK1, SPELL_CURSE_OF_TONGUE_RANK2, SPELL_MIND_NUMBING_POISON }; + struct boss_shade_of_aran : public BossAI { boss_shade_of_aran(Creature* creature) : BossAI(creature, DATA_ARAN), _atieshReaction(false) { } @@ -118,6 +124,9 @@ struct boss_shade_of_aran : public BossAI _drinking = false; _hasDrunk = false; + for (int i = 0; i < immuneSpells.size(); i++) + me->ApplySpellImmune(0, IMMUNITY_ID, immuneSpells[i], true); + if (GameObject* libraryDoor = instance->instance->GetGameObject(instance->GetGuidData(DATA_GO_LIBRARY_DOOR))) { libraryDoor->SetGoState(GO_STATE_ACTIVE); From 78725aa1389393da06b8a5d7c163025b4eb825f7 Mon Sep 17 00:00:00 2001 From: Gultask <100873791+Gultask@users.noreply.github.com> Date: Sat, 6 Jul 2024 06:23:06 -0300 Subject: [PATCH 54/68] fix(DB/Creature): Verog the Dervish ReactState (#19308) Create rev_1720233129521675900.sql --- data/sql/updates/pending_db_world/rev_1720233129521675900.sql | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1720233129521675900.sql diff --git a/data/sql/updates/pending_db_world/rev_1720233129521675900.sql b/data/sql/updates/pending_db_world/rev_1720233129521675900.sql new file mode 100644 index 000000000..62f2d8044 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1720233129521675900.sql @@ -0,0 +1,4 @@ +-- +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 3395) AND (`source_type` = 0) AND (`id` IN (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 +(3395, 0, 0, 0, 1, 0, 100, 1, 4000, 4000, 0, 0, 0, 0, 53, 0, 3395, 0, 0, 600000, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Verog the Dervish - Out of Combat - Start Waypoint Movement (No Repeat)'); From 0ab361d48de5e771f1b90ee6ab413ac1b99b9a1f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 6 Jul 2024 09:23:09 +0000 Subject: [PATCH 55/68] chore(DB): import pending files Referenced commit(s): 9e6eca979bc9fb7f5489ef541fe0eb9fa964483f --- .../rev_1720233129521675900.sql => db_world/2024_07_06_05.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1720233129521675900.sql => db_world/2024_07_06_05.sql} (94%) diff --git a/data/sql/updates/pending_db_world/rev_1720233129521675900.sql b/data/sql/updates/db_world/2024_07_06_05.sql similarity index 94% rename from data/sql/updates/pending_db_world/rev_1720233129521675900.sql rename to data/sql/updates/db_world/2024_07_06_05.sql index 62f2d8044..9f83fb107 100644 --- a/data/sql/updates/pending_db_world/rev_1720233129521675900.sql +++ b/data/sql/updates/db_world/2024_07_06_05.sql @@ -1,3 +1,4 @@ +-- DB update 2024_07_06_04 -> 2024_07_06_05 -- DELETE FROM `smart_scripts` WHERE (`entryorguid` = 3395) AND (`source_type` = 0) AND (`id` IN (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 From 67e63f3ec8ce2f78e6dd23314a80d74df64e6ca2 Mon Sep 17 00:00:00 2001 From: Gultask <100873791+Gultask@users.noreply.github.com> Date: Sat, 6 Jul 2024 06:23:34 -0300 Subject: [PATCH 56/68] fix(DB/Creature): Prevent Hellfire Peninsula's Pit Commander from cancelling Timed Event (#19307) Create rev_1720232245698455400.sql --- .../pending_db_world/rev_1720232245698455400.sql | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1720232245698455400.sql diff --git a/data/sql/updates/pending_db_world/rev_1720232245698455400.sql b/data/sql/updates/pending_db_world/rev_1720232245698455400.sql new file mode 100644 index 000000000..667f488a7 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1720232245698455400.sql @@ -0,0 +1,10 @@ +-- +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 18945) AND (`source_type` = 0) AND (`id` IN (4, 5, 6)); +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 +(18945, 0, 4, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 80, 1894500, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Pit Commander - On Respawn - Run Script'), +(18945, 0, 5, 0, 21, 0, 100, 0, 0, 0, 0, 0, 0, 0, 22, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Pit Commander - On Reached Home - Set Event Phase'); + +DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` = 1894500); +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 +(1894500, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 11, 51347, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Pit Commander - Actionlist - Cast \'Teleport Visual Only\''), +(1894500, 9, 1, 0, 0, 0, 100, 0, 4000, 4000, 0, 0, 0, 0, 53, 0, 18945, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Pit Commander - Actionlist - Start Waypoint Path 18945'); From 65870ec1a114c88da37d8695bdf9873e942e6f6a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 6 Jul 2024 09:23:58 +0000 Subject: [PATCH 57/68] chore(DB): import pending files Referenced commit(s): 78725aa1389393da06b8a5d7c163025b4eb825f7 --- .../rev_1720232245698455400.sql => db_world/2024_07_06_06.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1720232245698455400.sql => db_world/2024_07_06_06.sql} (97%) diff --git a/data/sql/updates/pending_db_world/rev_1720232245698455400.sql b/data/sql/updates/db_world/2024_07_06_06.sql similarity index 97% rename from data/sql/updates/pending_db_world/rev_1720232245698455400.sql rename to data/sql/updates/db_world/2024_07_06_06.sql index 667f488a7..3fd7d1a0c 100644 --- a/data/sql/updates/pending_db_world/rev_1720232245698455400.sql +++ b/data/sql/updates/db_world/2024_07_06_06.sql @@ -1,3 +1,4 @@ +-- DB update 2024_07_06_05 -> 2024_07_06_06 -- DELETE FROM `smart_scripts` WHERE (`entryorguid` = 18945) AND (`source_type` = 0) AND (`id` IN (4, 5, 6)); 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 From f42ed2efa55133f53985fa87b306b90e92e90e02 Mon Sep 17 00:00:00 2001 From: Kitzunu <24550914+Kitzunu@users.noreply.github.com> Date: Sat, 6 Jul 2024 13:46:10 +0200 Subject: [PATCH 58/68] feat(Core/SAI): SetData now has invoker (#19296) * cherry-pick commit (https://github.com/TrinityCore/TrinityCore/commit/cfc77fd84355d28737f3f85f2ba318be5caacdea) * cherry-pick commit (https://github.com/TrinityCore/TrinityCore/commit/beb333738db0d493bf95994eb5557e174e5dd3a6) * Move IsSmart function from headerfile Co-authored-by: Treeston <14020072+Treeston@users.noreply.github.com> Co-authored-by: Shauren --- src/server/game/AI/CoreAI/UnitAI.h | 11 ++++ .../game/AI/ScriptedAI/ScriptedCreature.h | 2 - src/server/game/AI/SmartScripts/SmartAI.cpp | 8 +-- src/server/game/AI/SmartScripts/SmartAI.h | 6 +- .../game/AI/SmartScripts/SmartScript.cpp | 65 +++++++++++++++++-- src/server/game/AI/SmartScripts/SmartScript.h | 33 ++-------- .../game/AI/SmartScripts/SmartScriptMgr.cpp | 1 + 7 files changed, 82 insertions(+), 44 deletions(-) diff --git a/src/server/game/AI/CoreAI/UnitAI.h b/src/server/game/AI/CoreAI/UnitAI.h index 865415f59..2f9bba321 100644 --- a/src/server/game/AI/CoreAI/UnitAI.h +++ b/src/server/game/AI/CoreAI/UnitAI.h @@ -23,6 +23,17 @@ #include "Unit.h" #include +#define CAST_AI(a, b) (dynamic_cast(b)) +#define ENSURE_AI(a,b) (EnsureAI(b)) + +template +T* EnsureAI(U* ai) +{ + T* cast_ai = dynamic_cast(ai); + ASSERT(cast_ai); + return cast_ai; +} + class Player; class Quest; class Unit; diff --git a/src/server/game/AI/ScriptedAI/ScriptedCreature.h b/src/server/game/AI/ScriptedAI/ScriptedCreature.h index be04450d0..f6ed31486 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedCreature.h +++ b/src/server/game/AI/ScriptedAI/ScriptedCreature.h @@ -25,8 +25,6 @@ #include "InstanceScript.h" #include "TaskScheduler.h" -#define CAST_AI(a, b) (dynamic_cast(b)) - typedef std::list ObjectList; class InstanceScript; diff --git a/src/server/game/AI/SmartScripts/SmartAI.cpp b/src/server/game/AI/SmartScripts/SmartAI.cpp index d126a9cfc..d3ec5eb51 100644 --- a/src/server/game/AI/SmartScripts/SmartAI.cpp +++ b/src/server/game/AI/SmartScripts/SmartAI.cpp @@ -962,9 +962,9 @@ uint32 SmartAI::GetData(uint32 /*id*/) const return 0; } -void SmartAI::SetData(uint32 id, uint32 value) +void SmartAI::SetData(uint32 id, uint32 value, Unit* invoker) { - GetScript()->ProcessEventsFor(SMART_EVENT_DATA_SET, nullptr, id, value); + GetScript()->ProcessEventsFor(SMART_EVENT_DATA_SET, invoker, id, value); } void SmartAI::SetGUID(ObjectGuid /*guid*/, int32 /*id*/) @@ -1232,9 +1232,9 @@ void SmartGameObjectAI::Destroyed(Player* player, uint32 eventId) GetScript()->ProcessEventsFor(SMART_EVENT_DEATH, player, eventId, 0, false, nullptr, me); } -void SmartGameObjectAI::SetData(uint32 id, uint32 value) +void SmartGameObjectAI::SetData(uint32 id, uint32 value, Unit* invoker) { - GetScript()->ProcessEventsFor(SMART_EVENT_DATA_SET, nullptr, id, value); + GetScript()->ProcessEventsFor(SMART_EVENT_DATA_SET, invoker, id, value); } void SmartGameObjectAI::SetScript9(SmartScriptHolder& e, uint32 entry, Unit* invoker) diff --git a/src/server/game/AI/SmartScripts/SmartAI.h b/src/server/game/AI/SmartScripts/SmartAI.h index acb52d904..0311590fe 100644 --- a/src/server/game/AI/SmartScripts/SmartAI.h +++ b/src/server/game/AI/SmartScripts/SmartAI.h @@ -159,7 +159,8 @@ public: uint32 GetData(uint32 id = 0) const override; // Used in scripts to share variables - void SetData(uint32 id, uint32 value) override; + void SetData(uint32 id, uint32 value) override { SetData(id, value, nullptr); } + void SetData(uint32 id, uint32 value, Unit* invoker); // Used in scripts to share variables void SetGUID(ObjectGuid guid, int32 id = 0) override; @@ -272,7 +273,8 @@ public: bool QuestAccept(Player* player, Quest const* quest) override; bool QuestReward(Player* player, Quest const* quest, uint32 opt) override; void Destroyed(Player* player, uint32 eventId) override; - void SetData(uint32 id, uint32 value) override; + void SetData(uint32 id, uint32 value) override { SetData(id, value, nullptr); } + void SetData(uint32 id, uint32 value, Unit* invoker); void SetScript9(SmartScriptHolder& e, uint32 entry, Unit* invoker); void OnGameEvent(bool start, uint16 eventId) override; void OnStateChanged(uint32 state, Unit* unit) override; diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index 3102b37bf..7930317bf 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -63,7 +63,46 @@ SmartScript::SmartScript() SmartScript::~SmartScript() { +} +bool SmartScript::IsSmart(Creature* c, bool silent) const +{ + if (!c) + return false; + + bool smart = true; + if (!dynamic_cast(c->AI())) + smart = false; + + if (!smart && !silent) + LOG_ERROR("sql.sql", "SmartScript: Action target Creature(entry: {}) is not using SmartAI, action skipped to prevent crash.", c ? c->GetEntry() : (me ? me->GetEntry() : 0)); + + return smart; +} + +bool SmartScript::IsSmart(GameObject* g, bool silent) const +{ + if (!g) + return false; + + bool smart = true; + if (!dynamic_cast(g->AI())) + smart = false; + + if (!smart && !silent) + LOG_ERROR("sql.sql", "SmartScript: Action target GameObject(entry: {}) is not using SmartGameObjectAI, action skipped to prevent crash.", g ? g->GetEntry() : (go ? go->GetEntry() : 0)); + + return smart; +} + +bool SmartScript::IsSmart(bool silent) const +{ + if (me) + return IsSmart(me, silent); + if (go) + return IsSmart(go, silent); + + return false; } void SmartScript::OnReset() @@ -1355,10 +1394,22 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u { for (WorldObject* target : targets) { - if (IsCreature(target)) - target->ToCreature()->AI()->SetData(e.action.setData.field, e.action.setData.data); - else if (IsGameObject(target)) - target->ToGameObject()->AI()->SetData(e.action.setData.field, e.action.setData.data); + if (Creature* cTarget = target->ToCreature()) + { + CreatureAI* ai = cTarget->AI(); + if (IsSmart(cTarget)) + ENSURE_AI(SmartAI, ai)->SetData(e.action.setData.field, e.action.setData.data, me); + else + ai->SetData(e.action.setData.field, e.action.setData.data); + } + else if (GameObject* oTarget = target->ToGameObject()) + { + GameObjectAI* ai = oTarget->AI(); + if (IsSmart(oTarget)) + ENSURE_AI(SmartGameObjectAI, ai)->SetData(e.action.setData.field, e.action.setData.data, me); + else + ai->SetData(e.action.setData.field, e.action.setData.data); + } } break; } @@ -1974,7 +2025,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u } else if (GameObject* go = target->ToGameObject()) { - if (IsSmartGO(go)) + if (IsSmart(go)) CAST_AI(SmartGameObjectAI, go->AI())->SetScript9(e, e.action.timedActionList.id, GetLastInvoker()); } } @@ -2061,7 +2112,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u } else if (GameObject* go = target->ToGameObject()) { - if (IsSmartGO(go)) + if (IsSmart(go)) CAST_AI(SmartGameObjectAI, go->AI())->SetScript9(e, id, GetLastInvoker()); } } @@ -2085,7 +2136,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u } else if (GameObject* go = target->ToGameObject()) { - if (IsSmartGO(go)) + if (IsSmart(go)) CAST_AI(SmartGameObjectAI, go->AI())->SetScript9(e, id, GetLastInvoker()); } } diff --git a/src/server/game/AI/SmartScripts/SmartScript.h b/src/server/game/AI/SmartScripts/SmartScript.h index b9ab57327..82ac3700d 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.h +++ b/src/server/game/AI/SmartScripts/SmartScript.h @@ -76,6 +76,10 @@ public: void DoFindFriendlyMissingBuff(std::vector& creatures, float range, uint32 spellid) const; Unit* DoFindClosestFriendlyInRange(float range, bool playerOnly) const; + bool IsSmart(Creature* c, bool silent = false) const; + bool IsSmart(GameObject* g, bool silent = false) const; + bool IsSmart(bool silent = false) const; + void StoreTargetList(ObjectVector const& targets, uint32 id) { // insert or replace @@ -83,35 +87,6 @@ public: _storedTargets.emplace(id, ObjectGuidVector(targets)); } - bool IsSmart(Creature* c = nullptr) - { - bool smart = true; - if (c && c->GetAIName() != "SmartAI") - smart = false; - - if (!me || me->GetAIName() != "SmartAI") - smart = false; - - if (!smart) - LOG_ERROR("sql.sql", "SmartScript: Action target Creature(entry: {}) is not using SmartAI, action skipped to prevent crash.", c ? c->GetEntry() : (me ? me->GetEntry() : 0)); - - return smart; - } - - bool IsSmartGO(GameObject* g = nullptr) - { - bool smart = true; - if (g && g->GetAIName() != "SmartGameObjectAI") - smart = false; - - if (!go || go->GetAIName() != "SmartGameObjectAI") - smart = false; - if (!smart) - LOG_ERROR("sql.sql", "SmartScript: Action target GameObject(entry: {}) is not using SmartGameObjectAI, action skipped to prevent crash.", g ? g->GetEntry() : (go ? go->GetEntry() : 0)); - - return smart; - } - ObjectVector const* GetStoredTargetVector(uint32 id, WorldObject const& ref) const { auto itr = _storedTargets.find(id); diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp index 1f2c3ae9b..a3d759a6d 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp @@ -346,6 +346,7 @@ void SmartAIMgr::LoadSmartAIFromDB() case SMART_EVENT_TRANSPORT_ADDCREATURE: case SMART_EVENT_NEAR_PLAYERS: case SMART_EVENT_SUMMONED_UNIT_EVADE: + case SMART_EVENT_DATA_SET: return true; default: return false; From f8f4788355e3d8a0aa5311d6b179dfcc181de52a Mon Sep 17 00:00:00 2001 From: avarishd <46330494+avarishd@users.noreply.github.com> Date: Sat, 6 Jul 2024 14:47:07 +0300 Subject: [PATCH 59/68] fix(DB/SAI): Zeppit's RP for collecting blood (#19318) --- .../rev_1720259679409109500.sql | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1720259679409109500.sql diff --git a/data/sql/updates/pending_db_world/rev_1720259679409109500.sql b/data/sql/updates/pending_db_world/rev_1720259679409109500.sql new file mode 100644 index 000000000..404272985 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1720259679409109500.sql @@ -0,0 +1,17 @@ +-- +DELETE FROM `creature_text` WHERE (`CreatureID` = 22484); +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(22484, 0, 0, '%s gathers the warp chaser\'s blood.', 16, 0, 100, 0, 0, 0, 20371, 0, 'Zeppit - Gather blood'); + +UPDATE `smart_scripts` SET`target_param2` = 25 WHERE `entryorguid`=18884 AND `source_type`=0 AND `id`=3; + +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 22484); +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 +(22484, 0, 0, 0, 38, 0, 100, 0, 1, 1, 3000, 3000, 0, 0, 69, 1, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Zeppit - On Data Set 1 1 - Move To Invoker'), +(22484, 0, 1, 0, 34, 0, 100, 0, 8, 1, 0, 0, 0, 0, 80, 2248400, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Zeppit - On Reached Point 1 - Run Script'); + +DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` = 2248400); +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 +(2248400, 9, 0, 0, 0, 0, 100, 0, 1500, 1500, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Zeppit - Actionlist - Say Line 0'), +(2248400, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 11, 39244, 0, 0, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 'Zeppit - Actionlist - Cast \'Gather Warp Chaser Blood\''), +(2248400, 9, 2, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 'Zeppit - Actionlist - Start Follow Owner Or Summoner'); From c41a5ff336b151f31da37dea8efdf52c796deef3 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 6 Jul 2024 11:47:59 +0000 Subject: [PATCH 60/68] chore(DB): import pending files Referenced commit(s): f8f4788355e3d8a0aa5311d6b179dfcc181de52a --- .../rev_1720259679409109500.sql => db_world/2024_07_06_07.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1720259679409109500.sql => db_world/2024_07_06_07.sql} (98%) diff --git a/data/sql/updates/pending_db_world/rev_1720259679409109500.sql b/data/sql/updates/db_world/2024_07_06_07.sql similarity index 98% rename from data/sql/updates/pending_db_world/rev_1720259679409109500.sql rename to data/sql/updates/db_world/2024_07_06_07.sql index 404272985..e3f324cda 100644 --- a/data/sql/updates/pending_db_world/rev_1720259679409109500.sql +++ b/data/sql/updates/db_world/2024_07_06_07.sql @@ -1,3 +1,4 @@ +-- DB update 2024_07_06_06 -> 2024_07_06_07 -- DELETE FROM `creature_text` WHERE (`CreatureID` = 22484); INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES From 3c50b1a135e06361f7c9d838f5e65de28849ea5b Mon Sep 17 00:00:00 2001 From: Kitzunu <24550914+Kitzunu@users.noreply.github.com> Date: Sat, 6 Jul 2024 15:05:34 +0200 Subject: [PATCH 61/68] fix(Core/Player): Vertical Message distance (#19302) * cherry-pick commit (https://github.com/TrinityCore/TrinityCore/commit/297541e9c9bf90d410922db397d2f94dff9592cc) * Get rid of unused param * Merge SendMessageToSetInRange_OwnTeam into SendMessageToSetInRange Co-authored-by: Badgersson <83663557+dekz120@users.noreply.github.com> --- .../game/Entities/GameObject/GameObject.cpp | 9 ---- .../game/Entities/GameObject/GameObject.h | 2 - src/server/game/Entities/Object/Object.cpp | 19 +++++--- src/server/game/Entities/Object/Object.h | 6 +-- src/server/game/Entities/Player/Player.cpp | 44 +++++++++++-------- src/server/game/Entities/Player/Player.h | 9 ++-- .../game/Grids/Notifiers/GridNotifiers.cpp | 30 ++++++++++--- .../game/Grids/Notifiers/GridNotifiers.h | 5 ++- src/server/game/Time/UpdateTime.cpp | 8 ++-- 9 files changed, 78 insertions(+), 54 deletions(-) diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 0db064434..44776dc46 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -2173,15 +2173,6 @@ bool GameObject::IsInRange(float x, float y, float z, float radius) const && dz < (info->maxZ * scale) + radius && dz > (info->minZ * scale) - radius; } -void GameObject::SendMessageToSetInRange(WorldPacket const* data, float dist, bool /*self*/, bool includeMargin, Player const* skipped_rcvr) const -{ - dist += GetObjectSize(); - if (includeMargin) - dist += VISIBILITY_COMPENSATION * 2.0f; // pussywizard: to ensure everyone receives all important packets - Acore::MessageDistDeliverer notifier(this, data, dist, false, skipped_rcvr); - Cell::VisitWorldObjects(this, notifier, dist); -} - void GameObject::EventInform(uint32 eventId) { if (!eventId) diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h index ed47aa084..678052b14 100644 --- a/src/server/game/Entities/GameObject/GameObject.h +++ b/src/server/game/Entities/GameObject/GameObject.h @@ -289,8 +289,6 @@ public: void SendCustomAnim(uint32 anim); [[nodiscard]] bool IsInRange(float x, float y, float z, float radius) const; - void SendMessageToSetInRange(WorldPacket const* data, float dist, bool /*self*/, bool includeMargin = false, Player const* skipped_rcvr = nullptr) const override; // pussywizard! - void ModifyHealth(int32 change, Unit* attackerOrHealer = nullptr, uint32 spellId = 0); void SetDestructibleBuildingModifyState(bool allow) { m_allowModifyDestructibleBuilding = allow; } // sets GameObject type 33 destruction flags and optionally default health for that state diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index 5f505655d..e6b60ffca 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -2077,15 +2077,24 @@ void Unit::BuildHeartBeatMsg(WorldPacket* data) const BuildMovementPacket(data); } -void WorldObject::SendMessageToSetInRange(WorldPacket const* data, float dist, bool /*self*/, bool includeMargin, Player const* skipped_rcvr) const +void WorldObject::SendMessageToSet(WorldPacket const* data, bool self) const { - dist += GetObjectSize(); - if (includeMargin) - dist += VISIBILITY_COMPENSATION; // pussywizard: to ensure everyone receives all important packets - Acore::MessageDistDeliverer notifier(this, data, dist, false, skipped_rcvr); + if (IsInWorld()) + SendMessageToSetInRange(data, GetVisibilityRange(), self); +} + +void WorldObject::SendMessageToSetInRange(WorldPacket const* data, float dist, bool /*self*/) const +{ + Acore::MessageDistDeliverer notifier(this, data, dist); Cell::VisitWorldObjects(this, notifier, dist); } +void WorldObject::SendMessageToSet(WorldPacket const* data, Player const* skipped_rcvr) const +{ + Acore::MessageDistDeliverer notifier(this, data, GetVisibilityRange(), false, skipped_rcvr); + Cell::VisitWorldObjects(this, notifier, GetVisibilityRange()); +} + void WorldObject::SendObjectDeSpawnAnim(ObjectGuid guid) { WorldPacket data(SMSG_GAMEOBJECT_DESPAWN_ANIM, 8); diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index f9a9ac69c..6dd7f0d7f 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -479,9 +479,9 @@ public: virtual void CleanupsBeforeDelete(bool finalCleanup = true); // used in destructor or explicitly before mass creature delete to remove cross-references to already deleted units - virtual void SendMessageToSet(WorldPacket const* data, bool self) const { if (IsInWorld()) SendMessageToSetInRange(data, GetVisibilityRange(), self, true); } // pussywizard! - virtual void SendMessageToSetInRange(WorldPacket const* data, float dist, bool /*self*/, bool includeMargin = false, Player const* skipped_rcvr = nullptr) const; // pussywizard! - virtual void SendMessageToSet(WorldPacket const* data, Player const* skipped_rcvr) const { if (IsInWorld()) SendMessageToSetInRange(data, GetVisibilityRange(), false, true, skipped_rcvr); } // pussywizard! + virtual void SendMessageToSet(WorldPacket const* data, bool self) const; + virtual void SendMessageToSetInRange(WorldPacket const* data, float dist, bool self) const; + virtual void SendMessageToSet(WorldPacket const* data, Player const* skipped_rcvr) const; virtual uint8 getLevelForTarget(WorldObject const* /*target*/) const { return 1; } diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 89ce0d76d..aeec7a934 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -5610,25 +5610,40 @@ void Player::SaveRecallPosition() m_recallO = GetOrientation(); } -void Player::SendMessageToSetInRange(WorldPacket const* data, float dist, bool self, bool includeMargin, Player const* skipped_rcvr) const +void Player::SendMessageToSet(WorldPacket const* data, bool self) const +{ + SendMessageToSetInRange(data, GetVisibilityRange(), self); +} + +void Player::SendMessageToSetInRange(WorldPacket const* data, float dist, bool self) const { if (self) - GetSession()->SendPacket(data); + SendDirectMessage(data); + + Acore::MessageDistDeliverer notifier(this, data, dist); + Cell::VisitWorldObjects(this, notifier, dist); +} + +void Player::SendMessageToSetInRange(WorldPacket const* data, float dist, bool self, bool includeMargin, bool ownTeamOnly, bool required3dDist) const +{ + if (self) + SendDirectMessage(data); dist += GetObjectSize(); if (includeMargin) dist += VISIBILITY_COMPENSATION; // pussywizard: to ensure everyone receives all important packets - Acore::MessageDistDeliverer notifier(this, data, dist, false, skipped_rcvr); + + Acore::MessageDistDeliverer notifier(this, data, dist, ownTeamOnly, nullptr, required3dDist); Cell::VisitWorldObjects(this, notifier, dist); } -void Player::SendMessageToSetInRange_OwnTeam(WorldPacket const* data, float dist, bool self) const +void Player::SendMessageToSet(WorldPacket const* data, Player const* skipped_rcvr) const { - if (self) - GetSession()->SendPacket(data); + if (skipped_rcvr != this) + SendDirectMessage(data); - Acore::MessageDistDeliverer notifier(this, data, dist, true); - Cell::VisitWorldObjects(this, notifier, dist); + Acore::MessageDistDeliverer notifier(this, data, GetVisibilityRange(), false, skipped_rcvr); + Cell::VisitWorldObjects(this, notifier, GetVisibilityRange()); } void Player::SendDirectMessage(WorldPacket const* data) const @@ -9289,7 +9304,7 @@ void Player::Say(std::string_view text, Language language, WorldObject const* /* WorldPacket data; ChatHandler::BuildChatPacket(data, CHAT_MSG_SAY, language, this, this, _text); - SendMessageToSetInRange(&data, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY), true); + SendMessageToSetInRange(&data, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY), true, false, false, true); } void Player::Say(uint32 textId, WorldObject const* target /*= nullptr*/) @@ -9310,7 +9325,7 @@ void Player::Yell(std::string_view text, Language language, WorldObject const* / WorldPacket data; ChatHandler::BuildChatPacket(data, CHAT_MSG_YELL, language, this, this, _text); - SendMessageToSetInRange(&data, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_YELL), true); + SendMessageToSetInRange(&data, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_YELL), true, false, false, true); } void Player::Yell(uint32 textId, WorldObject const* target /*= nullptr*/) @@ -9332,14 +9347,7 @@ void Player::TextEmote(std::string_view text, WorldObject const* /*= nullptr*/, WorldPacket data; ChatHandler::BuildChatPacket(data, CHAT_MSG_EMOTE, LANG_UNIVERSAL, this, this, _text); - if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_EMOTE)) - { - SendMessageToSetInRange(&data, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE), true); - } - else - { - SendMessageToSetInRange_OwnTeam(&data, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE), true); - } + SendMessageToSetInRange(&data, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE), true, false, !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_EMOTE), true); } void Player::TextEmote(uint32 textId, WorldObject const* target /*= nullptr*/, bool /*isBossEmote = false*/) diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 59d394947..5e8eda233 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -2000,11 +2000,10 @@ public: void ProcessTerrainStatusUpdate() override; - void SendMessageToSet(WorldPacket const* data, bool self) const override { SendMessageToSetInRange(data, GetVisibilityRange(), self, true); } // pussywizard! - void SendMessageToSetInRange(WorldPacket const* data, float dist, bool self, bool includeMargin = false, Player const* skipped_rcvr = nullptr) const override; // pussywizard! - void SendMessageToSetInRange_OwnTeam(WorldPacket const* data, float dist, bool self) const; // pussywizard! param includeMargin not needed here - void SendMessageToSet(WorldPacket const* data, Player const* skipped_rcvr) const override { SendMessageToSetInRange(data, GetVisibilityRange(), skipped_rcvr != this, true, skipped_rcvr); } // pussywizard! - + void SendMessageToSet(WorldPacket const* data, bool self) const override; + void SendMessageToSetInRange(WorldPacket const* data, float dist, bool self) const override; + void SendMessageToSetInRange(WorldPacket const* data, float dist, bool self, bool includeMargin, bool ownTeamOnly, bool required3dDist = false) const; + void SendMessageToSet(WorldPacket const* data, Player const* skipped_rcvr) const override; void SendTeleportAckPacket(); [[nodiscard]] Corpse* GetCorpse() const; diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.cpp b/src/server/game/Grids/Notifiers/GridNotifiers.cpp index db2ad0a67..42661e934 100644 --- a/src/server/game/Grids/Notifiers/GridNotifiers.cpp +++ b/src/server/game/Grids/Notifiers/GridNotifiers.cpp @@ -217,8 +217,14 @@ void MessageDistDeliverer::Visit(PlayerMapType& m) if (!target->InSamePhase(i_phaseMask)) continue; - if (target->GetExactDist2dSq(i_source) > i_distSq) - continue; + if (required3dDist) + { + if (target->GetExactDistSq(i_source) > i_distSq) + continue; + } + else + if (target->GetExactDist2dSq(i_source) > i_distSq) + continue; // Send packet to all who are sharing the player's vision if (target->HasSharedVision()) @@ -242,8 +248,14 @@ void MessageDistDeliverer::Visit(CreatureMapType& m) if (!target->HasSharedVision() || !target->InSamePhase(i_phaseMask)) continue; - if (target->GetExactDist2dSq(i_source) > i_distSq) - continue; + if (required3dDist) + { + if (target->GetExactDistSq(i_source) > i_distSq) + continue; + } + else + if (target->GetExactDist2dSq(i_source) > i_distSq) + continue; // Send packet to all who are sharing the creature's vision SharedVisionList::const_iterator i = target->GetSharedVisionList().begin(); @@ -265,8 +277,14 @@ void MessageDistDeliverer::Visit(DynamicObjectMapType& m) if (!target->IsViewpoint()) continue; - if (target->GetExactDist2dSq(i_source) > i_distSq) - continue; + if (required3dDist) + { + if (target->GetExactDistSq(i_source) > i_distSq) + continue; + } + else + if (target->GetExactDist2dSq(i_source) > i_distSq) + continue; // Send packet back to the caster if the caster has vision of dynamic object Player* caster = (Player*)target->GetCaster(); diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.h b/src/server/game/Grids/Notifiers/GridNotifiers.h index e06b9091f..97189e16c 100644 --- a/src/server/game/Grids/Notifiers/GridNotifiers.h +++ b/src/server/game/Grids/Notifiers/GridNotifiers.h @@ -102,10 +102,11 @@ namespace Acore float i_distSq; TeamId teamId; Player const* skipped_receiver; - MessageDistDeliverer(WorldObject const* src, WorldPacket const* msg, float dist, bool own_team_only = false, Player const* skipped = nullptr) + bool required3dDist; + MessageDistDeliverer(WorldObject const* src, WorldPacket const* msg, float dist, bool own_team_only = false, Player const* skipped = nullptr, bool req3dDist = false) : i_source(src), i_message(msg), i_phaseMask(src->GetPhaseMask()), i_distSq(dist * dist) , teamId((own_team_only && src->GetTypeId() == TYPEID_PLAYER) ? src->ToPlayer()->GetTeamId() : TEAM_NEUTRAL) - , skipped_receiver(skipped) + , skipped_receiver(skipped), required3dDist(req3dDist) { } void Visit(PlayerMapType& m); diff --git a/src/server/game/Time/UpdateTime.cpp b/src/server/game/Time/UpdateTime.cpp index 182323ab0..3c4886376 100644 --- a/src/server/game/Time/UpdateTime.cpp +++ b/src/server/game/Time/UpdateTime.cpp @@ -165,11 +165,11 @@ void WorldUpdateTime::RecordUpdateTime(Milliseconds gameTimeMs, uint32 diff, uin { if (GetMSTimeDiff(_lastRecordTime, gameTimeMs) > _recordUpdateTimeInverval) { - LOG_INFO("time.update", "Update time diff: {} with {} players online", GetLastUpdateTime(), sessionCount); + LOG_INFO("time.update", "Update time diff: {}ms with {} players online", GetLastUpdateTime(), sessionCount); LOG_INFO("time.update", "Last {} diffs summary:", GetDatasetSize()); - LOG_INFO("time.update", "|- Mean: {}", GetAverageUpdateTime()); - LOG_INFO("time.update", "|- Median: {}", GetPercentile(50)); - LOG_INFO("time.update", "|- Percentiles (95, 99, max): {}, {}, {}", GetPercentile(95), GetPercentile(99), GetPercentile(100)); + LOG_INFO("time.update", "|- Mean: {}ms", GetAverageUpdateTime()); + LOG_INFO("time.update", "|- Median: {}ms", GetPercentile(50)); + LOG_INFO("time.update", "|- Percentiles (95, 99, max): {}ms, {}ms, {}ms", GetPercentile(95), GetPercentile(99), GetPercentile(100)); _lastRecordTime = gameTimeMs; } } From 1632045ba88221daee04e84302192708889da44b Mon Sep 17 00:00:00 2001 From: Dan <83884799+elthehablo@users.noreply.github.com> Date: Sat, 6 Jul 2024 16:37:15 +0200 Subject: [PATCH 62/68] fix(DB/TheBlackTemple): make Promenade Sentinel kick immune (#19316) init --- data/sql/updates/pending_db_world/promenade-kick-immune.sql | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 data/sql/updates/pending_db_world/promenade-kick-immune.sql diff --git a/data/sql/updates/pending_db_world/promenade-kick-immune.sql b/data/sql/updates/pending_db_world/promenade-kick-immune.sql new file mode 100644 index 000000000..9429d7d0d --- /dev/null +++ b/data/sql/updates/pending_db_world/promenade-kick-immune.sql @@ -0,0 +1,2 @@ +-- +UPDATE `creature_template` SET `mechanic_immune_mask` = `mechanic_immune_mask`|33554432 WHERE `entry` = 23394; From 344261fa7bc7bd8c2379b0546a4a5a73a9391daa Mon Sep 17 00:00:00 2001 From: Dan <83884799+elthehablo@users.noreply.github.com> Date: Sat, 6 Jul 2024 16:37:29 +0200 Subject: [PATCH 63/68] fix(DB/TheBlackTemple): Ashtongue Feral Spirit detection range (#19315) init --- data/sql/updates/pending_db_world/detect.sql | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 data/sql/updates/pending_db_world/detect.sql diff --git a/data/sql/updates/pending_db_world/detect.sql b/data/sql/updates/pending_db_world/detect.sql new file mode 100644 index 000000000..a3cdc25d8 --- /dev/null +++ b/data/sql/updates/pending_db_world/detect.sql @@ -0,0 +1,2 @@ +-- +UPDATE `creature_template` SET `detection_range` = 55 WHERE `entry` = 22849; From 49656ea40333e6346970d467f9211fcd1eb66e22 Mon Sep 17 00:00:00 2001 From: Kitzunu <24550914+Kitzunu@users.noreply.github.com> Date: Sat, 6 Jul 2024 16:37:59 +0200 Subject: [PATCH 64/68] fix(DB/Quest): Spirits of the Feralfen (#19310) * fix(DB/Quest): Spirits of the Feralfen * closes https://github.com/chromiecraft/chromiecraft/issues/6241 * cute Co-authored-by: Benjamin Jackson <38561765+heyitsbench@users.noreply.github.com> --------- Co-authored-by: Benjamin Jackson <38561765+heyitsbench@users.noreply.github.com> --- data/sql/updates/pending_db_world/rev_1720238285754402600.sql | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1720238285754402600.sql diff --git a/data/sql/updates/pending_db_world/rev_1720238285754402600.sql b/data/sql/updates/pending_db_world/rev_1720238285754402600.sql new file mode 100644 index 000000000..8e3179e8a --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1720238285754402600.sql @@ -0,0 +1,2 @@ +-- +UPDATE `quest_template` SET `AllowableRaces` = 690 WHERE `ID` = 9846; From 8121356e860e01bee76b4fcd8711e73a76fbad9d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 6 Jul 2024 14:38:08 +0000 Subject: [PATCH 65/68] chore(DB): import pending files Referenced commit(s): 1632045ba88221daee04e84302192708889da44b --- .../{pending_db_world/detect.sql => db_world/2024_07_06_08.sql} | 1 + .../promenade-kick-immune.sql => db_world/2024_07_06_09.sql} | 1 + .../rev_1720238285754402600.sql => db_world/2024_07_06_10.sql} | 1 + 3 files changed, 3 insertions(+) rename data/sql/updates/{pending_db_world/detect.sql => db_world/2024_07_06_08.sql} (64%) rename data/sql/updates/{pending_db_world/promenade-kick-immune.sql => db_world/2024_07_06_09.sql} (72%) rename data/sql/updates/{pending_db_world/rev_1720238285754402600.sql => db_world/2024_07_06_10.sql} (62%) diff --git a/data/sql/updates/pending_db_world/detect.sql b/data/sql/updates/db_world/2024_07_06_08.sql similarity index 64% rename from data/sql/updates/pending_db_world/detect.sql rename to data/sql/updates/db_world/2024_07_06_08.sql index a3cdc25d8..1a7faa883 100644 --- a/data/sql/updates/pending_db_world/detect.sql +++ b/data/sql/updates/db_world/2024_07_06_08.sql @@ -1,2 +1,3 @@ +-- DB update 2024_07_06_07 -> 2024_07_06_08 -- UPDATE `creature_template` SET `detection_range` = 55 WHERE `entry` = 22849; diff --git a/data/sql/updates/pending_db_world/promenade-kick-immune.sql b/data/sql/updates/db_world/2024_07_06_09.sql similarity index 72% rename from data/sql/updates/pending_db_world/promenade-kick-immune.sql rename to data/sql/updates/db_world/2024_07_06_09.sql index 9429d7d0d..d364f1302 100644 --- a/data/sql/updates/pending_db_world/promenade-kick-immune.sql +++ b/data/sql/updates/db_world/2024_07_06_09.sql @@ -1,2 +1,3 @@ +-- DB update 2024_07_06_08 -> 2024_07_06_09 -- UPDATE `creature_template` SET `mechanic_immune_mask` = `mechanic_immune_mask`|33554432 WHERE `entry` = 23394; diff --git a/data/sql/updates/pending_db_world/rev_1720238285754402600.sql b/data/sql/updates/db_world/2024_07_06_10.sql similarity index 62% rename from data/sql/updates/pending_db_world/rev_1720238285754402600.sql rename to data/sql/updates/db_world/2024_07_06_10.sql index 8e3179e8a..903d2adcd 100644 --- a/data/sql/updates/pending_db_world/rev_1720238285754402600.sql +++ b/data/sql/updates/db_world/2024_07_06_10.sql @@ -1,2 +1,3 @@ +-- DB update 2024_07_06_09 -> 2024_07_06_10 -- UPDATE `quest_template` SET `AllowableRaces` = 690 WHERE `ID` = 9846; From ebf5f6710a0de5efa3067d3b58491ef8d25b8ae8 Mon Sep 17 00:00:00 2001 From: Kitzunu <24550914+Kitzunu@users.noreply.github.com> Date: Sat, 6 Jul 2024 19:13:24 +0200 Subject: [PATCH 66/68] =?UTF-8?q?feat(Core/Chat):=20Provide=20a=20fully-fo?= =?UTF-8?q?rmed=20protocol=20for=20addons=20to=20intera=E2=80=A6=20(#19305?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(Core/Chat): Provide a fully-formed protocol for addons to interact with GM commands * Send success/fail state, allow interleaving, and indicate end of output. Add framework for supporting non-human-readable output in commands. * cherry-pick commit (https://github.com/TrinityCore/TrinityCore/commit/508c9d2fc1b20dc2cb40df533e823e1dfe2becc3) This PR implements a well-formed protocol for addons to communicate with the server, outlined below: - All communication happens over the addon channel (`LANG_ADDON` in terms of the core, `CHAT_MSG_ADDON`/`SendAddonMessage` for the client). The prefix used for all messages is `AzerothCore` (in client terms - in core terms, every message starts with `AzerothCore\t`). - In each message, the first character is the opcode. The following four characters are a unique identifier for the invocation in question, and will be echoed back by the server in every message related to that invocation. Following is the message body, if any. - The following opcodes are supported: - Client to server: - `p` - Ping request. The core will always respond by ACKing with the passed identifier. No body. - `i` or `h` - Command invocation. The message body is the command text without prefix. `i` requests machine-readable output, `h` requests human-readable. - Server to client: - `a` - ACK. The first message sent in response to any invocation (before any output). No body. - `m` - Message. Sent once per line of output the server generates. Body = output line. - `o` - OK. Indicates that the command finished processing with no errors. No body. - `f` - Failed. Indicates that command processing is done, but there was an error. No body. Expected overhead is minimal, and this integrates seamlessly with existing command scripts (no changes necessary). PS: There's also a client-side addon library that exposes this protocol in a developer-friendly way over at https://github.com/azerothcore/LibAzerothCore-1.0 --------- Co-authored-by: Treeston <14020072+Treeston@users.noreply.github.com> --- src/server/game/Chat/Chat.cpp | 103 +++++++++++++++++++++++ src/server/game/Chat/Chat.h | 20 +++++ src/server/game/Handlers/ChatHandler.cpp | 22 +++-- 3 files changed, 138 insertions(+), 7 deletions(-) diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp index 170782631..57836678c 100644 --- a/src/server/game/Chat/Chat.cpp +++ b/src/server/game/Chat/Chat.cpp @@ -33,6 +33,7 @@ #include "World.h" #include "WorldPacket.h" #include "WorldSession.h" +#include Player* ChatHandler::GetPlayer() const { @@ -888,3 +889,105 @@ int CliHandler::GetSessionDbLocaleIndex() const { return sObjectMgr->GetDBCLocaleIndex(); } + +bool AddonChannelCommandHandler::ParseCommands(std::string_view str) +{ + if (memcmp(str.data(), "AzerothCore\t", 12)) + return false; + char opcode = str[12]; + if (!opcode) // str[12] is opcode + return false; + if (!str[13] || !str[14] || !str[15] || !str[16]) // str[13] through str[16] is 4-character command counter + return false; + echo = str.substr(13); + + switch (opcode) + { + case 'p': // p Ping + SendAck(); + return true; + case 'h': // h Issue human-readable command + case 'i': // i Issue command + if (!str[17]) + return false; + humanReadable = (opcode == 'h'); + if (_ParseCommands(str.substr(17))) // actual command starts at str[17] + { + if (!hadAck) + SendAck(); + if (HasSentErrorMessage()) + SendFailed(); + else + SendOK(); + } + else + { + SendSysMessage(LANG_CMD_INVALID); + SendFailed(); + } + return true; + default: + return false; + } +} + +void AddonChannelCommandHandler::Send(std::string const& msg) +{ + WorldPacket data; + ChatHandler::BuildChatPacket(data, CHAT_MSG_WHISPER, LANG_ADDON, GetSession()->GetPlayer(), GetSession()->GetPlayer(), msg); + GetSession()->SendPacket(&data); +} + +void AddonChannelCommandHandler::SendAck() // a Command acknowledged, no body +{ + ASSERT(echo.size()); + std::string ack = "AzerothCore\ta"; + ack.resize(18); + memcpy(&ack[13], echo.data(), 4); + ack[17] = '\0'; + Send(ack); + hadAck = true; +} + +void AddonChannelCommandHandler::SendOK() // o Command OK, no body +{ + ASSERT(echo.size()); + std::string ok = "AzerothCore\to"; + ok.resize(18); + memcpy(&ok[13], echo.data(), 4); + ok[17] = '\0'; + Send(ok); +} + +void AddonChannelCommandHandler::SendFailed() // f Command failed, no body +{ + ASSERT(echo.size()); + std::string fail = "AzerothCore\tf"; + fail.resize(18); + memcpy(&fail[13], echo.data(), 4); + fail[17] = '\0'; + Send(fail); +} + +// m Command message, message in body +void AddonChannelCommandHandler::SendSysMessage(std::string_view str, bool escapeCharacters) +{ + ASSERT(echo.size()); + if (!hadAck) + SendAck(); + + std::string msg = "AzerothCore\tm"; + msg.append(echo.data(), 4); + std::string body(str); + if (escapeCharacters) + boost::replace_all(body, "|", "||"); + size_t pos, lastpos; + for (lastpos = 0, pos = body.find('\n', lastpos); pos != std::string::npos; lastpos = pos + 1, pos = body.find('\n', lastpos)) + { + std::string line(msg); + line.append(body, lastpos, pos - lastpos); + Send(line); + } + msg.append(body, lastpos, pos - lastpos); + Send(msg); +} diff --git a/src/server/game/Chat/Chat.h b/src/server/game/Chat/Chat.h index d6f91bb86..c4873f2cc 100644 --- a/src/server/game/Chat/Chat.h +++ b/src/server/game/Chat/Chat.h @@ -168,4 +168,24 @@ private: Print* m_print; }; +class AC_GAME_API AddonChannelCommandHandler : public ChatHandler +{ + public: + using ChatHandler::ChatHandler; + bool ParseCommands(std::string_view str) override; + void SendSysMessage(std::string_view str, bool escapeCharacters) override; + using ChatHandler::SendSysMessage; + bool IsHumanReadable() const override { return humanReadable; } + + private: + void Send(std::string const& msg); + void SendAck(); + void SendOK(); + void SendFailed(); + + std::string echo; + bool hadAck = false; + bool humanReadable = false; +}; + #endif diff --git a/src/server/game/Handlers/ChatHandler.cpp b/src/server/game/Handlers/ChatHandler.cpp index 874d34aa6..6ce76ef06 100644 --- a/src/server/game/Handlers/ChatHandler.cpp +++ b/src/server/game/Handlers/ChatHandler.cpp @@ -283,14 +283,22 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) if (msg.empty()) return; - if (ChatHandler(this).ParseCommands(msg.c_str())) - return; - - if (!_player->CanSpeak()) + if (lang == LANG_ADDON) { - std::string timeStr = secsToTimeString(m_muteTime - GameTime::GetGameTime().count()); - SendNotification(GetAcoreString(LANG_WAIT_BEFORE_SPEAKING), timeStr.c_str()); - return; + if (AddonChannelCommandHandler(this).ParseCommands(msg.c_str())) + return; + } + else + { + if (ChatHandler(this).ParseCommands(msg.c_str())) + return; + + if (!_player->CanSpeak()) + { + std::string timeStr = secsToTimeString(m_muteTime - GameTime::GetGameTime().count()); + SendNotification(GetAcoreString(LANG_WAIT_BEFORE_SPEAKING), timeStr.c_str()); + return; + } } } From d0cd4358072ec3e1ae3c8aebfb3504f82e4be934 Mon Sep 17 00:00:00 2001 From: Benjamin Jackson <38561765+heyitsbench@users.noreply.github.com> Date: Sat, 6 Jul 2024 14:02:35 -0400 Subject: [PATCH 67/68] fix(Scripts/HyjalSummit): Add damage over time component to Doomfire debuff. (#19317) * Init. https: //github.com/mangostwo/server/commit/6a2e23cac09a88d7ec1221393ba96482d71187f6 Co-Authored-By: Miroslav Drbal [ApoC] * Don't forget the query. * Add spell attribute. * Adjust tick script. More dynamically calculates damage from ticks. Co-Authored-By: avarishd <46330494+avarishd@users.noreply.github.com> * Remove unnecessary `aurEff` Co-Authored-By: avarishd <46330494+avarishd@users.noreply.github.com> * #include --------- Co-authored-by: Miroslav Drbal [ApoC] Co-authored-by: avarishd <46330494+avarishd@users.noreply.github.com> --- .../updates/pending_db_world/doomfire-dot.sql | 5 ++++ .../BattleForMountHyjal/boss_archimonde.cpp | 30 +++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 data/sql/updates/pending_db_world/doomfire-dot.sql diff --git a/data/sql/updates/pending_db_world/doomfire-dot.sql b/data/sql/updates/pending_db_world/doomfire-dot.sql new file mode 100644 index 000000000..994dcd3de --- /dev/null +++ b/data/sql/updates/pending_db_world/doomfire-dot.sql @@ -0,0 +1,5 @@ +DELETE FROM `spell_script_names` WHERE `spell_id` = 31944; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES (31944, 'spell_doomfire'); + +DELETE FROM `spell_custom_attr` WHERE `spell_id` = 31944; +INSERT INTO `spell_custom_attr` (`spell_id`, `attributes`) VALUES (31944, 4194304); diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp index eea967559..6b5fae927 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp @@ -18,6 +18,7 @@ #include "CreatureScript.h" #include "Player.h" #include "ScriptedCreature.h" +#include "SpellAuraEffects.h" #include "SpellAuras.h" #include "SpellScript.h" #include "SpellScriptLoader.h" @@ -51,6 +52,7 @@ enum ArchiSpells SPELL_DOOMFIRE_STRIKE = 31903, //summons two creatures SPELL_DOOMFIRE_SPAWN = 32074, SPELL_DOOMFIRE = 31945, + SPELL_DOOMFIRE_DOT = 31969, SPELL_SOUL_CHARGE_YELLOW = 32045, SPELL_SOUL_CHARGE_GREEN = 32051, SPELL_SOUL_CHARGE_RED = 32052, @@ -484,10 +486,38 @@ class spell_air_burst : public SpellScript } }; +class spell_doomfire : public AuraScript +{ + PrepareAuraScript(spell_doomfire); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_DOOMFIRE_DOT }); + } + + void PeriodicTick(AuraEffect const* aurEff) + { + Unit* target = GetTarget(); + if (!target) + return; + + int32 bp = GetSpellInfo()->Effects[EFFECT_1].CalcValue(); + float tickCoef = (static_cast(aurEff->GetTickNumber() - 1) / aurEff->GetTotalTicks()); // Tick moved back to ensure proper damage on each tick + int32 damage = bp - (bp*tickCoef); + SpellCastResult result = target->CastCustomSpell(target, SPELL_DOOMFIRE_DOT, &damage, &damage, &damage, true, nullptr, nullptr, target->GetGUID()); + } + + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_doomfire::PeriodicTick, EFFECT_ALL, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + } +}; + void AddSC_boss_archimonde() { RegisterSpellScript(spell_red_sky_effect); RegisterSpellScript(spell_air_burst); + RegisterSpellScript(spell_doomfire); RegisterHyjalAI(boss_archimonde); RegisterHyjalAI(npc_ancient_wisp); RegisterHyjalAI(npc_doomfire_spirit); From f85d8433a66e98a97e0969182ecc5a1429a838b6 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 6 Jul 2024 18:03:28 +0000 Subject: [PATCH 68/68] chore(DB): import pending files Referenced commit(s): d0cd4358072ec3e1ae3c8aebfb3504f82e4be934 --- .../doomfire-dot.sql => db_world/2024_07_06_11.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/doomfire-dot.sql => db_world/2024_07_06_11.sql} (87%) diff --git a/data/sql/updates/pending_db_world/doomfire-dot.sql b/data/sql/updates/db_world/2024_07_06_11.sql similarity index 87% rename from data/sql/updates/pending_db_world/doomfire-dot.sql rename to data/sql/updates/db_world/2024_07_06_11.sql index 994dcd3de..8a74db700 100644 --- a/data/sql/updates/pending_db_world/doomfire-dot.sql +++ b/data/sql/updates/db_world/2024_07_06_11.sql @@ -1,3 +1,4 @@ +-- DB update 2024_07_06_10 -> 2024_07_06_11 DELETE FROM `spell_script_names` WHERE `spell_id` = 31944; INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES (31944, 'spell_doomfire');