#include "InventoryService.h" #include #include #include #include #include #include #include #include #include #include namespace { Console::Setting bEnableItemDrops{"Gameplay:bEnableItemDrops", "(Experimental) Syncs dropped items by players", false}; } InventoryService::InventoryService(World& aWorld, entt::dispatcher& aDispatcher) : m_world(aWorld) { m_inventoryChangeConnection = aDispatcher.sink>().connect<&InventoryService::OnInventoryChanges>(this); m_equipmentChangeConnection = aDispatcher.sink>().connect<&InventoryService::OnEquipmentChanges>(this); m_drawWeaponConnection = aDispatcher.sink>().connect<&InventoryService::OnWeaponDrawnRequest>(this); } void InventoryService::OnInventoryChanges(const PacketEvent& acMessage) noexcept { auto& message = acMessage.Packet; auto view = m_world.view(); const auto it = view.find(static_cast(message.ServerId)); if (it != view.end()) { auto& inventoryComponent = view.get(*it); inventoryComponent.Content.AddOrRemoveEntry(message.Item); } if (!message.UpdateClients) return; NotifyInventoryChanges notify; notify.ServerId = message.ServerId; notify.Item = message.Item; notify.Drop = bEnableItemDrops ? message.Drop : false; const entt::entity cOrigin = static_cast(message.ServerId); if (!GameServer::Get()->SendToPlayersInRange(notify, cOrigin, acMessage.GetSender())) spdlog::error("{}: SendToPlayersInRange failed", __FUNCTION__); } void InventoryService::OnEquipmentChanges(const PacketEvent& acMessage) noexcept { auto& message = acMessage.Packet; auto view = m_world.view(); const auto it = view.find(static_cast(message.ServerId)); if (it != view.end()) { auto& inventoryComponent = view.get(*it); inventoryComponent.Content.UpdateEquipment(message.CurrentInventory); } NotifyEquipmentChanges notify; notify.ServerId = message.ServerId; notify.ItemId = message.ItemId; notify.EquipSlotId = message.EquipSlotId; notify.Count = message.Count; notify.Unequip = message.Unequip; notify.IsSpell = message.IsSpell; notify.IsShout = message.IsShout; const entt::entity cOrigin = static_cast(message.ServerId); if (!GameServer::Get()->SendToPlayersInRange(notify, cOrigin, acMessage.GetSender())) spdlog::error("{}: SendToPlayersInRange failed", __FUNCTION__); } void InventoryService::OnWeaponDrawnRequest(const PacketEvent& acMessage) noexcept { auto& message = acMessage.Packet; auto characterView = m_world.view(); const auto it = characterView.find(static_cast(message.Id)); if (it != std::end(characterView) && characterView.get(*it).GetOwner() == acMessage.pPlayer) { auto& characterComponent = characterView.get(*it); characterComponent.SetWeaponDrawn(message.IsWeaponDrawn); spdlog::debug("Updating weapon drawn state {:x}:{}", message.Id, message.IsWeaponDrawn); } }