aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Entities/Creature/Creature.cpp20
-rw-r--r--src/server/game/Entities/Creature/Creature.h2
-rw-r--r--src/server/game/Entities/Creature/CreatureData.h22
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp66
-rw-r--r--src/server/game/Globals/ObjectMgr.h5
-rw-r--r--src/server/game/World/World.cpp3
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