aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Entities/Creature
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2024-10-30 14:41:27 +0100
committerShauren <shauren.trinity@gmail.com>2024-10-30 14:41:27 +0100
commit68db469ee1f992bcdc81de64d6af1007d303be05 (patch)
tree776b61e7c2eaf0a07e1d8a711c09c1131603a13c /src/server/game/Entities/Creature
parent91c12c64037ca906c30f9718fadab619359f1616 (diff)
Core/PacketIO: Updated SMSG_UPDATE_OBJECT for 11.0.5
Diffstat (limited to 'src/server/game/Entities/Creature')
-rw-r--r--src/server/game/Entities/Creature/Creature.cpp82
-rw-r--r--src/server/game/Entities/Creature/Creature.h18
2 files changed, 95 insertions, 5 deletions
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp
index 37eeab24446..0b8a3483b1f 100644
--- a/src/server/game/Entities/Creature/Creature.cpp
+++ b/src/server/game/Entities/Creature/Creature.cpp
@@ -606,9 +606,17 @@ bool Creature::UpdateEntry(uint32 entry, CreatureData const* data /*= nullptr*/,
if (cInfo->flags_extra & CREATURE_FLAG_EXTRA_WORLDEVENT)
npcFlags |= sGameEventMgr->GetNPCFlag(this);
+ if (IsVendor() && !(npcFlags & UNIT_NPC_FLAG_VENDOR_MASK))
+ SetVendor(UNIT_NPC_FLAG_VENDOR_MASK, false);
+
ReplaceAllNpcFlags(NPCFlags(npcFlags & 0xFFFFFFFF));
ReplaceAllNpcFlags2(NPCFlags2(npcFlags >> 32));
+ if (npcFlags & UNIT_NPC_FLAG_VENDOR_MASK)
+ SetVendor(NPCFlags(npcFlags & UNIT_NPC_FLAG_VENDOR_MASK), true);
+
+ SetPetitioner((npcFlags & UNIT_NPC_FLAG_PETITIONER) != 0);
+
// if unit is in combat, keep this flag
unitFlags &= ~UNIT_FLAG_IN_COMBAT;
if (IsInCombat())
@@ -3255,6 +3263,52 @@ uint32 Creature::UpdateVendorItemCurrentCount(VendorItem const* vItem, uint32 us
return vCount->count;
}
+void Creature::SetVendor(NPCFlags flags, bool apply)
+{
+ flags &= UNIT_NPC_FLAG_VENDOR_MASK;
+ VendorDataTypeFlags vendorFlags = static_cast<VendorDataTypeFlags>(AsUnderlyingType(flags) >> 7);
+ if (apply)
+ {
+ if (!m_vendorData)
+ m_entityFragments.Add(WowCS::EntityFragment::FVendor_C, IsInWorld());
+
+ SetNpcFlag(flags);
+ SetUpdateFieldFlagValue(m_values.ModifyValue(&Creature::m_vendorData, 0).ModifyValue(&UF::VendorData::Flags), AsUnderlyingType(vendorFlags));
+ }
+ else if (m_vendorData)
+ {
+ RemoveNpcFlag(flags);
+ RemoveUpdateFieldFlagValue(m_values.ModifyValue(&Creature::m_vendorData, 0).ModifyValue(&UF::VendorData::Flags), AsUnderlyingType(vendorFlags));
+ if (!m_vendorData->Flags)
+ {
+ RemoveOptionalUpdateFieldValue(m_values.ModifyValue(&Creature::m_vendorData));
+ m_entityFragments.Remove(WowCS::EntityFragment::FVendor_C);
+ }
+ }
+}
+
+void Creature::SetPetitioner(bool apply)
+{
+ if (apply)
+ {
+ if (!m_vendorData)
+ m_entityFragments.Add(WowCS::EntityFragment::FVendor_C, IsInWorld());
+
+ SetNpcFlag(UNIT_NPC_FLAG_PETITIONER);
+ SetUpdateFieldFlagValue(m_values.ModifyValue(&Creature::m_vendorData, 0).ModifyValue(&UF::VendorData::Flags), AsUnderlyingType(VendorDataTypeFlags::Petition));
+ }
+ else if (m_vendorData)
+ {
+ RemoveNpcFlag(UNIT_NPC_FLAG_PETITIONER);
+ RemoveUpdateFieldFlagValue(m_values.ModifyValue(&Creature::m_vendorData, 0).ModifyValue(&UF::VendorData::Flags), AsUnderlyingType(VendorDataTypeFlags::Petition));
+ if (!m_vendorData->Flags)
+ {
+ RemoveOptionalUpdateFieldValue(m_values.ModifyValue(&Creature::m_vendorData));
+ m_entityFragments.Remove(WowCS::EntityFragment::FVendor_C);
+ }
+ }
+}
+
// overwrite WorldObject function for proper name localization
std::string Creature::GetNameForLocaleIdx(LocaleConstant locale) const
{
@@ -3775,17 +3829,26 @@ void Creature::BuildValuesCreate(ByteBuffer* data, UF::UpdateFieldFlag flags, Pl
{
m_objectData->WriteCreate(*data, flags, this, target);
m_unitData->WriteCreate(*data, flags, this, target);
+
+ if (m_vendorData)
+ m_vendorData->WriteCreate(*data, flags, this, target);
}
void Creature::BuildValuesUpdate(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const
{
- *data << uint32(m_values.GetChangedObjectTypeMask());
+ if (m_entityFragments.ContentsChangedMask & m_entityFragments.GetUpdateMaskFor(WowCS::EntityFragment::CGObject))
+ {
+ *data << uint32(m_values.GetChangedObjectTypeMask());
+
+ if (m_values.HasChanged(TYPEID_OBJECT))
+ m_objectData->WriteUpdate(*data, flags, this, target);
- if (m_values.HasChanged(TYPEID_OBJECT))
- m_objectData->WriteUpdate(*data, flags, this, target);
+ if (m_values.HasChanged(TYPEID_UNIT))
+ m_unitData->WriteUpdate(*data, flags, this, target);
+ }
- if (m_values.HasChanged(TYPEID_UNIT))
- m_unitData->WriteUpdate(*data, flags, this, target);
+ if (m_vendorData && m_entityFragments.ContentsChangedMask & m_entityFragments.GetUpdateMaskFor(WowCS::EntityFragment::FVendor_C))
+ m_vendorData->WriteUpdate(*data, flags, this, target);
}
void Creature::BuildValuesUpdateWithFlag(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const
@@ -3816,6 +3879,7 @@ void Creature::BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::ObjectDa
ByteBuffer& buffer = PrepareValuesUpdateBuffer(data);
std::size_t sizePos = buffer.wpos();
buffer << uint32(0);
+ BuildEntityFragmentsForValuesUpdateForPlayerWithMask(&buffer, flags);
buffer << uint32(valuesMask.GetBlock(0));
if (valuesMask[TYPEID_OBJECT])
@@ -3839,3 +3903,11 @@ void Creature::ValuesUpdateForPlayerWithMaskSender::operator()(Player const* pla
udata.BuildPacket(&packet);
player->SendDirectMessage(&packet);
}
+
+void Creature::ClearUpdateMask(bool remove)
+{
+ if (m_vendorData)
+ m_values.ClearChangesMask(&Creature::m_vendorData);
+
+ Unit::ClearUpdateMask(remove);
+}
diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h
index 9bb49a334a1..02dbef80715 100644
--- a/src/server/game/Entities/Creature/Creature.h
+++ b/src/server/game/Entities/Creature/Creature.h
@@ -59,6 +59,18 @@ enum class VendorInventoryReason : uint8
Empty = 1
};
+enum class VendorDataTypeFlags : int32
+{
+ Generic = 0x01,
+ Ammo = 0x02,
+ Food = 0x04,
+ Poison = 0x08,
+ Reagent = 0x10,
+ Petition = 0x20,
+};
+
+DEFINE_ENUM_FLAG(VendorDataTypeFlags);
+
static constexpr uint8 WILD_BATTLE_PET_DEFAULT_LEVEL = 1;
static constexpr size_t CREATURE_TAPPERS_SOFT_CAP = 5;
@@ -248,6 +260,8 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma
VendorItemData const* GetVendorItems() const;
uint32 GetVendorItemCurrentCount(VendorItem const* vItem);
uint32 UpdateVendorItemCurrentCount(VendorItem const* vItem, uint32 used_count);
+ void SetVendor(NPCFlags flags, bool apply);
+ void SetPetitioner(bool apply);
CreatureTemplate const* GetCreatureTemplate() const { return m_creatureInfo; }
CreatureData const* GetCreatureData() const { return m_creatureData; }
@@ -468,6 +482,8 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma
void InitializeInteractSpellId();
void SetInteractSpellId(int32 interactSpellId) { SetUpdateFieldValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::InteractSpellID), interactSpellId); }
+ UF::OptionalUpdateField<UF::VendorData, int32(WowCS::EntityFragment::FVendor_C), 0> m_vendorData;
+
protected:
void BuildValuesCreate(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const override;
void BuildValuesUpdate(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const override;
@@ -489,6 +505,8 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma
};
protected:
+ void ClearUpdateMask(bool remove) override;
+
bool CreateFromProto(ObjectGuid::LowType guidlow, uint32 entry, CreatureData const* data = nullptr, uint32 vehId = 0);
bool InitEntry(uint32 entry, CreatureData const* data = nullptr);