From 41a04c5ee1775a80012901211c46ac3b5d526af1 Mon Sep 17 00:00:00 2001 From: mpfans Date: Sun, 12 Jun 2022 00:47:57 +0800 Subject: [PATCH 01/18] fix(db/translation): Chinese translation of road signs (#11981) * Fix(DB/translate):Chinese translation of road signs * Boat to Azuremyst * Boat to Teldrassil * Boat to Stormwind --- .../updates/pending_db_world/rev_1654674618622504335.sql | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1654674618622504335.sql diff --git a/data/sql/updates/pending_db_world/rev_1654674618622504335.sql b/data/sql/updates/pending_db_world/rev_1654674618622504335.sql new file mode 100644 index 000000000..fdc15a24e --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1654674618622504335.sql @@ -0,0 +1,6 @@ +-- Add Chinese translation of road signs +DELETE FROM `gameobject_template_locale` WHERE `entry` IN (184084,176365,176364) AND `locale` = 'zhCN'; +INSERT INTO `gameobject_template_locale` (`entry`, `locale`, `name`, `castBarCaption`, `VerifiedBuild`) VALUES +(184084, 'zhCN', '开往秘蓝岛的船只', '', 18019), +(176365, 'zhCN', '开往泰达希尔的船只', '', 18019), +(176364, 'zhCN', '开往暴风城的船只', '', 18019); From 913bc19aa0162748e9abe8e0178b8de1701c751f Mon Sep 17 00:00:00 2001 From: AzerothCoreBot Date: Sat, 11 Jun 2022 16:50:06 +0000 Subject: [PATCH 02/18] chore(DB): import pending files Referenced commit(s): 41a04c5ee1775a80012901211c46ac3b5d526af1 --- .../rev_1654674618622504335.sql => db_world/2022_06_11_00.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1654674618622504335.sql => db_world/2022_06_11_00.sql} (90%) diff --git a/data/sql/updates/pending_db_world/rev_1654674618622504335.sql b/data/sql/updates/db_world/2022_06_11_00.sql similarity index 90% rename from data/sql/updates/pending_db_world/rev_1654674618622504335.sql rename to data/sql/updates/db_world/2022_06_11_00.sql index fdc15a24e..28161c69b 100644 --- a/data/sql/updates/pending_db_world/rev_1654674618622504335.sql +++ b/data/sql/updates/db_world/2022_06_11_00.sql @@ -1,3 +1,4 @@ +-- DB update 2022_06_09_01 -> 2022_06_11_00 -- Add Chinese translation of road signs DELETE FROM `gameobject_template_locale` WHERE `entry` IN (184084,176365,176364) AND `locale` = 'zhCN'; INSERT INTO `gameobject_template_locale` (`entry`, `locale`, `name`, `castBarCaption`, `VerifiedBuild`) VALUES From 491f73382b4620d91fcd0cc47459f6b5f9c2aabc Mon Sep 17 00:00:00 2001 From: temperrr Date: Sun, 12 Jun 2022 21:32:44 +0200 Subject: [PATCH 03/18] =?UTF-8?q?fix(Scripts/EmeraldDragons):=20Emerald=20?= =?UTF-8?q?dragons=20should=20'enrage'=20at=20health=20per=E2=80=A6=20(#12?= =?UTF-8?q?029)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../scripts/World/boss_emerald_dragons.cpp | 22 ++++++++----------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/src/server/scripts/World/boss_emerald_dragons.cpp b/src/server/scripts/World/boss_emerald_dragons.cpp index 7acf32a31..8be574a4d 100644 --- a/src/server/scripts/World/boss_emerald_dragons.cpp +++ b/src/server/scripts/World/boss_emerald_dragons.cpp @@ -262,9 +262,9 @@ public: } // Summon druid spirits on 75%, 50% and 25% health - void DamageTaken(Unit*, uint32& /*damage*/, DamageEffectType, SpellSchoolMask) override + void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override { - if (!HealthAbovePct(100 - 25 * _stage)) + if (me->HealthBelowPctDamaged(100 - (25 * _stage), damage)) { Talk(SAY_YSONDRE_SUMMON_DRUIDS); @@ -349,9 +349,9 @@ public: WorldBossAI::EnterCombat(who); } - void DamageTaken(Unit*, uint32& /*damage*/, DamageEffectType, SpellSchoolMask) override + void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override { - if (!HealthAbovePct(100 - 25 * _stage)) + if (me->HealthBelowPctDamaged(100 - (25 * _stage), damage)) { Talk(SAY_LETHON_DRAW_SPIRIT); DoCast(me, SPELL_DRAW_SPIRIT); @@ -481,9 +481,9 @@ public: WorldBossAI::EnterCombat(who); } - void DamageTaken(Unit*, uint32& /*damage*/, DamageEffectType, SpellSchoolMask) override + void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override { - if (!HealthAbovePct(100 - 25 * _stage)) + if (me->HealthBelowPctDamaged(100 - (25 * _stage), damage)) { Talk(SAY_EMERISS_CAST_CORRUPTION); DoCast(me, SPELL_CORRUPTION_OF_EARTH, true); @@ -541,7 +541,6 @@ uint32 const TaerarShadeSpells[] = { SPELL_SUMMON_SHADE_1, SPELL_SUMMON_SHADE_2, SPELL_SUMMON_SHADE_3 }; - class boss_taerar : public CreatureScript { public: @@ -578,11 +577,11 @@ public: --_shades; } - void DamageTaken(Unit*, uint32& /*damage*/, DamageEffectType, SpellSchoolMask) override + void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override { // At 75, 50 or 25 percent health, we need to activate the shades and go "banished" // Note: _stage holds the amount of times they have been summoned - if (!_banished && !HealthAbovePct(100 - 25 * _stage)) + if (!_banished && me->HealthBelowPctDamaged(100 - (25 * _stage), damage)) { _banished = true; _banishedTimer = 60000; @@ -594,9 +593,8 @@ public: uint32 count = sizeof(TaerarShadeSpells) / sizeof(uint32); for (uint32 i = 0; i < count; ++i) - DoCastVictim(TaerarShadeSpells[i], true); + DoCast(TaerarShadeSpells[i]); _shades += count; - DoCast(SPELL_SHADE); me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE); me->SetReactState(REACT_PASSIVE); @@ -604,7 +602,6 @@ public: ++_stage; } } - void ExecuteEvent(uint32 eventId) override { switch (eventId) @@ -648,7 +645,6 @@ public: return; } - emerald_dragonAI::UpdateAI(diff); } From a2bc0ae02827bfc9ca6310022f532497ec2fdeab Mon Sep 17 00:00:00 2001 From: UltraNix <80540499+UltraNix@users.noreply.github.com> Date: Mon, 13 Jun 2022 06:03:06 +0200 Subject: [PATCH 04/18] =?UTF-8?q?fix(Core/Objects):=20Include=20combat=20r?= =?UTF-8?q?each=20instead=20of=20object=20size=20in=20LoS=E2=80=A6=20(#120?= =?UTF-8?q?13)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ... calculations. Fixed LoS calculations for dynamic objects. Modified combat reach of Deep Pool Threshfin. Fixes #11886 --- .../pending_db_world/rev_1654964701013345100.sql | 2 ++ src/server/game/Entities/Object/Object.cpp | 2 +- src/server/game/Spells/Auras/SpellAuras.cpp | 16 ++++++++-------- 3 files changed, 11 insertions(+), 9 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1654964701013345100.sql diff --git a/data/sql/updates/pending_db_world/rev_1654964701013345100.sql b/data/sql/updates/pending_db_world/rev_1654964701013345100.sql new file mode 100644 index 000000000..17dd3f7d9 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1654964701013345100.sql @@ -0,0 +1,2 @@ +-- +UPDATE `creature_model_info` SET `CombatReach`=1.5 WHERE `DisplayID`=2836; diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index 023632c0f..f894f9355 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -1234,7 +1234,7 @@ Position WorldObject::GetHitSpherePointFor(Position const& dest) const { G3D::Vector3 vThis(GetPositionX(), GetPositionY(), GetPositionZ() + GetCollisionHeight()); G3D::Vector3 vObj(dest.GetPositionX(), dest.GetPositionY(), dest.GetPositionZ()); - G3D::Vector3 contactPoint = vThis + (vObj - vThis).directionOrZero() * std::min(dest.GetExactDist(this), GetObjectSize()); + G3D::Vector3 contactPoint = vThis + (vObj - vThis).directionOrZero() * std::min(dest.GetExactDist(this), GetCombatReach()); return Position(contactPoint.x, contactPoint.y, contactPoint.z, GetAngle(contactPoint.x, contactPoint.y)); } diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp index d962deb72..e24899bf2 100644 --- a/src/server/game/Spells/Auras/SpellAuras.cpp +++ b/src/server/game/Spells/Auras/SpellAuras.cpp @@ -2842,9 +2842,10 @@ void DynObjAura::FillTargetMap(std::map& targets, Unit* /*caster*/ { if (!HasEffect(effIndex)) continue; + + SpellInfo const* spellInfo = GetSpellInfo(); UnitList targetList; - if (GetSpellInfo()->Effects[effIndex].TargetB.GetTarget() == TARGET_DEST_DYNOBJ_ALLY - || GetSpellInfo()->Effects[effIndex].TargetB.GetTarget() == TARGET_UNIT_DEST_AREA_ALLY) + if (spellInfo->Effects[effIndex].TargetB.GetTarget() == TARGET_DEST_DYNOBJ_ALLY || spellInfo->Effects[effIndex].TargetB.GetTarget() == TARGET_UNIT_DEST_AREA_ALLY) { Acore::AnyFriendlyUnitInObjectRangeCheck u_check(GetDynobjOwner(), dynObjOwnerCaster, radius); Acore::UnitListSearcher searcher(GetDynobjOwner(), targetList, u_check); @@ -2852,7 +2853,7 @@ void DynObjAura::FillTargetMap(std::map& targets, Unit* /*caster*/ } // pussywizard: TARGET_DEST_DYNOBJ_NONE is supposed to search for both friendly and unfriendly targets, so for any unit // what about EffectImplicitTargetA? - else if (GetSpellInfo()->Effects[effIndex].TargetB.GetTarget() == TARGET_DEST_DYNOBJ_NONE) + else if (spellInfo->Effects[effIndex].TargetB.GetTarget() == TARGET_DEST_DYNOBJ_NONE) { Acore::AnyAttackableUnitExceptForOriginalCasterInObjectRangeCheck u_check(GetDynobjOwner(), dynObjOwnerCaster, radius); Acore::UnitListSearcher searcher(GetDynobjOwner(), targetList, u_check); @@ -2867,12 +2868,11 @@ void DynObjAura::FillTargetMap(std::map& targets, Unit* /*caster*/ for (UnitList::iterator itr = targetList.begin(); itr != targetList.end(); ++itr) { - // xinef: check z level and los dependence Unit* target = *itr; - float zLevel = GetDynobjOwner()->GetPositionZ(); - if (target->GetPositionZ() + 3.0f < zLevel || target->GetPositionZ() - 5.0f > zLevel) - if (!target->IsWithinLOSInMap(GetDynobjOwner())) - continue; + if (!spellInfo->HasAttribute(SPELL_ATTR2_IGNORE_LINE_OF_SIGHT) && !spellInfo->HasAttribute(SPELL_ATTR5_ALWAYS_AOE_LINE_OF_SIGHT) && !target->IsWithinLOSInMap(GetDynobjOwner())) + { + continue; + } std::map::iterator existing = targets.find(*itr); if (existing != targets.end()) From 30d55ef2faacc4f515ad65aa9422e45a407fec87 Mon Sep 17 00:00:00 2001 From: AzerothCoreBot Date: Mon, 13 Jun 2022 04:05:17 +0000 Subject: [PATCH 05/18] chore(DB): import pending files Referenced commit(s): a2bc0ae02827bfc9ca6310022f532497ec2fdeab --- .../rev_1654964701013345100.sql => db_world/2022_06_13_00.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1654964701013345100.sql => db_world/2022_06_13_00.sql} (63%) diff --git a/data/sql/updates/pending_db_world/rev_1654964701013345100.sql b/data/sql/updates/db_world/2022_06_13_00.sql similarity index 63% rename from data/sql/updates/pending_db_world/rev_1654964701013345100.sql rename to data/sql/updates/db_world/2022_06_13_00.sql index 17dd3f7d9..a21c8f798 100644 --- a/data/sql/updates/pending_db_world/rev_1654964701013345100.sql +++ b/data/sql/updates/db_world/2022_06_13_00.sql @@ -1,2 +1,3 @@ +-- DB update 2022_06_11_00 -> 2022_06_13_00 -- UPDATE `creature_model_info` SET `CombatReach`=1.5 WHERE `DisplayID`=2836; From b273da1a5938aab4b587e732a8fce620fe0b12f3 Mon Sep 17 00:00:00 2001 From: Skjalf <47818697+Nyeriah@users.noreply.github.com> Date: Mon, 13 Jun 2022 06:36:26 -0300 Subject: [PATCH 06/18] fix(Scripts/World): Fix Emeriss putrid mushrooms not doing anything (#12035) * fix(Scripts/World): Fix Emeriss putrid mushrooms not doing anything * Update rev_1655056541364669100.sql --- .../updates/pending_db_world/rev_1655056541364669100.sql | 7 +++++++ src/server/scripts/World/boss_emerald_dragons.cpp | 5 ++++- 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 data/sql/updates/pending_db_world/rev_1655056541364669100.sql diff --git a/data/sql/updates/pending_db_world/rev_1655056541364669100.sql b/data/sql/updates/pending_db_world/rev_1655056541364669100.sql new file mode 100644 index 000000000..e7179a541 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1655056541364669100.sql @@ -0,0 +1,7 @@ +-- +UPDATE `gameobject_template` SET `AIName` = 'SmartGameObjectAI' WHERE `entry` = 180517; + +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 180517) AND (`source_type` = 1) AND (`id` IN (0, 1)); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(180517, 1, 0, 0, 63, 0, 100, 0, 0, 0, 0, 0, 0, 11, 24871, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Putrid Mushroom - On Just Created - Cast \'Spore Cloud\''), +(180517, 1, 1, 0, 1, 0, 100, 0, 120000, 120000, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Putrid Mushroom - Out of Combat - Despawn Instant'); diff --git a/src/server/scripts/World/boss_emerald_dragons.cpp b/src/server/scripts/World/boss_emerald_dragons.cpp index 8be574a4d..84a9740f6 100644 --- a/src/server/scripts/World/boss_emerald_dragons.cpp +++ b/src/server/scripts/World/boss_emerald_dragons.cpp @@ -471,7 +471,10 @@ public: void KilledUnit(Unit* who) override { if (who->GetTypeId() == TYPEID_PLAYER) - DoCast(who, SPELL_PUTRID_MUSHROOM, true); + { + who->CastSpell(who, SPELL_PUTRID_MUSHROOM, true); + } + emerald_dragonAI::KilledUnit(who); } From b455206ac3dda9b41c6c348189e40ff7293bc941 Mon Sep 17 00:00:00 2001 From: AzerothCoreBot Date: Mon, 13 Jun 2022 09:38:25 +0000 Subject: [PATCH 07/18] chore(DB): import pending files Referenced commit(s): b273da1a5938aab4b587e732a8fce620fe0b12f3 --- .../rev_1655056541364669100.sql => db_world/2022_06_13_01.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1655056541364669100.sql => db_world/2022_06_13_01.sql} (95%) diff --git a/data/sql/updates/pending_db_world/rev_1655056541364669100.sql b/data/sql/updates/db_world/2022_06_13_01.sql similarity index 95% rename from data/sql/updates/pending_db_world/rev_1655056541364669100.sql rename to data/sql/updates/db_world/2022_06_13_01.sql index e7179a541..2a50534c3 100644 --- a/data/sql/updates/pending_db_world/rev_1655056541364669100.sql +++ b/data/sql/updates/db_world/2022_06_13_01.sql @@ -1,3 +1,4 @@ +-- DB update 2022_06_13_00 -> 2022_06_13_01 -- UPDATE `gameobject_template` SET `AIName` = 'SmartGameObjectAI' WHERE `entry` = 180517; From 3b0cd43d122b05ee77318c8363612c06a94dfa47 Mon Sep 17 00:00:00 2001 From: Eddy Vega <61223313+Si1ker@users.noreply.github.com> Date: Mon, 13 Jun 2022 05:52:28 -0600 Subject: [PATCH 08/18] fix(scripts/ZulGurub): Rewrite Broodlord Mandokir and Ohgan (#11854) Co-authored-by: Nefertumm --- .../rev_1653580726731163907.sql | 3 + .../game/Spells/SpellInfoCorrections.cpp | 6 + .../ZulGurub/boss_mandokir.cpp | 319 +++++++++++++++--- .../EasternKingdoms/ZulGurub/zulgurub.h | 4 +- 4 files changed, 278 insertions(+), 54 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1653580726731163907.sql diff --git a/data/sql/updates/pending_db_world/rev_1653580726731163907.sql b/data/sql/updates/pending_db_world/rev_1653580726731163907.sql new file mode 100644 index 000000000..47eda61ab --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1653580726731163907.sql @@ -0,0 +1,3 @@ + +UPDATE `creature_template` SET `ScriptName`='npc_chained_spirit', `speed_run`=0.4, `unit_flags`=`unit_flags`|33554432 WHERE `entry`=15117; + diff --git a/src/server/game/Spells/SpellInfoCorrections.cpp b/src/server/game/Spells/SpellInfoCorrections.cpp index f2d8a9de0..9e85278f4 100644 --- a/src/server/game/Spells/SpellInfoCorrections.cpp +++ b/src/server/game/Spells/SpellInfoCorrections.cpp @@ -1363,6 +1363,12 @@ void SpellMgr::LoadSpellInfoCorrections() spellInfo->Effects[EFFECT_0].Amplitude = 15000; }); + // Threatening Gaze + ApplySpellFix({ 24314 }, [](SpellInfo* spellInfo) + { + spellInfo->AuraInterruptFlags |= AURA_INTERRUPT_FLAG_CAST; + }); + // Isle of Conquest ApplySpellFix({ 66551 }, [](SpellInfo* spellInfo) { diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp index 9e6dd8bc2..4f04748b8 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp +++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp @@ -15,19 +15,14 @@ * with this program. If not, see . */ -/* ScriptData -SDName: Boss_Mandokir -SD%Complete: 90 -SDComment: Ohgan function needs improvements. -SDCategory: Zul'Gurub -EndScriptData */ - #include "ScriptMgr.h" #include "ScriptedCreature.h" #include "Spell.h" #include "SpellAuras.h" #include "SpellScript.h" #include "zulgurub.h" +#include "Player.h" +#include "TaskScheduler.h" enum Says { @@ -41,15 +36,19 @@ enum Says enum Spells { - SPELL_CHARGE = 24408, // seen - SPELL_OVERPOWER = 24407, // Seen - SPELL_FEAR = 29321, - SPELL_WHIRLWIND = 13736, // Triggers 15589 - SPELL_MORTAL_STRIKE = 16856, // Seen - SPELL_FRENZY = 24318, // seen - SPELL_WATCH = 24314, // seen 24315, 24316 - SPELL_WATCH_CHARGE = 24315, // Triggers 24316 - SPELL_LEVEL_UP = 24312 // + SPELL_CHARGE = 24408, + SPELL_OVERPOWER = 24407, + SPELL_FRIGHTENING_SHOUT = 19134, + SPELL_WHIRLWIND = 13736, // triggers 15589 + SPELL_MORTAL_STRIKE = 16856, + SPELL_FRENZY = 24318, + SPELL_WATCH = 24314, // triggers 24315 and 24316 + SPELL_WATCH_CHARGE = 24315, // triggers 24316 + SPELL_LEVEL_UP = 24312, + SPELL_EXECUTE = 7160, + SPELL_MANDOKIR_CLEAVE = 20691, + + SPELL_REVIVE = 24341 // chained spirit }; enum Events @@ -62,18 +61,29 @@ enum Events EVENT_WHIRLWIND = 6, EVENT_CHECK_OHGAN = 7, EVENT_WATCH_PLAYER = 8, - EVENT_CHARGE_PLAYER = 9 + EVENT_CHARGE_PLAYER = 9, + EVENT_EXECUTE = 10, + EVENT_FRIGHTENING_SHOUT = 11, + EVENT_CLEAVE = 12 +}; + +enum Action +{ + ACTION_START_REVIVE = 1, // broodlord mandokir + ACTION_REVIVE = 2 // chained spirit }; enum Misc { + POINT_START_REVIVE = 1, // chained spirit + MODEL_OHGAN_MOUNT = 15271, PATH_MANDOKIR = 492861, POINT_MANDOKIR_END = 24, - CHAINED_SPIRT_COUNT = 20 + CHAINED_SPIRIT_COUNT = 20 }; -Position const PosSummonChainedSpirits[CHAINED_SPIRT_COUNT] = +Position const PosSummonChainedSpirits[CHAINED_SPIRIT_COUNT] = { { -12167.17f, -1979.330f, 133.0992f, 2.268928f }, { -12262.74f, -1953.394f, 133.5496f, 0.593412f }, @@ -114,28 +124,36 @@ public: void Reset() override { + BossAI::Reset(); + killCount = 0; if (me->GetPositionZ() > 140.0f) { events.ScheduleEvent(EVENT_CHECK_START, 1000); if (Creature* speaker = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_VILEBRANCH_SPEAKER))) + { if (!speaker->IsAlive()) + { speaker->Respawn(true); + } + } } - - killCount = 0; me->RemoveAurasDueToSpell(SPELL_FRENZY); me->RemoveUnitFlag(UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC); - summons.DespawnAll(); instance->SetBossState(DATA_OHGAN, NOT_STARTED); me->Mount(MODEL_OHGAN_MOUNT); + reviveGUID.Clear(); } void JustDied(Unit* /*killer*/) override { // Do not want to unsummon Ohgan - for (int i = 0; i < CHAINED_SPIRT_COUNT; ++i) - if (Creature* unsummon = ObjectAccessor::GetCreature(*me, chainedSpirtGUIDs[i])) + for (int i = 0; i < CHAINED_SPIRIT_COUNT; ++i) + { + if (Creature* unsummon = ObjectAccessor::GetCreature(*me, chainedSpiritGUIDs[i])) + { unsummon->DespawnOrUnsummon(); + } + } instance->SetBossState(DATA_MANDOKIR, DONE); instance->SaveToDB(); } @@ -143,22 +161,23 @@ public: void EnterCombat(Unit* /*who*/) override { _EnterCombat(); - events.ScheduleEvent(EVENT_OVERPOWER, urand(7000, 9000)); - events.ScheduleEvent(EVENT_MORTAL_STRIKE, urand(12000, 18000)); + events.ScheduleEvent(EVENT_OVERPOWER, urand(6000, 8000)); + events.ScheduleEvent(EVENT_MORTAL_STRIKE, urand(14000, 28000)); events.ScheduleEvent(EVENT_WHIRLWIND, urand(24000, 30000)); events.ScheduleEvent(EVENT_CHECK_OHGAN, 1000); - events.ScheduleEvent(EVENT_WATCH_PLAYER, urand(13000, 15000)); - events.ScheduleEvent(EVENT_CHARGE_PLAYER, urand(33000, 38000)); + events.ScheduleEvent(EVENT_WATCH_PLAYER, urand(12000, 24000)); + events.ScheduleEvent(EVENT_CHARGE_PLAYER, urand(30000, 40000)); + events.ScheduleEvent(EVENT_EXECUTE, urand(7000, 14000)); + events.ScheduleEvent(EVENT_CLEAVE, urand(10000, 20000)); me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation()); Talk(SAY_AGGRO); me->Dismount(); // Summon Ohgan (Spell missing) TEMP HACK me->SummonCreature(NPC_OHGAN, me->GetPositionX() - 3, me->GetPositionY(), me->GetPositionZ(), me->GetOrientation(), TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 35000); - // Summon Chained Spirits - for (int i = 0; i < CHAINED_SPIRT_COUNT; ++i) + for (int i = 0; i < CHAINED_SPIRIT_COUNT; ++i) { - Creature* chainedSpirt = me->SummonCreature(NPC_CHAINED_SPIRT, PosSummonChainedSpirits[i], TEMPSUMMON_CORPSE_DESPAWN); - chainedSpirtGUIDs[i] = chainedSpirt->GetGUID(); + Creature* chainedSpirit = me->SummonCreature(NPC_CHAINED_SPIRIT, PosSummonChainedSpirits[i], TEMPSUMMON_CORPSE_DESPAWN); + chainedSpiritGUIDs[i] = chainedSpirit->GetGUID(); } DoZoneInCombat(); } @@ -168,17 +187,49 @@ public: if (victim->GetTypeId() != TYPEID_PLAYER) return; + reviveGUID = victim->GetGUID(); + DoAction(ACTION_START_REVIVE); if (++killCount == 3) { Talk(SAY_DING_KILL); if (Creature* jindo = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_JINDO))) + { if (jindo->IsAlive()) + { jindo->AI()->Talk(SAY_GRATS_JINDO); + } + } DoCast(me, SPELL_LEVEL_UP, true); killCount = 0; } } + void DoAction(int32 action) override + { + if (action == ACTION_START_REVIVE) + { + std::list creatures; + GetCreatureListWithEntryInGrid(creatures, me, NPC_CHAINED_SPIRIT, 200.0f); + if (creatures.empty()) + return; + + for (std::list::iterator itr = creatures.begin(); itr != creatures.end(); ++itr) + { + if (Creature* chainedSpirit = ObjectAccessor::GetCreature(*me, (*itr)->GetGUID())) + { + chainedSpirit->AI()->SetGUID(reviveGUID); + chainedSpirit->AI()->DoAction(ACTION_REVIVE); + reviveGUID.Clear(); + } + } + } + } + + void SetGUID(ObjectGuid const guid, int32 /*type = 0 */) override + { + reviveGUID = guid; + } + void MovementInform(uint32 type, uint32 id) override { if (type == WAYPOINT_MOTION_TYPE) @@ -211,7 +262,9 @@ public: events.ScheduleEvent(EVENT_STARTED, 6000); } else + { events.ScheduleEvent(EVENT_CHECK_START, 1000); + } break; case EVENT_STARTED: me->RemoveUnitFlag(UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC); @@ -232,13 +285,12 @@ public: switch (eventId) { case EVENT_OVERPOWER: - DoCastVictim(SPELL_OVERPOWER, true); - events.ScheduleEvent(EVENT_OVERPOWER, urand(6000, 12000)); + DoCastVictim(SPELL_OVERPOWER); + events.ScheduleEvent(EVENT_OVERPOWER, urand(6000, 8000)); break; case EVENT_MORTAL_STRIKE: - if (me->GetVictim() && me->GetVictim()->HealthBelowPct(50)) - DoCastVictim(SPELL_MORTAL_STRIKE, true); - events.ScheduleEvent(EVENT_MORTAL_STRIKE, urand(12000, 18000)); + DoCastVictim(SPELL_MORTAL_STRIKE); + events.ScheduleEvent(EVENT_MORTAL_STRIKE, urand(14000, 28000)); break; case EVENT_WHIRLWIND: DoCast(me, SPELL_WHIRLWIND); @@ -251,7 +303,9 @@ public: Talk(SAY_OHGAN_DEAD); } else + { events.ScheduleEvent(EVENT_CHECK_OHGAN, 1000); + } break; case EVENT_WATCH_PLAYER: if (Unit* player = SelectTarget(SelectTargetMethod::Random, 0, 100, true)) @@ -259,23 +313,57 @@ public: DoCast(player, SPELL_WATCH); Talk(SAY_WATCH, player); } - events.ScheduleEvent(EVENT_WATCH_PLAYER, urand(12000, 15000)); + events.ScheduleEvent(EVENT_WATCH_PLAYER, urand(12000, 24000)); break; case EVENT_CHARGE_PLAYER: DoCast(SelectTarget(SelectTargetMethod::Random, 0, 40, true), SPELL_CHARGE); - events.ScheduleEvent(EVENT_CHARGE_PLAYER, urand(22000, 30000)); + events.ScheduleEvent(EVENT_FRIGHTENING_SHOUT, 1500); + if (Unit* mainTarget = SelectTarget(SelectTargetMethod::MaxThreat, 0, 100.0f)) + { + me->GetThreatMgr().modifyThreatPercent(mainTarget, -100); + } + events.ScheduleEvent(EVENT_CHARGE_PLAYER, urand(30000, 40000)); break; + case EVENT_EXECUTE: + if (me->GetVictim() && me->GetVictim()->HealthBelowPct(20)) + { + DoCastVictim(SPELL_EXECUTE, true); + } + events.ScheduleEvent(EVENT_EXECUTE, urand(7000, 14000)); + break; + case EVENT_FRIGHTENING_SHOUT: + DoCastAOE(SPELL_FRIGHTENING_SHOUT); + break; + case EVENT_CLEAVE: + { + std::list meleeRangeTargets; + auto i = me->GetThreatMgr().getThreatList().begin(); + for (; i != me->GetThreatMgr().getThreatList().end(); ++i) + { + Unit* target = (*i)->getTarget(); + if (me->IsWithinMeleeRange(target)) + { + meleeRangeTargets.push_back(target); + } + } + if (meleeRangeTargets.size() >= 5) + { + DoCastVictim(SPELL_MANDOKIR_CLEAVE); + } + events.ScheduleEvent(EVENT_CLEAVE, urand(10000, 20000)); + break; + } default: break; } } - DoMeleeAttackIfReady(); } private: uint8 killCount; - ObjectGuid chainedSpirtGUIDs[CHAINED_SPIRT_COUNT]; + ObjectGuid chainedSpiritGUIDs[CHAINED_SPIRIT_COUNT]; + ObjectGuid reviveGUID; }; CreatureAI* GetAI(Creature* creature) const override @@ -288,7 +376,8 @@ public: enum OhganSpells { - SPELL_SUNDERARMOR = 24317 + SPELL_SUNDERARMOR = 24317, + SPELL_THRASH = 3417 // Triggers 3391 }; class npc_ohgan : public CreatureScript @@ -302,10 +391,61 @@ public: void Reset() override { - SunderArmor_Timer = 5000; + me->AddAura(SPELL_THRASH, me); + _scheduler.CancelAll(); + _scheduler.SetValidator([this] + { + return !me->HasUnitState(UNIT_STATE_CASTING); + }); + + reviveGUID.Clear(); } - void EnterCombat(Unit* /*who*/) override { } + void EnterCombat(Unit* victim) override + { + if (victim->GetTypeId() != TYPEID_PLAYER) + return; + + reviveGUID = victim->GetGUID(); + DoAction(ACTION_START_REVIVE); + _scheduler.Schedule(6s, 12s, [this](TaskContext context) + { + DoCastVictim(SPELL_SUNDERARMOR); + context.Repeat(6s, 12s); + }); + } + + void KilledUnit(Unit* victim) override + { + if (victim->GetTypeId() != TYPEID_PLAYER) + return; + + reviveGUID = victim->GetGUID(); + DoAction(ACTION_START_REVIVE); + } + + void DoAction(int32 action) override + { + if (action == ACTION_START_REVIVE) + { + std::list creatures; + GetCreatureListWithEntryInGrid(creatures, me, NPC_CHAINED_SPIRIT, 200.0f); + if (creatures.empty()) + return; + + for (Creature* chainedSpirit : creatures) + { + chainedSpirit->AI()->SetGUID(reviveGUID); + chainedSpirit->AI()->DoAction(ACTION_REVIVE); + reviveGUID.Clear(); + } + } + } + + void SetGUID(ObjectGuid const guid, int32 /*type = 0 */) override + { + reviveGUID = guid; + } void JustDied(Unit* /*killer*/) override { @@ -314,23 +454,20 @@ public: void UpdateAI(uint32 diff) override { - // Return since we have no target - if (!UpdateVictim()) - return; + _scheduler.Update(diff); - if (SunderArmor_Timer <= diff) + if (!UpdateVictim()) { - DoCastVictim(SPELL_SUNDERARMOR, true); - SunderArmor_Timer = urand(10000, 15000); + return; } - else SunderArmor_Timer -= diff; DoMeleeAttackIfReady(); } private: - uint32 SunderArmor_Timer; InstanceScript* instance; + ObjectGuid reviveGUID; + TaskScheduler _scheduler; }; CreatureAI* GetAI(Creature* creature) const override @@ -339,6 +476,75 @@ public: } }; +struct npc_chained_spirit : public ScriptedAI +{ +public: + npc_chained_spirit(Creature* creature) : ScriptedAI(creature) + { + instance = me->GetInstanceScript(); + me->AddUnitMovementFlag(MOVEMENTFLAG_HOVER); + } + + void Reset() override + { + revivePlayerGUID.Clear(); + } + + void SetGUID(ObjectGuid const guid, int32 /*id*/) override + { + revivePlayerGUID = guid; + } + + void DoAction(int32 action) override + { + if (action == ACTION_REVIVE) + { + if (Player* target = ObjectAccessor::GetPlayer(*me, revivePlayerGUID)) + { + Position pos; + target->GetNearPoint(me, pos.m_positionX, pos.m_positionY, pos.m_positionZ, 0.0f, 0.0f, target->GetAbsoluteAngle(me)); + me->GetMotionMaster()->MovePoint(POINT_START_REVIVE, pos); + } + } + } + + void MovementInform(uint32 type, uint32 pointId) override + { + if (type != POINT_MOTION_TYPE || !revivePlayerGUID) + return; + + if (pointId == POINT_START_REVIVE) + { + if (Player* target = ObjectAccessor::GetPlayer(*me, revivePlayerGUID)) + { + DoCast(target, SPELL_REVIVE); + } + me->DespawnOrUnsummon(1000); + } + } + + void JustDied(Unit* /*killer*/) override + { + Player* target = ObjectAccessor::GetPlayer(*me, revivePlayerGUID); + if (!target || target->IsAlive()) + return; + + if (Creature* mandokir = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_MANDOKIR))) + { + mandokir->GetAI()->SetGUID(target->GetGUID()); + mandokir->GetAI()->DoAction(ACTION_START_REVIVE); + } + me->DespawnOrUnsummon(); + } + + void UpdateAI(uint32 /*diff*/) override { } + +private: + InstanceScript* instance; + ObjectGuid revivePlayerGUID; + +}; + enum VilebranchSpells { SPELL_DEMORALIZING_SHOUT = 13730, @@ -414,9 +620,15 @@ public: void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { if (Unit* caster = GetCaster()) + { if (Unit* target = GetTarget()) + { if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE && GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_DEATH) - caster->CastSpell(target, SPELL_WATCH_CHARGE); + { + caster->CastSpell(target, SPELL_WATCH_CHARGE, true); + } + } + } } void Register() override @@ -435,6 +647,7 @@ void AddSC_boss_mandokir() { new boss_mandokir(); new npc_ohgan(); + RegisterZulGurubCreatureAI(npc_chained_spirit); new npc_vilebranch_speaker(); new spell_threatening_gaze(); } diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/zulgurub.h b/src/server/scripts/EasternKingdoms/ZulGurub/zulgurub.h index 8c44120d1..79e40b4c4 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/zulgurub.h +++ b/src/server/scripts/EasternKingdoms/ZulGurub/zulgurub.h @@ -57,7 +57,7 @@ enum CreatureIds NPC_MANDOKIR = 11382, // Mandokir Event NPC_OHGAN = 14988, // Mandokir Event NPC_VILEBRANCH_SPEAKER = 11391, // Mandokir Event - NPC_CHAINED_SPIRT = 15117, // Mandokir Event + NPC_CHAINED_SPIRIT = 15117, // Mandokir Event NPC_HAKKAR = 14834, NPC_ZULGURUB_TIGER = 11361 }; @@ -74,4 +74,6 @@ inline AI* GetZulGurubAI(T* obj) return GetInstanceAI(obj, ZGScriptName); } +#define RegisterZulGurubCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetZulGurubAI) + #endif From 94b73fadaa1bafc7cdf3ee15a53c6001acb59e6d Mon Sep 17 00:00:00 2001 From: AzerothCoreBot Date: Mon, 13 Jun 2022 11:54:35 +0000 Subject: [PATCH 09/18] chore(DB): import pending files Referenced commit(s): 3b0cd43d122b05ee77318c8363612c06a94dfa47 --- .../rev_1653580726731163907.sql => db_world/2022_06_13_02.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1653580726731163907.sql => db_world/2022_06_13_02.sql} (76%) diff --git a/data/sql/updates/pending_db_world/rev_1653580726731163907.sql b/data/sql/updates/db_world/2022_06_13_02.sql similarity index 76% rename from data/sql/updates/pending_db_world/rev_1653580726731163907.sql rename to data/sql/updates/db_world/2022_06_13_02.sql index 47eda61ab..c4069397a 100644 --- a/data/sql/updates/pending_db_world/rev_1653580726731163907.sql +++ b/data/sql/updates/db_world/2022_06_13_02.sql @@ -1,3 +1,4 @@ +-- DB update 2022_06_13_01 -> 2022_06_13_02 UPDATE `creature_template` SET `ScriptName`='npc_chained_spirit', `speed_run`=0.4, `unit_flags`=`unit_flags`|33554432 WHERE `entry`=15117; From db41a0132e2f8c1e1ede0e8fdb064daac8140cc9 Mon Sep 17 00:00:00 2001 From: UltraNix <80540499+UltraNix@users.noreply.github.com> Date: Mon, 13 Jun 2022 13:57:35 +0200 Subject: [PATCH 10/18] fix(Core/Misc): Fixed radius of areatriggers in battlegrounds. (#12017) * fix(Core/Misc): Fixed radius of areatriggers in battlegrounds. Fixes #12004 * buildfix. --- src/server/game/Entities/Player/Player.cpp | 4 +--- src/server/game/Entities/Player/Player.h | 2 +- src/server/game/Entities/Player/PlayerUpdates.cpp | 7 ++++--- src/server/game/Handlers/MiscHandler.cpp | 5 +++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index b73d8602c..7cd658988 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -2139,10 +2139,8 @@ void Player::SetInWater(bool apply) getHostileRefMgr().updateThreatTables(); } -bool Player::IsInAreaTriggerRadius(const AreaTrigger* trigger) const +bool Player::IsInAreaTriggerRadius(AreaTrigger const* trigger, float delta) const { - static const float delta = 5.0f; - if (!trigger || GetMapId() != trigger->map) return false; diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 4e8f21599..1ab612d5d 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -1095,7 +1095,7 @@ public: [[nodiscard]] bool IsInWater() const override { return m_isInWater; } [[nodiscard]] bool IsFalling() const; - bool IsInAreaTriggerRadius(const AreaTrigger* trigger) const; + bool IsInAreaTriggerRadius(AreaTrigger const* trigger, float delta = 0.f) const; void SendInitialPacketsBeforeAddToMap(); void SendInitialPacketsAfterAddToMap(); diff --git a/src/server/game/Entities/Player/PlayerUpdates.cpp b/src/server/game/Entities/Player/PlayerUpdates.cpp index 86230835b..04f7fd011 100644 --- a/src/server/game/Entities/Player/PlayerUpdates.cpp +++ b/src/server/game/Entities/Player/PlayerUpdates.cpp @@ -277,10 +277,11 @@ void Player::Update(uint32 p_time) // supposed to be in one if (HasRestFlag(REST_FLAG_IN_TAVERN)) { - AreaTrigger const* atEntry = - sObjectMgr->GetAreaTrigger(GetInnTriggerId()); - if (!atEntry || !IsInAreaTriggerRadius(atEntry)) + AreaTrigger const* atEntry = sObjectMgr->GetAreaTrigger(GetInnTriggerId()); + if (!atEntry || !IsInAreaTriggerRadius(atEntry, 5.f)) + { RemoveRestFlag(REST_FLAG_IN_TAVERN); + } } uint32 newzone, newarea; diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index 973cee758..dc5b48e68 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -731,7 +731,8 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket& recv_data) return; } - if (!player->IsInAreaTriggerRadius(atEntry)) + bool isTavernAreatrigger = sObjectMgr->IsTavernAreaTrigger(triggerId); + if (!player->IsInAreaTriggerRadius(atEntry, isTavernAreatrigger ? 5.f : 0.f)) { LOG_DEBUG("network", "HandleAreaTriggerOpcode: Player {} ({}) too far (trigger map: {} player map: {}), ignore Area Trigger ID: {}", player->GetName(), player->GetGUID().ToString(), atEntry->map, player->GetMapId(), triggerId); @@ -749,7 +750,7 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket& recv_data) if (player->GetQuestStatus(questId) == QUEST_STATUS_INCOMPLETE) player->AreaExploredOrEventHappens(questId); - if (sObjectMgr->IsTavernAreaTrigger(triggerId)) + if (isTavernAreatrigger) { // set resting flag we are in the inn player->SetRestFlag(REST_FLAG_IN_TAVERN, atEntry->entry); From 8cbc1b0a5536dbb4155c4b047e69e97aea801cc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefano=20Borz=C3=AC?= Date: Mon, 13 Jun 2022 13:58:03 +0200 Subject: [PATCH 11/18] chore: restore googletest main repo reference (#12011) chore: retore googletest main repo reference --- src/cmake/googletest-download.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cmake/googletest-download.cmake b/src/cmake/googletest-download.cmake index 0d7cd6744..1cc4361e5 100644 --- a/src/cmake/googletest-download.cmake +++ b/src/cmake/googletest-download.cmake @@ -22,7 +22,7 @@ ExternalProject_Add( SOURCE_DIR "@GOOGLETEST_DOWNLOAD_ROOT@/googletest-src" BINARY_DIR "@GOOGLETEST_DOWNLOAD_ROOT@/googletest-build" GIT_REPOSITORY - https://github.com/Helias/googletest.git + https://github.com/google/googletest.git GIT_TAG main CONFIGURE_COMMAND "" From 8e7c4fa226c2757f73df8d2b9af4af0b388ddb6f Mon Sep 17 00:00:00 2001 From: Kempec Halk <80704304+Gozzim@users.noreply.github.com> Date: Mon, 13 Jun 2022 13:58:49 +0200 Subject: [PATCH 12/18] fix(Core): Deserter overrides from BG and Command (#11961) * fix(Core/Command): Deserter offline add * feat(Core/Command): Deserter online add restriction * fix(Core/Battleground): Deserter overrides longer debuff --- src/server/game/Entities/Player/Player.cpp | 6 +++++- src/server/scripts/Commands/cs_deserter.cpp | 22 ++++++++++++++++++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 7cd658988..2dadc9023 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -1620,7 +1620,11 @@ void Player::ProcessDelayedOperations() SaveToDB(false, false); if (m_DelayedOperations & DELAYED_SPELL_CAST_DESERTER) - CastSpell(this, 26013, true); // Deserter + { + Aura* aura = GetAura(26013); + if (!aura || aura->GetDuration() <= 900000) + CastSpell(this, 26013, true); + } if (m_DelayedOperations & DELAYED_BG_MOUNT_RESTORE) { diff --git a/src/server/scripts/Commands/cs_deserter.cpp b/src/server/scripts/Commands/cs_deserter.cpp index 0cc93a62b..648464186 100644 --- a/src/server/scripts/Commands/cs_deserter.cpp +++ b/src/server/scripts/Commands/cs_deserter.cpp @@ -117,8 +117,14 @@ public: if (target) { - Aura* aura = target->AddAura(isInstance ? LFG_SPELL_DUNGEON_DESERTER : BG_SPELL_DESERTER, target); + Aura* aura = target->GetAura(isInstance ? LFG_SPELL_DUNGEON_DESERTER : BG_SPELL_DESERTER); + if (aura && aura->GetDuration() >= (int32)time * IN_MILLISECONDS) + { + handler->PSendSysMessage("Player %s already has a longer %s Deserter active.", handler->playerLink(player->GetName()), isInstance ? "Instance" : "Battleground"); + return true; + } + aura = target->AddAura(isInstance ? LFG_SPELL_DUNGEON_DESERTER : BG_SPELL_DESERTER, target); if (!aura) { handler->SendSysMessage(LANG_BAD_VALUE); @@ -130,6 +136,20 @@ public: return true; } + int32 duration = 0; + if (QueryResult result = CharacterDatabase.Query("SELECT remainTime FROM character_aura WHERE guid = {} AND spell = {}", player->GetGUID().GetCounter(), isInstance ? LFG_SPELL_DUNGEON_DESERTER : BG_SPELL_DESERTER)) + { + Field* fields = result->Fetch(); + duration = fields[0].Get(); + + if (duration < 0 || duration >= (int32)time * IN_MILLISECONDS) + { + handler->PSendSysMessage("Player %s already has a longer %s Deserter active.", handler->playerLink(player->GetName()), isInstance ? "Instance" : "Battleground"); + return true; + } + CharacterDatabase.Query("DELETE FROM character_aura WHERE guid = {} AND spell = {}", player->GetGUID().GetCounter(), isInstance ? LFG_SPELL_DUNGEON_DESERTER : BG_SPELL_DESERTER); + } + uint8 index = 0; CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_AURA); stmt->SetData(index++, player->GetGUID().GetCounter()); From d3b381c238914353452317f9f8c9c473861b9ab2 Mon Sep 17 00:00:00 2001 From: temperrr Date: Mon, 13 Jun 2022 14:01:50 +0200 Subject: [PATCH 13/18] fix(Scripts/BRD): Emperor should not yell when dead. (#12046) Co-authored-by: Skjalf <47818697+Nyeriah@users.noreply.github.com> --- .../BlackrockDepths/boss_emperor_dagran_thaurissan.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_emperor_dagran_thaurissan.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_emperor_dagran_thaurissan.cpp index f018a9f13..7fd7fa2af 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_emperor_dagran_thaurissan.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_emperor_dagran_thaurissan.cpp @@ -80,7 +80,10 @@ public: { if (hasYelled < 5) { - Talk(SenatorYells[hasYelled]); + if (me->IsAlive()) + { + Talk(SenatorYells[hasYelled]); + } } hasYelled++; } From d236dc9d078f301d484623182cdae1f6ef828998 Mon Sep 17 00:00:00 2001 From: UltraNix <80540499+UltraNix@users.noreply.github.com> Date: Mon, 13 Jun 2022 14:02:57 +0200 Subject: [PATCH 14/18] fix(Scripts/ZulGurub): Wushoolay - improvements: (#11968) * fix(Scripts/ZulGurub): Wushoolay - improvements: Added missing spells and events. Removed invalid spells Corrected event timers. Fixes #11627 * Update. --- .../ZulGurub/boss_wushoolay.cpp | 47 ++++++++++--------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_wushoolay.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_wushoolay.cpp index 6f4cbaf78..4e117d9c7 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_wushoolay.cpp +++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_wushoolay.cpp @@ -28,14 +28,16 @@ EndScriptData */ enum Spells { - SPELL_LIGHTNINGCLOUD = 25033, - SPELL_LIGHTNINGWAVE = 24819 + SPELL_LIGHTNING_CLOUD = 24683, + SPELL_CHAIN_LIGHTNING = 24680, + SPELL_FORKED_LIGHTNING = 24682 }; enum Events { - EVENT_LIGHTNINGCLOUD = 1, - EVENT_LIGHTNINGWAVE = 2 + EVENT_LIGHTNING_CLOUD = 1, + EVENT_CHAIN_LIGHTNING = 2, + EVENT_FORKED_LIGHTNING = 3 }; class boss_wushoolay : public CreatureScript @@ -47,21 +49,12 @@ public: { boss_wushoolayAI(Creature* creature) : BossAI(creature, DATA_EDGE_OF_MADNESS) { } - void Reset() override - { - _Reset(); - } - - void JustDied(Unit* /*killer*/) override - { - _JustDied(); - } - void EnterCombat(Unit* /*who*/) override { _EnterCombat(); - events.ScheduleEvent(EVENT_LIGHTNINGCLOUD, urand(5000, 10000)); - events.ScheduleEvent(EVENT_LIGHTNINGWAVE, urand(8000, 16000)); + events.ScheduleEvent(EVENT_LIGHTNING_CLOUD, 7s, 15s); + events.ScheduleEvent(EVENT_CHAIN_LIGHTNING, 12s, 16s); + events.ScheduleEvent(EVENT_FORKED_LIGHTNING, 8s, 12s); } void UpdateAI(uint32 diff) override @@ -78,13 +71,23 @@ public: { switch (eventId) { - case EVENT_LIGHTNINGCLOUD: - DoCastVictim(SPELL_LIGHTNINGCLOUD, true); - events.ScheduleEvent(EVENT_LIGHTNINGCLOUD, urand(15000, 20000)); + case EVENT_LIGHTNING_CLOUD: + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0)) + { + me->CastSpell(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), SPELL_LIGHTNING_CLOUD, false); + } + events.ScheduleEvent(EVENT_LIGHTNING_CLOUD, 9s, 20s); break; - case EVENT_LIGHTNINGWAVE: - DoCast(SelectTarget(SelectTargetMethod::Random, 0, 100, true), SPELL_LIGHTNINGWAVE); - events.ScheduleEvent(EVENT_LIGHTNINGWAVE, urand(12000, 16000)); + case EVENT_CHAIN_LIGHTNING: + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0)) + { + DoCast(target, SPELL_CHAIN_LIGHTNING); + } + events.ScheduleEvent(EVENT_CHAIN_LIGHTNING, 12s, 24s); + break; + case EVENT_FORKED_LIGHTNING: + DoCastAOE(SPELL_FORKED_LIGHTNING); + events.ScheduleEvent(EVENT_FORKED_LIGHTNING, 8s, 20s); break; default: break; From 3c434cee12f0cab55071a2580ced81de53233f9d Mon Sep 17 00:00:00 2001 From: Kempec Halk <80704304+Gozzim@users.noreply.github.com> Date: Mon, 13 Jun 2022 19:05:26 +0200 Subject: [PATCH 15/18] feat(Core/Command): Use timestring with all commands (#12050) --- .../rev_1654372051309044400.sql | 18 +++ src/server/scripts/Commands/cs_bf.cpp | 27 +++- src/server/scripts/Commands/cs_deserter.cpp | 97 ++++++++++---- src/server/scripts/Commands/cs_misc.cpp | 41 ++++-- src/server/scripts/Commands/cs_npc.cpp | 29 +++- src/server/scripts/Commands/cs_server.cpp | 124 ++++++++++++++++-- 6 files changed, 285 insertions(+), 51 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1654372051309044400.sql diff --git a/data/sql/updates/pending_db_world/rev_1654372051309044400.sql b/data/sql/updates/pending_db_world/rev_1654372051309044400.sql new file mode 100644 index 000000000..e19b8912d --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1654372051309044400.sql @@ -0,0 +1,18 @@ +-- +DELETE FROM `acore_string` WHERE `entry` IN (283,298,300,301,11003); +INSERT INTO `acore_string` (`entry`, `content_default`, `locale_koKR`, `locale_frFR`, `locale_deDE`, `locale_zhCN`, `locale_zhTW`, `locale_esES`, `locale_esMX`, `locale_ruRU`) VALUES +(283, "%s has disabled %s's chat for %s, effective at the player's next login. Reason: %s.", NULL, NULL, "Ihr habt dem Spieler %s das chatten für %s gesperrt, beginnend mit dem nächsten Login des Spielers. Grund: %s.", "你已经被 %s 禁言 %s,将在下一次登陆时生效。原因: %s。", NULL, "%s ha deshabilitado el chat de %s por %s, efectivo en el próximo ingreso del jugador. Razón: %s.", "%s ha deshabilitado el chat de %s por %s, efectivo en el próximo ingreso del jugador. Razón: %s.", NULL), +(298, "Spawn time changed to: %s", NULL, NULL, "Spawnzeit wurde auf: %s abgeändert", "复生时间改变为: %s", NULL, "Tiempo de desove cambiado a: %s", "Tiempo de desove cambiado a: %s", NULL), +(300, "Your chat has been disabled for %s. By: %s, Reason: %s.", NULL, NULL, "Euer Chat wurde für %s abgeschaltet. Von: %s, Grund: %s", "你将被禁言 %s.", NULL, "Tu chat ha sido desactivado durante %u. Por: %s ,Razón: %s.", "Tu chat ha sido desactivado durante %u. Por: %s ,Razón: %s.", NULL), +(301, "%s has disabled %s's chat for %s. Reason: %s.", NULL, NULL, "Ihr hab den Chat von %s für %s abgeschaltet. Von: %s, Grund: %s", NULL, NULL, "%s ha desactivado el chat de %s durante %s. Razón: %s.", "%s ha desactivado el chat de %s durante %s. Razón: %s.", NULL), +(11003, "Server: %s has muted %s for %s, reason: %s", NULL, NULL, NULL, "系统公告: %s has muted %s for %s, 原因: %s", NULL, NULL, NULL, "Server: %s замутил %s на %s, причина: %s"); + +UPDATE `command` SET `help` = "Syntax: .mute [$playerName] $mutetime [$reason]\r\nDisible chat messaging for any character from account of character $playerName (or currently selected) at $mutetime time. Player can be offline.\n$mutetime: use a timestring like \"1d15h33s\"." WHERE `name` = "mute"; +UPDATE `command` SET `help` = "Syntax: .npc set spawntime #time\r\nAdjust spawntime of selected creature to #time.\n#time: use a timestring like \"10m30s\"." WHERE `name` = "npc set spawntime"; +UPDATE `command` SET `help` = "Syntax: .server idlerestart #delay\r\nRestart the server after #delay if no active connections are present (no players). Use #exist_code or 2 as program exist code.\n#delay: use a timestring like \"1h15m30s\"." WHERE `name` = "server idlerestart"; +UPDATE `command` SET `help` = "Syntax: .server idleshutdown #delay [#exist_code]\r\nShut the server down after #delay if no active connections are present (no players). Use #exist_code or 0 as program exist code.\n#delay: use a timestring like \"1h15m30s\"." WHERE `name` = "server idleshutdown"; +UPDATE `command` SET `help` = "Syntax: .server restart #delay\r\nRestart the server after #delay. Use #exist_code or 2 as program exist code.\n#delay: use a timestring like \"1h15m30s\"." WHERE `name` = "server restart"; +UPDATE `command` SET `help` = "Syntax: .server shutdown #delay [#exit_code]\r\nShut the server down after #delay. Use #exit_code or 0 as program exit code.\n#delay: use a timestring like \"1h15m30s\"." WHERE `name` = "server shutdown"; +UPDATE `command` SET `help` = "Syntax: .bf timer #battleid #timer\n#timer: use a timestring like \"1h15m30s\"." WHERE `name` = "bf timer"; +UPDATE `command` SET `help` = "Syntax: .deserter bg add $playerName <$time>\r\nAdds the bg deserter debuff to a player or your target with $time.\nOptional $time: use a timestring like \"1h15m30s\".Default: 15m" WHERE `name` = "deserter bg add"; +UPDATE `command` SET `help` = "Syntax: .deserter instance add $playerName <$time>\r\nAdds the instance deserter debuff to a player or your target with $time.\nOptional $time: use a timestring like \"1h15m30s\". Default: 30m" WHERE `name` = "deserter instance add"; \ No newline at end of file diff --git a/src/server/scripts/Commands/cs_bf.cpp b/src/server/scripts/Commands/cs_bf.cpp index 06bf77871..2610a2c62 100644 --- a/src/server/scripts/Commands/cs_bf.cpp +++ b/src/server/scripts/Commands/cs_bf.cpp @@ -117,8 +117,33 @@ public: return true; } - static bool HandleBattlefieldTimer(ChatHandler* handler, uint32 battleId, uint32 time) + static bool HandleBattlefieldTimer(ChatHandler* handler, uint32 battleId, std::string timeStr) { + if (timeStr.empty()) + { + return false; + } + + if (Acore::StringTo(timeStr).value_or(0) < 0) + { + handler->SendSysMessage(LANG_BAD_VALUE); + handler->SetSentErrorMessage(true); + return false; + } + + int32 time = TimeStringToSecs(timeStr); + if (time <= 0) + { + time = Acore::StringTo(timeStr).value_or(0); + } + + if (time <= 0) + { + handler->SendSysMessage(LANG_BAD_VALUE); + handler->SetSentErrorMessage(true); + return false; + } + Battlefield* bf = sBattlefieldMgr->GetBattlefieldByBattleId(battleId); if (!bf) diff --git a/src/server/scripts/Commands/cs_deserter.cpp b/src/server/scripts/Commands/cs_deserter.cpp index 648464186..17761aaf6 100644 --- a/src/server/scripts/Commands/cs_deserter.cpp +++ b/src/server/scripts/Commands/cs_deserter.cpp @@ -79,7 +79,8 @@ public: * selected player, with the provided duration in seconds. * * @param handler The ChatHandler, passed by the system. - * @param time The provided duration in seconds. + * @param playerName Player by name. Optional, defaults to selected or self. + * @param time The provided duration as TimeString. Optional, defaults to bg/instance default time. * @param isInstance provided by the relaying functions, so we don't have * to write that much code :) * @@ -87,40 +88,80 @@ public: * * Example Usage: * @code - * .deserter instance add 3600 (one hour) + * .deserter instance add 1h30m * -or- - * .deserter bg add 3600 (one hour) + * .deserter bg add 1h30m * @endcode */ - static bool HandleDeserterAdd(ChatHandler* handler, Optional player, uint32 time, bool isInstance) + static bool HandleDeserterAdd(ChatHandler* handler, Optional playerName, Optional time, bool isInstance) { - if (!player) + Player* target = handler->getSelectedPlayerOrSelf(); + ObjectGuid guid; + + if (playerName) { - player = PlayerIdentifier::FromTargetOrSelf(handler); + if (!normalizePlayerName(*playerName)) + { + handler->SendSysMessage(LANG_PLAYER_NOT_FOUND); + handler->SetSentErrorMessage(true); + return false; + } + + guid = sCharacterCache->GetCharacterGuidByName(*playerName); + if (guid) + { + target = ObjectAccessor::FindPlayerByName(*playerName); + } + else + { + if (time) + { + handler->SendSysMessage(LANG_PLAYER_NOT_FOUND); + handler->SetSentErrorMessage(true); + return false; + } + + time = playerName; + playerName = ""; + } } - if (!player) + if (!playerName || playerName->empty()) { - handler->SendSysMessage(LANG_NO_CHAR_SELECTED); - handler->SetSentErrorMessage(true); - return false; + if (!handler->GetSession()) + { + return false; + } + + playerName = target->GetName(); + guid = target->GetGUID(); } if (!time) + { + time = isInstance ? "30m" : "15m"; + } + + int32 duration = TimeStringToSecs(*time); + + if (duration == 0) + { + duration = Acore::StringTo(*time).value_or(0); + } + + if (duration == 0) { handler->SendSysMessage(LANG_BAD_VALUE); handler->SetSentErrorMessage(true); return false; } - Player* target = player->GetConnectedPlayer(); - if (target) { Aura* aura = target->GetAura(isInstance ? LFG_SPELL_DUNGEON_DESERTER : BG_SPELL_DESERTER); - if (aura && aura->GetDuration() >= (int32)time * IN_MILLISECONDS) + if (aura && aura->GetDuration() >= duration * IN_MILLISECONDS) { - handler->PSendSysMessage("Player %s already has a longer %s Deserter active.", handler->playerLink(player->GetName()), isInstance ? "Instance" : "Battleground"); + handler->PSendSysMessage("Player %s already has a longer %s Deserter active.", handler->playerLink(*playerName), isInstance ? "Instance" : "Battleground"); return true; } @@ -131,29 +172,29 @@ public: handler->SetSentErrorMessage(true); return false; } - aura->SetDuration(time * IN_MILLISECONDS); + aura->SetDuration(duration * IN_MILLISECONDS); return true; } - int32 duration = 0; - if (QueryResult result = CharacterDatabase.Query("SELECT remainTime FROM character_aura WHERE guid = {} AND spell = {}", player->GetGUID().GetCounter(), isInstance ? LFG_SPELL_DUNGEON_DESERTER : BG_SPELL_DESERTER)) + int32 remainTime = 0; + if (QueryResult result = CharacterDatabase.Query("SELECT remainTime FROM character_aura WHERE guid = {} AND spell = {}", guid.GetCounter(), isInstance ? LFG_SPELL_DUNGEON_DESERTER : BG_SPELL_DESERTER)) { Field* fields = result->Fetch(); - duration = fields[0].Get(); + remainTime = fields[0].Get(); - if (duration < 0 || duration >= (int32)time * IN_MILLISECONDS) + if (remainTime < 0 || remainTime >= duration * IN_MILLISECONDS) { - handler->PSendSysMessage("Player %s already has a longer %s Deserter active.", handler->playerLink(player->GetName()), isInstance ? "Instance" : "Battleground"); + handler->PSendSysMessage("Player %s already has a longer %s Deserter active.", handler->playerLink(*playerName), isInstance ? "Instance" : "Battleground"); return true; } - CharacterDatabase.Query("DELETE FROM character_aura WHERE guid = {} AND spell = {}", player->GetGUID().GetCounter(), isInstance ? LFG_SPELL_DUNGEON_DESERTER : BG_SPELL_DESERTER); + CharacterDatabase.Query("DELETE FROM character_aura WHERE guid = {} AND spell = {}", guid.GetCounter(), isInstance ? LFG_SPELL_DUNGEON_DESERTER : BG_SPELL_DESERTER); } uint8 index = 0; CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_AURA); - stmt->SetData(index++, player->GetGUID().GetCounter()); - stmt->SetData(index++, player->GetGUID().GetCounter()); + stmt->SetData(index++, guid.GetCounter()); + stmt->SetData(index++, guid.GetCounter()); stmt->SetData(index++, 0); stmt->SetData(index++, isInstance ? LFG_SPELL_DUNGEON_DESERTER : BG_SPELL_DESERTER); stmt->SetData(index++, 1); @@ -166,7 +207,7 @@ public: stmt->SetData(index++, 0); stmt->SetData(index++, 0); stmt->SetData(index++, isInstance ? 1800000 : 900000); - stmt->SetData(index++, time * 1000); + stmt->SetData(index++, duration * 1000); stmt->SetData(index, 0); CharacterDatabase.Execute(stmt); @@ -240,15 +281,15 @@ public: } /// @sa HandleDeserterAdd() - static bool HandleDeserterInstanceAdd(ChatHandler* handler, Optional player, uint32 time) + static bool HandleDeserterInstanceAdd(ChatHandler* handler, Optional playerName, Optional time) { - return HandleDeserterAdd(handler, player, time, true); + return HandleDeserterAdd(handler, playerName, time, true); } /// @sa HandleDeserterAdd() - static bool HandleDeserterBGAdd(ChatHandler* handler, Optional player, uint32 time) + static bool HandleDeserterBGAdd(ChatHandler* handler, Optional playerName, Optional time) { - return HandleDeserterAdd(handler, player, time, false); + return HandleDeserterAdd(handler, playerName, time, false); } /// @sa HandleDeserterRemove() diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index d6b9bbd8e..33ed6b6d1 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -2374,10 +2374,22 @@ public: } // mute player for some times - static bool HandleMuteCommand(ChatHandler* handler, Optional player, uint32 notSpeakTime, Tail muteReason) + static bool HandleMuteCommand(ChatHandler* handler, Optional player, std::string notSpeakTime, Tail muteReason) { std::string muteReasonStr{ muteReason }; + if (notSpeakTime.empty()) + { + return false; + } + + if (Acore::StringTo(notSpeakTime).value_or(0) < 0) + { + handler->SendSysMessage(LANG_BAD_VALUE); + handler->SetSentErrorMessage(true); + return false; + } + if (muteReason.empty()) { muteReasonStr = handler->GetAcoreString(LANG_NO_REASON); @@ -2412,6 +2424,19 @@ public: } LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_MUTE_TIME); + int32 muteDuration = TimeStringToSecs(notSpeakTime); + if (muteDuration <= 0) + { + muteDuration = Acore::StringTo(notSpeakTime).value_or(0); + } + + if (muteDuration <= 0) + { + handler->SendSysMessage(LANG_BAD_VALUE); + handler->SetSentErrorMessage(true); + return false; + } + std::string muteBy = ""; if (handler->GetSession()) { @@ -2425,22 +2450,22 @@ public: if (target) { // Target is online, mute will be in effect right away. - int64 muteTime = GameTime::GetGameTime().count() + notSpeakTime * MINUTE; + int64 muteTime = GameTime::GetGameTime().count() + muteDuration; target->GetSession()->m_muteTime = muteTime; stmt->SetData(0, muteTime); std::string nameLink = handler->playerLink(player->GetName()); if (sWorld->getBoolConfig(CONFIG_SHOW_MUTE_IN_WORLD)) { - sWorld->SendWorldText(LANG_COMMAND_MUTEMESSAGE_WORLD, muteBy.c_str(), nameLink.c_str(), notSpeakTime, muteReasonStr.c_str()); + sWorld->SendWorldText(LANG_COMMAND_MUTEMESSAGE_WORLD, muteBy.c_str(), nameLink.c_str(), secsToTimeString(muteDuration, true).c_str(), muteReasonStr.c_str()); } - ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOUR_CHAT_DISABLED, notSpeakTime, muteBy.c_str(), muteReasonStr.c_str()); + ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOUR_CHAT_DISABLED, secsToTimeString(muteDuration, true).c_str(), muteBy.c_str(), muteReasonStr.c_str()); } else { // Target is offline, mute will be in effect starting from the next login. - stmt->SetData(0, -int32(notSpeakTime * MINUTE)); + stmt->SetData(0, -int32(muteDuration)); } stmt->SetData(1, muteReasonStr); @@ -2450,7 +2475,7 @@ public: stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_ACCOUNT_MUTE); stmt->SetData(0, accountId); - stmt->SetData(1, notSpeakTime); + stmt->SetData(1, muteDuration / MINUTE); stmt->SetData(2, muteBy); stmt->SetData(3, muteReasonStr); LoginDatabase.Execute(stmt); @@ -2459,7 +2484,7 @@ public: if (sWorld->getBoolConfig(CONFIG_SHOW_MUTE_IN_WORLD) && !target) { - sWorld->SendWorldText(LANG_COMMAND_MUTEMESSAGE_WORLD, muteBy.c_str(), nameLink.c_str(), notSpeakTime, muteReasonStr.c_str()); + sWorld->SendWorldText(LANG_COMMAND_MUTEMESSAGE_WORLD, muteBy.c_str(), nameLink.c_str(), secsToTimeString(muteDuration, true).c_str(), muteReasonStr.c_str()); } else { @@ -2469,7 +2494,7 @@ public: for (HashMapHolder::MapType::const_iterator itr = m.begin(); itr != m.end(); ++itr) if (itr->second->GetSession()->GetSecurity()) ChatHandler(itr->second->GetSession()).PSendSysMessage(target ? LANG_YOU_DISABLE_CHAT : LANG_COMMAND_DISABLE_CHAT_DELAYED, - (handler->GetSession() ? handler->GetSession()->GetPlayerName().c_str() : handler->GetAcoreString(LANG_CONSOLE)), nameLink.c_str(), notSpeakTime, muteReasonStr.c_str()); + (handler->GetSession() ? handler->GetSession()->GetPlayerName().c_str() : handler->GetAcoreString(LANG_CONSOLE)), nameLink.c_str(), secsToTimeString(muteDuration, true).c_str(), muteReasonStr.c_str()); } return true; diff --git a/src/server/scripts/Commands/cs_npc.cpp b/src/server/scripts/Commands/cs_npc.cpp index 2490c1d40..d722a5478 100644 --- a/src/server/scripts/Commands/cs_npc.cpp +++ b/src/server/scripts/Commands/cs_npc.cpp @@ -987,19 +987,44 @@ public: } //spawn time handling - static bool HandleNpcSetSpawnTimeCommand(ChatHandler* handler, uint32 spawnTime) + static bool HandleNpcSetSpawnTimeCommand(ChatHandler* handler, std::string spawnTimeStr) { + if (spawnTimeStr.empty()) + { + return false; + } + + if (Acore::StringTo(spawnTimeStr).value_or(0) < 0) + { + handler->SendSysMessage(LANG_BAD_VALUE); + handler->SetSentErrorMessage(true); + return false; + } + Creature* creature = handler->getSelectedCreature(); if (!creature) return false; + int32 spawnTime = TimeStringToSecs(spawnTimeStr); + if (spawnTime <= 0) + { + spawnTime = Acore::StringTo(spawnTimeStr).value_or(0); + } + + if (spawnTime <= 0) + { + handler->SendSysMessage(LANG_BAD_VALUE); + handler->SetSentErrorMessage(true); + return false; + } + WorldDatabasePreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_CREATURE_SPAWN_TIME_SECS); stmt->SetData(0, spawnTime); stmt->SetData(1, creature->GetSpawnId()); WorldDatabase.Execute(stmt); creature->SetRespawnDelay(spawnTime); - handler->PSendSysMessage(LANG_COMMAND_SPAWNTIME, spawnTime); + handler->PSendSysMessage(LANG_COMMAND_SPAWNTIME, secsToTimeString(spawnTime, true).c_str()); return true; } diff --git a/src/server/scripts/Commands/cs_server.cpp b/src/server/scripts/Commands/cs_server.cpp index 2e0c47200..2e60148a2 100644 --- a/src/server/scripts/Commands/cs_server.cpp +++ b/src/server/scripts/Commands/cs_server.cpp @@ -269,11 +269,23 @@ public: return true; } - static bool HandleServerShutDownCommand(ChatHandler* /*handler*/, int32 time, Optional exitCode, Tail reason) + static bool HandleServerShutDownCommand(ChatHandler* handler, std::string time, Optional exitCode, Tail reason) { std::wstring wReason = std::wstring(); std::string strReason = std::string(); + if (time.empty()) + { + return false; + } + + if (Acore::StringTo(time).value_or(0) < 0) + { + handler->SendSysMessage(LANG_BAD_VALUE); + handler->SetSentErrorMessage(true); + return false; + } + if (!reason.empty()) { if (!Utf8toWStr(reason, wReason)) @@ -287,23 +299,48 @@ public: } } + int32 delay = TimeStringToSecs(time); + if (delay <= 0) + { + delay = Acore::StringTo(time).value_or(0); + } + + if (delay <= 0) + { + handler->SendSysMessage(LANG_BAD_VALUE); + handler->SetSentErrorMessage(true); + return false; + } + if (exitCode && *exitCode >= 0 && *exitCode <= 125) { - sWorld->ShutdownServ(time, 0, *exitCode); + sWorld->ShutdownServ(delay, 0, *exitCode); } else { - sWorld->ShutdownServ(time, 0, SHUTDOWN_EXIT_CODE, strReason); + sWorld->ShutdownServ(delay, 0, SHUTDOWN_EXIT_CODE, strReason); } return true; } - static bool HandleServerRestartCommand(ChatHandler* /*handler*/, int32 time, Optional exitCode, Tail reason) + static bool HandleServerRestartCommand(ChatHandler* handler, std::string time, Optional exitCode, Tail reason) { std::wstring wReason = std::wstring(); std::string strReason = std::string(); + if (time.empty()) + { + return false; + } + + if (Acore::StringTo(time).value_or(0) < 0) + { + handler->SendSysMessage(LANG_BAD_VALUE); + handler->SetSentErrorMessage(true); + return false; + } + if (!reason.empty()) { if (!Utf8toWStr(reason, wReason)) @@ -317,23 +354,48 @@ public: } } + int32 delay = TimeStringToSecs(time); + if (delay <= 0) + { + delay = Acore::StringTo(time).value_or(0); + } + + if (delay <= 0) + { + handler->SendSysMessage(LANG_BAD_VALUE); + handler->SetSentErrorMessage(true); + return false; + } + if (exitCode && *exitCode >= 0 && *exitCode <= 125) { - sWorld->ShutdownServ(time, SHUTDOWN_MASK_RESTART, *exitCode); + sWorld->ShutdownServ(delay, SHUTDOWN_MASK_RESTART, *exitCode); } else { - sWorld->ShutdownServ(time, SHUTDOWN_MASK_RESTART, RESTART_EXIT_CODE, strReason); + sWorld->ShutdownServ(delay, SHUTDOWN_MASK_RESTART, RESTART_EXIT_CODE, strReason); } return true; } - static bool HandleServerIdleRestartCommand(ChatHandler* /*handler*/, int32 time, Optional exitCode, Tail reason) + static bool HandleServerIdleRestartCommand(ChatHandler* handler, std::string time, Optional exitCode, Tail reason) { std::wstring wReason = std::wstring(); std::string strReason = std::string(); + if (time.empty()) + { + return false; + } + + if (Acore::StringTo(time).value_or(0) < 0) + { + handler->SendSysMessage(LANG_BAD_VALUE); + handler->SetSentErrorMessage(true); + return false; + } + if (!reason.empty()) { if (!Utf8toWStr(reason, wReason)) @@ -347,23 +409,48 @@ public: } } + int32 delay = TimeStringToSecs(time); + if (delay <= 0) + { + delay = Acore::StringTo(time).value_or(0); + } + + if (delay <= 0) + { + handler->SendSysMessage(LANG_BAD_VALUE); + handler->SetSentErrorMessage(true); + return false; + } + if (exitCode && *exitCode >= 0 && *exitCode <= 125) { - sWorld->ShutdownServ(time, SHUTDOWN_MASK_RESTART | SHUTDOWN_MASK_IDLE, *exitCode); + sWorld->ShutdownServ(delay, SHUTDOWN_MASK_RESTART | SHUTDOWN_MASK_IDLE, *exitCode); } else { - sWorld->ShutdownServ(time, SHUTDOWN_MASK_RESTART | SHUTDOWN_MASK_IDLE, RESTART_EXIT_CODE, strReason); + sWorld->ShutdownServ(delay, SHUTDOWN_MASK_RESTART | SHUTDOWN_MASK_IDLE, RESTART_EXIT_CODE, strReason); } return true; } - static bool HandleServerIdleShutDownCommand(ChatHandler* /*handler*/, int32 time, Optional exitCode, Tail reason) + static bool HandleServerIdleShutDownCommand(ChatHandler* handler, std::string time, Optional exitCode, Tail reason) { std::wstring wReason = std::wstring(); std::string strReason = std::string(); + if (time.empty()) + { + return false; + } + + if (Acore::StringTo(time).value_or(0) < 0) + { + handler->SendSysMessage(LANG_BAD_VALUE); + handler->SetSentErrorMessage(true); + return false; + } + if (!reason.empty()) { if (!Utf8toWStr(reason, wReason)) @@ -377,13 +464,26 @@ public: } } + int32 delay = TimeStringToSecs(time); + if (delay <= 0) + { + delay = Acore::StringTo(time).value_or(0); + } + + if (delay <= 0) + { + handler->SendSysMessage(LANG_BAD_VALUE); + handler->SetSentErrorMessage(true); + return false; + } + if (exitCode && *exitCode >= 0 && *exitCode <= 125) { - sWorld->ShutdownServ(time, SHUTDOWN_MASK_IDLE, *exitCode); + sWorld->ShutdownServ(delay, SHUTDOWN_MASK_IDLE, *exitCode); } else { - sWorld->ShutdownServ(time, SHUTDOWN_MASK_IDLE, SHUTDOWN_EXIT_CODE, strReason); + sWorld->ShutdownServ(delay, SHUTDOWN_MASK_IDLE, SHUTDOWN_EXIT_CODE, strReason); } return true; From 783060f94918163ff9a7bf07329b92dd24355ba3 Mon Sep 17 00:00:00 2001 From: AzerothCoreBot Date: Mon, 13 Jun 2022 17:07:46 +0000 Subject: [PATCH 16/18] chore(DB): import pending files Referenced commit(s): 3c434cee12f0cab55071a2580ced81de53233f9d --- .../rev_1654372051309044400.sql => db_world/2022_06_13_03.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1654372051309044400.sql => db_world/2022_06_13_03.sql} (98%) diff --git a/data/sql/updates/pending_db_world/rev_1654372051309044400.sql b/data/sql/updates/db_world/2022_06_13_03.sql similarity index 98% rename from data/sql/updates/pending_db_world/rev_1654372051309044400.sql rename to data/sql/updates/db_world/2022_06_13_03.sql index e19b8912d..9f32541bb 100644 --- a/data/sql/updates/pending_db_world/rev_1654372051309044400.sql +++ b/data/sql/updates/db_world/2022_06_13_03.sql @@ -1,3 +1,4 @@ +-- DB update 2022_06_13_02 -> 2022_06_13_03 -- DELETE FROM `acore_string` WHERE `entry` IN (283,298,300,301,11003); INSERT INTO `acore_string` (`entry`, `content_default`, `locale_koKR`, `locale_frFR`, `locale_deDE`, `locale_zhCN`, `locale_zhTW`, `locale_esES`, `locale_esMX`, `locale_ruRU`) VALUES From 077068802538094596f13390746b9d3ab1da262d Mon Sep 17 00:00:00 2001 From: temperrr Date: Mon, 13 Jun 2022 19:41:59 +0200 Subject: [PATCH 17/18] fix(DB/factionchange_items): Adding missing 58 pvp faction change items (#12049) * fix(DB/factionchange_items): Adding missing 58 pvp faction change items * refactor --- .../pvp58factionchangeitems.sql | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 data/sql/updates/pending_db_world/pvp58factionchangeitems.sql diff --git a/data/sql/updates/pending_db_world/pvp58factionchangeitems.sql b/data/sql/updates/pending_db_world/pvp58factionchangeitems.sql new file mode 100644 index 000000000..6d808791c --- /dev/null +++ b/data/sql/updates/pending_db_world/pvp58factionchangeitems.sql @@ -0,0 +1,44 @@ +DELETE FROM `player_factionchange_items` WHERE `alliance_id` IN (16393, 16397, 16423, 16422, 16424, 16421, 16401, 16403, 16425, 16426, 16427, 16428, 16369, 16391, 16413, 16414, 16415, 16416, 17594, 17596, 17598, 17599, 17600, 17601) OR `horde_id` IN (16498, 16499, 16505, 16506, 16507, 16508, 17570, 17571, 17572, 17573, 17576, 17577, 16509, 16510, 16513, 16514, 16515, 16516, 16494, 16496, 16501, 16503, 16504); +INSERT INTO `player_factionchange_items` (`alliance_id`, `alliance_comment`, `horde_id`, `horde_comment`) VALUES +(16393, 'Knight-Lieutenant\'s Dragonhide Footwraps', 16494, 'Blood Guard\'s Dragonhide Boots'), +(16397, 'Knight-Lieutenant\'s Dragonhide Gloves', 16496, 'Blood Guard\'s Dragonhide Gauntlets'), +(16423, 'Lieutenant Commander\'s Dragonhide Epaulets', 16501, 'Champion\'s Dragonhide Spaulders'), +(16422, 'Knight-Captain\'s Dragonhide Leggings', 16502, 'Legionnaire\'s Dragonhide Trousers'), +(16424, 'Lieutenant Commander\'s Dragonhide Shroud', 16503, 'Champion\'s Dragonhide Helm'), +(16421, 'Knight-Captain\'s Dragonhide Tunic', 16504, 'Legionnaire\'s Dragonhide Breastplate'), +(16401, 'Knight-Lieutenant\'s Chain Boots', 16531, 'Blood Guard\'s Chain Boots'), +(16403, 'Knight-Lieutenant\'s Chain Gauntlets', 16530, 'Blood Guard\'s Chain Gauntlets'), +(16425, 'Knight-Captain\'s Chain Hauberk', 16525, 'Legionnaire\'s Chain Breastplate'), +(16426, 'Knight-Captain\'s Chain Leggings', 16527, 'Legionnaire\'s Chain Leggings'), +(16427, 'Lieutenant Commander\'s Chain Pauldrons', 16528, 'Champion\'s Chain Pauldrons'), +(16428, 'Lieutenant Commander\'s Chain Helmet', 16526, 'Champion\'s Chain Headguard'), +(16369, 'Knight-Lieutenant\'s Silk Boots', 16485, 'Blood Guard\'s Silk Footwraps'), +(16391, 'Knight-Lieutenant\'s Silk Gloves', 16487, 'Blood Guard\'s Silk Gloves'), +(16413, 'Knight-Captain\'s Silk Raiment', 16491, 'Legionnaire\'s Silk Robes'), +(16414, 'Knight-Captain\'s Silk Leggings', 16490, 'Legionnaire\'s Silk Pants'), +(16415, 'Lieutenant Commander\'s Silk Spaulders', 16492, 'Champion\'s Silk Shoulderpads'), +(16416, 'Lieutenant Commander\'s Crown', 16489, 'Champion\'s Silk Hood'), +(16392, 'Knight-Lieutenant\'s Leather Boots', 16498, 'Blood Guard\'s Leather Treads'), +(16396, 'Knight-Lieutenant\'s Leather Gauntlets', 16499, 'Blood Guard\'s Leather Vices'), +(16417, 'Knight-Captain\'s Leather Armor', 16505, 'Legionnaire\'s Leather Hauberk'), +(16418, 'Lieutenant Commander\'s Leather Veil', 16506, 'Champion\'s Leather Headguard'), +(16419, 'Knight-Captain\'s Leather Legguards', 16508, 'Legionnaire\'s Leather Leggings'), +(16420, 'Lieutenant Commander\'s Leather Spaulders', 16507, 'Champion\'s Leather Mantle'), +(17594, 'Knight-Lieutenant\'s Satin Boots', 17616, 'Blood Guard\'s Satin Boots'), +(17596, 'Knight-Lieutenant\'s Satin Gloves', 17617, 'Blood Guard\'s Satin Gloves'), +(17598, 'Lieutenant Commander\'s Diadem', 17610, 'Champion\'s Satin Cowl'), +(17599, 'Knight-Captain\'s Satin Leggings', 17611, 'Legionnaire\'s Satin Trousers'), +(17600, 'Knight-Captain\'s Satin Robes', 17612, 'Legionnaire\'s Satin Vestments'), +(17601, 'Lieutenant Commander\'s Satin Amice', 17613, 'Champion\'s Satin Shoulderpads'), +(17562, 'Knight-Lieutenant\'s Dreadweave Boots', 17576, 'Blood Guard\'s Dreadweave Boots'), +(17564, 'Knight-Lieutenant\'s Dreadweave Gloves', 17577, 'Blood Guard\'s Dreadweave Gloves'), +(17566, 'Lieutenant Commander\'s Headguard', 17570, 'Champion\'s Dreadweave Hood'), +(17567, 'Knight-Captain\'s Dreadweave Leggings', 17571, 'Legionnaire\'s Dreadweave Leggings'), +(17568, 'Knight-Captain\'s Dreadweave Robe', 17572, 'Legionnaire\'s Dreadweave Robe'), +(17569, 'Lieutenant Commander\'s Dreadweave Mantle', 17573, 'Champion\'s Dreadweave Shoulders'), +(16405, 'Knight-Lieutenant\'s Plate Boots', 16509, 'Blood Guard\'s Plate Boots'), +(16406, 'Knight-Lieutenant\'s Plate Gauntlets', 16510, 'Blood Guard\'s Plate Gloves'), +(16429, 'Lieutenant Commander\'s Plate Helm',16514, 'Champion\'s Plate Headguard'), +(16430, 'Knight-Captain\'s Plate Chestguard', 16513, 'Legionnaire\'s Plate Armor'), +(16431, 'Knight-Captain\'s Plate Leggings', 16515, 'Legionnaire\'s Plate Legguards'), +(16432, 'Lieutenant Commander\'s Plate Pauldrons', 16516, 'Champion\'s Plate Pauldrons'); From bf04f280d21494572552d3fd8f3af0fa5ff85f76 Mon Sep 17 00:00:00 2001 From: AzerothCoreBot Date: Mon, 13 Jun 2022 17:44:06 +0000 Subject: [PATCH 18/18] chore(DB): import pending files Referenced commit(s): 077068802538094596f13390746b9d3ab1da262d --- .../pvp58factionchangeitems.sql => db_world/2022_06_13_04.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/pvp58factionchangeitems.sql => db_world/2022_06_13_04.sql} (98%) diff --git a/data/sql/updates/pending_db_world/pvp58factionchangeitems.sql b/data/sql/updates/db_world/2022_06_13_04.sql similarity index 98% rename from data/sql/updates/pending_db_world/pvp58factionchangeitems.sql rename to data/sql/updates/db_world/2022_06_13_04.sql index 6d808791c..72d90fe66 100644 --- a/data/sql/updates/pending_db_world/pvp58factionchangeitems.sql +++ b/data/sql/updates/db_world/2022_06_13_04.sql @@ -1,3 +1,4 @@ +-- DB update 2022_06_13_03 -> 2022_06_13_04 DELETE FROM `player_factionchange_items` WHERE `alliance_id` IN (16393, 16397, 16423, 16422, 16424, 16421, 16401, 16403, 16425, 16426, 16427, 16428, 16369, 16391, 16413, 16414, 16415, 16416, 17594, 17596, 17598, 17599, 17600, 17601) OR `horde_id` IN (16498, 16499, 16505, 16506, 16507, 16508, 17570, 17571, 17572, 17573, 17576, 17577, 16509, 16510, 16513, 16514, 16515, 16516, 16494, 16496, 16501, 16503, 16504); INSERT INTO `player_factionchange_items` (`alliance_id`, `alliance_comment`, `horde_id`, `horde_comment`) VALUES (16393, 'Knight-Lieutenant\'s Dragonhide Footwraps', 16494, 'Blood Guard\'s Dragonhide Boots'),