[General] Rework PacketPlayerInventory

Save the Action for each item. Now you can add or remove multiple items
sol2-server-rewrite
Koncord 7 years ago
parent de0bb3cdab
commit 29ba07fe8c

@ -33,7 +33,7 @@ void Inventory::Init(LuaState &lua)
); );
} }
Inventory::Inventory(NetActor *actor) : netActor(actor), equipmentChanged(false), inventoryChanged(mwmp::InventoryChanges::Type::None) Inventory::Inventory(NetActor *actor) : netActor(actor), equipmentChanged(false), inventoryChanged(false)
{ {
printf("Inventory::Inventory()\n"); printf("Inventory::Inventory()\n");
} }
@ -85,13 +85,6 @@ void Inventory::update()
inventoryChanged = 0;*/ inventoryChanged = 0;*/
} }
void Inventory::InitializeInventoryChanges()
{
netActor->getNetCreature()->inventoryChanges.items.clear();
netActor->getNetCreature()->inventoryChanges.action = mwmp::InventoryChanges::Type::Set;
}
int Inventory::getChangesSize() const int Inventory::getChangesSize() const
{ {
return netActor->getNetCreature()->inventoryChanges.items.size(); return netActor->getNetCreature()->inventoryChanges.items.size();
@ -121,10 +114,8 @@ void Inventory::unequipItem( unsigned short slot)
void Inventory::addItem(const std::string &refId, unsigned int count, int charge, float enchantmentCharge) void Inventory::addItem(const std::string &refId, unsigned int count, int charge, float enchantmentCharge)
{ {
if (inventoryChanged == mwmp::InventoryChanges::Type::Remove) if(!inventoryChanged)
return; resetInventoryFlag();
if (inventoryChanged == mwmp::InventoryChanges::Type::None)
InitializeInventoryChanges();
mwmp::Item item; mwmp::Item item;
item.refId = refId; item.refId = refId;
@ -132,29 +123,24 @@ void Inventory::addItem(const std::string &refId, unsigned int count, int charge
item.charge = charge; item.charge = charge;
item.enchantmentCharge = enchantmentCharge; item.enchantmentCharge = enchantmentCharge;
netActor->getNetCreature()->inventoryChanges.items.push_back(item); netActor->getNetCreature()->inventoryChanges.items.emplace_back(item, mwmp::InventoryChanges::Action::Add);
netActor->getNetCreature()->inventoryChanges.action = mwmp::InventoryChanges::Type::Add; if (netActor->isPlayer())
if (inventoryChanged == mwmp::InventoryChanges::Type::None && netActor->isPlayer())
netActor->toPlayer()->addToUpdateQueue(); netActor->toPlayer()->addToUpdateQueue();
inventoryChanged = netActor->getNetCreature()->inventoryChanges.action; inventoryChanged = true;
} }
void Inventory::removeItem(const std::string &refId, unsigned short count) void Inventory::removeItem(const std::string &refId, unsigned short count)
{ {
if (inventoryChanged == mwmp::InventoryChanges::Type::Add) if(!inventoryChanged)
return; resetInventoryFlag();
if (inventoryChanged == mwmp::InventoryChanges::Type::None)
InitializeInventoryChanges();
mwmp::Item item; mwmp::Item item;
item.refId = refId; item.refId = refId;
item.count = count; item.count = count;
netActor->getNetCreature()->inventoryChanges.items.push_back(item); netActor->getNetCreature()->inventoryChanges.items.emplace_back(item, mwmp::InventoryChanges::Action::Remove);
netActor->getNetCreature()->inventoryChanges.action = mwmp::InventoryChanges::Type::Remove; if (netActor->isPlayer())
if (inventoryChanged == mwmp::InventoryChanges::Type::None && netActor->isPlayer())
netActor->toPlayer()->addToUpdateQueue(); netActor->toPlayer()->addToUpdateQueue();
inventoryChanged = netActor->getNetCreature()->inventoryChanges.action; inventoryChanged = true;
} }
bool Inventory::hasItemEquipped(const std::string &refId) const bool Inventory::hasItemEquipped(const std::string &refId) const
@ -173,7 +159,7 @@ std::tuple<std::string, int, int, double> Inventory::getEquipmentItem(unsigned s
std::tuple<std::string, int, int, double> Inventory::getInventoryItem(unsigned int slot) const std::tuple<std::string, int, int, double> Inventory::getInventoryItem(unsigned int slot) const
{ {
const auto &item = netActor->getNetCreature()->inventoryChanges.items.at(slot); const auto &item = netActor->getNetCreature()->inventoryChanges.items.at(slot).first;
return make_tuple(item.refId, item.count, item.charge, item.enchantmentCharge); return make_tuple(item.refId, item.count, item.charge, item.enchantmentCharge);
} }
@ -189,15 +175,14 @@ bool Inventory::isEquipmentChanged()
return equipmentChanged; return equipmentChanged;
} }
void Inventory::resetInventoryFlag() bool Inventory::isInventoryChanged()
{
inventoryChanged = mwmp::InventoryChanges::Type::None;
}
mwmp::InventoryChanges::Type Inventory::inventoryChangeType()
{ {
return inventoryChanged; return inventoryChanged;
} }
void Inventory::resetInventoryFlag()
{
inventoryChanged = false;
netActor->getNetCreature()->inventoryChanges.items.clear();
}

@ -16,7 +16,7 @@ public:
static void Init(LuaState &lua); static void Init(LuaState &lua);
bool isEquipmentChanged(); bool isEquipmentChanged();
void resetEquipmentFlag(); void resetEquipmentFlag();
mwmp::InventoryChanges::Type inventoryChangeType(); bool isInventoryChanged();
void resetInventoryFlag(); void resetInventoryFlag();
public: public:
explicit Inventory(NetActor *netActor); explicit Inventory(NetActor *netActor);
@ -49,15 +49,11 @@ public:
*/ */
std::tuple<std::string,int, int, double> getEquipmentItem(unsigned short slot) const; std::tuple<std::string,int, int, double> getEquipmentItem(unsigned short slot) const;
private:
void InitializeInventoryChanges();
private: private:
// not controlled pointer // not controlled pointer
NetActor *netActor; NetActor *netActor;
bool equipmentChanged; bool equipmentChanged;
mwmp::InventoryChanges::Type inventoryChanged; bool inventoryChanged;
}; };

