Merge branch 'master' into Playerbot
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -711,6 +711,10 @@ struct DungeonEncounter
|
||||
typedef std::list<DungeonEncounter const*> DungeonEncounterList;
|
||||
typedef std::unordered_map<uint32, DungeonEncounterList> DungeonEncounterContainer;
|
||||
|
||||
typedef std::map<std::pair<SummonSlot /*TotemSlot*/, Races /*RaceId*/>, uint32 /*DisplayId*/> PlayerTotemModelMap;
|
||||
|
||||
typedef std::map<std::tuple<ShapeshiftForm /*ShapeshiftID*/, uint8 /*RaceID*/, uint8 /*CustomizationID*/, uint8 /*GenderID*/>, uint32 /*ModelID*/> PlayerShapeshiftModelMap;
|
||||
|
||||
static constexpr uint32 MAX_QUEST_MONEY_REWARDS = 10;
|
||||
typedef std::array<uint32, MAX_QUEST_MONEY_REWARDS> QuestMoneyRewardArray;
|
||||
typedef std::unordered_map<uint32, QuestMoneyRewardArray> QuestMoneyRewardStore;
|
||||
@@ -777,6 +781,10 @@ public:
|
||||
[[nodiscard]] ItemTemplateContainer const* GetItemTemplateStore() const { return &_itemTemplateStore; }
|
||||
[[nodiscard]] std::vector<ItemTemplate*> const* GetItemTemplateStoreFast() const { return &_itemTemplateStoreFast; }
|
||||
|
||||
uint32 GetModelForTotem(SummonSlot totemSlot, Races race) const;
|
||||
|
||||
uint32 GetModelForShapeshift(ShapeshiftForm form, Player* player) const;
|
||||
|
||||
ItemSetNameEntry const* GetItemSetNameEntry(uint32 itemId)
|
||||
{
|
||||
ItemSetNameContainer::iterator itr = _itemSetNameStore.find(itemId);
|
||||
@@ -1036,6 +1044,8 @@ public:
|
||||
void LoadCreatureAddons();
|
||||
void LoadGameObjectAddons();
|
||||
void LoadCreatureModelInfo();
|
||||
void LoadPlayerTotemModels();
|
||||
void LoadPlayerShapeshiftModels();
|
||||
void LoadEquipmentTemplates();
|
||||
void LoadCreatureMovementOverrides();
|
||||
void LoadGameObjectLocales();
|
||||
@@ -1623,6 +1633,10 @@ private:
|
||||
|
||||
std::set<uint32> _transportMaps; // Helper container storing map ids that are for transports only, loaded from gameobject_template
|
||||
|
||||
PlayerTotemModelMap _playerTotemModel;
|
||||
|
||||
PlayerShapeshiftModelMap _playerShapeshiftModel;
|
||||
|
||||
QuestMoneyRewardStore _questMoneyRewards;
|
||||
|
||||
struct GameobjectInstanceSavedState
|
||||
|
||||
Reference in New Issue
Block a user