aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/database/Database/Implementation/HotfixDatabase.cpp13
-rw-r--r--src/server/database/Database/Implementation/HotfixDatabase.h3
-rw-r--r--src/server/game/DataStores/DB2LoadInfo.h14
-rw-r--r--src/server/game/DataStores/DB2Stores.cpp2
-rw-r--r--src/server/game/DataStores/DB2Stores.h1
-rw-r--r--src/server/game/DataStores/DB2Structure.h9
-rw-r--r--src/server/game/Handlers/SpellHandler.cpp13
-rw-r--r--src/server/game/Server/Packets/SpellPackets.cpp5
-rw-r--r--src/server/game/Server/Packets/SpellPackets.h10
-rw-r--r--src/server/game/Server/Protocol/Opcodes.cpp2
-rw-r--r--src/server/game/Server/WorldSession.h2
-rw-r--r--src/server/game/Spells/Auras/SpellAuraDefines.h2
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.cpp2
13 files changed, 71 insertions, 7 deletions
diff --git a/src/server/database/Database/Implementation/HotfixDatabase.cpp b/src/server/database/Database/Implementation/HotfixDatabase.cpp
index f6e3f0ec08f..2df820e6fb4 100644
--- a/src/server/database/Database/Implementation/HotfixDatabase.cpp
+++ b/src/server/database/Database/Implementation/HotfixDatabase.cpp
@@ -23,13 +23,13 @@
// Force max id statements to appear exactly right after normal data fetch statement
#define PREPARE_MAX_ID_STMT(stmtBase, sql, con) \
- static_assert(stmtBase + HOTFIX_MAX_ID_STMT_OFFSET == stmtBase##_MAX_ID, "Invalid prepared statement index for " #stmtBase "_MAX_ID"); \
- PrepareStatement(stmtBase##_MAX_ID, sql, con);
+ static_assert((stmtBase) + HOTFIX_MAX_ID_STMT_OFFSET == stmtBase##_MAX_ID, "Invalid prepared statement index for " #stmtBase "_MAX_ID"); \
+ PrepareStatement(stmtBase##_MAX_ID, sql, con)
// Force locale statements to be right after max id fetch statement
#define PREPARE_LOCALE_STMT(stmtBase, sql, con) \
- static_assert(stmtBase + HOTFIX_LOCALE_STMT_OFFSET == stmtBase##_LOCALE, "Invalid prepared statement index for " #stmtBase "_LOCALE"); \
- PrepareStatement(stmtBase##_LOCALE, sql, con);
+ static_assert((stmtBase) + HOTFIX_LOCALE_STMT_OFFSET == stmtBase##_LOCALE, "Invalid prepared statement index for " #stmtBase "_LOCALE"); \
+ PrepareStatement(stmtBase##_LOCALE, sql, con)
void HotfixDatabaseConnection::DoPrepareStatements()
{
@@ -1465,6 +1465,11 @@ void HotfixDatabaseConnection::DoPrepareStatements()
"Logic1, Logic2, Logic3, Logic4, Logic5 FROM spell_item_enchantment_condition WHERE (`VerifiedBuild` > 0) = ?", CONNECTION_SYNCH);
PREPARE_MAX_ID_STMT(HOTFIX_SEL_SPELL_ITEM_ENCHANTMENT_CONDITION, "SELECT MAX(ID) + 1 FROM spell_item_enchantment_condition", CONNECTION_SYNCH);
+ // SpellKeyboundOverride.db2
+ PrepareStatement(HOTFIX_SEL_SPELL_KEYBOUND_OVERRIDE, "SELECT ID, `Function`, Type, Data, Flags FROM spell_keybound_override"
+ " WHERE (`VerifiedBuild` > 0) = ?", CONNECTION_SYNCH);
+ PREPARE_MAX_ID_STMT(HOTFIX_SEL_SPELL_KEYBOUND_OVERRIDE, "SELECT MAX(ID) + 1 FROM spell_keybound_override", CONNECTION_SYNCH);
+
// SpellLabel.db2
PrepareStatement(HOTFIX_SEL_SPELL_LABEL, "SELECT ID, LabelID, SpellID FROM spell_label WHERE (`VerifiedBuild` > 0) = ?", CONNECTION_SYNCH);
PREPARE_MAX_ID_STMT(HOTFIX_SEL_SPELL_LABEL, "SELECT MAX(ID) + 1 FROM spell_label", CONNECTION_SYNCH);
diff --git a/src/server/database/Database/Implementation/HotfixDatabase.h b/src/server/database/Database/Implementation/HotfixDatabase.h
index 46da89df7b0..a926f045989 100644
--- a/src/server/database/Database/Implementation/HotfixDatabase.h
+++ b/src/server/database/Database/Implementation/HotfixDatabase.h
@@ -844,6 +844,9 @@ enum HotfixDatabaseStatements : uint32
HOTFIX_SEL_SPELL_ITEM_ENCHANTMENT_CONDITION,
HOTFIX_SEL_SPELL_ITEM_ENCHANTMENT_CONDITION_MAX_ID,
+ HOTFIX_SEL_SPELL_KEYBOUND_OVERRIDE,
+ HOTFIX_SEL_SPELL_KEYBOUND_OVERRIDE_MAX_ID,
+
HOTFIX_SEL_SPELL_LABEL,
HOTFIX_SEL_SPELL_LABEL_MAX_ID,
diff --git a/src/server/game/DataStores/DB2LoadInfo.h b/src/server/game/DataStores/DB2LoadInfo.h
index cd2098622ca..567a98e8d95 100644
--- a/src/server/game/DataStores/DB2LoadInfo.h
+++ b/src/server/game/DataStores/DB2LoadInfo.h
@@ -4876,6 +4876,20 @@ struct SpellItemEnchantmentConditionLoadInfo
static constexpr DB2LoadInfo Instance{ Fields, 31, &SpellItemEnchantmentConditionMeta::Instance, HOTFIX_SEL_SPELL_ITEM_ENCHANTMENT_CONDITION };
};
+struct SpellKeyboundOverrideLoadInfo
+{
+ static constexpr DB2FieldMeta Fields[5] =
+ {
+ { false, FT_INT, "ID" },
+ { false, FT_STRING_NOT_LOCALIZED, "Function" },
+ { true, FT_BYTE, "Type" },
+ { true, FT_INT, "Data" },
+ { true, FT_INT, "Flags" },
+ };
+
+ static constexpr DB2LoadInfo Instance{ Fields, 5, &SpellKeyboundOverrideMeta::Instance, HOTFIX_SEL_SPELL_KEYBOUND_OVERRIDE };
+};
+
struct SpellLabelLoadInfo
{
static constexpr DB2FieldMeta Fields[3] =
diff --git a/src/server/game/DataStores/DB2Stores.cpp b/src/server/game/DataStores/DB2Stores.cpp
index d57b0842b71..489e676b01d 100644
--- a/src/server/game/DataStores/DB2Stores.cpp
+++ b/src/server/game/DataStores/DB2Stores.cpp
@@ -286,6 +286,7 @@ DB2Storage<SpellFocusObjectEntry> sSpellFocusObjectStore("SpellFoc
DB2Storage<SpellInterruptsEntry> sSpellInterruptsStore("SpellInterrupts.db2", &SpellInterruptsLoadInfo::Instance);
DB2Storage<SpellItemEnchantmentEntry> sSpellItemEnchantmentStore("SpellItemEnchantment.db2", &SpellItemEnchantmentLoadInfo::Instance);
DB2Storage<SpellItemEnchantmentConditionEntry> sSpellItemEnchantmentConditionStore("SpellItemEnchantmentCondition.db2", &SpellItemEnchantmentConditionLoadInfo::Instance);
+DB2Storage<SpellKeyboundOverrideEntry> sSpellKeyboundOverrideStore("SpellKeyboundOverride.db2", &SpellKeyboundOverrideLoadInfo::Instance);
DB2Storage<SpellLabelEntry> sSpellLabelStore("SpellLabel.db2", &SpellLabelLoadInfo::Instance);
DB2Storage<SpellLearnSpellEntry> sSpellLearnSpellStore("SpellLearnSpell.db2", &SpellLearnSpellLoadInfo::Instance);
DB2Storage<SpellLevelsEntry> sSpellLevelsStore("SpellLevels.db2", &SpellLevelsLoadInfo::Instance);
@@ -887,6 +888,7 @@ uint32 DB2Manager::LoadStores(std::string const& dataPath, LocaleConstant defaul
LOAD_DB2(sSpellInterruptsStore);
LOAD_DB2(sSpellItemEnchantmentStore);
LOAD_DB2(sSpellItemEnchantmentConditionStore);
+ LOAD_DB2(sSpellKeyboundOverrideStore);
LOAD_DB2(sSpellLabelStore);
LOAD_DB2(sSpellLearnSpellStore);
LOAD_DB2(sSpellLevelsStore);
diff --git a/src/server/game/DataStores/DB2Stores.h b/src/server/game/DataStores/DB2Stores.h
index bc6cf523d27..c7ddcfebafc 100644
--- a/src/server/game/DataStores/DB2Stores.h
+++ b/src/server/game/DataStores/DB2Stores.h
@@ -212,6 +212,7 @@ TC_GAME_API extern DB2Storage<SpellFocusObjectEntry> sSpellFocusO
TC_GAME_API extern DB2Storage<SpellInterruptsEntry> sSpellInterruptsStore;
TC_GAME_API extern DB2Storage<SpellItemEnchantmentEntry> sSpellItemEnchantmentStore;
TC_GAME_API extern DB2Storage<SpellItemEnchantmentConditionEntry> sSpellItemEnchantmentConditionStore;
+TC_GAME_API extern DB2Storage<SpellKeyboundOverrideEntry> sSpellKeyboundOverrideStore;
TC_GAME_API extern DB2Storage<SpellLabelEntry> sSpellLabelStore;
TC_GAME_API extern DB2Storage<SpellLearnSpellEntry> sSpellLearnSpellStore;
TC_GAME_API extern DB2Storage<SpellLevelsEntry> sSpellLevelsStore;
diff --git a/src/server/game/DataStores/DB2Structure.h b/src/server/game/DataStores/DB2Structure.h
index 289f1be35fe..4b3fffe3996 100644
--- a/src/server/game/DataStores/DB2Structure.h
+++ b/src/server/game/DataStores/DB2Structure.h
@@ -3535,6 +3535,15 @@ struct SpellItemEnchantmentConditionEntry
std::array<uint8, 5> Logic;
};
+struct SpellKeyboundOverrideEntry
+{
+ uint32 ID;
+ char const* Function;
+ int8 Type;
+ int32 Data;
+ int32 Flags;
+};
+
struct SpellLabelEntry
{
uint32 ID;
diff --git a/src/server/game/Handlers/SpellHandler.cpp b/src/server/game/Handlers/SpellHandler.cpp
index 020709d3864..c91a2714ff5 100644
--- a/src/server/game/Handlers/SpellHandler.cpp
+++ b/src/server/game/Handlers/SpellHandler.cpp
@@ -683,3 +683,16 @@ void WorldSession::HandleRequestCategoryCooldowns(WorldPackets::Spells::RequestC
{
_player->SendSpellCategoryCooldowns();
}
+
+void WorldSession::HandleKeyboundOverride(WorldPackets::Spells::KeyboundOverride& keyboundOverride)
+{
+ Player* player = GetPlayer();
+ if (!player->HasAuraTypeWithMiscvalue(SPELL_AURA_KEYBOUND_OVERRIDE, keyboundOverride.OverrideID))
+ return;
+
+ SpellKeyboundOverrideEntry const* spellKeyboundOverride = sSpellKeyboundOverrideStore.LookupEntry(keyboundOverride.OverrideID);
+ if (!spellKeyboundOverride)
+ return;
+
+ player->CastSpell(player, spellKeyboundOverride->Data);
+}
diff --git a/src/server/game/Server/Packets/SpellPackets.cpp b/src/server/game/Server/Packets/SpellPackets.cpp
index d3010690bbc..a91b74076f8 100644
--- a/src/server/game/Server/Packets/SpellPackets.cpp
+++ b/src/server/game/Server/Packets/SpellPackets.cpp
@@ -1053,4 +1053,9 @@ void TradeSkillSetFavorite::Read()
_worldPacket >> RecipeID;
IsFavorite = _worldPacket.ReadBit();
}
+
+void KeyboundOverride::Read()
+{
+ _worldPacket >> OverrideID;
+}
}
diff --git a/src/server/game/Server/Packets/SpellPackets.h b/src/server/game/Server/Packets/SpellPackets.h
index deb37c81647..c4abdceb31f 100644
--- a/src/server/game/Server/Packets/SpellPackets.h
+++ b/src/server/game/Server/Packets/SpellPackets.h
@@ -1083,6 +1083,16 @@ namespace WorldPackets
bool IsFavorite = false;
};
+ class KeyboundOverride final : public ClientPacket
+ {
+ public:
+ KeyboundOverride(WorldPacket&& packet) : ClientPacket(CMSG_KEYBOUND_OVERRIDE, std::move(packet)) { }
+
+ void Read() override;
+
+ uint16 OverrideID = 0;
+ };
+
ByteBuffer& operator>>(ByteBuffer& buffer, SpellCastRequest& request);
}
}
diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp
index 823539281d0..60ca120a7a5 100644
--- a/src/server/game/Server/Protocol/Opcodes.cpp
+++ b/src/server/game/Server/Protocol/Opcodes.cpp
@@ -535,7 +535,7 @@ void OpcodeTable::Initialize()
DEFINE_HANDLER(CMSG_JOIN_PET_BATTLE_QUEUE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL);
DEFINE_HANDLER(CMSG_JOIN_RATED_BATTLEGROUND, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL);
DEFINE_HANDLER(CMSG_KEEP_ALIVE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_EarlyProccess);
- DEFINE_HANDLER(CMSG_KEYBOUND_OVERRIDE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL);
+ DEFINE_HANDLER(CMSG_KEYBOUND_OVERRIDE, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleKeyboundOverride);
DEFINE_HANDLER(CMSG_LATENCY_REPORT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::Handle_NULL);
DEFINE_HANDLER(CMSG_LEARN_PVP_TALENTS, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleLearnPvpTalentsOpcode);
DEFINE_HANDLER(CMSG_LEARN_TALENTS, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleLearnTalentsOpcode);
diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h
index 2d154099d77..3bdbbb23db3 100644
--- a/src/server/game/Server/WorldSession.h
+++ b/src/server/game/Server/WorldSession.h
@@ -721,6 +721,7 @@ namespace WorldPackets
class MissileTrajectoryCollision;
class UpdateMissileTrajectory;
class TradeSkillSetFavorite;
+ class KeyboundOverride;
}
namespace Talent
@@ -1734,6 +1735,7 @@ class TC_GAME_API WorldSession
void HandleRequestCategoryCooldowns(WorldPackets::Spells::RequestCategoryCooldowns& requestCategoryCooldowns);
void HandleCloseInteraction(WorldPackets::Misc::CloseInteraction& closeInteraction);
void HandleConversationLineStarted(WorldPackets::Misc::ConversationLineStarted& conversationLineStarted);
+ void HandleKeyboundOverride(WorldPackets::Spells::KeyboundOverride& keyboundOverride);
// Adventure Journal
void HandleAdventureJournalOpenQuest(WorldPackets::AdventureJournal::AdventureJournalOpenQuest& openQuest);
diff --git a/src/server/game/Spells/Auras/SpellAuraDefines.h b/src/server/game/Spells/Auras/SpellAuraDefines.h
index 3b4b4b34f74..96419d42b7f 100644
--- a/src/server/game/Spells/Auras/SpellAuraDefines.h
+++ b/src/server/game/Spells/Auras/SpellAuraDefines.h
@@ -497,7 +497,7 @@ enum AuraType : uint32
SPELL_AURA_OVERRIDE_SPELL_VISUAL = 403,
SPELL_AURA_OVERRIDE_ATTACK_POWER_BY_SP_PCT = 404,
SPELL_AURA_MOD_RATING_PCT = 405,
- SPELL_AURA_KEYBOUND_OVERRIDE = 406, // NYI
+ SPELL_AURA_KEYBOUND_OVERRIDE = 406,
SPELL_AURA_MOD_FEAR_2 = 407, // NYI
SPELL_AURA_SET_ACTION_BUTTON_SPELL_COUNT = 408,
SPELL_AURA_CAN_TURN_WHILE_FALLING = 409,
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
index 83d5673933a..2fcb31059d7 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -473,7 +473,7 @@ NonDefaultConstructible<pAuraEffectHandler> AuraEffectHandler[TOTAL_AURAS]=
&AuraEffect::HandleNoImmediateEffect, //403 SPELL_AURA_OVERRIDE_SPELL_VISUAL implemented in Unit::GetCastSpellXSpellVisualId
&AuraEffect::HandleOverrideAttackPowerBySpellPower, //404 SPELL_AURA_OVERRIDE_ATTACK_POWER_BY_SP_PCT
&AuraEffect::HandleModRatingPct, //405 SPELL_AURA_MOD_RATING_PCT
- &AuraEffect::HandleNULL, //406 SPELL_AURA_KEYBOUND_OVERRIDE
+ &AuraEffect::HandleNoImmediateEffect, //406 SPELL_AURA_KEYBOUND_OVERRIDE implemented in WorldSession::HandleKeyboundOverride
&AuraEffect::HandleNULL, //407 SPELL_AURA_MOD_FEAR_2
&AuraEffect::HandleUnused, //408 SPELL_AURA_SET_ACTION_BUTTON_SPELL_COUNT clientside
&AuraEffect::HandleAuraCanTurnWhileFalling, //409 SPELL_AURA_CAN_TURN_WHILE_FALLING