@ -219,7 +219,7 @@ void Player::update()
inventory.resetEquipmentFlag(); inventory.resetEquipmentFlag();
} }
if (inventory.inventoryChangeType() != mwmp::InventoryChanges::Type::None) if (inventory.isInventoryChanged())
{ {
auto packet = plPCtrl->GetPacket(ID_PLAYER_INVENTORY); auto packet = plPCtrl->GetPacket(ID_PLAYER_INVENTORY);
packet->setPlayer(this); packet->setPlayer(this);

@ -498,7 +498,7 @@ void LocalPlayer::updateInventory(bool forceUpdate)
if (setItem(item, *result)) if (setItem(item, *result))
continue; continue;
if (item == itemOld) if (item == itemOld.first)
break; break;
} }
if (result == ptrInventory.end()) if (result == ptrInventory.end())
@ -518,7 +518,9 @@ void LocalPlayer::updateInventory(bool forceUpdate)
auto items = inventoryChanges.items; auto items = inventoryChanges.items;
if (find(items.begin(), items.end(), item) == items.end()) if (find_if(items.begin(), items.end(), [&item](const std::pair<Item, InventoryChanges::Action> &a) {
return item == a.first;
}) == items.end())
{ {
invChanged = true; invChanged = true;
break; break;
@ -648,27 +650,25 @@ void LocalPlayer::updateAnimFlags(bool forceUpdate)
} }
} }
void LocalPlayer::addItems() void LocalPlayer::addItem(const Item &item)
{ {
MWWorld::Ptr ptrPlayer = getPlayerPtr(); MWWorld::Ptr ptrPlayer = getPlayerPtr();
MWWorld::ContainerStore &ptrStore = ptrPlayer.getClass().getContainerStore(ptrPlayer); MWWorld::ContainerStore &ptrStore = ptrPlayer.getClass().getContainerStore(ptrPlayer);
for (const auto &item : inventoryChanges.items) try
{ {
try MWWorld::Ptr itemPtr = *ptrStore.add(item.refId, item.count, ptrPlayer);
{ if (item.charge != -1)
MWWorld::Ptr itemPtr = *ptrStore.add(item.refId, item.count, ptrPlayer); itemPtr.getCellRef().setCharge(item.charge);
if (item.charge != -1)
itemPtr.getCellRef().setCharge(item.charge);
if (item.enchantmentCharge != -1) if (item.enchantmentCharge != -1.0f)
itemPtr.getCellRef().setEnchantmentCharge(item.enchantmentCharge); itemPtr.getCellRef().setEnchantmentCharge(item.enchantmentCharge);
}
catch (std::exception&)
{
LOG_APPEND(Log::LOG_INFO, "- Ignored addition of invalid inventory item %s", item.refId.c_str());
}
} }
catch (std::exception&)
{
LOG_APPEND(Log::LOG_INFO, "- Ignored addition of invalid inventory item %s", item.refId.c_str());
}
} }
void LocalPlayer::addSpells() void LocalPlayer::addSpells()
@ -730,13 +730,12 @@ void LocalPlayer::addTopics()
} }
} }
void LocalPlayer::removeItems() void LocalPlayer::removeItem(const Item &item)
{ {
MWWorld::Ptr ptrPlayer = getPlayerPtr(); MWWorld::Ptr ptrPlayer = getPlayerPtr();
MWWorld::ContainerStore &ptrStore = ptrPlayer.getClass().getContainerStore(ptrPlayer); MWWorld::ContainerStore &ptrStore = ptrPlayer.getClass().getContainerStore(ptrPlayer);
for (const auto &item : inventoryChanges.items) ptrStore.remove(item.refId, item.count, ptrPlayer);
ptrStore.remove(item.refId, item.count, ptrPlayer);
} }
void LocalPlayer::removeSpells() void LocalPlayer::removeSpells()
@ -985,7 +984,11 @@ void LocalPlayer::setInventory()
ptrStore.clear(); ptrStore.clear();
// Proceed by adding items // Proceed by adding items
addItems(); for(const auto &item : inventoryChanges.items)
{
if(item.second == InventoryChanges::Action::Set)
addItem(item.first);
}
// Don't automatically setEquipment() here, or the player could end // Don't automatically setEquipment() here, or the player could end
// up getting a new set of their starting clothes, or other items // up getting a new set of their starting clothes, or other items
@ -1180,10 +1183,9 @@ void LocalPlayer::sendInventory()
item.charge = iter.getCellRef().getCharge(); item.charge = iter.getCellRef().getCharge();
item.enchantmentCharge = iter.getCellRef().getEnchantmentCharge(); item.enchantmentCharge = iter.getCellRef().getEnchantmentCharge();
inventoryChanges.items.push_back(item); inventoryChanges.items.emplace_back(item, InventoryChanges::Action::Set);
} }
inventoryChanges.action = InventoryChanges::Type::Set;
getNetworking()->getPlayerPacket(ID_PLAYER_INVENTORY)->setPlayer(this); getNetworking()->getPlayerPacket(ID_PLAYER_INVENTORY)->setPlayer(this);
getNetworking()->getPlayerPacket(ID_PLAYER_INVENTORY)->Send(); getNetworking()->getPlayerPacket(ID_PLAYER_INVENTORY)->Send();
} }

