mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-22 18:15:31 +01:00
Core/Creatures: Implemented sending different creature id for summoner (#28066)
Co-authored-by: Shauren <shauren.trinity@gmail.com>
This commit is contained in:
18
sql/updates/world/master/2022_07_03_00_world.sql
Normal file
18
sql/updates/world/master/2022_07_03_00_world.sql
Normal 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);
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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])
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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()))
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user