From 972bcc31132147614f0c5a35aa55770bc217236e Mon Sep 17 00:00:00 2001 From: Malcrom Date: Mon, 19 Sep 2022 16:35:34 -0300 Subject: [PATCH 01/18] Feature(Smart Scripts/SMART_EVENT_RANGE): Proper fix to prevent Initial timer (#13059) * Feature(Smart Scripts/SMART_EVENT_RANGE): Proper fix to prevent Initial timer * Update SmartScript.cpp --- .../game/AI/SmartScripts/SmartScript.cpp | 23 ++++++++++++++----- .../game/AI/SmartScripts/SmartScriptMgr.cpp | 18 ++++++++++++--- .../game/AI/SmartScripts/SmartScriptMgr.h | 10 +++++++- 3 files changed, 41 insertions(+), 10 deletions(-) diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index 69da11bac..0f1e187fb 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -3428,15 +3428,19 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui if (!me || !me->IsEngaged() || !me->GetVictim()) return; - if (me->IsInRange(me->GetVictim(), (float)e.event.minMaxRepeat.min, (float)e.event.minMaxRepeat.max)) - ProcessTimedAction(e, e.event.minMaxRepeat.repeatMin, e.event.minMaxRepeat.repeatMax, me->GetVictim()); - else + if (me->IsInRange(me->GetVictim(), (float)e.event.rangeRepeat.minRange, (float)e.event.rangeRepeat.maxRange)) { - if (!e.event.minMaxRepeat.controller) - RecalcTimer(e, 500, 500); // xinef: make it predictable "Malcrom: This seems to be done to standardize min, max start rather than using the range values for the timer." + if (e.event.rangeRepeat.onlyFireOnRepeat == 2) + { + e.event.rangeRepeat.onlyFireOnRepeat = 1; + RecalcTimer(e, e.event.rangeRepeat.repeatMin, e.event.rangeRepeat.repeatMax); + } else - RecalcTimer(e, e.event.minMaxRepeat.repeatMin, e.event.minMaxRepeat.repeatMax); // Malcrom: if param5 value is greater than 0 first action will not happen until after repeat timer fires. + ProcessTimedAction(e, e.event.rangeRepeat.repeatMin, e.event.rangeRepeat.repeatMax, me->GetVictim()); } + else + RecalcTimer(e, 500, 500); // make it predictable + break; } case SMART_EVENT_VICTIM_CASTING: @@ -4000,6 +4004,13 @@ void SmartScript::InitTimer(SmartScriptHolder& e) switch (e.GetEventType()) { //set only events which have initial timers + case SMART_EVENT_RANGE: + // If onlyFireOnRepeat is true set to 2 before entering combat. Will be set back to 1 after entering combat to ignore initial firing. + if (e.event.rangeRepeat.onlyFireOnRepeat == 1) + e.event.rangeRepeat.onlyFireOnRepeat = 2; + // make it predictable + RecalcTimer(e, 500, 500); + break; case SMART_EVENT_NEAR_PLAYERS: case SMART_EVENT_NEAR_PLAYERS_NEGATION: RecalcTimer(e, e.event.nearPlayer.firstTimer, e.event.nearPlayer.firstTimer); diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp index 80c2eb221..3da4072b2 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp @@ -260,7 +260,6 @@ void SmartAIMgr::LoadSmartAIFromDB() case SMART_EVENT_TARGET_HEALTH_PCT: case SMART_EVENT_MANA_PCT: case SMART_EVENT_TARGET_MANA_PCT: - case SMART_EVENT_RANGE: case SMART_EVENT_FRIENDLY_HEALTH: case SMART_EVENT_FRIENDLY_HEALTH_PCT: case SMART_EVENT_FRIENDLY_MISSING_BUFF: @@ -269,6 +268,13 @@ void SmartAIMgr::LoadSmartAIFromDB() if (temp.event.minMaxRepeat.repeatMin == 0 && temp.event.minMaxRepeat.repeatMax == 0) temp.event.event_flags |= SMART_EVENT_FLAG_NOT_REPEATABLE; break; + case SMART_EVENT_RANGE: + if (temp.event.rangeRepeat.repeatMin == 0 && temp.event.rangeRepeat.repeatMax == 0) + temp.event.event_flags |= SMART_EVENT_FLAG_NOT_REPEATABLE; + // Will only work properly if value is 0 or 1 + if (temp.event.rangeRepeat.onlyFireOnRepeat > 1) + temp.event.rangeRepeat.onlyFireOnRepeat = 1; + break; case SMART_EVENT_VICTIM_CASTING: case SMART_EVENT_IS_BEHIND_TARGET: if (temp.event.minMaxRepeat.min == 0 && temp.event.minMaxRepeat.max == 0) @@ -472,7 +478,7 @@ bool SmartAIMgr::CheckUnusedEventParams(SmartScriptHolder const& e) case SMART_EVENT_DEATH: return NO_PARAMS; case SMART_EVENT_EVADE: return NO_PARAMS; case SMART_EVENT_SPELLHIT: return sizeof(SmartEvent::spellHit); - case SMART_EVENT_RANGE: return sizeof(SmartEvent::minMaxRepeat); + case SMART_EVENT_RANGE: return sizeof(SmartEvent::rangeRepeat); case SMART_EVENT_OOC_LOS: return sizeof(SmartEvent::los); case SMART_EVENT_RESPAWN: return sizeof(SmartEvent::respawn); case SMART_EVENT_TARGET_HEALTH_PCT: return sizeof(SmartEvent::minMaxRepeat); @@ -911,7 +917,6 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) case SMART_EVENT_MANA_PCT: case SMART_EVENT_TARGET_HEALTH_PCT: case SMART_EVENT_TARGET_MANA_PCT: - case SMART_EVENT_RANGE: case SMART_EVENT_DAMAGED: case SMART_EVENT_DAMAGED_TARGET: case SMART_EVENT_RECEIVE_HEAL: @@ -921,6 +926,13 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) if (!IsMinMaxValid(e, e.event.minMaxRepeat.repeatMin, e.event.minMaxRepeat.repeatMax)) return false; break; + case SMART_EVENT_RANGE: + if (!IsMinMaxValid(e, e.event.rangeRepeat.minRange, e.event.rangeRepeat.maxRange)) + return false; + + if (!IsMinMaxValid(e, e.event.rangeRepeat.repeatMin, e.event.rangeRepeat.repeatMax)) + return false; + break; case SMART_EVENT_SPELLHIT: case SMART_EVENT_SPELLHIT_TARGET: if (e.event.spellHit.spell) diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h index 74e9c9199..e7a1bcd32 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h @@ -221,9 +221,17 @@ struct SmartEvent uint32 max; uint32 repeatMin; uint32 repeatMax; - uint32 controller; } minMaxRepeat; + struct + { + uint32 minRange; + uint32 maxRange; + uint32 repeatMin; + uint32 repeatMax; + uint32 onlyFireOnRepeat; + } rangeRepeat; + struct { uint32 cooldownMin; From a82c11e75130be8d3f4d07bb84f522c63d243948 Mon Sep 17 00:00:00 2001 From: Benjamin Jackson <38561765+heyitsbench@users.noreply.github.com> Date: Mon, 19 Sep 2022 20:05:01 -0400 Subject: [PATCH 02/18] fix(Core/DBCLoader): Add handler for possibly unused DBC format data type (#13045) --- src/server/shared/DataStores/DBCDatabaseLoader.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/server/shared/DataStores/DBCDatabaseLoader.cpp b/src/server/shared/DataStores/DBCDatabaseLoader.cpp index 47016cf2d..05fb5e1c2 100644 --- a/src/server/shared/DataStores/DBCDatabaseLoader.cpp +++ b/src/server/shared/DataStores/DBCDatabaseLoader.cpp @@ -104,9 +104,10 @@ char* DBCDatabaseLoader::Load(uint32& records, char**& indexTable) break; case FT_SORT: case FT_NA: + case FT_NA_BYTE: break; default: - ASSERT(false, "Unsupported data type '%c' in table '{}'", *dbcFormat, _sqlTableName); + ASSERT(false, "Unsupported data type '{}' in table '{}'", *dbcFormat, _sqlTableName); return nullptr; } From 2ded17464ad25d03cc208a7f51c396a4a8129cef Mon Sep 17 00:00:00 2001 From: UltraNix <80540499+UltraNix@users.noreply.github.com> Date: Tue, 20 Sep 2022 02:08:19 +0200 Subject: [PATCH 03/18] fix(Core): Crashfix on vehicle uninstall. (#13036) --- src/server/game/Entities/Vehicle/Vehicle.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/server/game/Entities/Vehicle/Vehicle.cpp b/src/server/game/Entities/Vehicle/Vehicle.cpp index 2ee067675..7256c0a6e 100644 --- a/src/server/game/Entities/Vehicle/Vehicle.cpp +++ b/src/server/game/Entities/Vehicle/Vehicle.cpp @@ -109,8 +109,10 @@ void Vehicle::Uninstall() LOG_DEBUG("vehicles", "Vehicle::Uninstall {}", _me->GetGUID().ToString()); RemoveAllPassengers(); - if (GetBase()->GetTypeId() == TYPEID_UNIT) + if (_me && _me->GetTypeId() == TYPEID_UNIT) + { sScriptMgr->OnUninstall(this); + } } void Vehicle::Reset(bool evading /*= false*/) From d5f839a4be933f944c0df46c233066e37966c263 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=A9=E9=B9=BF?= Date: Tue, 20 Sep 2022 09:00:10 +0800 Subject: [PATCH 04/18] fix(Core): SMART_EVENT_RANGE (#13064) * Update SmartScriptMgr.h * Update SmartScript.cpp --- src/server/game/AI/SmartScripts/SmartScript.cpp | 8 ++++---- src/server/game/AI/SmartScripts/SmartScriptMgr.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index 0f1e187fb..4fe9984c7 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -4302,10 +4302,10 @@ void SmartScript::OnInitialize(WorldObject* obj, AreaTrigger const* at) InitTimer((*i));//calculate timers for first time use if (i->GetEventType() == SMART_EVENT_RANGE && i->GetActionType() == SMART_ACTION_ALLOW_COMBAT_MOVEMENT) { - if (i->action.combatMove.move == 1 && i->event.minMaxRepeat.min > minEnableDist) - minEnableDist = i->event.minMaxRepeat.min; - else if (i->action.combatMove.move == 0 && (i->event.minMaxRepeat.max < maxDisableDist || maxDisableDist == 0)) - maxDisableDist = i->event.minMaxRepeat.max; + if (i->action.combatMove.move == 1 && i->event.rangeRepeat.minRange > minEnableDist) + minEnableDist = i->event.rangeRepeat.minRange; + else if (i->action.combatMove.move == 0 && (i->event.rangeRepeat.maxRange < maxDisableDist || maxDisableDist == 0)) + maxDisableDist = i->event.rangeRepeat.maxRange; } // Xinef: if smartcast combat move flag is present diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h index e7a1bcd32..4bd38286b 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h @@ -124,7 +124,7 @@ enum SMART_EVENT SMART_EVENT_DEATH = 6, // NONE SMART_EVENT_EVADE = 7, // NONE SMART_EVENT_SPELLHIT = 8, // SpellID, School, CooldownMin, CooldownMax - SMART_EVENT_RANGE = 9, // MinDist, MaxDist, RepeatMin, RepeatMax + SMART_EVENT_RANGE = 9, // minRange, maxRange, repeatMin, repeatMax, onlyFireOnRepeat SMART_EVENT_OOC_LOS = 10, // HostilityMode, MaxRnage, CooldownMin, CooldownMax, PlayerOnly SMART_EVENT_RESPAWN = 11, // type, MapId, ZoneId SMART_EVENT_TARGET_HEALTH_PCT = 12, // HPMin%, HPMax%, RepeatMin, RepeatMax From fd08f6150f0bacfcc3ea5e999e8b22cb20ba7ccd Mon Sep 17 00:00:00 2001 From: ZhengPeiRu21 <98835050+ZhengPeiRu21@users.noreply.github.com> Date: Tue, 20 Sep 2022 12:07:30 -0600 Subject: [PATCH 05/18] fix(Core): Hunter Readiness crash fix (#12987) Co-authored-by: Angelo Venturini --- src/server/scripts/Spells/spell_hunter.cpp | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/server/scripts/Spells/spell_hunter.cpp b/src/server/scripts/Spells/spell_hunter.cpp index 759141d94..bead12996 100644 --- a/src/server/scripts/Spells/spell_hunter.cpp +++ b/src/server/scripts/Spells/spell_hunter.cpp @@ -655,13 +655,12 @@ class spell_hun_readiness : public SpellScript SpellCooldowns& cooldowns = caster->GetSpellCooldownMap(); - SpellCooldowns::iterator itr, next; - for (itr = cooldowns.begin(); itr != cooldowns.end(); itr = next) - { - next = itr; - ++next; + std::set> spellsToRemove; + std::set categoriesToRemove; - SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itr->first); + for (const auto& [spellId, cooldown] : cooldowns) + { + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId); if (spellInfo && spellInfo->SpellFamilyName == SPELLFAMILY_HUNTER && spellInfo->Id != SPELL_HUNTER_READINESS @@ -669,12 +668,18 @@ class spell_hun_readiness : public SpellScript && spellInfo->Id != SPELL_DRAENEI_GIFT_OF_THE_NAARU) { if (spellInfo->RecoveryTime > 0) - caster->RemoveSpellCooldown(spellInfo->Id, itr->second.needSendToClient); + spellsToRemove.insert(std::make_pair(spellInfo->Id, cooldown.needSendToClient)); if (spellInfo->CategoryRecoveryTime > 0) - caster->RemoveCategoryCooldown(spellInfo->GetCategory()); + categoriesToRemove.insert(spellInfo->GetCategory()); } } + + // we can't remove spell cooldowns while iterating. + for (const auto& [spellId, sendToClient] : spellsToRemove) + caster->RemoveSpellCooldown(spellId, sendToClient); + for (const auto& category : categoriesToRemove) + caster->RemoveCategoryCooldown(category); } void Register() override From 6a357da28c715ca9c3fdc1bffdf48bf1ef845024 Mon Sep 17 00:00:00 2001 From: Benjamin Jackson <38561765+heyitsbench@users.noreply.github.com> Date: Wed, 21 Sep 2022 07:32:33 -0400 Subject: [PATCH 06/18] fix(Core/Player): Give Death Knight's twenty silver on character creation (#12974) * Make sacrifices to workflow god Best note ever ^^ --- src/server/apps/worldserver/worldserver.conf.dist | 8 ++++++++ src/server/game/Entities/Player/Player.cpp | 4 +++- src/server/game/World/IWorld.h | 1 + src/server/game/World/World.cpp | 7 +++++++ 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/server/apps/worldserver/worldserver.conf.dist b/src/server/apps/worldserver/worldserver.conf.dist index 711c23287..646d7706b 100644 --- a/src/server/apps/worldserver/worldserver.conf.dist +++ b/src/server/apps/worldserver/worldserver.conf.dist @@ -868,6 +868,14 @@ StartHeroicPlayerLevel = 55 StartPlayerMoney = 0 +# +# StartHeroicPlayerMoney +# Description: Amount of money (in Copper) that heroic class characters have after creation. +# Default: 2000 +# 2000 - (20 Silver) + +StartHeroicPlayerMoney = 2000 + # # MaxHonorPoints # Description: Maximum honor points a character can have. diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index d1fb0338e..2c473e09c 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -569,7 +569,9 @@ bool Player::Create(ObjectGuid::LowType guidlow, CharacterCreateInfo* createInfo InitRunes(); - SetUInt32Value(PLAYER_FIELD_COINAGE, sWorld->getIntConfig(CONFIG_START_PLAYER_MONEY)); + SetUInt32Value(PLAYER_FIELD_COINAGE, getClass() != CLASS_DEATH_KNIGHT + ? sWorld->getIntConfig(CONFIG_START_PLAYER_MONEY) + : sWorld->getIntConfig(CONFIG_START_HEROIC_PLAYER_MONEY)); SetHonorPoints(sWorld->getIntConfig(CONFIG_START_HONOR_POINTS)); SetArenaPoints(sWorld->getIntConfig(CONFIG_START_ARENA_POINTS)); diff --git a/src/server/game/World/IWorld.h b/src/server/game/World/IWorld.h index 48da90242..ec6a880f9 100644 --- a/src/server/game/World/IWorld.h +++ b/src/server/game/World/IWorld.h @@ -231,6 +231,7 @@ enum WorldIntConfigs CONFIG_START_PLAYER_LEVEL, CONFIG_START_HEROIC_PLAYER_LEVEL, CONFIG_START_PLAYER_MONEY, + CONFIG_START_HEROIC_PLAYER_MONEY, CONFIG_MAX_HONOR_POINTS, CONFIG_MAX_HONOR_POINTS_MONEY_PER_POINT, CONFIG_START_HONOR_POINTS, diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 9763ea44a..318af1ab6 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -848,6 +848,13 @@ void World::LoadConfigSettings(bool reload) m_int_configs[CONFIG_START_PLAYER_MONEY] = 0; } + m_int_configs[CONFIG_START_HEROIC_PLAYER_MONEY] = sConfigMgr->GetOption("StartHeroicPlayerMoney", 2000); + if (int32(m_int_configs[CONFIG_START_HEROIC_PLAYER_MONEY]) < 0 || int32(m_int_configs[CONFIG_START_HEROIC_PLAYER_MONEY]) > MAX_MONEY_AMOUNT) + { + LOG_ERROR("server.loading", "StartHeroicPlayerMoney ({}) must be in range 0..{}. Set to {}.", m_int_configs[CONFIG_START_HEROIC_PLAYER_MONEY], MAX_MONEY_AMOUNT, 2000); + m_int_configs[CONFIG_START_HEROIC_PLAYER_MONEY] = 2000; + } + m_int_configs[CONFIG_MAX_HONOR_POINTS] = sConfigMgr->GetOption("MaxHonorPoints", 75000); if (int32(m_int_configs[CONFIG_MAX_HONOR_POINTS]) < 0) { From 4be7bbe67982ac0a142f6e96ccdc59a198bf7c35 Mon Sep 17 00:00:00 2001 From: Gultask <100873791+Gultask@users.noreply.github.com> Date: Wed, 21 Sep 2022 08:40:43 -0300 Subject: [PATCH 07/18] fix(DB/creature_formations): Prevent Jin'do from being pulled with trash (#13042) Create rev_1663431752393067900.sql --- .../rev_1663431752393067900.sql | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1663431752393067900.sql diff --git a/data/sql/updates/pending_db_world/rev_1663431752393067900.sql b/data/sql/updates/pending_db_world/rev_1663431752393067900.sql new file mode 100644 index 000000000..cb3aec230 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1663431752393067900.sql @@ -0,0 +1,48 @@ +-- +UPDATE `creature_template` SET `flags_extra`=`flags_extra`|0x02000000 WHERE `entry` IN (14825, 14882, 14883); +UPDATE `creature_formations` SET `groupAI`=515 WHERE `LeaderGUID`=49359 AND `memberGUID` IN (49359,49361,49362,49389); +UPDATE `creature_formations` SET `groupAI`=515 WHERE `LeaderGUID`=49651 AND `memberGUID` IN (49651,49652,49653,49654); + +DELETE FROM `creature_formations` WHERE `LeaderGUID` IN (49363,49383,49387,49397,49373) AND `memberGUID` IN (49363,49364,49365,49366,49367,49368,49369,49370,49371,49372,49373,49374,49375,49376,49377,49378,49379,49380,49381,49382,49383,49384,49385,49386,49387,49388,49390,49391,49392,49393,49394,49395,49396,49397,49398,49399,49400); +INSERT INTO `creature_formations` (`leaderGUID`, `memberGUID`, `dist`, `angle`, `groupAI`, `point_1`, `point_2`) VALUES +(49363, 49363, 0, 0, 3, 0, 0), +(49363, 49370, 0, 0, 3, 0, 0), +(49363, 49364, 0, 0, 3, 0, 0), +(49363, 49368, 0, 0, 3, 0, 0), +(49363, 49372, 0, 0, 3, 0, 0), +(49363, 49371, 0, 0, 3, 0, 0), +(49363, 49367, 0, 0, 3, 0, 0), +(49363, 49365, 0, 0, 3, 0, 0), +(49363, 49366, 0, 0, 3, 0, 0), +(49363, 49369, 0, 0, 3, 0, 0), + +(49383, 49383, 0, 0, 3, 0, 0), +(49383, 49384, 0, 0, 3, 0, 0), +(49383, 49385, 0, 0, 3, 0, 0), +(49383, 49386, 0, 0, 3, 0, 0), + +(49387, 49387, 0, 0, 3, 0, 0), +(49387, 49393, 0, 0, 3, 0, 0), +(49387, 49388, 0, 0, 3, 0, 0), +(49387, 49392, 0, 0, 3, 0, 0), +(49387, 49390, 0, 0, 3, 0, 0), +(49387, 49396, 0, 0, 3, 0, 0), +(49387, 49391, 0, 0, 3, 0, 0), +(49387, 49395, 0, 0, 3, 0, 0), +(49387, 49394, 0, 0, 3, 0, 0), + +(49397, 49397, 0, 0, 3, 0, 0), +(49397, 49398, 0, 0, 3, 0, 0), +(49397, 49399, 0, 0, 3, 0, 0), +(49397, 49400, 0, 0, 3, 0, 0), + +(49373, 49373, 0, 0, 3, 0, 0), +(49373, 49381, 0, 0, 3, 0, 0), +(49373, 49382, 0, 0, 3, 0, 0), +(49373, 49380, 0, 0, 3, 0, 0), +(49373, 49379, 0, 0, 3, 0, 0), +(49373, 49375, 0, 0, 3, 0, 0), +(49373, 49378, 0, 0, 3, 0, 0), +(49373, 49376, 0, 0, 3, 0, 0), +(49373, 49377, 0, 0, 3, 0, 0), +(49373, 49374, 0, 0, 3, 0, 0); From 9819b2d700ca1d7d22cbb743f39b84ddf7810af7 Mon Sep 17 00:00:00 2001 From: Angelo Venturini Date: Wed, 21 Sep 2022 08:41:27 -0300 Subject: [PATCH 08/18] fix(DB/TempleOfAhnQiraj): Sartura formation groupAI (#13066) --- data/sql/updates/pending_db_world/rev_1663648375302333300.sql | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1663648375302333300.sql diff --git a/data/sql/updates/pending_db_world/rev_1663648375302333300.sql b/data/sql/updates/pending_db_world/rev_1663648375302333300.sql new file mode 100644 index 000000000..e977cd5fd --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1663648375302333300.sql @@ -0,0 +1,2 @@ +-- +UPDATE `creature_formations` SET `groupAI` = 515 WHERE `leaderGUID` = 87648 AND `memberGUID` IN (87649, 87650, 87651); From d9390e34b4384dda4b1a75d563acedc4116a7a16 Mon Sep 17 00:00:00 2001 From: ZhengPeiRu21 <98835050+ZhengPeiRu21@users.noreply.github.com> Date: Wed, 21 Sep 2022 05:42:56 -0600 Subject: [PATCH 09/18] fix(Core): CanAccountCreateCharacter hook parameters (#13060) --- src/server/game/Handlers/CharacterHandler.cpp | 2 +- src/server/game/Scripting/ScriptDefines/AccountScript.cpp | 4 ++-- src/server/game/Scripting/ScriptMgr.h | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index ae84e8347..04a9f5d0e 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -432,7 +432,7 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData) std::function finalizeCharacterCreation = [this, createInfo](PreparedQueryResult result) { - if (!sScriptMgr->CanAccountCreateCharacter(createInfo, GetAccountId())) + if (!sScriptMgr->CanAccountCreateCharacter(GetAccountId(), createInfo->Race, createInfo->Class)) { SendCharCreate(CHAR_CREATE_DISABLED); return; diff --git a/src/server/game/Scripting/ScriptDefines/AccountScript.cpp b/src/server/game/Scripting/ScriptDefines/AccountScript.cpp index 4368e87d0..ff12bd54e 100644 --- a/src/server/game/Scripting/ScriptDefines/AccountScript.cpp +++ b/src/server/game/Scripting/ScriptDefines/AccountScript.cpp @@ -82,11 +82,11 @@ void ScriptMgr::OnFailedPasswordChange(uint32 accountId) }); } -bool ScriptMgr::CanAccountCreateCharacter(std::shared_ptr createInfo, uint32 accountId) +bool ScriptMgr::CanAccountCreateCharacter(uint32 accountId, uint8 charRace, uint8 charClass) { auto ret = IsValidBoolScript([&](AccountScript* script) { - return !script->CanAccountCreateCharacter(createInfo, accountId); + return !script->CanAccountCreateCharacter(accountId, charRace, charClass); }); if (ret && *ret) diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h index ec4fa798e..680c75747 100644 --- a/src/server/game/Scripting/ScriptMgr.h +++ b/src/server/game/Scripting/ScriptMgr.h @@ -1461,7 +1461,7 @@ public: virtual void OnFailedPasswordChange(uint32 /*accountId*/) { } // Called when creating a character on the Account - [[nodiscard]] virtual bool CanAccountCreateCharacter(std::shared_ptr /*createInfo*/, uint32 /*accountId*/) { return true;} + [[nodiscard]] virtual bool CanAccountCreateCharacter(uint32 /*accountId*/, uint8 /*charRace*/, uint8 /*charClass*/) { return true;} }; class GuildScript : public ScriptObject @@ -2360,7 +2360,7 @@ public: /* AccountScript */ void OnFailedEmailChange(uint32 accountId); void OnPasswordChange(uint32 accountId); void OnFailedPasswordChange(uint32 accountId); - bool CanAccountCreateCharacter(std::shared_ptr createInfo, uint32 accountId); + bool CanAccountCreateCharacter(uint32 accountId, uint8 charRace, uint8 charClass); public: /* GuildScript */ void OnGuildAddMember(Guild* guild, Player* player, uint8& plRank); From decc5e0c03eaace1a78732634e99691ecb452aba Mon Sep 17 00:00:00 2001 From: AzerothCoreBot Date: Wed, 21 Sep 2022 11:45:24 +0000 Subject: [PATCH 10/18] chore(DB): import pending files Referenced commit(s): d9390e34b4384dda4b1a75d563acedc4116a7a16 --- .../rev_1663431752393067900.sql => db_world/2022_09_21_00.sql} | 1 + .../rev_1663648375302333300.sql => db_world/2022_09_21_01.sql} | 1 + 2 files changed, 2 insertions(+) rename data/sql/updates/{pending_db_world/rev_1663431752393067900.sql => db_world/2022_09_21_00.sql} (97%) rename data/sql/updates/{pending_db_world/rev_1663648375302333300.sql => db_world/2022_09_21_01.sql} (73%) diff --git a/data/sql/updates/pending_db_world/rev_1663431752393067900.sql b/data/sql/updates/db_world/2022_09_21_00.sql similarity index 97% rename from data/sql/updates/pending_db_world/rev_1663431752393067900.sql rename to data/sql/updates/db_world/2022_09_21_00.sql index cb3aec230..d20a4e4e3 100644 --- a/data/sql/updates/pending_db_world/rev_1663431752393067900.sql +++ b/data/sql/updates/db_world/2022_09_21_00.sql @@ -1,3 +1,4 @@ +-- DB update 2022_09_19_08 -> 2022_09_21_00 -- UPDATE `creature_template` SET `flags_extra`=`flags_extra`|0x02000000 WHERE `entry` IN (14825, 14882, 14883); UPDATE `creature_formations` SET `groupAI`=515 WHERE `LeaderGUID`=49359 AND `memberGUID` IN (49359,49361,49362,49389); diff --git a/data/sql/updates/pending_db_world/rev_1663648375302333300.sql b/data/sql/updates/db_world/2022_09_21_01.sql similarity index 73% rename from data/sql/updates/pending_db_world/rev_1663648375302333300.sql rename to data/sql/updates/db_world/2022_09_21_01.sql index e977cd5fd..7774f0c63 100644 --- a/data/sql/updates/pending_db_world/rev_1663648375302333300.sql +++ b/data/sql/updates/db_world/2022_09_21_01.sql @@ -1,2 +1,3 @@ +-- DB update 2022_09_21_00 -> 2022_09_21_01 -- UPDATE `creature_formations` SET `groupAI` = 515 WHERE `leaderGUID` = 87648 AND `memberGUID` IN (87649, 87650, 87651); From 2d8c880bdcb1ff8f2a0545d14f5a6df5a402fcac Mon Sep 17 00:00:00 2001 From: Benjamin Jackson <38561765+heyitsbench@users.noreply.github.com> Date: Wed, 21 Sep 2022 07:45:58 -0400 Subject: [PATCH 11/18] fix(DB/quest_offer_reward): Correct incorrect newline for Kranal Fiss (#13052) * Create blackrock-drakes.sql * Guess I guess * get rid of it it's not funny anymore * slap that bad boy on there * get rid of it because i'm not a comedian * make it --- data/sql/updates/pending_db_world/bWell-then.sql | 1 + 1 file changed, 1 insertion(+) create mode 100644 data/sql/updates/pending_db_world/bWell-then.sql diff --git a/data/sql/updates/pending_db_world/bWell-then.sql b/data/sql/updates/pending_db_world/bWell-then.sql new file mode 100644 index 000000000..446a7cce2 --- /dev/null +++ b/data/sql/updates/pending_db_world/bWell-then.sql @@ -0,0 +1 @@ +UPDATE `quest_offer_reward` SET `RewardText`='Hmmm, Narm sent you to me, did he?$b$bWell then, Narm could always be trusted, so that must mean you\'re ready to take part of the next sapta--the sapta of fire.$b$bI see it in your eyes already, the burning, the desire. You\'ve tasted power, and now you\'re ready for more of it. Patience, $N. Remember what earth taught you. Power and destruction will come easily, but you must still know when to stay your hand.' WHERE `ID`=2984; From a91b788304730e201eeb6fa382bcdcc1ab52c2d5 Mon Sep 17 00:00:00 2001 From: AzerothCoreBot Date: Wed, 21 Sep 2022 11:48:05 +0000 Subject: [PATCH 12/18] chore(DB): import pending files Referenced commit(s): 2d8c880bdcb1ff8f2a0545d14f5a6df5a402fcac --- .../bWell-then.sql => db_world/2022_09_21_02.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/bWell-then.sql => db_world/2022_09_21_02.sql} (91%) diff --git a/data/sql/updates/pending_db_world/bWell-then.sql b/data/sql/updates/db_world/2022_09_21_02.sql similarity index 91% rename from data/sql/updates/pending_db_world/bWell-then.sql rename to data/sql/updates/db_world/2022_09_21_02.sql index 446a7cce2..b47ea3afe 100644 --- a/data/sql/updates/pending_db_world/bWell-then.sql +++ b/data/sql/updates/db_world/2022_09_21_02.sql @@ -1 +1,2 @@ +-- DB update 2022_09_21_01 -> 2022_09_21_02 UPDATE `quest_offer_reward` SET `RewardText`='Hmmm, Narm sent you to me, did he?$b$bWell then, Narm could always be trusted, so that must mean you\'re ready to take part of the next sapta--the sapta of fire.$b$bI see it in your eyes already, the burning, the desire. You\'ve tasted power, and now you\'re ready for more of it. Patience, $N. Remember what earth taught you. Power and destruction will come easily, but you must still know when to stay your hand.' WHERE `ID`=2984; From 7a137767fab342732211fec5e8d302e9035a32df Mon Sep 17 00:00:00 2001 From: ZhengPeiRu21 <98835050+ZhengPeiRu21@users.noreply.github.com> Date: Wed, 21 Sep 2022 06:28:19 -0600 Subject: [PATCH 13/18] feat(Core): OnBeforeLootMoney hook (#13030) --- src/server/game/Handlers/LootHandler.cpp | 1 + src/server/game/Scripting/ScriptDefines/PlayerScript.cpp | 8 ++++++++ src/server/game/Scripting/ScriptMgr.h | 4 ++++ 3 files changed, 13 insertions(+) diff --git a/src/server/game/Handlers/LootHandler.cpp b/src/server/game/Handlers/LootHandler.cpp index 5b8ec44d3..41044a07c 100644 --- a/src/server/game/Handlers/LootHandler.cpp +++ b/src/server/game/Handlers/LootHandler.cpp @@ -168,6 +168,7 @@ void WorldSession::HandleLootMoneyOpcode(WorldPacket& /*recvData*/) if (loot) { + sScriptMgr->OnBeforeLootMoney(player, loot); loot->NotifyMoneyRemoved(); if (shareMoney && player->GetGroup()) //item, pickpocket and players can be looted only single player { diff --git a/src/server/game/Scripting/ScriptDefines/PlayerScript.cpp b/src/server/game/Scripting/ScriptDefines/PlayerScript.cpp index 5cb773dce..756231338 100644 --- a/src/server/game/Scripting/ScriptDefines/PlayerScript.cpp +++ b/src/server/game/Scripting/ScriptDefines/PlayerScript.cpp @@ -146,6 +146,14 @@ void ScriptMgr::OnPlayerMoneyChanged(Player* player, int32& amount) }); } +void ScriptMgr::OnBeforeLootMoney(Player* player, Loot* loot) +{ + ExecuteScript([&](PlayerScript* script) + { + script->OnBeforeLootMoney(player, loot); + }); +} + void ScriptMgr::OnGivePlayerXP(Player* player, uint32& amount, Unit* victim) { ExecuteScript([&](PlayerScript* script) diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h index 680c75747..57913d695 100644 --- a/src/server/game/Scripting/ScriptMgr.h +++ b/src/server/game/Scripting/ScriptMgr.h @@ -1021,6 +1021,9 @@ public: // Called when a player's money is modified (before the modification is done) virtual void OnMoneyChanged(Player* /*player*/, int32& /*amount*/) { } + // Called before looted money is added to a player + virtual void OnBeforeLootMoney(Player* /*player*/, Loot* /*loot*/) {} + // Called when a player gains XP (before anything is given) virtual void OnGiveXP(Player* /*player*/, uint32& /*amount*/, Unit* /*victim*/) { } @@ -2208,6 +2211,7 @@ public: /* PlayerScript */ void OnPlayerFreeTalentPointsChanged(Player* player, uint32 newPoints); void OnPlayerTalentsReset(Player* player, bool noCost); void OnPlayerMoneyChanged(Player* player, int32& amount); + void OnBeforeLootMoney(Player* player, Loot* loot); void OnGivePlayerXP(Player* player, uint32& amount, Unit* victim); bool OnPlayerReputationChange(Player* player, uint32 factionID, int32& standing, bool incremental); void OnPlayerReputationRankChange(Player* player, uint32 factionID, ReputationRank newRank, ReputationRank oldRank, bool increased); From dfa49e9433d71c89afd01f769842de4cd76f9259 Mon Sep 17 00:00:00 2001 From: ZhengPeiRu21 <98835050+ZhengPeiRu21@users.noreply.github.com> Date: Wed, 21 Sep 2022 06:29:54 -0600 Subject: [PATCH 14/18] feat(Core): Hide Game Object Quest Markers Config Option (#13013) --- src/server/apps/worldserver/worldserver.conf.dist | 8 ++++++++ src/server/game/Handlers/QuestHandler.cpp | 5 ++++- src/server/game/World/IWorld.h | 1 + src/server/game/World/World.cpp | 2 ++ 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/server/apps/worldserver/worldserver.conf.dist b/src/server/apps/worldserver/worldserver.conf.dist index 646d7706b..65b54feb7 100644 --- a/src/server/apps/worldserver/worldserver.conf.dist +++ b/src/server/apps/worldserver/worldserver.conf.dist @@ -2164,6 +2164,14 @@ Visibility.Notify.Period.InBGArenas = 1000 Visibility.ObjectSparkles = 1 +# +# Visibility.ObjectQuestMarkers +# Description: Show quest icons above game objects in the same way as creature quest givers. +# Default: 1 - (Show quest markers, post patch 2.3 behavior) +# 0 - (Hide quest markers, pre patch 2.3 behavior) + +Visibility.ObjectQuestMarkers = 1 + # ################################################################################################### diff --git a/src/server/game/Handlers/QuestHandler.cpp b/src/server/game/Handlers/QuestHandler.cpp index 49e951549..5f2927303 100644 --- a/src/server/game/Handlers/QuestHandler.cpp +++ b/src/server/game/Handlers/QuestHandler.cpp @@ -63,7 +63,10 @@ void WorldSession::HandleQuestgiverStatusQueryOpcode(WorldPacket& recvData) case TYPEID_GAMEOBJECT: { LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_STATUS_QUERY for GameObject {}", guid.ToString()); - questStatus = _player->GetQuestDialogStatus(questGiver); + if (sWorld->getBoolConfig(CONFIG_OBJECT_QUEST_MARKERS)) + { + questStatus = _player->GetQuestDialogStatus(questGiver); + } break; } default: diff --git a/src/server/game/World/IWorld.h b/src/server/game/World/IWorld.h index ec6a880f9..ce2b13faf 100644 --- a/src/server/game/World/IWorld.h +++ b/src/server/game/World/IWorld.h @@ -177,6 +177,7 @@ enum WorldBoolConfigs CONFIG_LEAVE_GROUP_ON_LOGOUT, CONFIG_VMAP_BLIZZLIKE_PVP_LOS, CONFIG_OBJECT_SPARKLES, + CONFIG_OBJECT_QUEST_MARKERS, BOOL_CONFIG_VALUE_COUNT }; diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 318af1ab6..b0b4a3110 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -950,6 +950,8 @@ void World::LoadConfigSettings(bool reload) m_bool_configs[CONFIG_OBJECT_SPARKLES] = sConfigMgr->GetOption("Visibility.ObjectSparkles", true); + m_bool_configs[CONFIG_OBJECT_QUEST_MARKERS] = sConfigMgr->GetOption("Visibility.ObjectQuestMarkers", true); + m_int_configs[CONFIG_MAIL_DELIVERY_DELAY] = sConfigMgr->GetOption("MailDeliveryDelay", HOUR); m_int_configs[CONFIG_UPTIME_UPDATE] = sConfigMgr->GetOption("UpdateUptimeInterval", 10); From d8598c764eb8691a4c5201fbb254b4d449fc2531 Mon Sep 17 00:00:00 2001 From: DavuKnight <112143769+DavuKnight@users.noreply.github.com> Date: Wed, 21 Sep 2022 07:33:28 -0500 Subject: [PATCH 15/18] feat(core): OnFfaPvpStateUpdate Event (#13023) * Event for Notification when the Player enters into or Leaves Ffa * Bug and Formatting Fixes --- .../game/Entities/GameObject/GameObject.cpp | 8 +++- src/server/game/Entities/Player/Player.cpp | 37 +++++++++++++++---- .../game/Entities/Player/PlayerMisc.cpp | 7 +++- .../game/Entities/Player/PlayerUpdates.cpp | 8 +++- src/server/game/Handlers/CharacterHandler.cpp | 6 ++- src/server/game/Handlers/MiscHandler.cpp | 8 +++- .../ScriptDefines/CreatureScript.cpp | 9 +++++ .../Scripting/ScriptDefines/PlayerScript.cpp | 9 +++++ src/server/game/Scripting/ScriptMgr.h | 12 ++++++ 9 files changed, 90 insertions(+), 14 deletions(-) diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 9f787e0e1..d58979f0d 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -2088,8 +2088,14 @@ void GameObject::CastSpell(Unit* target, uint32 spellId) if (owner->HasUnitFlag(UNIT_FLAG_PLAYER_CONTROLLED)) trigger->SetUnitFlag(UNIT_FLAG_PLAYER_CONTROLLED); if (owner->IsFFAPvP()) - trigger->SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP); + { + if (!HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP)) + { + sScriptMgr->OnFfaPvpStateUpdate(trigger, true); + trigger->SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP); + } + } // xinef: Remove Immunity flags trigger->SetImmuneToNPC(false); // xinef: set proper orientation, fixes cast against stealthed targets diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 2c473e09c..79d8565cd 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -2179,8 +2179,11 @@ void Player::SetGameMaster(bool on) pet->SetFaction(FACTION_FRIENDLY); pet->getHostileRefMgr().setOnlineOfflineState(false); } - - RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP); + if (HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP)) + { + RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP); + sScriptMgr->OnFfaPvpStateUpdate(this, false); + } ResetContestedPvP(); getHostileRefMgr().setOnlineOfflineState(false); @@ -2212,8 +2215,13 @@ void Player::SetGameMaster(bool on) // restore FFA PvP Server state if (sWorld->IsFFAPvPRealm()) - SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP); - + { + if (!HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP)) + { + SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP); + sScriptMgr->OnFfaPvpStateUpdate(this, true); + } + } // restore FFA PvP area state, remove not allowed for GM mounts UpdateArea(m_areaUpdateId); @@ -2656,8 +2664,12 @@ void Player::InitStatsForLevel(bool reapplyMods) RemovePlayerFlag(PLAYER_FLAGS_AFK | PLAYER_FLAGS_DND | PLAYER_FLAGS_GM | PLAYER_FLAGS_GHOST | PLAYER_ALLOW_ONLY_ABILITY); RemoveStandFlags(UNIT_STAND_FLAGS_ALL); // one form stealth modified bytes - RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP | UNIT_BYTE2_FLAG_SANCTUARY); + if (HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP)) + { + RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP | UNIT_BYTE2_FLAG_SANCTUARY); + sScriptMgr->OnFfaPvpStateUpdate(this, false); + } // restore if need some important flags SetUInt32Value(PLAYER_FIELD_BYTES2, 0); // flags empty by default @@ -15001,7 +15013,11 @@ void Player::SetIsSpectator(bool on) AddUnitState(UNIT_STATE_ISOLATED); //SetFaction(1100); SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE); - RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP); + if (HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP)) + { + RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP); + sScriptMgr->OnFfaPvpStateUpdate(this, false); + } ResetContestedPvP(); SetDisplayId(23691); } @@ -15021,7 +15037,14 @@ void Player::SetIsSpectator(bool on) // restore FFA PvP Server state // Xinef: it will be removed if necessery in UpdateArea called in WorldPortOpcode if (sWorld->IsFFAPvPRealm()) - SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP); + { + if (!HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP)) + { + SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP); + sScriptMgr->OnFfaPvpStateUpdate(this, true); + + } + } } } } diff --git a/src/server/game/Entities/Player/PlayerMisc.cpp b/src/server/game/Entities/Player/PlayerMisc.cpp index 173b366f7..8c32b2cae 100644 --- a/src/server/game/Entities/Player/PlayerMisc.cpp +++ b/src/server/game/Entities/Player/PlayerMisc.cpp @@ -396,8 +396,11 @@ void Player::UpdateFFAPvPFlag(time_t currTime) } pvpInfo.FFAPvPEndTimer = time_t(0); - - RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP); + if (HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP)) + { + RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP); + sScriptMgr->OnFfaPvpStateUpdate(this, false); + } for (ControlSet::iterator itr = m_Controlled.begin(); itr != m_Controlled.end(); ++itr) (*itr)->RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP); diff --git a/src/server/game/Entities/Player/PlayerUpdates.cpp b/src/server/game/Entities/Player/PlayerUpdates.cpp index 04f7fd011..953c35e69 100644 --- a/src/server/game/Entities/Player/PlayerUpdates.cpp +++ b/src/server/game/Entities/Player/PlayerUpdates.cpp @@ -1401,6 +1401,7 @@ void Player::UpdateFFAPvPState(bool reset /*= true*/) { if (!IsFFAPvP()) { + sScriptMgr->OnFfaPvpStateUpdate(this, true); SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP); for (ControlSet::iterator itr = m_Controlled.begin(); itr != m_Controlled.end(); ++itr) @@ -1419,8 +1420,11 @@ void Player::UpdateFFAPvPState(bool reset /*= true*/) !pvpInfo.EndTimer) { pvpInfo.FFAPvPEndTimer = time_t(0); - - RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP); + if (HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP)) + { + RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP); + sScriptMgr->OnFfaPvpStateUpdate(this, false); + } for (ControlSet::iterator itr = m_Controlled.begin(); itr != m_Controlled.end(); ++itr) (*itr)->RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index 04a9f5d0e..70eb6ef98 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -954,7 +954,11 @@ void WorldSession::HandlePlayerLoginFromDB(LoginQueryHolder const& holder) // Set FFA PvP for non GM in non-rest mode if (sWorld->IsFFAPvPRealm() && !pCurrChar->IsGameMaster() && !pCurrChar->HasPlayerFlag(PLAYER_FLAGS_RESTING)) - pCurrChar->SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP); + if (!pCurrChar->HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP)) + { + sScriptMgr->OnFfaPvpStateUpdate(pCurrChar,true); + pCurrChar->SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP); + } if (pCurrChar->HasPlayerFlag(PLAYER_FLAGS_CONTESTED_PVP)) { diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index e3d8912ea..ed96dfd1a 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -772,8 +772,14 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket& recv_data) player->SetRestFlag(REST_FLAG_IN_TAVERN, atEntry->entry); if (sWorld->IsFFAPvPRealm()) - player->RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP); + { + if (player->HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP)) + { + player->RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP); + sScriptMgr->OnFfaPvpStateUpdate(player, false); + } + } return; } diff --git a/src/server/game/Scripting/ScriptDefines/CreatureScript.cpp b/src/server/game/Scripting/ScriptDefines/CreatureScript.cpp index 1bbc61f97..aadf276f1 100644 --- a/src/server/game/Scripting/ScriptDefines/CreatureScript.cpp +++ b/src/server/game/Scripting/ScriptDefines/CreatureScript.cpp @@ -170,6 +170,15 @@ CreatureAI* ScriptMgr::GetCreatureAI(Creature* creature) return tempScript ? tempScript->GetAI(creature) : nullptr; } +//Fires whenever the UNIT_BYTE2_FLAG_FFA_PVP bit is Changed on the player +void ScriptMgr::OnFfaPvpStateUpdate(Creature* creature, bool InPvp) +{ + ExecuteScript([&](AllCreatureScript* script) + { + script->OnFfaPvpStateUpdate(creature, InPvp); + }); +} + void ScriptMgr::OnCreatureUpdate(Creature* creature, uint32 diff) { ASSERT(creature); diff --git a/src/server/game/Scripting/ScriptDefines/PlayerScript.cpp b/src/server/game/Scripting/ScriptDefines/PlayerScript.cpp index 756231338..a8794e821 100644 --- a/src/server/game/Scripting/ScriptDefines/PlayerScript.cpp +++ b/src/server/game/Scripting/ScriptDefines/PlayerScript.cpp @@ -1263,6 +1263,7 @@ void ScriptMgr::OnGetArenaTeamId(Player* player, uint8 slot, uint32& result) }); } +//Signifies that IsFfaPvp has been called. void ScriptMgr::OnIsFFAPvP(Player* player, bool& result) { ExecuteScript([&](PlayerScript* script) @@ -1270,6 +1271,14 @@ void ScriptMgr::OnIsFFAPvP(Player* player, bool& result) script->OnIsFFAPvP(player, result); }); } +//Fires whenever the UNIT_BYTE2_FLAG_FFA_PVP bit is Changed +void ScriptMgr::OnFfaPvpStateUpdate(Player* player, bool result) +{ + ExecuteScript([&](PlayerScript* script) + { + script->OnFfaPvpStateUpdate(player, result); + }); +} void ScriptMgr::OnIsPvP(Player* player, bool& result) { diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h index 57913d695..c84a6dfae 100644 --- a/src/server/game/Scripting/ScriptMgr.h +++ b/src/server/game/Scripting/ScriptMgr.h @@ -619,6 +619,9 @@ public: // Called when a CreatureAI object is needed for the creature. [[nodiscard]] virtual CreatureAI* GetCreatureAI(Creature* /*creature*/) const { return nullptr; } + + //Called Whenever the UNIT_BYTE2_FLAG_FFA_PVP Bit is set on the creature + virtual void OnFfaPvpStateUpdate(Creature* /*creature*/, bool /*InPvp*/) {} }; class AllItemScript : public ScriptObject @@ -743,6 +746,10 @@ public: // Called when a CreatureAI object is needed for the creature. virtual CreatureAI* GetAI(Creature* /*creature*/) const { return nullptr; } + + //Called whenever the UNIT_BYTE2_FLAG_FFA_PVP bit is Changed on the player + virtual void OnFfaPvpStateUpdate(Creature* /*player*/, bool /*result*/) { } + }; class GameObjectScript : public ScriptObject, public UpdatableScript @@ -1307,6 +1314,9 @@ public: virtual void OnIsFFAPvP(Player* /*player*/, bool& /*result*/) { } + //Fires whenever the UNIT_BYTE2_FLAG_FFA_PVP bit is Changed on the player + virtual void OnFfaPvpStateUpdate(Player* /*player*/, bool /*result*/) { } + virtual void OnIsPvP(Player* /*player*/, bool& /*result*/) { } virtual void OnGetMaxSkillValueForLevel(Player* /*player*/, uint16& /*result*/) { } @@ -2127,6 +2137,7 @@ public: /* CreatureScript */ void OnCreatureUpdate(Creature* creature, uint32 diff); void OnCreatureAddWorld(Creature* creature); void OnCreatureRemoveWorld(Creature* creature); + void OnFfaPvpStateUpdate(Creature* creature, bool InPvp); public: /* GameObjectScript */ bool OnGossipHello(Player* player, GameObject* go); @@ -2324,6 +2335,7 @@ public: /* PlayerScript */ bool NotAvoidSatisfy(Player* player, DungeonProgressionRequirements const* ar, uint32 target_map, bool report); bool NotVisibleGloballyFor(Player* player, Player const* u); void OnGetArenaPersonalRating(Player* player, uint8 slot, uint32& result); + void OnFfaPvpStateUpdate(Player* player, bool result); void OnGetArenaTeamId(Player* player, uint8 slot, uint32& result); void OnIsFFAPvP(Player* player, bool& result); void OnIsPvP(Player* player, bool& result); From f75aceb9a9b45a97452aad5b658ac52042c7c8cf Mon Sep 17 00:00:00 2001 From: schell244 Date: Wed, 21 Sep 2022 15:09:26 +0200 Subject: [PATCH 16/18] fix(Core): Small improvements for weapon/defence skill handling (#12253) * Improve weaponskill handling * replace pvp check TYPEID_PLAYER with IsCharmedOwnedByPlayerOrPlayer * remove no longer needed pvp checks * move pvp check back to ProcDamageAndSpellFor() * rename plevel -> playerLevel, add LOG to verify increase chances * fix issue due to negative value in uint * revert change which allowed blocked attacks to increase weapon skill Co-authored-by: schell244 <> --- .../game/Entities/Player/PlayerUpdates.cpp | 50 ++++++++++++------- src/server/game/Entities/Unit/Unit.cpp | 13 ++--- 2 files changed, 37 insertions(+), 26 deletions(-) diff --git a/src/server/game/Entities/Player/PlayerUpdates.cpp b/src/server/game/Entities/Player/PlayerUpdates.cpp index 953c35e69..2993b7d58 100644 --- a/src/server/game/Entities/Player/PlayerUpdates.cpp +++ b/src/server/game/Entities/Player/PlayerUpdates.cpp @@ -980,42 +980,56 @@ void Player::UpdateWeaponSkill(Unit* victim, WeaponAttackType attType, Item* ite void Player::UpdateCombatSkills(Unit* victim, WeaponAttackType attType, bool defence, Item* item /*= nullptr*/) { - uint8 plevel = getLevel(); // if defense than victim == attacker - uint8 greylevel = Acore::XP::GetGrayLevel(plevel); - uint8 moblevel = victim->getLevelForTarget(this); + uint8 playerLevel = getLevel(); + uint16 currentSkillValue = defence ? GetBaseDefenseSkillValue() : GetBaseWeaponSkillValue(attType); + uint16 currentSkillMax = 5 * playerLevel; + int32 skillDiff = currentSkillMax - currentSkillValue; + + // Max skill reached for level. + // Can in some cases be less than 0: having max skill and then .level -1 as example. + if (skillDiff <= 0) + { + return; + } + + uint8 greylevel = Acore::XP::GetGrayLevel(playerLevel); + uint8 moblevel = defence ? victim->getLevelForTarget(this) : victim->getLevel(); // if defense than victim == attacker /*if (moblevel < greylevel) return;*/ // Patch 3.0.8 (2009-01-20): You can no longer skill up weapons on mobs that are immune to damage. - if (moblevel > plevel + 5) - moblevel = plevel + 5; + if (moblevel > playerLevel + 5) + { + moblevel = playerLevel + 5; + } - uint8 lvldif = moblevel - greylevel; + int16 lvldif = moblevel - greylevel; if (lvldif < 3) + { lvldif = 3; + } - uint32 skilldif = 5 * plevel - (defence ? GetBaseDefenseSkillValue() - : GetBaseWeaponSkillValue(attType)); - if (skilldif <= 0) - return; - - float chance = float(3 * lvldif * skilldif) / plevel; + float chance = float(3 * lvldif * skillDiff) / playerLevel; if (!defence) - if (getClass() == CLASS_WARRIOR || getClass() == CLASS_ROGUE) - chance += chance * 0.02f * GetStat(STAT_INTELLECT); + { + chance += chance * 0.02f * GetStat(STAT_INTELLECT); + } - chance = - chance < 1.0f ? 1.0f : chance; // minimum chance to increase skill is 1% + chance = chance < 1.0f ? 1.0f : chance; // minimum chance to increase skill is 1% + + LOG_DEBUG("entities.player", "Player::UpdateCombatSkills(defence:{}, playerLevel:{}, moblevel:{}) -> ({}/{}) chance to increase skill is {}\%", defence, playerLevel, moblevel, currentSkillValue, currentSkillMax, chance); if (roll_chance_f(chance)) { if (defence) + { UpdateDefense(); + } else + { UpdateWeaponSkill(victim, attType, item); + } } - else - return; } void Player::UpdateSkillsForLevel() diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 33e7e4c0f..c2b03b3e4 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -15742,21 +15742,18 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u // Update skills here for players // only when you are not fighting other players or their pets/totems (pvp) - if (GetTypeId() == TYPEID_PLAYER && - target->GetTypeId() != TYPEID_PLAYER && - !(target->IsTotem() && target->ToTotem()->GetOwner()->IsPlayer()) && - !target->IsPet() - ) + if (IsPlayer() && !target->IsCharmedOwnedByPlayerOrPlayer()) { // On melee based hit/miss/resist/parry/dodge need to update skill (for victim and attacker) if (procExtra & (PROC_EX_NORMAL_HIT | PROC_EX_MISS | PROC_EX_RESIST | PROC_EX_PARRY | PROC_EX_DODGE)) { - if (target->GetTypeId() != TYPEID_PLAYER) - ToPlayer()->UpdateCombatSkills(target, attType, isVictim, procSpell ? procSpell->m_weaponItem : nullptr); + ToPlayer()->UpdateCombatSkills(target, attType, isVictim, procSpell ? procSpell->m_weaponItem : nullptr); } - // Update defence if player is victim and we block + // Update defence if player is victim and we block - TODO: confirm that blocked attacks only have a chance to increase defence skill else if (isVictim && procExtra & (PROC_EX_BLOCK)) + { ToPlayer()->UpdateCombatSkills(target, attType, true); + } } // If exist crit/parry/dodge/block need update aura state (for victim and attacker) if (procExtra & (PROC_EX_CRITICAL_HIT | PROC_EX_PARRY | PROC_EX_DODGE | PROC_EX_BLOCK)) From e273d6f4f0490b3a637dc738db8c9156053dd564 Mon Sep 17 00:00:00 2001 From: Grimgravy Date: Wed, 21 Sep 2022 12:03:43 -0300 Subject: [PATCH 17/18] fix(Scripts/Quest): improved egg freezing (#12575) --- .../rev_1659051490224635700.sql | 5 ++++ src/server/scripts/Spells/spell_item.cpp | 24 +++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1659051490224635700.sql diff --git a/data/sql/updates/pending_db_world/rev_1659051490224635700.sql b/data/sql/updates/pending_db_world/rev_1659051490224635700.sql new file mode 100644 index 000000000..3a9d984a4 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1659051490224635700.sql @@ -0,0 +1,5 @@ +-- +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_item_freeze_rookery_egg'; +INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES +(15748, 'spell_item_freeze_rookery_egg'), -- item +(16028, 'spell_item_freeze_rookery_egg'); -- quest diff --git a/src/server/scripts/Spells/spell_item.cpp b/src/server/scripts/Spells/spell_item.cpp index 9eeaeb14e..2dc0731cc 100644 --- a/src/server/scripts/Spells/spell_item.cpp +++ b/src/server/scripts/Spells/spell_item.cpp @@ -3702,6 +3702,29 @@ class spell_item_snowman : public SpellScript } }; +// https://www.wowhead.com/wotlk/spell=16028 Freeze Rookery Egg - Prototype +// https://www.wowhead.com/wotlk/spell=15748 Freeze Rookery Egg +class spell_item_freeze_rookery_egg : public SpellScript +{ + PrepareSpellScript(spell_item_freeze_rookery_egg); + + void HandleOpenObject(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + + if (GameObject* rookery = GetHitGObj()) + { + if (rookery->getLootState() == GO_READY) + rookery->UseDoorOrButton(0, true); + } + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_item_freeze_rookery_egg::HandleOpenObject, EFFECT_0, SPELL_EFFECT_OPEN_LOCK); + } +}; + void AddSC_item_spell_scripts() { RegisterSpellScript(spell_item_massive_seaforium_charge); @@ -3816,4 +3839,5 @@ void AddSC_item_spell_scripts() RegisterSpellScript(spell_item_wraith_scythe_drain_life); RegisterSpellScript(spell_item_mirrens_drinking_hat); RegisterSpellScript(spell_item_snowman); + RegisterSpellScript(spell_item_freeze_rookery_egg); } From 103ab5704a2eb9fd4b0e824545216e01cf2ca952 Mon Sep 17 00:00:00 2001 From: AzerothCoreBot Date: Wed, 21 Sep 2022 15:05:51 +0000 Subject: [PATCH 18/18] chore(DB): import pending files Referenced commit(s): e273d6f4f0490b3a637dc738db8c9156053dd564 --- .../rev_1659051490224635700.sql => db_world/2022_09_21_03.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1659051490224635700.sql => db_world/2022_09_21_03.sql} (85%) diff --git a/data/sql/updates/pending_db_world/rev_1659051490224635700.sql b/data/sql/updates/db_world/2022_09_21_03.sql similarity index 85% rename from data/sql/updates/pending_db_world/rev_1659051490224635700.sql rename to data/sql/updates/db_world/2022_09_21_03.sql index 3a9d984a4..b0f776203 100644 --- a/data/sql/updates/pending_db_world/rev_1659051490224635700.sql +++ b/data/sql/updates/db_world/2022_09_21_03.sql @@ -1,3 +1,4 @@ +-- DB update 2022_09_21_02 -> 2022_09_21_03 -- DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_item_freeze_rookery_egg'; INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES