diff options
| author | Shauren <shauren.trinity@gmail.com> | 2024-10-30 14:41:27 +0100 |
|---|---|---|
| committer | Shauren <shauren.trinity@gmail.com> | 2024-10-30 14:41:27 +0100 |
| commit | 68db469ee1f992bcdc81de64d6af1007d303be05 (patch) | |
| tree | 776b61e7c2eaf0a07e1d8a711c09c1131603a13c /src/server/game/Entities/Creature | |
| parent | 91c12c64037ca906c30f9718fadab619359f1616 (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.cpp | 82 | ||||
| -rw-r--r-- | src/server/game/Entities/Creature/Creature.h | 18 |
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); |
