aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/updates/hotfixes/master/2021_10_10_00_hotfixes.sql23
-rw-r--r--src/server/database/Database/Implementation/HotfixDatabase.cpp5
-rw-r--r--src/server/database/Database/Implementation/HotfixDatabase.h3
-rw-r--r--src/server/game/DataStores/DB2LoadInfo.h16
-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.h8
-rw-r--r--src/server/game/Spells/Spell.cpp37
-rw-r--r--src/server/game/Spells/SpellInfo.cpp2
-rw-r--r--src/server/game/Spells/SpellInfo.h1
-rw-r--r--src/server/game/Spells/SpellMgr.cpp6
-rw-r--r--src/server/game/Spells/SpellMgr.h2
12 files changed, 103 insertions, 3 deletions
diff --git a/sql/updates/hotfixes/master/2021_10_10_00_hotfixes.sql b/sql/updates/hotfixes/master/2021_10_10_00_hotfixes.sql
new file mode 100644
index 00000000000..8ec989f1b64
--- /dev/null
+++ b/sql/updates/hotfixes/master/2021_10_10_00_hotfixes.sql
@@ -0,0 +1,23 @@
+--
+-- Table structure for table `spell_reagents_currency`
+--
+DROP TABLE IF EXISTS `spell_reagents_currency`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!50503 SET character_set_client = utf8mb4 */;
+CREATE TABLE `spell_reagents_currency` (
+ `ID` int(10) unsigned NOT NULL DEFAULT '0',
+ `SpellID` int(11) NOT NULL DEFAULT '0',
+ `CurrencyTypesID` smallint(5) unsigned NOT NULL DEFAULT '0',
+ `CurrencyCount` smallint(5) unsigned NOT NULL DEFAULT '0',
+ `VerifiedBuild` int(11) NOT NULL DEFAULT '0',
+ PRIMARY KEY (`ID`,`VerifiedBuild`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table data for table `spell_reagents_currency`
+--
+INSERT INTO `spell_reagents_currency`
+SELECT hb.`RecordId`, CONV(HEX(SUBSTRING(hb.`Blob`, 1, 4)), 16, 10), CONV(HEX(SUBSTRING(hb.`Blob`, 5, 2)), 16, 10), CONV(HEX(SUBSTRING(hb.`Blob`, 7, 2)), 16, 10), hb.`VerifiedBuild` FROM `hotfix_blob` hb WHERE hb.`TableHash`=0x2049B60C AND hb.`locale`='enUS';
+
+DELETE FROM `hotfix_blob` WHERE `TableHash`=0x2049B60C;
diff --git a/src/server/database/Database/Implementation/HotfixDatabase.cpp b/src/server/database/Database/Implementation/HotfixDatabase.cpp
index 67420de9325..4ec6219cb45 100644
--- a/src/server/database/Database/Implementation/HotfixDatabase.cpp
+++ b/src/server/database/Database/Implementation/HotfixDatabase.cpp
@@ -1423,6 +1423,11 @@ void HotfixDatabaseConnection::DoPrepareStatements()
" WHERE (`VerifiedBuild` > 0) = ?", CONNECTION_SYNCH);
PREPARE_MAX_ID_STMT(HOTFIX_SEL_SPELL_REAGENTS, "SELECT MAX(ID) + 1 FROM spell_reagents", CONNECTION_SYNCH);
+ // SpellReagentsCurrency.db2
+ PrepareStatement(HOTFIX_SEL_SPELL_REAGENTS_CURRENCY, "SELECT ID, SpellID, CurrencyTypesID, CurrencyCount FROM spell_reagents_currency"
+ " WHERE (`VerifiedBuild` > 0) = ?", CONNECTION_SYNCH);
+ PREPARE_MAX_ID_STMT(HOTFIX_SEL_SPELL_REAGENTS_CURRENCY, "SELECT MAX(ID) + 1 FROM spell_reagents_currency", CONNECTION_SYNCH);
+
// SpellScaling.db2
PrepareStatement(HOTFIX_SEL_SPELL_SCALING, "SELECT ID, SpellID, MinScalingLevel, MaxScalingLevel, ScalesFromItemLevel FROM spell_scaling"
" WHERE (`VerifiedBuild` > 0) = ?", CONNECTION_SYNCH);
diff --git a/src/server/database/Database/Implementation/HotfixDatabase.h b/src/server/database/Database/Implementation/HotfixDatabase.h
index 431dfef994b..e11c93a7fb7 100644
--- a/src/server/database/Database/Implementation/HotfixDatabase.h
+++ b/src/server/database/Database/Implementation/HotfixDatabase.h
@@ -826,6 +826,9 @@ enum HotfixDatabaseStatements : uint32
HOTFIX_SEL_SPELL_REAGENTS,
HOTFIX_SEL_SPELL_REAGENTS_MAX_ID,
+ HOTFIX_SEL_SPELL_REAGENTS_CURRENCY,
+ HOTFIX_SEL_SPELL_REAGENTS_CURRENCY_MAX_ID,
+
HOTFIX_SEL_SPELL_SCALING,
HOTFIX_SEL_SPELL_SCALING_MAX_ID,
diff --git a/src/server/game/DataStores/DB2LoadInfo.h b/src/server/game/DataStores/DB2LoadInfo.h
index 460e49c73bb..9ad1558fc06 100644
--- a/src/server/game/DataStores/DB2LoadInfo.h
+++ b/src/server/game/DataStores/DB2LoadInfo.h
@@ -5467,6 +5467,22 @@ struct SpellReagentsLoadInfo
}
};
+struct SpellReagentsCurrencyLoadInfo
+{
+ static DB2LoadInfo const* Instance()
+ {
+ static DB2FieldMeta const fields[] =
+ {
+ { false, FT_INT, "ID" },
+ { true, FT_INT, "SpellID" },
+ { false, FT_SHORT, "CurrencyTypesID" },
+ { false, FT_SHORT, "CurrencyCount" },
+ };
+ static DB2LoadInfo const loadInfo(&fields[0], std::extent<decltype(fields)>::value, SpellReagentsCurrencyMeta::Instance(), HOTFIX_SEL_SPELL_REAGENTS_CURRENCY);
+ return &loadInfo;
+ }
+};
+
struct SpellScalingLoadInfo
{
static DB2LoadInfo const* Instance()
diff --git a/src/server/game/DataStores/DB2Stores.cpp b/src/server/game/DataStores/DB2Stores.cpp
index cabdc8606a9..7254de7c37e 100644
--- a/src/server/game/DataStores/DB2Stores.cpp
+++ b/src/server/game/DataStores/DB2Stores.cpp
@@ -284,6 +284,7 @@ DB2Storage<SpellProcsPerMinuteModEntry> sSpellProcsPerMinuteModStore("Sp
DB2Storage<SpellRadiusEntry> sSpellRadiusStore("SpellRadius.db2", SpellRadiusLoadInfo::Instance());
DB2Storage<SpellRangeEntry> sSpellRangeStore("SpellRange.db2", SpellRangeLoadInfo::Instance());
DB2Storage<SpellReagentsEntry> sSpellReagentsStore("SpellReagents.db2", SpellReagentsLoadInfo::Instance());
+DB2Storage<SpellReagentsCurrencyEntry> sSpellReagentsCurrencyStore("SpellReagentsCurrency.db2", SpellReagentsCurrencyLoadInfo::Instance());
DB2Storage<SpellScalingEntry> sSpellScalingStore("SpellScaling.db2", SpellScalingLoadInfo::Instance());
DB2Storage<SpellShapeshiftEntry> sSpellShapeshiftStore("SpellShapeshift.db2", SpellShapeshiftLoadInfo::Instance());
DB2Storage<SpellShapeshiftFormEntry> sSpellShapeshiftFormStore("SpellShapeshiftForm.db2", SpellShapeshiftFormLoadInfo::Instance());
@@ -834,6 +835,7 @@ uint32 DB2Manager::LoadStores(std::string const& dataPath, LocaleConstant defaul
LOAD_DB2(sSpellRadiusStore);
LOAD_DB2(sSpellRangeStore);
LOAD_DB2(sSpellReagentsStore);
+ LOAD_DB2(sSpellReagentsCurrencyStore);
LOAD_DB2(sSpellScalingStore);
LOAD_DB2(sSpellShapeshiftStore);
LOAD_DB2(sSpellShapeshiftFormStore);
diff --git a/src/server/game/DataStores/DB2Stores.h b/src/server/game/DataStores/DB2Stores.h
index 55bce5e6a41..278fab3fa12 100644
--- a/src/server/game/DataStores/DB2Stores.h
+++ b/src/server/game/DataStores/DB2Stores.h
@@ -212,6 +212,7 @@ TC_GAME_API extern DB2Storage<SpellProcsPerMinuteEntry> sSpellProcsP
TC_GAME_API extern DB2Storage<SpellRadiusEntry> sSpellRadiusStore;
TC_GAME_API extern DB2Storage<SpellRangeEntry> sSpellRangeStore;
TC_GAME_API extern DB2Storage<SpellReagentsEntry> sSpellReagentsStore;
+TC_GAME_API extern DB2Storage<SpellReagentsCurrencyEntry> sSpellReagentsCurrencyStore;
TC_GAME_API extern DB2Storage<SpellScalingEntry> sSpellScalingStore;
TC_GAME_API extern DB2Storage<SpellShapeshiftEntry> sSpellShapeshiftStore;
TC_GAME_API extern DB2Storage<SpellShapeshiftFormEntry> sSpellShapeshiftFormStore;
diff --git a/src/server/game/DataStores/DB2Structure.h b/src/server/game/DataStores/DB2Structure.h
index 351f6e3d94e..39805e50e1d 100644
--- a/src/server/game/DataStores/DB2Structure.h
+++ b/src/server/game/DataStores/DB2Structure.h
@@ -3322,6 +3322,14 @@ struct SpellReagentsEntry
int16 ReagentCount[MAX_SPELL_REAGENTS];
};
+struct SpellReagentsCurrencyEntry
+{
+ uint32 ID;
+ int32 SpellID;
+ uint16 CurrencyTypesID;
+ uint16 CurrencyCount;
+};
+
struct SpellScalingEntry
{
uint32 ID;
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index bb1ab3c7333..dac726f2c56 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -4152,7 +4152,6 @@ inline void FillSpellCastFailedArgs(T& packet, ObjectGuid castId, SpellInfo cons
packet.FailedArg1 = *param1;
else
{
- uint32 missingItem = 0;
for (uint32 i = 0; i < MAX_SPELL_REAGENTS; i++)
{
if (spellInfo->Reagent[i] <= 0)
@@ -4163,12 +4162,27 @@ inline void FillSpellCastFailedArgs(T& packet, ObjectGuid castId, SpellInfo cons
if (!caster->HasItemCount(itemid, itemcount))
{
- missingItem = itemid;
+ packet.FailedArg1 = itemid; // first missing item
break;
}
}
- packet.FailedArg1 = missingItem; // first missing item
}
+
+ if (param2)
+ packet.FailedArg2 = *param2;
+ else if (!param1)
+ {
+ for (SpellReagentsCurrencyEntry const* reagentsCurrency : spellInfo->ReagentsCurrency)
+ {
+ if (!caster->HasCurrency(reagentsCurrency->CurrencyTypesID, reagentsCurrency->CurrencyCount))
+ {
+ packet.FailedArg1 = -1;
+ packet.FailedArg2 = reagentsCurrency->CurrencyTypesID;
+ break;
+ }
+ }
+ }
+
break;
}
case SPELL_FAILED_CANT_UNTALENT:
@@ -5019,6 +5033,9 @@ void Spell::TakeReagents()
p_caster->DestroyItemCount(itemid, itemcount, true);
}
+
+ for (SpellReagentsCurrencyEntry const* reagentsCurrency : m_spellInfo->ReagentsCurrency)
+ p_caster->ModifyCurrency(reagentsCurrency->CurrencyTypesID, -int32(reagentsCurrency->CurrencyCount), false, true);
}
void Spell::HandleThreatSpells()
@@ -6753,6 +6770,20 @@ SpellCastResult Spell::CheckItems(int32* param1 /*= nullptr*/, int32* param2 /*=
return SPELL_FAILED_REAGENTS;
}
}
+
+ for (SpellReagentsCurrencyEntry const* reagentsCurrency : m_spellInfo->ReagentsCurrency)
+ {
+ if (!player->HasCurrency(reagentsCurrency->CurrencyTypesID, reagentsCurrency->CurrencyCount))
+ {
+ if (param1)
+ *param1 = -1;
+
+ if (param2)
+ *param2 = reagentsCurrency->CurrencyTypesID;
+
+ return SPELL_FAILED_REAGENTS;
+ }
+ }
}
// check totem-item requirements (items presence in inventory)
diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp
index 61e04f1c8e4..0e5b1cb59fe 100644
--- a/src/server/game/Spells/SpellInfo.cpp
+++ b/src/server/game/Spells/SpellInfo.cpp
@@ -1228,6 +1228,8 @@ SpellInfo::SpellInfo(SpellNameEntry const* spellName, ::Difficulty difficulty, S
std::copy(std::begin(_reagents->ReagentCount), std::end(_reagents->ReagentCount), ReagentCount.begin());
}
+ ReagentsCurrency = data.ReagentsCurrency;
+
// SpellShapeshiftEntry
if (SpellShapeshiftEntry const* _shapeshift = data.Shapeshift)
{
diff --git a/src/server/game/Spells/SpellInfo.h b/src/server/game/Spells/SpellInfo.h
index fbd18c7eb07..7e29f202a73 100644
--- a/src/server/game/Spells/SpellInfo.h
+++ b/src/server/game/Spells/SpellInfo.h
@@ -402,6 +402,7 @@ class TC_GAME_API SpellInfo
std::array<uint32, MAX_SPELL_TOTEMS> TotemCategory = {};
std::array<int32, MAX_SPELL_REAGENTS> Reagent = {};
std::array<uint32, MAX_SPELL_REAGENTS> ReagentCount = {};
+ std::vector<SpellReagentsCurrencyEntry const*> ReagentsCurrency;
int32 EquippedItemClass = -1;
int32 EquippedItemSubClassMask = 0;
int32 EquippedItemInventoryTypeMask = 0;
diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp
index 8425b6a1a5f..c0261282783 100644
--- a/src/server/game/Spells/SpellMgr.cpp
+++ b/src/server/game/Spells/SpellMgr.cpp
@@ -2557,6 +2557,9 @@ void SpellMgr::LoadSpellInfoStore()
for (SpellReagentsEntry const* reagents : sSpellReagentsStore)
loadData[{ reagents->SpellID, DIFFICULTY_NONE }].Reagents = reagents;
+ for (SpellReagentsCurrencyEntry const* reagentsCurrency : sSpellReagentsCurrencyStore)
+ loadData[{ reagentsCurrency->SpellID, DIFFICULTY_NONE }].ReagentsCurrency.push_back(reagentsCurrency);
+
for (SpellScalingEntry const* scaling : sSpellScalingStore)
loadData[{ scaling->SpellID, DIFFICULTY_NONE }].Scaling = scaling;
@@ -2639,6 +2642,9 @@ void SpellMgr::LoadSpellInfoStore()
if (!data.second.Reagents)
data.second.Reagents = fallbackData->Reagents;
+ if (data.second.ReagentsCurrency.empty())
+ data.second.ReagentsCurrency = fallbackData->ReagentsCurrency;
+
if (!data.second.Scaling)
data.second.Scaling = fallbackData->Scaling;
diff --git a/src/server/game/Spells/SpellMgr.h b/src/server/game/Spells/SpellMgr.h
index df6ebba3a45..840648ecdfe 100644
--- a/src/server/game/Spells/SpellMgr.h
+++ b/src/server/game/Spells/SpellMgr.h
@@ -56,6 +56,7 @@ struct SpellMiscEntry;
struct SpellNameEntry;
struct SpellPowerEntry;
struct SpellReagentsEntry;
+struct SpellReagentsCurrencyEntry;
struct SpellScalingEntry;
struct SpellShapeshiftEntry;
struct SpellTargetRestrictionsEntry;
@@ -617,6 +618,7 @@ struct SpellInfoLoadHelper
SpellMiscEntry const* Misc = nullptr;
std::array<SpellPowerEntry const*, MAX_POWERS_PER_SPELL> Powers;
SpellReagentsEntry const* Reagents = nullptr;
+ std::vector<SpellReagentsCurrencyEntry const*> ReagentsCurrency;
SpellScalingEntry const* Scaling = nullptr;
SpellShapeshiftEntry const* Shapeshift = nullptr;
SpellTargetRestrictionsEntry const* TargetRestrictions = nullptr;