@ -38,12 +38,12 @@ namespace mwmp
void updateDeadState(bool forceUpdate = false); void updateDeadState(bool forceUpdate = false);
void updateAnimFlags(bool forceUpdate = false); void updateAnimFlags(bool forceUpdate = false);
void addItems(); void addItem(const Item &item);
void addSpells(); void addSpells();
void addJournalItems(); void addJournalItems();
void addTopics(); void addTopics();
void removeItems(); void removeItem(const Item &item);
void removeSpells(); void removeSpells();
void closeInventoryWindows(); void closeInventoryWindows();

@ -29,12 +29,19 @@ namespace mwmp
{ {
LocalPlayer &localPlayer = static_cast<LocalPlayer&>(*player); LocalPlayer &localPlayer = static_cast<LocalPlayer&>(*player);
if (localPlayer.inventoryChanges.action == InventoryChanges::Type::Add) for (const auto &item : localPlayer.inventoryChanges.items)
localPlayer.addItems(); {
else if (localPlayer.inventoryChanges.action == InventoryChanges::Type::Remove) if (item.second == InventoryChanges::Action::Add)
localPlayer.removeItems(); localPlayer.addItem(item.first);
else // InventoryChanges::SET else if (item.second == InventoryChanges::Action::Remove)
localPlayer.setInventory(); localPlayer.removeItem(item.first);
else // InventoryChanges::SET
{
// found set flag, clear and reset inventory
localPlayer.setInventory();
break;
}
}
} }
} }
}; };

@ -240,7 +240,6 @@ namespace mwmp
BasePlayer(RakNet::RakNetGUID guid) : guid(guid) BasePlayer(RakNet::RakNetGUID guid) : guid(guid)
{ {
inventoryChanges.action = InventoryChanges::Type::None;
spellbookChanges.action = SpellbookChanges::Type::None; spellbookChanges.action = SpellbookChanges::Type::None;
useCreatureName = false; useCreatureName = false;
isWerewolf = false; isWerewolf = false;

@ -22,15 +22,14 @@ namespace mwmp
struct InventoryChanges struct InventoryChanges
{ {
std::vector<Item> items; enum class Action: int8_t
enum class Type: int8_t
{ {
None = -1, None = -1,
Set = 0, Set = 0,
Add, Add,
Remove Remove
}; };
Type action; // 0 - Clear and set in entirety, 1 - Add item, 2 - Remove item std::vector<std::pair<Item, Action>> items;
}; };
struct Target struct Target

@ -17,8 +17,6 @@ void PacketPlayerInventory::Packet(RakNet::BitStream *bs, bool send)
{ {
PlayerPacket::Packet(bs, send); PlayerPacket::Packet(bs, send);
RW(player->inventoryChanges.action, send);
uint32_t count; uint32_t count;
if (send) if (send)
@ -34,9 +32,10 @@ void PacketPlayerInventory::Packet(RakNet::BitStream *bs, bool send)
for (auto &&item : player->inventoryChanges.items) for (auto &&item : player->inventoryChanges.items)
{ {
RW(item.refId, send, true); RW(item.first.refId, send, true);
RW(item.count, send); RW(item.first.count, send);
RW(item.charge, send); RW(item.first.charge, send);
RW(item.enchantmentCharge, send); RW(item.first.enchantmentCharge, send);
RW(item.second, send, true); // compress byte to bits
} }
} }

Loading…
Cancel
Save