Core/Creatures: Implemented sending different creature id for summoner (#28066)

Co-authored-by: Shauren <shauren.trinity@gmail.com>
This commit is contained in:
Teleqraph
2022-07-03 16:00:14 +02:00
committed by GitHub
parent 9fcf920d0e
commit ebf1b6eb5c
9 changed files with 153 additions and 2 deletions

View File

@@ -0,0 +1,18 @@
--
-- Table structure for table `creature_summoned_data`
--
DROP TABLE IF EXISTS `creature_summoned_data`;
CREATE TABLE `creature_summoned_data` (
`CreatureID` int unsigned NOT NULL,
`CreatureIDVisibleToSummoner` int DEFAULT NULL,
`GroundMountDisplayID` int unsigned DEFAULT NULL,
`FlyingMountDisplayID` int unsigned DEFAULT NULL,
PRIMARY KEY (`CreatureID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Dumping data for table `creature_summoned_data`
--
INSERT INTO `creature_summoned_data` VALUES
(90382,90240,54563,46930),
(91911,91913,59339,NULL);

View File

@@ -20,6 +20,7 @@
#include "Common.h"
#include "DBCEnums.h"
#include "Optional.h"
#include "SharedDefines.h"
#include "SpawnData.h"
#include "UnitDefines.h"
@@ -605,6 +606,13 @@ struct CreatureModelInfo
bool is_trigger;
};
struct CreatureSummonedData
{
Optional<uint32> CreatureIDVisibleToSummoner;
Optional<uint32> GroundMountDisplayID;
Optional<uint32> FlyingMountDisplayID;
};
enum InhabitTypeValues
{
INHABIT_GROUND = 1,

View File

@@ -25,6 +25,7 @@
#include "Log.h"
#include "Map.h"
#include "ObjectAccessor.h"
#include "ObjectMgr.h"
#include "Pet.h"
#include "Player.h"
#include "SmoothPhasing.h"
@@ -194,6 +195,19 @@ void TempSummon::InitStats(uint32 duration)
if (owner->GetTypeId() == TYPEID_PLAYER)
m_ControlledByPlayer = true;
if (owner && owner->IsPlayer())
{
if (CreatureSummonedData const* summonedData = sObjectMgr->GetCreatureSummonedData(GetEntry()))
{
m_creatureIdVisibleToSummoner = summonedData->CreatureIDVisibleToSummoner;
if (summonedData->CreatureIDVisibleToSummoner)
{
CreatureTemplate const* creatureTemplateVisibleToSummoner = ASSERT_NOTNULL(sObjectMgr->GetCreatureTemplate(*summonedData->CreatureIDVisibleToSummoner));
m_displayIdVisibleToSummoner = ObjectMgr::ChooseDisplayId(creatureTemplateVisibleToSummoner, nullptr)->CreatureDisplayID;
}
}
}
if (!m_Properties)
return;

View File

@@ -61,6 +61,8 @@ class TC_GAME_API TempSummon : public Creature
ObjectGuid GetSummonerGUID() const { return m_summonerGUID; }
TempSummonType GetSummonType() const { return m_type; }
uint32 GetTimer() const { return m_timer; }
Optional<uint32> GetCreatureIdVisibleToSummoner() const { return m_creatureIdVisibleToSummoner; }
Optional<uint32> GetDisplayIdVisibleToSummoner() const { return m_displayIdVisibleToSummoner; }
bool CanFollowOwner() const { return m_canFollowOwner; }
void SetCanFollowOwner(bool can) { m_canFollowOwner = can; }
@@ -72,6 +74,8 @@ class TC_GAME_API TempSummon : public Creature
uint32 m_timer;
uint32 m_lifetime;
ObjectGuid m_summonerGUID;
Optional<uint32> m_creatureIdVisibleToSummoner;
Optional<uint32> m_displayIdVisibleToSummoner;
bool m_canFollowOwner;
};

View File

@@ -37,7 +37,7 @@ namespace UF
{
void ObjectData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Object const* owner, Player const* receiver) const
{
data << int32(EntryID);
data << int32(ViewerDependentValue<EntryIDTag>::GetValue(this, owner, receiver));
data << uint32(ViewerDependentValue<DynamicFlagsTag>::GetValue(this, owner, receiver));
data << float(Scale);
}
@@ -56,7 +56,7 @@ void ObjectData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ign
{
if (changesMask[1])
{
data << int32(EntryID);
data << int32(ViewerDependentValue<EntryIDTag>::GetValue(this, owner, receiver));
}
if (changesMask[2])
{

View File

@@ -47,6 +47,7 @@ namespace UF
struct ObjectData : public IsUpdateFieldStructureTag, public HasChangesMask<4>
{
UpdateField<int32, 0, 1> EntryID;
struct EntryIDTag : ViewerDependentValueTag<int32> {};
UpdateField<uint32, 0, 2> DynamicFlags;
struct DynamicFlagsTag : ViewerDependentValueTag<uint32> {};
UpdateField<float, 0, 3> Scale;

View File

@@ -26,6 +26,7 @@
#include "Player.h"
#include "SpellInfo.h"
#include "SpellMgr.h"
#include "TemporarySummon.h"
#include "World.h"
#include "WorldSession.h"
@@ -36,6 +37,25 @@ class ViewerDependentValue
{
};
template<>
class ViewerDependentValue<UF::ObjectData::EntryIDTag>
{
public:
using value_type = UF::ObjectData::EntryIDTag::value_type;
static value_type GetValue(UF::ObjectData const* objectData, Object const* object, Player const* receiver)
{
value_type entryId = objectData->EntryID;
if (Unit const* unit = object->ToUnit())
if (TempSummon const* summon = unit->ToTempSummon())
if (summon->GetSummonerGUID() == receiver->GetGUID() && summon->GetCreatureIdVisibleToSummoner())
entryId = *summon->GetCreatureIdVisibleToSummoner();
return entryId;
}
};
template<>
class ViewerDependentValue<UF::ObjectData::DynamicFlagsTag>
{
@@ -121,6 +141,18 @@ public:
{
CreatureTemplate const* cinfo = unit->ToCreature()->GetCreatureTemplate();
if (TempSummon const* summon = unit->ToTempSummon())
{
if (summon->GetSummonerGUID() == receiver->GetGUID())
{
if (summon->GetCreatureIdVisibleToSummoner())
cinfo = sObjectMgr->GetCreatureTemplate(*summon->GetCreatureIdVisibleToSummoner());
if (summon->GetDisplayIdVisibleToSummoner())
displayId = *summon->GetDisplayIdVisibleToSummoner();
}
}
// this also applies for transform auras
if (SpellInfo const* transform = sSpellMgr->GetSpellInfo(unit->GetTransformSpell(), unit->GetMap()->GetDifficultyID()))
{

View File

@@ -391,6 +391,8 @@ void ObjectMgr::LoadCreatureTemplates()
// We load the creature models after loading but before checking
LoadCreatureTemplateModels();
LoadCreatureSummonedData();
// Checking needs to be done after loading because of the difficulty self referencing
for (auto const& ctPair : _creatureTemplateStore)
CheckCreatureTemplate(&ctPair.second);
@@ -642,6 +644,70 @@ void ObjectMgr::LoadCreatureTemplateModels()
TC_LOG_INFO("server.loading", ">> Loaded %u creature template models in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
}
void ObjectMgr::LoadCreatureSummonedData()
{
uint32 oldMSTime = getMSTime();
// 0 1 2 3
QueryResult result = WorldDatabase.Query("SELECT CreatureID, CreatureIDVisibleToSummoner, GroundMountDisplayID, FlyingMountDisplayID FROM creature_summoned_data");
if (!result)
{
TC_LOG_INFO("server.loading", ">> Loaded 0 creature summoned data definitions. DB table `creature_summoned_data` is empty.");
return;
}
do
{
Field* fields = result->Fetch();
uint32 creatureId = fields[0].GetUInt32();
if (!GetCreatureTemplate(creatureId))
{
TC_LOG_ERROR("sql.sql", "Table `creature_summoned_data` references non-existing creature %u, skipped", creatureId);
continue;
}
CreatureSummonedData& summonedData = _creatureSummonedDataStore[creatureId];
if (!fields[1].IsNull())
{
summonedData.CreatureIDVisibleToSummoner = fields[1].GetUInt32();
if (!GetCreatureTemplate(*summonedData.CreatureIDVisibleToSummoner))
{
TC_LOG_ERROR("sql.sql", "Table `creature_summoned_data` references non-existing creature %u in CreatureIDVisibleToSummoner for creature %u, set to 0",
*summonedData.CreatureIDVisibleToSummoner, creatureId);
summonedData.CreatureIDVisibleToSummoner.reset();
}
}
if (!fields[2].IsNull())
{
summonedData.GroundMountDisplayID = fields[2].GetUInt32();
if (!sCreatureDisplayInfoStore.LookupEntry(*summonedData.GroundMountDisplayID))
{
TC_LOG_ERROR("sql.sql", "Table `creature_summoned_data` references non-existing display id %u in GroundMountDisplayID for creature %u, set to 0",
*summonedData.GroundMountDisplayID, creatureId);
summonedData.CreatureIDVisibleToSummoner.reset();
}
}
if (!fields[3].IsNull())
{
summonedData.FlyingMountDisplayID = fields[3].GetUInt32();
if (!sCreatureDisplayInfoStore.LookupEntry(*summonedData.FlyingMountDisplayID))
{
TC_LOG_ERROR("sql.sql", "Table `creature_summoned_data` references non-existing display id %u in FlyingMountDisplayID for creature %u, set to 0",
*summonedData.FlyingMountDisplayID, creatureId);
summonedData.GroundMountDisplayID.reset();
}
}
} while (result->NextRow());
TC_LOG_INFO("server.loading", ">> Loaded " SZFMTD " creature summoned data definitions in %u ms", _creatureSummonedDataStore.size(), GetMSTimeDiffToNow(oldMSTime));
}
void ObjectMgr::LoadCreatureTemplateAddons()
{
uint32 oldMSTime = getMSTime();
@@ -1616,6 +1682,11 @@ CreatureModelInfo const* ObjectMgr::GetCreatureModelInfo(uint32 modelId) const
return nullptr;
}
CreatureSummonedData const* ObjectMgr::GetCreatureSummonedData(uint32 entryId) const
{
return Trinity::Containers::MapGetValuePtr(_creatureSummonedDataStore, entryId);
}
CreatureModel const* ObjectMgr::ChooseDisplayId(CreatureTemplate const* cinfo, CreatureData const* data /*= nullptr*/)
{
// Load creature model (display id)

View File

@@ -1140,6 +1140,7 @@ class TC_GAME_API ObjectMgr
CreatureTemplateContainer const& GetCreatureTemplates() const { return _creatureTemplateStore; }
CreatureModelInfo const* GetCreatureModelInfo(uint32 modelId) const;
CreatureModelInfo const* GetCreatureModelRandomGender(CreatureModel* model, CreatureTemplate const* creatureTemplate) const;
CreatureSummonedData const* GetCreatureSummonedData(uint32 entryId) const;
static CreatureModel const* ChooseDisplayId(CreatureTemplate const* cinfo, CreatureData const* data = nullptr);
static void ChooseCreatureFlags(CreatureTemplate const* cInfo, uint64* npcFlags, uint32* unitFlags, uint32* unitFlags2, uint32* unitFlags3, uint32* dynamicFlags, CreatureData const* data = nullptr);
EquipmentInfo const* GetEquipmentInfo(uint32 entry, int8& id) const;
@@ -1318,6 +1319,7 @@ class TC_GAME_API ObjectMgr
void LoadCreatureTemplateResistances();
void LoadCreatureTemplateSpells();
void LoadCreatureTemplateModels();
void LoadCreatureSummonedData();
void LoadCreatureScalingData();
void CheckCreatureTemplate(CreatureTemplate const* cInfo);
void CheckCreatureMovement(char const* table, uint64 id, CreatureMovementData& creatureMovement);
@@ -1908,6 +1910,7 @@ class TC_GAME_API ObjectMgr
CreatureDataContainer _creatureDataStore;
CreatureTemplateContainer _creatureTemplateStore;
CreatureModelContainer _creatureModelStore;
std::unordered_map<uint32, CreatureSummonedData> _creatureSummonedDataStore;
CreatureAddonContainer _creatureAddonStore;
CreatureTemplateAddonContainer _creatureTemplateAddonStore;
std::unordered_map<ObjectGuid::LowType, CreatureMovementData> _creatureMovementOverrides;