summaryrefslogtreecommitdiff
path: root/src/server/game/Globals/ObjectMgr.cpp
diff options
context:
space:
mode:
authorBenjamin Jackson <38561765+heyitsbench@users.noreply.github.com>2025-05-27 09:40:57 -0400
committerGitHub <noreply@github.com>2025-05-27 14:40:57 +0100
commitdb18d5b0352a3ad122134a8847b836e21918f812 (patch)
tree311778519c2fb2670d2cf16301c41e354669172f /src/server/game/Globals/ObjectMgr.cpp
parentc10e4dc015390837abe7f4908aff1422a36d871a (diff)
refactor(Core): Use database tables for Shaman totems and Druid shapeshift forms. (#22104)
Co-authored-by: DoctorKraft <25483209+doctorkraft@users.noreply.github.com> Co-authored-by: Shauren <shauren.trinity@gmail.com> Co-authored-by: ForesterDev <11771800+ForesterDev@users.noreply.github.com>
Diffstat (limited to 'src/server/game/Globals/ObjectMgr.cpp')
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp133
1 files changed, 133 insertions, 0 deletions
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index a4033ca1cb..330ee91e0b 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -1785,6 +1785,139 @@ void ObjectMgr::LoadCreatureModelInfo()
LOG_INFO("server.loading", " ");
}
+void ObjectMgr::LoadPlayerTotemModels()
+{
+ uint32 oldMSTime = getMSTime();
+
+ QueryResult result = WorldDatabase.Query("SELECT TotemID, RaceID, ModelID from player_totem_model");
+
+ if (!result)
+ {
+ LOG_INFO("server.loading", ">> Loaded 0 player totem model records. DB table `player_totem_model` is empty.");
+ return;
+ }
+
+ uint32 count = 0;
+ do
+ {
+ Field* fields = result->Fetch();
+
+ SummonSlot totemSlot = SummonSlot(fields[0].Get<uint8>());
+ uint8 race = fields[1].Get<uint8>();
+ uint32 displayId = fields[2].Get<uint32>();
+
+ if (totemSlot < SUMMON_SLOT_TOTEM_FIRE || totemSlot >= MAX_TOTEM_SLOT)
+ {
+ LOG_ERROR("sql.sql", "Wrong TotemSlot {} in `player_totem_model` table, skipped.", totemSlot);
+ continue;
+ }
+
+ ChrRacesEntry const* raceEntry = sChrRacesStore.LookupEntry(race);
+ if (!raceEntry)
+ {
+ LOG_ERROR("sql.sql", "Race {} defined in `player_totem_model` does not exists, skipped.", uint32(race));
+ continue;
+ }
+
+ CreatureDisplayInfoEntry const* displayEntry = sCreatureDisplayInfoStore.LookupEntry(displayId);
+ if (!displayEntry)
+ {
+ LOG_ERROR("sql.sql", "TotemSlot: {} defined in `player_totem_model` has non-existing model ({}), skipped.", totemSlot, displayId);
+ continue;
+ }
+
+ _playerTotemModel[std::make_pair(totemSlot, Races(race))] = displayId;
+ ++count;
+ } while (result->NextRow());
+
+ LOG_INFO("server.loading", ">> Loaded {} player totem model records in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
+ LOG_INFO("server.loading", " ");
+}
+
+uint32 ObjectMgr::GetModelForTotem(SummonSlot totemSlot, Races race) const
+{
+ auto itr = _playerTotemModel.find(std::make_pair(totemSlot, race));
+ if (itr != _playerTotemModel.end())
+ return itr->second;
+
+ LOG_ERROR("misc", "TotemSlot {} with RaceID ({}) have no totem model data defined, set to default model.", totemSlot, race);
+ return 0;
+}
+
+void ObjectMgr::LoadPlayerShapeshiftModels()
+{
+ uint32 oldMSTime = getMSTime();
+
+ QueryResult result = WorldDatabase.Query("SELECT ShapeshiftID, RaceID, CustomizationID, GenderID, ModelID from player_shapeshift_model");
+
+ if (!result)
+ {
+ LOG_INFO("server.loading", ">> Loaded 0 player shapeshift model records. DB table `player_shapeshift_model` is empty.");
+ return;
+ }
+
+ uint32 count = 0;
+ do
+ {
+ Field* fields = result->Fetch();
+
+ ShapeshiftForm shapeshiftForm = ShapeshiftForm(fields[0].Get<uint8>());
+ uint8 race = fields[1].Get<uint8>();
+ uint8 customizationID = fields[2].Get<uint8>();
+ uint8 genderID = Gender(fields[3].Get<uint8>());
+ uint32 modelId = fields[4].Get<uint32>();
+
+ ChrRacesEntry const* raceEntry = sChrRacesStore.LookupEntry(race);
+ if (!raceEntry)
+ {
+ LOG_ERROR("sql.sql", "Race {} defined in `player_shapeshift_model` does not exists, skipped.", uint32(race));
+ continue;
+ }
+
+ CreatureDisplayInfoEntry const* displayEntry = sCreatureDisplayInfoStore.LookupEntry(modelId);
+ if (!displayEntry)
+ {
+ LOG_ERROR("sql.sql", "ShapeshiftForm: {}, Race: {} defined in `player_shapeshift_model` has non-existing model ({}), skipped.", shapeshiftForm, race, modelId);
+ continue;
+ }
+
+ _playerShapeshiftModel[std::make_tuple(shapeshiftForm, race, customizationID, genderID)] = modelId;
+ ++count;
+ } while (result->NextRow());
+
+ LOG_INFO("server.loading", ">> Loaded {} player totem model records in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
+ LOG_INFO("server.loading", " ");
+}
+
+uint32 ObjectMgr::GetModelForShapeshift(ShapeshiftForm form, Player* player) const
+{
+ uint8 customizationID;
+
+ if (player->GetTeamId() == TEAM_ALLIANCE)
+ customizationID = player->GetByteValue(PLAYER_BYTES, 3); // Use Hair Color
+ else
+ customizationID = player->GetByteValue(PLAYER_BYTES, 0); // Use Skin Color
+
+ auto itr = _playerShapeshiftModel.find(std::make_tuple(form, player->getRace(), customizationID, player->getGender()));
+ if (itr != _playerShapeshiftModel.end())
+ return itr->second; // Explicit combination
+
+ itr = _playerShapeshiftModel.find(std::make_tuple(form, player->getRace(), customizationID, GENDER_NONE));
+ if (itr != _playerShapeshiftModel.end())
+ return itr->second; // Combination applied to both genders
+
+ itr = _playerShapeshiftModel.find(std::make_tuple(form, player->getRace(), 255, player->getGender()));
+ if (itr != _playerShapeshiftModel.end())
+ return itr->second; // Default gender-dependent model
+
+ itr = _playerShapeshiftModel.find(std::make_tuple(form, player->getRace(), 255, GENDER_NONE));
+ if (itr != _playerShapeshiftModel.end())
+ return itr->second; // Last resort
+
+ LOG_DEBUG("entities.player", "ShapeshiftForm {} with RaceID ({}) have no shapeshift model data defined, using fallback data.", form, player->getRace());
+ return 0;
+}
+
void ObjectMgr::LoadLinkedRespawn()
{
uint32 oldMSTime = getMSTime();