diff options
| -rw-r--r-- | sql/updates/hotfixes/master/2021_10_10_00_hotfixes.sql | 23 | ||||
| -rw-r--r-- | src/server/database/Database/Implementation/HotfixDatabase.cpp | 5 | ||||
| -rw-r--r-- | src/server/database/Database/Implementation/HotfixDatabase.h | 3 | ||||
| -rw-r--r-- | src/server/game/DataStores/DB2LoadInfo.h | 16 | ||||
| -rw-r--r-- | src/server/game/DataStores/DB2Stores.cpp | 2 | ||||
| -rw-r--r-- | src/server/game/DataStores/DB2Stores.h | 1 | ||||
| -rw-r--r-- | src/server/game/DataStores/DB2Structure.h | 8 | ||||
| -rw-r--r-- | src/server/game/Spells/Spell.cpp | 37 | ||||
| -rw-r--r-- | src/server/game/Spells/SpellInfo.cpp | 2 | ||||
| -rw-r--r-- | src/server/game/Spells/SpellInfo.h | 1 | ||||
| -rw-r--r-- | src/server/game/Spells/SpellMgr.cpp | 6 | ||||
| -rw-r--r-- | src/server/game/Spells/SpellMgr.h | 2 |
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; |
