diff options
-rw-r--r-- | sql/updates/hotfixes/master/2024_03_28_00_hotfixes.sql | 12 | ||||
-rw-r--r-- | src/server/database/Database/Implementation/HotfixDatabase.cpp | 4 | ||||
-rw-r--r-- | src/server/database/Database/Implementation/HotfixDatabase.h | 3 | ||||
-rw-r--r-- | src/server/game/DataStores/DB2LoadInfo.h | 13 | ||||
-rw-r--r-- | src/server/game/DataStores/DB2Stores.cpp | 11 | ||||
-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/Server/Packets/HotfixPackets.h | 3 | ||||
-rw-r--r-- | src/server/scripts/Spells/spell_generic.cpp | 54 |
9 files changed, 59 insertions, 50 deletions
diff --git a/sql/updates/hotfixes/master/2024_03_28_00_hotfixes.sql b/sql/updates/hotfixes/master/2024_03_28_00_hotfixes.sql new file mode 100644 index 00000000000..e0e8a296116 --- /dev/null +++ b/sql/updates/hotfixes/master/2024_03_28_00_hotfixes.sql @@ -0,0 +1,12 @@ +-- +-- Table structure for table `char_base_info` +-- +DROP TABLE IF EXISTS `char_base_info`; +CREATE TABLE `char_base_info` ( + `ID` int unsigned NOT NULL DEFAULT '0', + `RaceID` tinyint NOT NULL DEFAULT '0', + `ClassID` tinyint NOT NULL DEFAULT '0', + `OtherFactionRaceID` int NOT NULL DEFAULT '0', + `VerifiedBuild` int NOT NULL DEFAULT '0', + PRIMARY KEY (`ID`,`VerifiedBuild`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; diff --git a/src/server/database/Database/Implementation/HotfixDatabase.cpp b/src/server/database/Database/Implementation/HotfixDatabase.cpp index 2c33390af10..4e5bec49b13 100644 --- a/src/server/database/Database/Implementation/HotfixDatabase.cpp +++ b/src/server/database/Database/Implementation/HotfixDatabase.cpp @@ -305,6 +305,10 @@ void HotfixDatabaseConnection::DoPrepareStatements() "MythicPlusSeasonID, PvPSeasonID, SrcItemBonusTreeID FROM challenge_mode_item_bonus_override WHERE (`VerifiedBuild` > 0) = ?", CONNECTION_SYNCH); PREPARE_MAX_ID_STMT(HOTFIX_SEL_CHALLENGE_MODE_ITEM_BONUS_OVERRIDE, "SELECT MAX(ID) + 1 FROM challenge_mode_item_bonus_override", CONNECTION_SYNCH); + // CharBaseInfo.db2 + PrepareStatement(HOTFIX_SEL_CHAR_BASE_INFO, "SELECT ID, RaceID, ClassID, OtherFactionRaceID FROM char_base_info WHERE (`VerifiedBuild` > 0) = ?", CONNECTION_SYNCH); + PREPARE_MAX_ID_STMT(HOTFIX_SEL_CHAR_BASE_INFO, "SELECT MAX(ID) + 1 FROM char_base_info", CONNECTION_SYNCH); + // CharTitles.db2 PrepareStatement(HOTFIX_SEL_CHAR_TITLES, "SELECT ID, Name, Name1, MaskID, Flags FROM char_titles WHERE (`VerifiedBuild` > 0) = ?", CONNECTION_SYNCH); PREPARE_MAX_ID_STMT(HOTFIX_SEL_CHAR_TITLES, "SELECT MAX(ID) + 1 FROM char_titles", CONNECTION_SYNCH); diff --git a/src/server/database/Database/Implementation/HotfixDatabase.h b/src/server/database/Database/Implementation/HotfixDatabase.h index 45600062398..7b1b6804571 100644 --- a/src/server/database/Database/Implementation/HotfixDatabase.h +++ b/src/server/database/Database/Implementation/HotfixDatabase.h @@ -192,6 +192,9 @@ enum HotfixDatabaseStatements : uint32 HOTFIX_SEL_CHALLENGE_MODE_ITEM_BONUS_OVERRIDE, HOTFIX_SEL_CHALLENGE_MODE_ITEM_BONUS_OVERRIDE_MAX_ID, + HOTFIX_SEL_CHAR_BASE_INFO, + HOTFIX_SEL_CHAR_BASE_INFO_MAX_ID, + HOTFIX_SEL_CHAR_TITLES, HOTFIX_SEL_CHAR_TITLES_MAX_ID, HOTFIX_SEL_CHAR_TITLES_LOCALE, diff --git a/src/server/game/DataStores/DB2LoadInfo.h b/src/server/game/DataStores/DB2LoadInfo.h index 7f52e54274c..b363192dfdf 100644 --- a/src/server/game/DataStores/DB2LoadInfo.h +++ b/src/server/game/DataStores/DB2LoadInfo.h @@ -841,6 +841,19 @@ struct ChallengeModeItemBonusOverrideLoadInfo static constexpr DB2LoadInfo Instance{ Fields, 8, &ChallengeModeItemBonusOverrideMeta::Instance, HOTFIX_SEL_CHALLENGE_MODE_ITEM_BONUS_OVERRIDE }; }; +struct CharBaseInfoLoadInfo +{ + static constexpr DB2FieldMeta Fields[4] = + { + { false, FT_INT, "ID" }, + { true, FT_BYTE, "RaceID" }, + { true, FT_BYTE, "ClassID" }, + { true, FT_INT, "OtherFactionRaceID" }, + }; + + static constexpr DB2LoadInfo Instance{ Fields, 4, &CharBaseInfoMeta::Instance, HOTFIX_SEL_CHAR_BASE_INFO }; +}; + struct CharTitlesLoadInfo { static constexpr DB2FieldMeta Fields[5] = diff --git a/src/server/game/DataStores/DB2Stores.cpp b/src/server/game/DataStores/DB2Stores.cpp index 8bd70407d92..2a30e0974a0 100644 --- a/src/server/game/DataStores/DB2Stores.cpp +++ b/src/server/game/DataStores/DB2Stores.cpp @@ -88,6 +88,7 @@ DB2Storage<BroadcastTextDurationEntry> sBroadcastTextDurationStore("Bro DB2Storage<Cfg_CategoriesEntry> sCfgCategoriesStore("Cfg_Categories.db2", &CfgCategoriesLoadInfo::Instance); DB2Storage<Cfg_RegionsEntry> sCfgRegionsStore("Cfg_Regions.db2", &CfgRegionsLoadInfo::Instance); DB2Storage<ChallengeModeItemBonusOverrideEntry> sChallengeModeItemBonusOverrideStore("ChallengeModeItemBonusOverride.db2", &ChallengeModeItemBonusOverrideLoadInfo::Instance); +DB2Storage<CharBaseInfoEntry> sCharBaseInfoStore("CharBaseInfo.db2", &CharBaseInfoLoadInfo::Instance); DB2Storage<CharTitlesEntry> sCharTitlesStore("CharTitles.db2", &CharTitlesLoadInfo::Instance); DB2Storage<CharacterLoadoutEntry> sCharacterLoadoutStore("CharacterLoadout.db2", &CharacterLoadoutLoadInfo::Instance); DB2Storage<CharacterLoadoutItemEntry> sCharacterLoadoutItemStore("CharacterLoadoutItem.db2", &CharacterLoadoutItemLoadInfo::Instance); @@ -450,6 +451,7 @@ namespace std::unordered_map<uint32 /*azeritePowerSetId*/, std::vector<AzeritePowerSetMemberEntry const*>> _azeritePowers; std::unordered_map<std::pair<uint32 /*azeriteUnlockSetId*/, ItemContext>, std::array<uint8, MAX_AZERITE_EMPOWERED_TIER>> _azeriteTierUnlockLevels; std::unordered_map<std::pair<int32 /*broadcastTextId*/, CascLocaleBit /*cascLocaleBit*/>, int32> _broadcastTextDurations; + std::unordered_map<std::pair<uint8, uint8>, CharBaseInfoEntry const*> _charBaseInfoByRaceAndClass; std::array<ChrClassUIDisplayEntry const*, MAX_CLASSES> _uiDisplayByClass; std::array<std::array<uint32, MAX_POWERS>, MAX_CLASSES> _powersByClass; std::unordered_map<uint32 /*chrCustomizationOptionId*/, std::vector<ChrCustomizationChoiceEntry const*>> _chrCustomizationChoicesByOption; @@ -688,6 +690,7 @@ uint32 DB2Manager::LoadStores(std::string const& dataPath, LocaleConstant defaul LOAD_DB2(sCfgCategoriesStore); LOAD_DB2(sCfgRegionsStore); LOAD_DB2(sChallengeModeItemBonusOverrideStore); + LOAD_DB2(sCharBaseInfoStore); LOAD_DB2(sCharTitlesStore); LOAD_DB2(sCharacterLoadoutStore); LOAD_DB2(sCharacterLoadoutItemStore); @@ -1078,6 +1081,9 @@ uint32 DB2Manager::LoadStores(std::string const& dataPath, LocaleConstant defaul for (BroadcastTextDurationEntry const* broadcastTextDuration : sBroadcastTextDurationStore) _broadcastTextDurations[{ broadcastTextDuration->BroadcastTextID, CascLocaleBit(broadcastTextDuration->Locale) }] = broadcastTextDuration->Duration; + for (CharBaseInfoEntry const* charBaseInfo : sCharBaseInfoStore) + _charBaseInfoByRaceAndClass[{ charBaseInfo->RaceID, charBaseInfo->ClassID }] = charBaseInfo; + for (ChrClassUIDisplayEntry const* uiDisplay : sChrClassUIDisplayStore) { ASSERT(uiDisplay->ChrClassesID < MAX_CLASSES); @@ -2026,6 +2032,11 @@ int32 const* DB2Manager::GetBroadcastTextDuration(int32 broadcastTextId, LocaleC return Trinity::Containers::MapGetValuePtr(_broadcastTextDurations, { broadcastTextId, WowLocaleToCascLocaleBit[locale] }); } +CharBaseInfoEntry const* DB2Manager::GetCharBaseInfo(Races race, Classes class_) +{ + return Trinity::Containers::MapGetValuePtr(_charBaseInfoByRaceAndClass, { race, class_ }); +} + ChrClassUIDisplayEntry const* DB2Manager::GetUiDisplayForClass(Classes unitClass) const { ASSERT(unitClass < MAX_CLASSES); diff --git a/src/server/game/DataStores/DB2Stores.h b/src/server/game/DataStores/DB2Stores.h index 97c8dc502a4..fda324418ca 100644 --- a/src/server/game/DataStores/DB2Stores.h +++ b/src/server/game/DataStores/DB2Stores.h @@ -437,6 +437,7 @@ public: uint32 GetRequiredAzeriteLevelForAzeritePowerTier(uint32 azeriteUnlockSetId, ItemContext context, uint32 tier) const; static char const* GetBroadcastTextValue(BroadcastTextEntry const* broadcastText, LocaleConstant locale = DEFAULT_LOCALE, uint8 gender = GENDER_MALE, bool forceGender = false); int32 const* GetBroadcastTextDuration(int32 broadcastTextId, LocaleConstant locale = DEFAULT_LOCALE) const; + static CharBaseInfoEntry const* GetCharBaseInfo(Races race, Classes class_); ChrClassUIDisplayEntry const* GetUiDisplayForClass(Classes unitClass) const; static char const* GetClassName(uint8 class_, LocaleConstant locale = DEFAULT_LOCALE); uint32 GetPowerIndexByClass(Powers power, uint32 classId) const; diff --git a/src/server/game/DataStores/DB2Structure.h b/src/server/game/DataStores/DB2Structure.h index 2b1243dbb8f..4afcdbb0635 100644 --- a/src/server/game/DataStores/DB2Structure.h +++ b/src/server/game/DataStores/DB2Structure.h @@ -582,6 +582,14 @@ struct ChallengeModeItemBonusOverrideEntry uint32 SrcItemBonusTreeID; }; +struct CharBaseInfoEntry +{ + uint32 ID; + int8 RaceID; + int8 ClassID; + int32 OtherFactionRaceID; +}; + struct CharTitlesEntry { uint32 ID; diff --git a/src/server/game/Server/Packets/HotfixPackets.h b/src/server/game/Server/Packets/HotfixPackets.h index 7d85637bf26..7c4ab389348 100644 --- a/src/server/game/Server/Packets/HotfixPackets.h +++ b/src/server/game/Server/Packets/HotfixPackets.h @@ -18,10 +18,9 @@ #ifndef HotfixPackets_h__ #define HotfixPackets_h__ -#include "Packet.h" #include "Common.h" #include "DB2Stores.h" -#include "ObjectGuid.h" +#include "Packet.h" namespace WorldPackets { diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index 323b3c175fa..ff12c258c5e 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -408,37 +408,6 @@ class spell_gen_bandage : public SpellScript // 193970 - Mercenary Shapeshift class spell_gen_battleground_mercenary_shapeshift : public AuraScript { - using OtherFactionRacePriorityList = std::array<Races, 3>; - - inline static std::unordered_map<Races, OtherFactionRacePriorityList> const RaceInfo = - { - { RACE_HUMAN, { RACE_UNDEAD_PLAYER, RACE_BLOODELF } }, - { RACE_ORC, { RACE_DWARF } }, - { RACE_DWARF, { RACE_ORC, RACE_UNDEAD_PLAYER, RACE_TAUREN } }, - { RACE_NIGHTELF, { RACE_TROLL, RACE_BLOODELF } }, - { RACE_UNDEAD_PLAYER, { RACE_HUMAN } }, - { RACE_TAUREN, { RACE_DRAENEI, RACE_NIGHTELF } }, - { RACE_GNOME, { RACE_GOBLIN, RACE_BLOODELF } }, - { RACE_TROLL, { RACE_NIGHTELF, RACE_HUMAN, RACE_DRAENEI } }, - { RACE_GOBLIN, { RACE_GNOME, RACE_DWARF } }, - { RACE_BLOODELF, { RACE_HUMAN, RACE_NIGHTELF } }, - { RACE_DRAENEI, { RACE_TAUREN, RACE_ORC } }, - { RACE_WORGEN, { RACE_TROLL } }, - { RACE_PANDAREN_NEUTRAL, { RACE_PANDAREN_NEUTRAL } }, - { RACE_PANDAREN_ALLIANCE, { RACE_PANDAREN_HORDE, RACE_PANDAREN_NEUTRAL } }, - { RACE_PANDAREN_HORDE, { RACE_PANDAREN_ALLIANCE, RACE_PANDAREN_NEUTRAL } }, - { RACE_NIGHTBORNE, { RACE_NIGHTELF, RACE_HUMAN } }, - { RACE_HIGHMOUNTAIN_TAUREN, { RACE_DRAENEI, RACE_NIGHTELF } }, - { RACE_VOID_ELF, { RACE_TROLL, RACE_BLOODELF } }, - { RACE_LIGHTFORGED_DRAENEI, { RACE_TAUREN, RACE_ORC } }, - { RACE_ZANDALARI_TROLL, { RACE_KUL_TIRAN, RACE_HUMAN } }, - { RACE_KUL_TIRAN, { RACE_ZANDALARI_TROLL } }, - { RACE_DARK_IRON_DWARF, { RACE_MAGHAR_ORC, RACE_ORC } }, - { RACE_VULPERA, { RACE_MECHAGNOME, RACE_DARK_IRON_DWARF /*guessed, for shamans*/ } }, - { RACE_MAGHAR_ORC, { RACE_DARK_IRON_DWARF } }, - { RACE_MECHAGNOME, { RACE_VULPERA } }, - }; - inline static std::unordered_map<Races, std::array<uint32, 2>> const RaceDisplayIds = { { RACE_HUMAN, { 55239, 55238 } }, @@ -472,10 +441,9 @@ class spell_gen_battleground_mercenary_shapeshift : public AuraScript static Races GetReplacementRace(Races nativeRace, Classes playerClass) { - if (OtherFactionRacePriorityList const* otherRaces = Trinity::Containers::MapGetValuePtr(RaceInfo, nativeRace)) - for (Races race : *otherRaces) - if (sObjectMgr->GetPlayerInfo(race, playerClass)) - return race; + if (CharBaseInfoEntry const* charBaseInfo = DB2Manager::GetCharBaseInfo(nativeRace, playerClass)) + if (sObjectMgr->GetPlayerInfo(charBaseInfo->OtherFactionRaceID, playerClass)) + return Races(charBaseInfo->OtherFactionRaceID); return RACE_NONE; } @@ -490,16 +458,6 @@ class spell_gen_battleground_mercenary_shapeshift : public AuraScript bool Validate(SpellInfo const* /*spellInfo*/) override { - for (auto const& [race, otherRaces] : RaceInfo) - { - if (!sChrRacesStore.LookupEntry(race)) - return false; - - for (Races otherRace : otherRaces) - if (!sChrRacesStore.LookupEntry(otherRace)) - return false; - } - for (auto const& [race, displayIds] : RaceDisplayIds) { if (!sChrRacesStore.LookupEntry(race)) @@ -518,7 +476,7 @@ class spell_gen_battleground_mercenary_shapeshift : public AuraScript return true; } - void HandleApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes mode) + void HandleApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes mode) const { Unit* owner = GetUnitOwner(); Races otherFactionRace = GetReplacementRace(Races(owner->GetRace()), Classes(owner->GetClass())); @@ -532,7 +490,7 @@ class spell_gen_battleground_mercenary_shapeshift : public AuraScript UpdateRacials(Races(owner->GetRace()), otherFactionRace); } - void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) const { Unit* owner = GetUnitOwner(); Races otherFactionRace = GetReplacementRace(Races(owner->GetRace()), Classes(owner->GetClass())); @@ -542,7 +500,7 @@ class spell_gen_battleground_mercenary_shapeshift : public AuraScript UpdateRacials(otherFactionRace, Races(owner->GetRace())); } - void UpdateRacials(Races oldRace, Races newRace) + void UpdateRacials(Races oldRace, Races newRace) const { Player* player = GetUnitOwner()->ToPlayer(); if (!player) |