diff options
author | Ovahlord <dreadkiller@gmx.de> | 2024-04-26 22:32:17 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-04-26 22:32:17 +0200 |
commit | b5ce4a66df0c76583c662056e46619c8fe98f297 (patch) | |
tree | 52e564422cac836f4e85e9ab0462f8f54d96e787 /src | |
parent | a361d3f5870a2b43f200c579314143a3bd219bab (diff) |
Core/Creature: implement overriding creature static flags based on spawnId and difficultyId (#29940)
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Entities/Creature/Creature.cpp | 20 | ||||
-rw-r--r-- | src/server/game/Entities/Creature/Creature.h | 2 | ||||
-rw-r--r-- | src/server/game/Entities/Creature/CreatureData.h | 22 | ||||
-rw-r--r-- | src/server/game/Globals/ObjectMgr.cpp | 66 | ||||
-rw-r--r-- | src/server/game/Globals/ObjectMgr.h | 5 | ||||
-rw-r--r-- | src/server/game/World/World.cpp | 3 |
6 files changed, 117 insertions, 1 deletions
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index c07672dd08c..b519961d569 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -561,7 +561,8 @@ bool Creature::InitEntry(uint32 entry, CreatureData const* data /*= nullptr*/) for (uint8 i = 0; i < MAX_CREATURE_SPELLS; ++i) m_spells[i] = GetCreatureTemplate()->spells[i]; - ApplyAllStaticFlags(m_creatureDifficulty->StaticFlags); + CreatureStaticFlagsHolder staticFlags = GenerateStaticFlags(m_creatureDifficulty, GetSpawnId(), GetMap()->GetDifficultyID()); + ApplyAllStaticFlags(staticFlags); _staticFlags.ApplyFlag(CREATURE_STATIC_FLAG_NO_XP, creatureInfo->type == CREATURE_TYPE_CRITTER || IsPet() @@ -701,6 +702,23 @@ bool Creature::UpdateEntry(uint32 entry, CreatureData const* data /*= nullptr*/, return true; } +CreatureStaticFlagsHolder Creature::GenerateStaticFlags(CreatureDifficulty const* creatureDifficulty, ObjectGuid::LowType spawnId, Difficulty difficultyId) const +{ + CreatureStaticFlagsOverride const* staticFlagsOverride = sObjectMgr->GetCreatureStaticFlagsOverride(spawnId, difficultyId); + if (!staticFlagsOverride) + return creatureDifficulty->StaticFlags; + + return CreatureStaticFlagsHolder( + staticFlagsOverride->StaticFlags1.value_or(creatureDifficulty->StaticFlags.GetFlags()), + staticFlagsOverride->StaticFlags2.value_or(creatureDifficulty->StaticFlags.GetFlags2()), + staticFlagsOverride->StaticFlags3.value_or(creatureDifficulty->StaticFlags.GetFlags3()), + staticFlagsOverride->StaticFlags4.value_or(creatureDifficulty->StaticFlags.GetFlags4()), + staticFlagsOverride->StaticFlags5.value_or(creatureDifficulty->StaticFlags.GetFlags5()), + staticFlagsOverride->StaticFlags6.value_or(creatureDifficulty->StaticFlags.GetFlags6()), + staticFlagsOverride->StaticFlags7.value_or(creatureDifficulty->StaticFlags.GetFlags7()), + staticFlagsOverride->StaticFlags8.value_or(creatureDifficulty->StaticFlags.GetFlags8())); +} + void Creature::ApplyAllStaticFlags(CreatureStaticFlagsHolder const& flags) { _staticFlags = flags; diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index a11b6b00ec9..3a29b188192 100644 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -557,6 +557,8 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma time_t _lastDamagedTime; // Part of Evade mechanics CreatureTextRepeatGroup m_textRepeat; + // Draws data from m_creatureDifficulty and spawn/difficulty based override data and returns a CreatureStaticFlagsHolder value which contains the data of both + CreatureStaticFlagsHolder GenerateStaticFlags(CreatureDifficulty const* creatureDifficulty, ObjectGuid::LowType spawnId, Difficulty difficultyId) const; void ApplyAllStaticFlags(CreatureStaticFlagsHolder const& flags); // Regenerate health diff --git a/src/server/game/Entities/Creature/CreatureData.h b/src/server/game/Entities/Creature/CreatureData.h index dea0e4be37b..be4a65dd417 100644 --- a/src/server/game/Entities/Creature/CreatureData.h +++ b/src/server/game/Entities/Creature/CreatureData.h @@ -317,6 +317,15 @@ public: void ApplyFlag(CreatureStaticFlags7 flag, bool apply) { if (apply) _flags7 |= flag; else _flags7 &= ~flag; } void ApplyFlag(CreatureStaticFlags8 flag, bool apply) { if (apply) _flags8 |= flag; else _flags8 &= ~flag; } + EnumFlag<CreatureStaticFlags> GetFlags() const { return _flags; } + EnumFlag<CreatureStaticFlags2> GetFlags2() const { return _flags2; } + EnumFlag<CreatureStaticFlags3> GetFlags3() const { return _flags3; } + EnumFlag<CreatureStaticFlags4> GetFlags4() const { return _flags4; } + EnumFlag<CreatureStaticFlags5> GetFlags5() const { return _flags5; } + EnumFlag<CreatureStaticFlags6> GetFlags6() const { return _flags6; } + EnumFlag<CreatureStaticFlags7> GetFlags7() const { return _flags7; } + EnumFlag<CreatureStaticFlags8> GetFlags8() const { return _flags8; } + private: EnumFlag<CreatureStaticFlags> _flags; EnumFlag<CreatureStaticFlags2> _flags2; @@ -646,6 +655,19 @@ struct CreatureAddon VisibilityDistanceType visibilityDistanceType; }; +// `creature_static_flags_override` table +struct CreatureStaticFlagsOverride +{ + Optional<CreatureStaticFlags> StaticFlags1; + Optional<CreatureStaticFlags2> StaticFlags2; + Optional<CreatureStaticFlags3> StaticFlags3; + Optional<CreatureStaticFlags4> StaticFlags4; + Optional<CreatureStaticFlags5> StaticFlags5; + Optional<CreatureStaticFlags6> StaticFlags6; + Optional<CreatureStaticFlags7> StaticFlags7; + Optional<CreatureStaticFlags8> StaticFlags8; +}; + // Vendors struct VendorItem { diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 7c933cdd774..10cb845f24d 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -10727,6 +10727,11 @@ JumpChargeParams const* ObjectMgr::GetJumpChargeParams(int32 id) const return Trinity::Containers::MapGetValuePtr(_jumpChargeParams, id); } +CreatureStaticFlagsOverride const* ObjectMgr::GetCreatureStaticFlagsOverride(ObjectGuid::LowType spawnId, Difficulty difficultyId) const +{ + return Trinity::Containers::MapGetValuePtr(_creatureStaticFlagsOverrideStore, std::make_pair(spawnId, difficultyId)); +} + void ObjectMgr::LoadGameObjectQuestItems() { uint32 oldMSTime = getMSTime(); @@ -10860,6 +10865,67 @@ void ObjectMgr::LoadCreatureQuestCurrencies() TC_LOG_INFO("server.loading", ">> Loaded {} creature quest currencies in {} ms", count, GetMSTimeDiffToNow(oldMSTime)); } +void ObjectMgr::LoadCreatureStaticFlagsOverride() +{ + // reload case + _creatureStaticFlagsOverrideStore.clear(); + + uint32 oldMSTime = getMSTime(); + + // 0 1 2 3 4 5 6 7 8 9 + QueryResult result = WorldDatabase.Query("SELECT SpawnId, DifficultyId, StaticFlags1, StaticFlags2, StaticFlags3, StaticFlags4, StaticFlags5, StaticFlags6, StaticFlags7, StaticFlags8 FROM creature_static_flags_override"); + + if (!result) + { + TC_LOG_INFO("server.loading", ">> Loaded 0 creature static flag overrides. DB table `creature_static_flags_override` is empty."); + return; + } + + uint32 count = 0; + do + { + Field* fields = result->Fetch(); + + ObjectGuid::LowType spawnId = fields[0].GetUInt64(); + Difficulty difficultyId = static_cast<Difficulty>(fields[1].GetUInt8()); + + CreatureData const* creatureData = GetCreatureData(spawnId); + if (!creatureData) + { + TC_LOG_ERROR("sql.sql", "Table `creature_static_flags_override` has data for nonexistent creature (SpawnId: {}), skipped", spawnId); + continue; + } + + if (std::find(creatureData->spawnDifficulties.begin(), creatureData->spawnDifficulties.end(), difficultyId) == creatureData->spawnDifficulties.end()) + { + TC_LOG_ERROR("sql.sql", "Table `creature_static_flags_override` has data for a creature that is not available for the specified DifficultyId (SpawnId: {}, DifficultyId: {}), skipped", spawnId, difficultyId); + continue; + } + + CreatureStaticFlagsOverride& staticFlagsOverride = _creatureStaticFlagsOverrideStore[std::make_pair(spawnId, difficultyId)]; + if (!fields[2].IsNull()) + staticFlagsOverride.StaticFlags1 = static_cast<CreatureStaticFlags>(fields[2].GetUInt32()); + if (!fields[3].IsNull()) + staticFlagsOverride.StaticFlags2 = static_cast<CreatureStaticFlags2>(fields[3].GetUInt32()); + if (!fields[4].IsNull()) + staticFlagsOverride.StaticFlags3 = static_cast<CreatureStaticFlags3>(fields[4].GetUInt32()); + if (!fields[5].IsNull()) + staticFlagsOverride.StaticFlags4 = static_cast<CreatureStaticFlags4>(fields[5].GetUInt32()); + if (!fields[6].IsNull()) + staticFlagsOverride.StaticFlags5 = static_cast<CreatureStaticFlags5>(fields[6].GetUInt32()); + if (!fields[7].IsNull()) + staticFlagsOverride.StaticFlags6 = static_cast<CreatureStaticFlags6>(fields[7].GetUInt32()); + if (!fields[8].IsNull()) + staticFlagsOverride.StaticFlags7 = static_cast<CreatureStaticFlags7>(fields[8].GetUInt32()); + if (!fields[9].IsNull()) + staticFlagsOverride.StaticFlags8 = static_cast<CreatureStaticFlags8>(fields[9].GetUInt32()); + + ++count; + } while (result->NextRow()); + + TC_LOG_INFO("server.loading", ">> Loaded {} creature static flag overrides in {} ms", count, GetMSTimeDiffToNow(oldMSTime)); +} + void ObjectMgr::InitializeQueriesData(QueryDataGroup mask) { uint32 oldMSTime = getMSTime(); diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index e26de428769..d373047127c 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -503,6 +503,7 @@ typedef std::unordered_map<uint32, EquipmentInfoContainerInternal> EquipmentInfo typedef std::unordered_map<uint32, CreatureModelInfo> CreatureModelContainer; typedef std::unordered_map<std::pair<uint32, Difficulty>, std::vector<uint32>> CreatureQuestItemMap; typedef std::unordered_map<uint32, std::vector<int32>> CreatureQuestCurrenciesMap; +typedef std::unordered_map<std::pair<ObjectGuid::LowType, Difficulty>, CreatureStaticFlagsOverride> CreatureStaticFlagsOverrideMap; typedef std::unordered_map<uint32, DestructibleHitpoint> DestructibleHitpointContainer; typedef std::unordered_map<uint32, GameObjectTemplate> GameObjectTemplateContainer; typedef std::unordered_map<uint32, GameObjectTemplateAddon> GameObjectTemplateAddonContainer; @@ -1322,6 +1323,7 @@ class TC_GAME_API ObjectMgr void LoadGameObjectQuestItems(); void LoadCreatureQuestItems(); void LoadCreatureQuestCurrencies(); + void LoadCreatureStaticFlagsOverride(); void LoadTempSummons(); void LoadCreatures(); void LoadLinkedRespawn(); @@ -1757,6 +1759,8 @@ class TC_GAME_API ObjectMgr JumpChargeParams const* GetJumpChargeParams(int32 id) const; + CreatureStaticFlagsOverride const* GetCreatureStaticFlagsOverride(ObjectGuid::LowType spawnId, Difficulty difficultyId) const; + private: // first free id for selected id type uint32 _auctionId; @@ -1899,6 +1903,7 @@ class TC_GAME_API ObjectMgr GameObjectQuestItemMap _gameObjectQuestItemStore; CreatureQuestItemMap _creatureQuestItemStore; CreatureQuestCurrenciesMap _creatureQuestCurrenciesStore; + CreatureStaticFlagsOverrideMap _creatureStaticFlagsOverrideStore; EquipmentInfoContainer _equipmentInfoStore; LinkedRespawnContainer _linkedRespawnStore; CreatureLocaleContainer _creatureLocaleStore; diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 9ed9c7c85d6..1c2255e30eb 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -2370,6 +2370,9 @@ void World::SetInitialWorldSettings() TC_LOG_INFO("server.loading", "Loading Creature Text Locales..."); sCreatureTextMgr->LoadCreatureTextLocales(); + TC_LOG_INFO("server.loading", "Loading creature StaticFlags overrides..."); + sObjectMgr->LoadCreatureStaticFlagsOverride(); // must be after LoadCreatures + TC_LOG_INFO("server.loading", "Initializing Scripts..."); sScriptMgr->Initialize(); sScriptMgr->OnConfigLoad(false); // must be done after the ScriptMgr has been properly initialized |