mirror of
https://github.com/Jous99/F4MP.git
synced 2026-01-13 00:20:54 +01:00
98 lines
3.6 KiB
C++
98 lines
3.6 KiB
C++
|
|
#include "InventoryService.h"
|
||
|
|
|
||
|
|
#include <Components.h>
|
||
|
|
#include <World.h>
|
||
|
|
#include <GameServer.h>
|
||
|
|
|
||
|
|
#include <Messages/NotifyObjectInventoryChanges.h>
|
||
|
|
#include <Messages/RequestInventoryChanges.h>
|
||
|
|
#include <Messages/NotifyInventoryChanges.h>
|
||
|
|
#include <Messages/RequestEquipmentChanges.h>
|
||
|
|
#include <Messages/NotifyEquipmentChanges.h>
|
||
|
|
#include <Messages/DrawWeaponRequest.h>
|
||
|
|
|
||
|
|
#include <Setting.h>
|
||
|
|
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<PacketEvent<RequestInventoryChanges>>().connect<&InventoryService::OnInventoryChanges>(this);
|
||
|
|
m_equipmentChangeConnection = aDispatcher.sink<PacketEvent<RequestEquipmentChanges>>().connect<&InventoryService::OnEquipmentChanges>(this);
|
||
|
|
m_drawWeaponConnection = aDispatcher.sink<PacketEvent<DrawWeaponRequest>>().connect<&InventoryService::OnWeaponDrawnRequest>(this);
|
||
|
|
}
|
||
|
|
|
||
|
|
void InventoryService::OnInventoryChanges(const PacketEvent<RequestInventoryChanges>& acMessage) noexcept
|
||
|
|
{
|
||
|
|
auto& message = acMessage.Packet;
|
||
|
|
|
||
|
|
auto view = m_world.view<InventoryComponent>();
|
||
|
|
|
||
|
|
const auto it = view.find(static_cast<entt::entity>(message.ServerId));
|
||
|
|
|
||
|
|
if (it != view.end())
|
||
|
|
{
|
||
|
|
auto& inventoryComponent = view.get<InventoryComponent>(*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<entt::entity>(message.ServerId);
|
||
|
|
if (!GameServer::Get()->SendToPlayersInRange(notify, cOrigin, acMessage.GetSender()))
|
||
|
|
spdlog::error("{}: SendToPlayersInRange failed", __FUNCTION__);
|
||
|
|
}
|
||
|
|
|
||
|
|
void InventoryService::OnEquipmentChanges(const PacketEvent<RequestEquipmentChanges>& acMessage) noexcept
|
||
|
|
{
|
||
|
|
auto& message = acMessage.Packet;
|
||
|
|
|
||
|
|
auto view = m_world.view<InventoryComponent>();
|
||
|
|
|
||
|
|
const auto it = view.find(static_cast<entt::entity>(message.ServerId));
|
||
|
|
|
||
|
|
if (it != view.end())
|
||
|
|
{
|
||
|
|
auto& inventoryComponent = view.get<InventoryComponent>(*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<entt::entity>(message.ServerId);
|
||
|
|
if (!GameServer::Get()->SendToPlayersInRange(notify, cOrigin, acMessage.GetSender()))
|
||
|
|
spdlog::error("{}: SendToPlayersInRange failed", __FUNCTION__);
|
||
|
|
}
|
||
|
|
|
||
|
|
void InventoryService::OnWeaponDrawnRequest(const PacketEvent<DrawWeaponRequest>& acMessage) noexcept
|
||
|
|
{
|
||
|
|
auto& message = acMessage.Packet;
|
||
|
|
|
||
|
|
auto characterView = m_world.view<CharacterComponent, OwnerComponent>();
|
||
|
|
const auto it = characterView.find(static_cast<entt::entity>(message.Id));
|
||
|
|
|
||
|
|
if (it != std::end(characterView) && characterView.get<OwnerComponent>(*it).GetOwner() == acMessage.pPlayer)
|
||
|
|
{
|
||
|
|
auto& characterComponent = characterView.get<CharacterComponent>(*it);
|
||
|
|
characterComponent.SetWeaponDrawn(message.IsWeaponDrawn);
|
||
|
|
spdlog::debug("Updating weapon drawn state {:x}:{}", message.Id, message.IsWeaponDrawn);
|
||
|
|
}
|
||
|
|
}
|