mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2024-11-09 17:58:20 +00:00
aaf446fe6e
* Added feature grouping logic * Add saving of brick buckets * Add edge case check for max group count * Use vector for storing groups * Update InventoryComponent.cpp * Update InventoryComponent.h * Update InventoryComponent.h * fix string log format * Update GameMessages.cpp
524 lines
16 KiB
C++
524 lines
16 KiB
C++
#pragma once
|
|
|
|
#ifndef INVENTORYCOMPONENT_H
|
|
#define INVENTORYCOMPONENT_H
|
|
|
|
#include <map>
|
|
#include <stack>
|
|
|
|
|
|
#include "BehaviorSlot.h"
|
|
#include "tinyxml2.h"
|
|
|
|
#include "dCommonVars.h"
|
|
#include "EquippedItem.h"
|
|
#include "Inventory.h"
|
|
#include "LDFFormat.h"
|
|
#include "DatabasePet.h"
|
|
#include "Component.h"
|
|
#include "ItemSetPassiveAbility.h"
|
|
#include "eItemSetPassiveAbilityID.h"
|
|
#include "PossessorComponent.h"
|
|
#include "eInventoryType.h"
|
|
#include "eReplicaComponentType.h"
|
|
#include "eLootSourceType.h"
|
|
|
|
class Entity;
|
|
class ItemSet;
|
|
|
|
typedef std::map<std::string, EquippedItem> EquipmentMap;
|
|
|
|
enum class eItemType : int32_t;
|
|
|
|
/**
|
|
* Handles the inventory of entity, including the items they possess and have equipped. An entity can have inventories
|
|
* of different types, each type representing a different group of items, see `eInventoryType` for a list of
|
|
* inventories.
|
|
*/
|
|
class InventoryComponent final : public Component {
|
|
public:
|
|
struct Group {
|
|
// Generated ID for the group. The ID is sent by the client and has the format user_group + Math.random() * UINT_MAX.
|
|
std::string groupId;
|
|
// Custom name assigned by the user.
|
|
std::string groupName;
|
|
// All the lots the user has in the group.
|
|
std::set<LOT> lots;
|
|
};
|
|
|
|
enum class GroupUpdateCommand {
|
|
ADD,
|
|
ADD_LOT,
|
|
MODIFY,
|
|
REMOVE,
|
|
REMOVE_LOT,
|
|
};
|
|
|
|
// Based on the command, certain fields will be used or not used.
|
|
// for example, ADD_LOT wont use groupName, MODIFY wont use lots, etc.
|
|
struct GroupUpdate {
|
|
std::string groupId;
|
|
std::string groupName;
|
|
LOT lot;
|
|
eInventoryType inventory;
|
|
GroupUpdateCommand command;
|
|
};
|
|
|
|
static constexpr uint32_t MaximumGroupCount = 50;
|
|
|
|
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::INVENTORY;
|
|
InventoryComponent(Entity* parent);
|
|
|
|
void Update(float deltaTime) override;
|
|
void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) override;
|
|
void LoadXml(const tinyxml2::XMLDocument& document);
|
|
void UpdateXml(tinyxml2::XMLDocument& document) override;
|
|
|
|
/**
|
|
* Returns an inventory of the specified type, if it exists
|
|
* @param type the inventory type to find an inventory for
|
|
* @return the inventory of the specified type
|
|
*/
|
|
Inventory* GetInventory(eInventoryType type);
|
|
|
|
/**
|
|
* Returns all the inventories this entity has, indexed by type
|
|
* @return all the inventories this entity has, indexed by type
|
|
*/
|
|
const std::map<eInventoryType, Inventory*>& GetInventories() const;
|
|
|
|
/**
|
|
* Returns the amount of items this entity possesses of a certain LOT
|
|
* @param lot the lot to search for
|
|
* @return the amount of items this entity possesses the specified LOT
|
|
*/
|
|
uint32_t GetLotCount(LOT lot) const;
|
|
|
|
/**
|
|
* Returns the amount of items this entity possesses of a LOT, given that they're not in a temporary inventory
|
|
* (vendor buyback, vault, etc).
|
|
* @param lot the lot to search for
|
|
* @return the amount of items this entity possesses of the specified lot
|
|
*/
|
|
uint32_t GetLotCountNonTransfer(LOT lot) const;
|
|
|
|
/**
|
|
* Returns the items that are currently equipped by this entity
|
|
* @return the items that are currently equipped by this entity
|
|
*/
|
|
const EquipmentMap& GetEquippedItems() const;
|
|
|
|
/**
|
|
* Adds an item to the inventory of the entity
|
|
* @param lot the lot to add
|
|
* @param count the amount of items to add
|
|
* @param inventoryType the inventory to add the item to
|
|
* @param config optional config for this item, used for example for rockets
|
|
* @param parent optional parent of this item, used for proxy items
|
|
* @param showFlyingLoot show a client animation if the item is added
|
|
* @param isModMoveAndEquip equips the item
|
|
* @param subKey optional sub ID of a related object, used by pets
|
|
* @param inventorySourceType if the inventory was moved, the source inventory
|
|
* @param sourceType the source of the item, used to determine if the item is dropped or mailed if the inventory is full
|
|
* @param bound whether this item is bound
|
|
* @param preferredSlot the preferred slot to store this item
|
|
* @param lootSourceType The source of the loot. Defaults to none.
|
|
*/
|
|
void AddItem(
|
|
LOT lot,
|
|
uint32_t count,
|
|
eLootSourceType lootSourceType = eLootSourceType::NONE,
|
|
eInventoryType inventoryType = INVALID,
|
|
const std::vector<LDFBaseData*>& config = {},
|
|
LWOOBJID parent = LWOOBJID_EMPTY,
|
|
bool showFlyingLoot = true,
|
|
bool isModMoveAndEquip = false,
|
|
LWOOBJID subKey = LWOOBJID_EMPTY,
|
|
eInventoryType inventorySourceType = INVALID,
|
|
int32_t sourceType = 0,
|
|
bool bound = false,
|
|
int32_t preferredSlot = -1
|
|
);
|
|
|
|
/**
|
|
* Removes a LOT from the inventory
|
|
* @param lot the lot to remove
|
|
* @param count the number of items to remove
|
|
* @param inventoryType optional inventory type to remove the item from
|
|
* @param ignoreBound ignores bound items
|
|
* @param silent silently remove the item
|
|
*/
|
|
bool RemoveItem(LOT lot, uint32_t count, eInventoryType inventoryType = INVALID, bool ignoreBound = false, bool silent = false);
|
|
|
|
/**
|
|
* Moves an existing item to an inventory of the entity
|
|
* @param item the item to add
|
|
* @param inventory the inventory to add the item to
|
|
* @param count the number of items to add
|
|
* @param showFlyingLot displays UI animation to the user
|
|
* @param isModMoveAndEquip equips the item
|
|
* @param ignoreEquipped does not stack on equipped items
|
|
* @param preferredSlot the preferred slot to store the item in
|
|
*/
|
|
void MoveItemToInventory(Item* item, eInventoryType inventory, uint32_t count, bool showFlyingLot = true, bool isModMoveAndEquip = false, bool ignoreEquipped = false, int32_t preferredSlot = -1);
|
|
|
|
/**
|
|
* Moves a stack of items to an inventory
|
|
* @param item the item to move
|
|
* @param inventory the inventory to move the item to
|
|
* @param slot the slot in the inventory to move the item to
|
|
*/
|
|
void MoveStack(Item* item, eInventoryType inventory, uint32_t slot = 0);
|
|
|
|
/**
|
|
* Returns an item in the inventory by object ID
|
|
* @param id the id of the item to find
|
|
* @return item in the inventory by object ID
|
|
*/
|
|
Item* FindItemById(LWOOBJID id) const;
|
|
|
|
/**
|
|
* Returns an item in the inventory that matches the specified LOT
|
|
* @param lot the lot of the item to find
|
|
* @param inventoryType optional inventory to search in
|
|
* @param ignoreEquipped ignores items that are equipped
|
|
* @param ignoreBound ignores items that are bound
|
|
* @return item in the inventory that matches the specified LOT
|
|
*/
|
|
Item* FindItemByLot(LOT lot, eInventoryType inventoryType = INVALID, bool ignoreEquipped = false, bool ignoreBound = false);
|
|
|
|
/**
|
|
* Finds an item in the inventory that has the specified subkey, useful for pets
|
|
* @param id the subkey to look for
|
|
* @param inventoryType optional inventory type to search in
|
|
* @return item in the inventory that has the specified subkey
|
|
*/
|
|
Item* FindItemBySubKey(LWOOBJID id, eInventoryType inventoryType = INVALID);
|
|
|
|
/**
|
|
* Checks if the entity has enough space for a batch of loot
|
|
* @param loot a map of items to add and how many to add
|
|
* @return whether the entity has enough space for all the items
|
|
*/
|
|
bool HasSpaceForLoot(const std::unordered_map<LOT, int32_t>& loot);
|
|
|
|
/**
|
|
* Equips an item in the specified slot
|
|
* @param location the location to store the item (e.g. chest, left hand, etc.)
|
|
* @param item the item to place
|
|
* @param keepCurrent stores the item in an additional temp slot if there's already an item equipped
|
|
*/
|
|
void UpdateSlot(const std::string& location, EquippedItem item, bool keepCurrent = false);
|
|
|
|
/**
|
|
* Removes a slot from the inventory
|
|
* @param location the slot to remove
|
|
*/
|
|
void RemoveSlot(const std::string& location);
|
|
|
|
/**
|
|
* Equips the given item, guesses the slot to equip it in
|
|
* @param item the item to equip
|
|
* @param skipChecks skips checks for equipping cars and rockets (e.g. no special behavior follows)
|
|
*/
|
|
void EquipItem(Item* item, bool skipChecks = false);
|
|
|
|
/**
|
|
* Unequips an item from the inventory
|
|
* @param item the item to unequip
|
|
*/
|
|
void UnEquipItem(Item* item);
|
|
|
|
/**
|
|
* Unequips an Item from the inventory
|
|
* @param item the Item to unequip
|
|
* @return if we were successful
|
|
*/
|
|
void HandlePossession(Item* item);
|
|
|
|
/**
|
|
* Adds a buff related to equipping a lot to the entity
|
|
* @param item the item to find buffs for
|
|
*/
|
|
void ApplyBuff(Item* item) const;
|
|
|
|
/**
|
|
* Removes buffs related to equipping a lot from the entity
|
|
* @param item the item to find buffs for
|
|
*/
|
|
void RemoveBuff(Item* item) const;
|
|
|
|
/**
|
|
* Saves the equipped items into a temp state
|
|
*/
|
|
void PushEquippedItems();
|
|
|
|
/**
|
|
* Unequips all the temporary items and equips the previous item state
|
|
*/
|
|
void PopEquippedItems();
|
|
|
|
/**
|
|
* Returns if the entity has an item equipped of the given lot
|
|
* @param lot to lot to search for
|
|
* @return if the entity has an item equipped of the given lot
|
|
*/
|
|
bool IsEquipped(LOT lot) const;
|
|
|
|
/**
|
|
* Checks and ensures that we have loaded the item set that might be related to this item
|
|
* @param lot the lot to check the item set for
|
|
*/
|
|
void CheckItemSet(LOT lot);
|
|
|
|
/**
|
|
* Sets the current consumable lot
|
|
* @param lot the lot to set as consumable
|
|
*/
|
|
void SetConsumable(LOT lot);
|
|
|
|
/**
|
|
* Returns the current consumable lot
|
|
* @return the current consumable lot
|
|
*/
|
|
LOT GetConsumable() const;
|
|
|
|
/**
|
|
* Finds all the buffs related to a lot
|
|
* @param item the item to get the buffs for
|
|
* @param castOnEquip if true, the skill missions for these buffs will be progressed
|
|
* @return the buffs related to the specified lot
|
|
*/
|
|
std::vector<uint32_t> FindBuffs(Item* item, bool castOnEquip) const;
|
|
|
|
/**
|
|
* Initializes the equipped items with a list of items
|
|
* @param items the items to equip
|
|
*/
|
|
void SetNPCItems(const std::vector<LOT>& items);
|
|
|
|
/**
|
|
* Adds a skill related to a passed item to the currently equipped skills
|
|
* @param lot the lot to add a skill for
|
|
*/
|
|
void AddItemSkills(LOT lot);
|
|
|
|
/**
|
|
* Removes the skills related to the passed LOT from the currently equipped skills
|
|
* @param lot the lot to remove
|
|
*/
|
|
void RemoveItemSkills(LOT lot);
|
|
|
|
/**
|
|
* Triggers one of the passive abilities from the equipped item set
|
|
* @param trigger the trigger to fire
|
|
*/
|
|
void TriggerPassiveAbility(PassiveAbilityTrigger trigger, Entity* target = nullptr);
|
|
|
|
/**
|
|
* Returns if the entity has any of the passed passive abilities equipped
|
|
* @param passiveIDs the IDs to check for
|
|
* @param equipmentRequirement the number of equipment required to be allowed to have the ability
|
|
* @return if the entity has any of the passed passive abilities equipped
|
|
*/
|
|
bool HasAnyPassive(const std::vector<eItemSetPassiveAbilityID>& passiveIDs, int32_t equipmentRequirement) const;
|
|
|
|
/**
|
|
* Despawns the currently active pet, if any
|
|
*/
|
|
void DespawnPet();
|
|
|
|
/**
|
|
* Spawns the item as a pet (if it is one)
|
|
* @param item the pet to spawn
|
|
*/
|
|
void SpawnPet(Item* item);
|
|
|
|
/**
|
|
* Updates the database pet data for an item (e.g. moderation status)
|
|
* @param id the id of the pet to find
|
|
* @param data the data to store on the pet
|
|
*/
|
|
void SetDatabasePet(LWOOBJID id, const DatabasePet& data);
|
|
|
|
/**
|
|
* Returns the database pet information for an object
|
|
* @param id the object ID to search for
|
|
* @return the database pet information for the object that belongs to the passed id
|
|
*/
|
|
const DatabasePet& GetDatabasePet(LWOOBJID id) const;
|
|
|
|
/**
|
|
* Checks if the provided object ID is in this inventory and is a pet
|
|
* @param id the id of the object to check for
|
|
* @return if the provided object ID is in this inventory and is a pet
|
|
*/
|
|
bool IsPet(LWOOBJID id) const;
|
|
|
|
/**
|
|
* Removes pet database information from the item with the specified object id
|
|
* @param id the object id to remove pet info for
|
|
*/
|
|
void RemoveDatabasePet(LWOOBJID id);
|
|
|
|
/**
|
|
* Returns the current behavior slot active for the passed item type
|
|
* @param type the item type to find the behavior slot for
|
|
* @return the current behavior slot active for the passed item type
|
|
*/
|
|
static BehaviorSlot FindBehaviorSlot(eItemType type);
|
|
|
|
/**
|
|
* Checks if the inventory type is a temp inventory
|
|
* @param type the inventory type to check
|
|
* @return if the inventory type is a temp inventory
|
|
*/
|
|
static bool IsTransferInventory(eInventoryType type);
|
|
|
|
/**
|
|
* Finds the skill related to the passed LOT from the ObjectSkills table
|
|
* @param lot the lot to find
|
|
* @return the skill related to the passed LOT
|
|
*/
|
|
static uint32_t FindSkill(LOT lot);
|
|
|
|
/**
|
|
* Call this when you equip an item. This calls OnFactionTriggerItemEquipped for any scripts found on the items.
|
|
*
|
|
* @param equippedItem The item script to lookup and call equip on
|
|
*/
|
|
void EquipScripts(Item* equippedItem);
|
|
|
|
/**
|
|
* Call this when you unequip an item. This calls OnFactionTriggerItemUnequipped for any scripts found on the items.
|
|
*
|
|
* @param unequippedItem The item script to lookup and call unequip on
|
|
*/
|
|
void UnequipScripts(Item* unequippedItem);
|
|
|
|
std::map<BehaviorSlot, uint32_t> GetSkills() { return m_Skills; };
|
|
|
|
bool SetSkill(int slot, uint32_t skillId);
|
|
bool SetSkill(BehaviorSlot slot, uint32_t skillId);
|
|
|
|
void UpdateGroup(const GroupUpdate& groupUpdate);
|
|
void RemoveGroup(const std::string& groupId);
|
|
|
|
~InventoryComponent() override;
|
|
|
|
private:
|
|
/**
|
|
* The key is the inventory the group belongs to, the value maps' key is the id for the group.
|
|
* This is only used for bricks and model inventories.
|
|
*/
|
|
std::map<eInventoryType, std::vector<Group>> m_Groups{ { eInventoryType::BRICKS, {} }, { eInventoryType::MODELS, {} } };
|
|
|
|
/**
|
|
* All the inventory this entity possesses
|
|
*/
|
|
std::map<eInventoryType, Inventory*> m_Inventories;
|
|
|
|
/**
|
|
* The skills that this entity currently has active
|
|
*/
|
|
std::map<BehaviorSlot, uint32_t> m_Skills;
|
|
|
|
/**
|
|
* The pets this entity has, mapped by object ID and pet info
|
|
*/
|
|
std::unordered_map<LWOOBJID, DatabasePet> m_Pets;
|
|
|
|
/**
|
|
* Cache of item sets this entity has encountered
|
|
*/
|
|
std::vector<ItemSet*> m_Itemsets;
|
|
|
|
/**
|
|
* The LOTs we've checked all the item sets for (for cache reasons)
|
|
*/
|
|
std::vector<LOT> m_ItemSetsChecked;
|
|
|
|
/**
|
|
* all the equipped items
|
|
*/
|
|
EquipmentMap m_Equipped;
|
|
|
|
/**
|
|
* Clone of the equipped items before unequipping all of them
|
|
*/
|
|
EquipmentMap m_Pushed;
|
|
|
|
/**
|
|
* If the inventory has changed
|
|
*/
|
|
bool m_Dirty;
|
|
|
|
/**
|
|
* The currently active consumable
|
|
*/
|
|
LOT m_Consumable;
|
|
|
|
/**
|
|
* Currently has a car equipped
|
|
*/
|
|
bool hasCarEquipped = false;
|
|
Entity* equippedCarEntity = nullptr;
|
|
LWOOBJID previousPossessableID = LWOOBJID_EMPTY;
|
|
LWOOBJID previousPossessorID = LWOOBJID_EMPTY;
|
|
/**
|
|
* Creates all the proxy items (subitems) for a parent item
|
|
* @param parent the parent item to generate all the subitems for
|
|
* @return the proxy items (subitems) for a parent item
|
|
*/
|
|
std::vector<Item*> GenerateProxies(Item* parent);
|
|
|
|
/**
|
|
* Finds all the proxy items in this inventory for a given parent item
|
|
* @param parent the parent to find proxy items for
|
|
* @return the proxy items for the parent
|
|
*/
|
|
std::vector<Item*> FindProxies(LWOOBJID parent);
|
|
|
|
/**
|
|
* Returns true if the provided LWOOBJID is the parent of this Item.
|
|
* @param parent the parent item to check for proxies
|
|
* @return if the provided ID is a valid proxy item
|
|
*/
|
|
bool IsValidProxy(LWOOBJID parent);
|
|
|
|
/**
|
|
* Returns if the provided ID is a valid proxy item (e.g. we have children for it)
|
|
* @param parent the parent item to check for
|
|
* @return if the provided ID is a valid proxy item
|
|
*/
|
|
bool IsParentValid(Item* root);
|
|
|
|
/**
|
|
* Removes all the proxy items that have a dangling parent
|
|
*/
|
|
void CheckProxyIntegrity();
|
|
|
|
/**
|
|
* Removes all the proxy items for a given parent from the inventory
|
|
* @param item the item to remove proxy items for
|
|
*/
|
|
void PurgeProxies(Item* item);
|
|
|
|
/**
|
|
* Saves all the pet information stored in inventory items to the database
|
|
* @param document the xml doc to save to
|
|
*/
|
|
void LoadPetXml(const tinyxml2::XMLDocument& document);
|
|
|
|
/**
|
|
* Loads all the pet information from an xml doc into items
|
|
* @param document the xml doc to load from
|
|
*/
|
|
void UpdatePetXml(tinyxml2::XMLDocument& document);
|
|
|
|
void LoadGroupXml(const tinyxml2::XMLElement& groups);
|
|
void UpdateGroupXml(tinyxml2::XMLElement& groups) const;
|
|
};
|
|
|
|
#endif
|