mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2025-08-04 09:44:10 +00:00
Public release of the DLU server code!
Have fun!
This commit is contained in:
26
dGame/dInventory/DatabasePet.h
Normal file
26
dGame/dInventory/DatabasePet.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include "dCommonVars.h"
|
||||
|
||||
/**
|
||||
* Database information that specifies a pet
|
||||
*/
|
||||
struct DatabasePet
|
||||
{
|
||||
/**
|
||||
* The lot of this pet
|
||||
*/
|
||||
LOT lot = LOT_NULL;
|
||||
|
||||
/**
|
||||
* The name of the pet
|
||||
*/
|
||||
std::string name;
|
||||
|
||||
/**
|
||||
* The current moderation state, see PetComponent for more info
|
||||
*/
|
||||
int32_t moderationState = 0;
|
||||
};
|
||||
|
||||
const DatabasePet DATABASE_PET_INVALID;
|
1
dGame/dInventory/EquippedItem.cpp
Normal file
1
dGame/dInventory/EquippedItem.cpp
Normal file
@@ -0,0 +1 @@
|
||||
#include "EquippedItem.h"
|
29
dGame/dInventory/EquippedItem.h
Normal file
29
dGame/dInventory/EquippedItem.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#include "dCommonVars.h"
|
||||
|
||||
/**
|
||||
* An item that's equipped, generally as a smaller return type than the regular Item class
|
||||
*/
|
||||
struct EquippedItem
|
||||
{
|
||||
/**
|
||||
* The object ID of the equipped item
|
||||
*/
|
||||
LWOOBJID id = LWOOBJID_EMPTY;
|
||||
|
||||
/**
|
||||
* The LOT of this equipped item
|
||||
*/
|
||||
LOT lot = LOT_NULL;
|
||||
|
||||
/**
|
||||
* The number of items that are stored in this slot
|
||||
*/
|
||||
uint32_t count = 0;
|
||||
|
||||
/**
|
||||
* The slot this item is stored in
|
||||
*/
|
||||
uint32_t slot = 0;
|
||||
};
|
354
dGame/dInventory/Inventory.cpp
Normal file
354
dGame/dInventory/Inventory.cpp
Normal file
@@ -0,0 +1,354 @@
|
||||
#include "Inventory.h"
|
||||
#include "GameMessages.h"
|
||||
#include "Game.h"
|
||||
#include "Item.h"
|
||||
|
||||
std::vector<LOT> Inventory::m_GameMasterRestrictedItems = {
|
||||
1727, // GM Only - JetPack
|
||||
2243, // GM Only - Hammer of Doom
|
||||
3293, // GM Only - Flamethrower
|
||||
3735, // GM Only - Large Jetpack
|
||||
5873, // GM Only - Winged Helm of Speed
|
||||
6407, // Gm Only - Hat of Pwnage
|
||||
14442 // The jamesster jetpack
|
||||
};
|
||||
|
||||
Inventory::Inventory(const eInventoryType type, const uint32_t size, const std::vector<Item*>& items, InventoryComponent* component)
|
||||
{
|
||||
this->type = type;
|
||||
this->size = size;
|
||||
this->free = size;
|
||||
this->component = component;
|
||||
|
||||
for (auto* item : items)
|
||||
{
|
||||
AddManagedItem(item);
|
||||
}
|
||||
}
|
||||
|
||||
eInventoryType Inventory::GetType() const
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
uint32_t Inventory::GetSize() const
|
||||
{
|
||||
return size;
|
||||
}
|
||||
|
||||
std::map<LWOOBJID, Item*>& Inventory::GetItems()
|
||||
{
|
||||
return items;
|
||||
}
|
||||
|
||||
std::map<uint32_t, Item*> Inventory::GetSlots() const
|
||||
{
|
||||
std::map<uint32_t, Item*> slots;
|
||||
|
||||
for (const auto& pair : items)
|
||||
{
|
||||
auto* item = pair.second;
|
||||
|
||||
slots.insert_or_assign(item->GetSlot(), item);
|
||||
}
|
||||
|
||||
return slots;
|
||||
}
|
||||
|
||||
InventoryComponent* Inventory::GetComponent() const
|
||||
{
|
||||
return component;
|
||||
}
|
||||
|
||||
uint32_t Inventory::GetLotCount(const LOT lot) const
|
||||
{
|
||||
uint32_t count = 0;
|
||||
|
||||
for (const auto& pair : items)
|
||||
{
|
||||
const auto* item = pair.second;
|
||||
|
||||
if (item->GetLot() == lot)
|
||||
{
|
||||
count += item->GetCount();
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
void Inventory::SetSize(const uint32_t value)
|
||||
{
|
||||
free += static_cast<int32_t>(value) - static_cast<int32_t>(size);
|
||||
|
||||
size = value;
|
||||
|
||||
GameMessages::SendSetInventorySize(component->GetParent(), type, static_cast<int>(size));
|
||||
}
|
||||
|
||||
int32_t Inventory::FindEmptySlot()
|
||||
{
|
||||
if (free <= 6) // Up from 1
|
||||
{
|
||||
if (type != ITEMS && type != VAULT_ITEMS)
|
||||
{
|
||||
uint32_t newSize = size;
|
||||
|
||||
if (type == MODELS || type == VAULT_MODELS)
|
||||
{
|
||||
newSize = 240;
|
||||
}
|
||||
else
|
||||
{
|
||||
newSize += 20;
|
||||
}
|
||||
|
||||
if (newSize > GetSize())
|
||||
{
|
||||
SetSize(newSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (free == 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
const auto slots = GetSlots();
|
||||
|
||||
for (auto i = 0u; i < size; ++i)
|
||||
{
|
||||
if (slots.find(i) == slots.end())
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32_t Inventory::GetEmptySlots()
|
||||
{
|
||||
return free;
|
||||
}
|
||||
|
||||
bool Inventory::IsSlotEmpty(int32_t slot)
|
||||
{
|
||||
const auto slots = GetSlots();
|
||||
|
||||
const auto& index = slots.find(slot);
|
||||
|
||||
return index == slots.end();
|
||||
}
|
||||
|
||||
Item* Inventory::FindItemById(const LWOOBJID id) const
|
||||
{
|
||||
const auto& index = items.find(id);
|
||||
|
||||
if (index == items.end())
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return index->second;
|
||||
}
|
||||
|
||||
Item* Inventory::FindItemByLot(const LOT lot, const bool ignoreEquipped, const bool ignoreBound) const
|
||||
{
|
||||
Item* smallest = nullptr;
|
||||
|
||||
for (const auto& pair : items)
|
||||
{
|
||||
auto* item = pair.second;
|
||||
|
||||
if (item->GetLot() != lot)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ignoreEquipped && item->IsEquipped())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ignoreBound && item->GetBound())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (smallest == nullptr)
|
||||
{
|
||||
smallest = item;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (smallest->GetCount() > item->GetCount())
|
||||
{
|
||||
smallest = item;
|
||||
}
|
||||
}
|
||||
|
||||
return smallest;
|
||||
}
|
||||
|
||||
Item* Inventory::FindItemBySlot(const uint32_t slot) const
|
||||
{
|
||||
const auto slots = GetSlots();
|
||||
|
||||
const auto index = slots.find(slot);
|
||||
|
||||
if (index == slots.end())
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return index->second;
|
||||
}
|
||||
|
||||
Item* Inventory::FindItemBySubKey(LWOOBJID id) const
|
||||
{
|
||||
for (const auto& item : items)
|
||||
{
|
||||
if (item.second->GetSubKey() == id)
|
||||
{
|
||||
return item.second;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Inventory::AddManagedItem(Item* item)
|
||||
{
|
||||
const auto id = item->GetId();
|
||||
|
||||
if (items.find(id) != items.end())
|
||||
{
|
||||
Game::logger->Log("Inventory", "Attempting to add an item with an already present id (%llu)!\n", id);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const auto slots = GetSlots();
|
||||
|
||||
const auto slot = item->GetSlot();
|
||||
|
||||
if (slots.find(slot) != slots.end())
|
||||
{
|
||||
Game::logger->Log("Inventory", "Attempting to add an item with and already present slot (%i)!\n", slot);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
items.insert_or_assign(id, item);
|
||||
|
||||
free--;
|
||||
}
|
||||
|
||||
void Inventory::RemoveManagedItem(Item* item)
|
||||
{
|
||||
const auto id = item->GetId();
|
||||
|
||||
if (items.find(id) == items.end())
|
||||
{
|
||||
Game::logger->Log("Inventory", "Attempting to remove an item with an invalid id (%llu), lot (%i)!\n", id, item->GetLot());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
items.erase(id);
|
||||
|
||||
free++;
|
||||
}
|
||||
|
||||
eInventoryType Inventory::FindInventoryTypeForLot(const LOT lot)
|
||||
{
|
||||
auto itemComponent = FindItemComponent(lot);
|
||||
|
||||
const auto itemType = static_cast<eItemType>(itemComponent.itemType);
|
||||
|
||||
switch (itemType) {
|
||||
case ITEM_TYPE_BRICK:
|
||||
return BRICKS;
|
||||
|
||||
case ITEM_TYPE_BEHAVIOR:
|
||||
return BEHAVIORS;
|
||||
|
||||
case ITEM_TYPE_PROPERTY:
|
||||
return PROPERTY_DEEDS;
|
||||
|
||||
case ITEM_TYPE_MODEL:
|
||||
case ITEM_TYPE_VEHICLE:
|
||||
case ITEM_TYPE_LOOT_MODEL:
|
||||
return MODELS;
|
||||
|
||||
case ITEM_TYPE_HAT:
|
||||
case ITEM_TYPE_HAIR:
|
||||
case ITEM_TYPE_NECK:
|
||||
case ITEM_TYPE_LEFT_HAND:
|
||||
case ITEM_TYPE_RIGHT_HAND:
|
||||
case ITEM_TYPE_LEGS:
|
||||
case ITEM_TYPE_LEFT_TRINKET:
|
||||
case ITEM_TYPE_RIGHT_TRINKET:
|
||||
case ITEM_TYPE_COLLECTIBLE:
|
||||
case ITEM_TYPE_CONSUMABLE:
|
||||
case ITEM_TYPE_CHEST:
|
||||
case ITEM_TYPE_EGG:
|
||||
case ITEM_TYPE_PET_FOOD:
|
||||
case ITEM_TYPE_PET_INVENTORY_ITEM:
|
||||
case ITEM_TYPE_PACKAGE:
|
||||
case ITEM_TYPE_CURRENCY:
|
||||
return ITEMS;
|
||||
|
||||
case ITEM_TYPE_QUEST_OBJECT:
|
||||
case ITEM_TYPE_UNKNOWN:
|
||||
default:
|
||||
return HIDDEN;
|
||||
}
|
||||
}
|
||||
|
||||
const CDItemComponent& Inventory::FindItemComponent(const LOT lot)
|
||||
{
|
||||
auto* registry = CDClientManager::Instance()->GetTable<CDComponentsRegistryTable>("ComponentsRegistry");
|
||||
|
||||
auto* itemComponents = CDClientManager::Instance()->GetTable<CDItemComponentTable>("ItemComponent");
|
||||
|
||||
const auto componentId = registry->GetByIDAndType(lot, COMPONENT_TYPE_ITEM);
|
||||
|
||||
if (componentId == 0)
|
||||
{
|
||||
Game::logger->Log("Inventory", "Failed to find item component for (%i)!\n", lot);
|
||||
|
||||
return CDItemComponentTable::Default;
|
||||
}
|
||||
|
||||
const auto& itemComponent = itemComponents->GetItemComponentByID(componentId);
|
||||
|
||||
return itemComponent;
|
||||
}
|
||||
|
||||
bool Inventory::IsValidItem(const LOT lot)
|
||||
{
|
||||
auto* registry = CDClientManager::Instance()->GetTable<CDComponentsRegistryTable>("ComponentsRegistry");
|
||||
|
||||
const auto componentId = registry->GetByIDAndType(lot, COMPONENT_TYPE_ITEM);
|
||||
|
||||
return componentId != 0;
|
||||
}
|
||||
|
||||
const std::vector<LOT>& Inventory::GetAllGMItems()
|
||||
{
|
||||
return m_GameMasterRestrictedItems;
|
||||
}
|
||||
|
||||
Inventory::~Inventory()
|
||||
{
|
||||
for (auto item : items)
|
||||
{
|
||||
delete item.second;
|
||||
}
|
||||
|
||||
items.clear();
|
||||
}
|
184
dGame/dInventory/Inventory.h
Normal file
184
dGame/dInventory/Inventory.h
Normal file
@@ -0,0 +1,184 @@
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
|
||||
#include "CDClientManager.h"
|
||||
#include "dCommonVars.h"
|
||||
|
||||
class Item;
|
||||
class InventoryComponent;
|
||||
|
||||
/**
|
||||
* An inventory of a certain type that's owned by an entity
|
||||
*/
|
||||
class Inventory final
|
||||
{
|
||||
public:
|
||||
explicit Inventory(eInventoryType type, uint32_t size, const std::vector<Item*>& items, InventoryComponent* component);
|
||||
|
||||
/**
|
||||
* Returns the type of this inventory
|
||||
* @return the type of this inventory
|
||||
*/
|
||||
eInventoryType GetType() const;
|
||||
|
||||
/**
|
||||
* Returns the maximum amount of items this inventory can contain
|
||||
* @return the maximum amount of items this inventory can contain
|
||||
*/
|
||||
uint32_t GetSize() const;
|
||||
|
||||
/**
|
||||
* Returns all the items that are currently in this inventory, mapped by object ID
|
||||
* @return all the items that are currently in this inventory, mapped by object ID
|
||||
*/
|
||||
std::map<LWOOBJID, Item*>& GetItems();
|
||||
|
||||
/**
|
||||
* Returns all the items that are currently in this inventory, mapped by slot
|
||||
* @return all the items that are currently in this inventory, mapped by slot
|
||||
*/
|
||||
std::map<uint32_t, Item*> GetSlots() const;
|
||||
|
||||
/**
|
||||
* Returns the inventory component that this inventory is part of
|
||||
* @return the inventory component that this inventory is part of
|
||||
*/
|
||||
InventoryComponent* GetComponent() const;
|
||||
|
||||
/**
|
||||
* Returns the amount of items this inventory contains of the specified LOT
|
||||
* @param lot the lot to find items for
|
||||
* @return the amount of items this inventory contains of the specified LOT
|
||||
*/
|
||||
uint32_t GetLotCount(LOT lot) const;
|
||||
|
||||
/**
|
||||
* Updates the max size of this inventory
|
||||
* @param value the size to set
|
||||
*/
|
||||
void SetSize(uint32_t value);
|
||||
|
||||
/**
|
||||
* Returns the first slot in this inventory that does not contain an item
|
||||
* @return the first slot in this inventory that does not contain an item
|
||||
*/
|
||||
int32_t FindEmptySlot();
|
||||
|
||||
/**
|
||||
* Returns the number of empty slots this inventory has left
|
||||
* @return the number of empty slots this inventory has left
|
||||
*/
|
||||
int32_t GetEmptySlots();
|
||||
|
||||
/**
|
||||
* Returns if the slot for the specified index is empty
|
||||
* @param slot the index to check occupation for
|
||||
* @return if the slot for the specified index is empty
|
||||
*/
|
||||
bool IsSlotEmpty(int32_t slot);
|
||||
|
||||
/**
|
||||
* Finds an item in this inventory by the provided id
|
||||
* @param id the object ID of the item to find
|
||||
* @return item in this inventory by the provided id
|
||||
*/
|
||||
Item* FindItemById(LWOOBJID id) const;
|
||||
|
||||
/**
|
||||
* Finds an item in the inventory for the provided LOT
|
||||
* @param lot the lot to find items for
|
||||
* @param ignoreEquipped ignores equipped items
|
||||
* @param ignoreBound ignores bound items
|
||||
* @return item in the inventory for the provided LOT
|
||||
*/
|
||||
Item* FindItemByLot(LOT lot, bool ignoreEquipped = false, bool ignoreBound = false) const;
|
||||
|
||||
/**
|
||||
* Finds an item in the inventory stored on the provied slot
|
||||
* @param slot to slot to find an item for
|
||||
* @return item in the inventory stored on the provied slot
|
||||
*/
|
||||
Item* FindItemBySlot(uint32_t slot) const;
|
||||
|
||||
/**
|
||||
* Finds an item based on a specified subkey (useful for pets)
|
||||
* @param id the subkey to look for in the items
|
||||
* @return item based on a specified subkey
|
||||
*/
|
||||
Item* FindItemBySubKey(LWOOBJID id) const;
|
||||
|
||||
/**
|
||||
* Adds an item to the inventory, finding a slot to place it in
|
||||
* @param item item to add to the inventory
|
||||
*/
|
||||
void AddManagedItem(Item* item);
|
||||
|
||||
/**
|
||||
* Removes an item from the inventory, clearing its slot
|
||||
* @param item
|
||||
*/
|
||||
void RemoveManagedItem(Item* item);
|
||||
|
||||
/**
|
||||
* Returns the inventory type an item of the specified lot should be placed in
|
||||
* @param lot the lot to find the inventory type for
|
||||
* @return the inventory type an item of the specified lot should be placed in
|
||||
*/
|
||||
static eInventoryType FindInventoryTypeForLot(LOT lot);
|
||||
|
||||
/**
|
||||
* Finds the database item component for a item of a certain LOT
|
||||
* @param lot the LOT of the item to get the database item component for
|
||||
* @return the database item component for a item of a certain LOT
|
||||
*/
|
||||
static const CDItemComponent& FindItemComponent(LOT lot);
|
||||
|
||||
/**
|
||||
* Cheks if the provided lot has a database item component
|
||||
* @param lot the LOT to check item validity for
|
||||
* @return if the provided lot has a database item component
|
||||
*/
|
||||
static bool IsValidItem(LOT lot);
|
||||
|
||||
/**
|
||||
* Returns all the items that are restricted to GMs
|
||||
* @return all the items that are restricted to GMs
|
||||
*/
|
||||
static const std::vector<LOT>& GetAllGMItems();
|
||||
|
||||
~Inventory();
|
||||
|
||||
private:
|
||||
/**
|
||||
* The type of this inventory
|
||||
*/
|
||||
eInventoryType type;
|
||||
|
||||
/**
|
||||
* The max size of this inventory
|
||||
*/
|
||||
uint32_t size;
|
||||
|
||||
/**
|
||||
* The amount of items that can still be stored in this inventroy
|
||||
*/
|
||||
uint32_t free;
|
||||
|
||||
/**
|
||||
* The items stored in this inventory
|
||||
*/
|
||||
std::map<LWOOBJID, Item*> items;
|
||||
|
||||
/**
|
||||
* The inventory component this inventory belongs to
|
||||
*/
|
||||
InventoryComponent* component;
|
||||
|
||||
/**
|
||||
* List of items that are GM restricted
|
||||
*/
|
||||
static std::vector<LOT> m_GameMasterRestrictedItems;
|
||||
};
|
500
dGame/dInventory/Item.cpp
Normal file
500
dGame/dInventory/Item.cpp
Normal file
@@ -0,0 +1,500 @@
|
||||
#include "Item.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include "../dWorldServer/ObjectIDManager.h"
|
||||
#include "GeneralUtils.h"
|
||||
#include "GameMessages.h"
|
||||
#include "Entity.h"
|
||||
#include "Game.h"
|
||||
#include "dLogger.h"
|
||||
#include "EntityManager.h"
|
||||
#include "RenderComponent.h"
|
||||
|
||||
class Inventory;
|
||||
|
||||
|
||||
Item::Item(const LWOOBJID id, const LOT lot, Inventory* inventory, const uint32_t slot, const uint32_t count, const bool bound, const std::vector<LDFBaseData*>& config, const LWOOBJID parent, LWOOBJID subKey)
|
||||
{
|
||||
if (!Inventory::IsValidItem(lot))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this->id = id;
|
||||
this->lot = lot;
|
||||
this->inventory = inventory;
|
||||
this->slot = slot;
|
||||
this->count = count;
|
||||
this->bound = bound;
|
||||
this->config = config;
|
||||
this->parent = parent;
|
||||
this->info = &Inventory::FindItemComponent(lot);
|
||||
this->preconditions = new PreconditionExpression(this->info->reqPrecondition);
|
||||
this->subKey = subKey;
|
||||
|
||||
inventory->AddManagedItem(this);
|
||||
}
|
||||
|
||||
Item::Item(
|
||||
const LOT lot,
|
||||
Inventory* inventory,
|
||||
const uint32_t slot,
|
||||
const uint32_t count,
|
||||
const std::vector<LDFBaseData*>& config,
|
||||
const LWOOBJID parent,
|
||||
bool showFlyingLoot,
|
||||
bool isModMoveAndEquip,
|
||||
LWOOBJID subKey,
|
||||
bool bound)
|
||||
{
|
||||
if (!Inventory::IsValidItem(lot))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (isModMoveAndEquip)
|
||||
{
|
||||
showFlyingLoot = false;
|
||||
}
|
||||
|
||||
this->lot = lot;
|
||||
this->inventory = inventory;
|
||||
this->slot = slot;
|
||||
this->count = count;
|
||||
this->config = config;
|
||||
this->parent = parent;
|
||||
this->id = LWOOBJID_EMPTY;
|
||||
this->info = &Inventory::FindItemComponent(lot);
|
||||
this->bound = info->isBOP || bound;
|
||||
this->preconditions = new PreconditionExpression(this->info->reqPrecondition);
|
||||
this->subKey = subKey;
|
||||
|
||||
LWOOBJID id = ObjectIDManager::GenerateRandomObjectID();
|
||||
|
||||
id = GeneralUtils::SetBit(id, OBJECT_BIT_CHARACTER);
|
||||
id = GeneralUtils::SetBit(id, OBJECT_BIT_PERSISTENT);
|
||||
|
||||
this->id = id;
|
||||
|
||||
inventory->AddManagedItem(this);
|
||||
|
||||
auto* entity = inventory->GetComponent()->GetParent();
|
||||
|
||||
GameMessages::SendAddItemToInventoryClientSync(entity, entity->GetSystemAddress(), this, id, showFlyingLoot, static_cast<int>(this->count), subKey);
|
||||
|
||||
if (isModMoveAndEquip)
|
||||
{
|
||||
Equip();
|
||||
|
||||
Game::logger->Log("Item", "Move and equipped (%i) from (%i)\n", this->lot, this->inventory->GetType());
|
||||
|
||||
EntityManager::Instance()->SerializeEntity(inventory->GetComponent()->GetParent());
|
||||
}
|
||||
}
|
||||
|
||||
LWOOBJID Item::GetId() const
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
LOT Item::GetLot() const
|
||||
{
|
||||
return lot;
|
||||
}
|
||||
|
||||
uint32_t Item::GetCount() const
|
||||
{
|
||||
return count;
|
||||
}
|
||||
|
||||
uint32_t Item::GetSlot() const
|
||||
{
|
||||
return slot;
|
||||
}
|
||||
|
||||
std::vector<LDFBaseData*>& Item::GetConfig()
|
||||
{
|
||||
return config;
|
||||
}
|
||||
|
||||
const CDItemComponent& Item::GetInfo() const
|
||||
{
|
||||
return *info;
|
||||
}
|
||||
|
||||
bool Item::GetBound() const
|
||||
{
|
||||
return bound;
|
||||
}
|
||||
|
||||
Inventory* Item::GetInventory() const
|
||||
{
|
||||
return inventory;
|
||||
}
|
||||
|
||||
LWOOBJID Item::GetParent() const
|
||||
{
|
||||
return parent;
|
||||
}
|
||||
|
||||
LWOOBJID Item::GetSubKey() const
|
||||
{
|
||||
return subKey;
|
||||
}
|
||||
|
||||
PreconditionExpression* Item::GetPreconditionExpression() const
|
||||
{
|
||||
return preconditions;
|
||||
}
|
||||
|
||||
void Item::SetCount(const uint32_t value, const bool silent, const bool disassemble, const bool showFlyingLoot)
|
||||
{
|
||||
if (value == count)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const auto delta = std::abs(static_cast<int32_t>(value) - static_cast<int32_t>(count));
|
||||
|
||||
const auto type = static_cast<eItemType>(info->itemType);
|
||||
|
||||
if (disassemble)
|
||||
{
|
||||
if (value < count)
|
||||
{
|
||||
for (auto i = 0; i < delta; ++i)
|
||||
{
|
||||
Disassemble();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!silent)
|
||||
{
|
||||
auto* entity = inventory->GetComponent()->GetParent();
|
||||
|
||||
if (value > count)
|
||||
{
|
||||
GameMessages::SendAddItemToInventoryClientSync(entity, entity->GetSystemAddress(), this, id, showFlyingLoot, delta);
|
||||
}
|
||||
else
|
||||
{
|
||||
GameMessages::SendRemoveItemFromInventory(entity, entity->GetSystemAddress(), id, lot, inventory->GetType(), delta, value);
|
||||
}
|
||||
}
|
||||
|
||||
count = value;
|
||||
|
||||
if (count == 0)
|
||||
{
|
||||
RemoveFromInventory();
|
||||
}
|
||||
}
|
||||
|
||||
void Item::SetSlot(const uint32_t value)
|
||||
{
|
||||
if (slot == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (const auto& pair : inventory->GetItems())
|
||||
{
|
||||
auto* item = pair.second;
|
||||
|
||||
if (item->slot == value)
|
||||
{
|
||||
item->slot = slot;
|
||||
}
|
||||
}
|
||||
|
||||
slot = value;
|
||||
}
|
||||
|
||||
void Item::SetBound(const bool value)
|
||||
{
|
||||
bound = value;
|
||||
}
|
||||
|
||||
void Item::SetSubKey(LWOOBJID value)
|
||||
{
|
||||
subKey = value;
|
||||
}
|
||||
|
||||
void Item::SetInventory(Inventory* value)
|
||||
{
|
||||
inventory->RemoveManagedItem(this);
|
||||
|
||||
inventory = value;
|
||||
|
||||
inventory->AddManagedItem(this);
|
||||
}
|
||||
|
||||
void Item::Equip(const bool skipChecks)
|
||||
{
|
||||
if (IsEquipped())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
inventory->GetComponent()->EquipItem(this, skipChecks);
|
||||
}
|
||||
|
||||
void Item::UnEquip()
|
||||
{
|
||||
if (!IsEquipped())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
inventory->GetComponent()->UnEquipItem(this);
|
||||
}
|
||||
|
||||
bool Item::IsEquipped() const
|
||||
{
|
||||
auto* component = inventory->GetComponent();
|
||||
|
||||
for (const auto& pair : component->GetEquippedItems())
|
||||
{
|
||||
const auto item = pair.second;
|
||||
|
||||
if (item.id == id)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Item::Consume()
|
||||
{
|
||||
auto* skillsTable = CDClientManager::Instance()->GetTable<CDObjectSkillsTable>("ObjectSkills");
|
||||
|
||||
auto skills = skillsTable->Query([=](const CDObjectSkills entry)
|
||||
{
|
||||
return entry.objectTemplate == static_cast<uint32_t>(lot);
|
||||
});
|
||||
|
||||
auto success = false;
|
||||
|
||||
for (auto& skill : skills)
|
||||
{
|
||||
if (skill.castOnType == 3) // Consumable type
|
||||
{
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
|
||||
Game::logger->Log("Item", "Consumed (%i) / (%llu) with (%d)\n", lot, id, success);
|
||||
|
||||
GameMessages::SendUseItemResult(inventory->GetComponent()->GetParent(), lot, success);
|
||||
|
||||
if (success)
|
||||
{
|
||||
inventory->GetComponent()->RemoveItem(lot, 1);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool Item::UseNonEquip()
|
||||
{
|
||||
auto* compRegistryTable = CDClientManager::Instance()->GetTable<CDComponentsRegistryTable>("ComponentsRegistry");
|
||||
|
||||
const auto packageComponentId = compRegistryTable->GetByIDAndType(lot, COMPONENT_TYPE_PACKAGE);
|
||||
|
||||
auto* packCompTable = CDClientManager::Instance()->GetTable<CDPackageComponentTable>("PackageComponent");
|
||||
|
||||
auto packages = packCompTable->Query([=](const CDPackageComponent entry) {return entry.id == static_cast<uint32_t>(packageComponentId); });
|
||||
|
||||
const auto success = !packages.empty();
|
||||
|
||||
Game::logger->Log("Item", "Used (%i) with (%d)\n", lot, success);
|
||||
|
||||
if (subKey != LWOOBJID_EMPTY)
|
||||
{
|
||||
const auto& databasePet = GetInventory()->GetComponent()->GetDatabasePet(subKey);
|
||||
|
||||
if (databasePet.lot != LOT_NULL)
|
||||
{
|
||||
GetInventory()->GetComponent()->SpawnPet(this);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (success)
|
||||
{
|
||||
auto* entityParent = inventory->GetComponent()->GetParent();
|
||||
|
||||
for (auto& pack : packages)
|
||||
{
|
||||
std::unordered_map<LOT, int32_t> result {};
|
||||
|
||||
Loot::CalculateLootMatrix(pack.LootMatrixIndex, entityParent, result);
|
||||
|
||||
if (!inventory->GetComponent()->HasSpaceForLoot(result))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Loot::GiveLoot(inventory->GetComponent()->GetParent(), result);
|
||||
}
|
||||
|
||||
inventory->GetComponent()->RemoveItem(lot, 1);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
void Item::Disassemble(const eInventoryType inventoryType)
|
||||
{
|
||||
for (auto* data : config)
|
||||
{
|
||||
if (data->GetKey() == u"assemblyPartLOTs")
|
||||
{
|
||||
auto modStr = data->GetValueAsString();
|
||||
|
||||
std::vector<LOT> modArray;
|
||||
|
||||
std::stringstream ssData(modStr);
|
||||
|
||||
std::string token;
|
||||
|
||||
const auto deliminator = '+';
|
||||
|
||||
while (std::getline(ssData, token, deliminator))
|
||||
{
|
||||
const auto modLot = std::stoi(token.substr(2, token.size() - 1));
|
||||
|
||||
modArray.push_back(modLot);
|
||||
}
|
||||
|
||||
for (const auto mod : modArray)
|
||||
{
|
||||
inventory->GetComponent()->AddItem(mod, 1, inventoryType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Item::DisassembleModel()
|
||||
{
|
||||
auto* table = CDClientManager::Instance()->GetTable<CDComponentsRegistryTable>("ComponentsRegistry");
|
||||
|
||||
const auto componentId = table->GetByIDAndType(GetLot(), COMPONENT_TYPE_RENDER);
|
||||
|
||||
std::stringstream query;
|
||||
|
||||
query << "SELECT render_asset FROM RenderComponent WHERE id = " << std::to_string(componentId) << ";";
|
||||
|
||||
auto result = CDClientDatabase::ExecuteQuery(query.str());
|
||||
|
||||
if (result.eof())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::string renderAsset = result.fieldIsNull(0) ? "" : std::string(result.getStringField(0));
|
||||
std::vector<std::string> renderAssetSplit = GeneralUtils::SplitString(renderAsset, '\\');
|
||||
|
||||
std::string lxfmlPath = "res/BrickModels/" + GeneralUtils::SplitString(renderAssetSplit.back(), '.')[0] + ".lxfml";
|
||||
std::ifstream file(lxfmlPath);
|
||||
|
||||
result.finalize();
|
||||
|
||||
if (!file.good())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::stringstream data;
|
||||
data << file.rdbuf();
|
||||
|
||||
if (data.str().empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto* doc = new tinyxml2::XMLDocument();
|
||||
|
||||
if (!doc)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (doc->Parse(data.str().c_str(), data.str().size()) != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<int> parts;
|
||||
|
||||
auto* lxfml = doc->FirstChildElement("LXFML");
|
||||
auto* bricks = lxfml->FirstChildElement("Bricks");
|
||||
std::string searchTerm = "Brick";
|
||||
|
||||
if (!bricks)
|
||||
{
|
||||
searchTerm = "Part";
|
||||
bricks = lxfml->FirstChildElement("Scene")->FirstChildElement("Model")->FirstChildElement("Group");
|
||||
|
||||
if (!bricks)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
auto* currentBrick = bricks->FirstChildElement(searchTerm.c_str());
|
||||
while (currentBrick)
|
||||
{
|
||||
if (currentBrick->Attribute("designID") != nullptr)
|
||||
{
|
||||
parts.push_back(std::stoi(currentBrick->Attribute("designID")));
|
||||
}
|
||||
|
||||
currentBrick = currentBrick->NextSiblingElement(searchTerm.c_str());
|
||||
}
|
||||
|
||||
auto* brickIDTable = CDClientManager::Instance()->GetTable<CDBrickIDTableTable>("BrickIDTable");
|
||||
|
||||
for (unsigned int part : parts)
|
||||
{
|
||||
const auto brickID = brickIDTable->Query([=](const CDBrickIDTable& entry)
|
||||
{
|
||||
return entry.LEGOBrickID == part;
|
||||
});
|
||||
|
||||
if (brickID.empty())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
GetInventory()->GetComponent()->AddItem(brickID[0].NDObjectID, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void Item::RemoveFromInventory()
|
||||
{
|
||||
UnEquip();
|
||||
|
||||
count = 0;
|
||||
|
||||
inventory->RemoveManagedItem(this);
|
||||
|
||||
delete this;
|
||||
}
|
||||
|
||||
Item::~Item()
|
||||
{
|
||||
delete preconditions;
|
||||
|
||||
for (auto* value : config)
|
||||
{
|
||||
delete value;
|
||||
}
|
||||
|
||||
config.clear();
|
||||
}
|
270
dGame/dInventory/Item.h
Normal file
270
dGame/dInventory/Item.h
Normal file
@@ -0,0 +1,270 @@
|
||||
#pragma once
|
||||
|
||||
#include "dCommonVars.h"
|
||||
#include "Inventory.h"
|
||||
#include "LDFFormat.h"
|
||||
#include "CDClientManager.h"
|
||||
#include "dLogger.h"
|
||||
#include "Preconditions.h"
|
||||
|
||||
/**
|
||||
* An item that can be stored in an inventory and optionally consumed or equipped
|
||||
* TODO: ideally this should be a component
|
||||
*/
|
||||
class Item final
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Creates an item, should be used if the item is not picked up but already exists
|
||||
* @param id the object ID of the item to create
|
||||
* @param lot the LOT of the item
|
||||
* @param inventory the inventory to add this item to
|
||||
* @param slot the slot in the inventory to add this item to
|
||||
* @param count the amount of items to add to the inventory
|
||||
* @param bound if the item should be bound
|
||||
* @param config config data for this item, e.g. for rockets
|
||||
* @param parent optional parent of this item, e.g. for proxy items
|
||||
* @param subKey optional subkey for this item, e.g. for pets
|
||||
*/
|
||||
explicit Item(
|
||||
LWOOBJID id,
|
||||
LOT lot,
|
||||
Inventory* inventory,
|
||||
uint32_t slot,
|
||||
uint32_t count,
|
||||
bool bound,
|
||||
const std::vector<LDFBaseData*>& config,
|
||||
LWOOBJID parent,
|
||||
LWOOBJID subKey
|
||||
);
|
||||
|
||||
/**
|
||||
* Creates an item, should be used if the item is picked up / added to the inventory after load
|
||||
* @param lot the LOT of the item
|
||||
* @param inventory the inventory to add this item to
|
||||
* @param slot the slot in the inventory to add this item to
|
||||
* @param count the amount of items to add to the inventory
|
||||
* @param config config data for this item, e.g. for rockets
|
||||
* @param parent optional parent of this item, e.g. for proxy items
|
||||
* @param showFlyingLoot show UI animation of the item being added
|
||||
* @param isModMoveAndEquip equips the item
|
||||
* @param subKey optional subkey for this item, e.g. for pets
|
||||
* @param bound if the item should be bound
|
||||
*/
|
||||
explicit Item(
|
||||
LOT lot,
|
||||
Inventory* inventory,
|
||||
uint32_t slot = 0,
|
||||
uint32_t count = 1,
|
||||
const std::vector<LDFBaseData*>& config = {},
|
||||
LWOOBJID parent = LWOOBJID_EMPTY,
|
||||
bool showFlyingLoot = true,
|
||||
bool isModMoveAndEquip = false,
|
||||
LWOOBJID subKey = LWOOBJID_EMPTY,
|
||||
bool bound = false
|
||||
);
|
||||
|
||||
~Item();
|
||||
|
||||
/**
|
||||
* Returns the object ID of this item
|
||||
* @return the object ID of this item
|
||||
*/
|
||||
LWOOBJID GetId() const;
|
||||
|
||||
/**
|
||||
* Returns the lot of this item
|
||||
* @return the lot of this item
|
||||
*/
|
||||
LOT GetLot() const;
|
||||
|
||||
/**
|
||||
* Sets the number of items this item represents
|
||||
* @param value the number to update by
|
||||
* @param silent if true, the client will not be notified of the change with GMs
|
||||
* @param disassemble if items were removed, this returns all the sub parts of the item individually if it had assembly part lots
|
||||
* @param showFlyingLoot shows flying loot to the client, if not silent
|
||||
*/
|
||||
void SetCount(uint32_t value, bool silent = false, bool disassemble = true, bool showFlyingLoot = true);
|
||||
|
||||
/**
|
||||
* Returns the number of items this item represents (e.g. for stacks)
|
||||
* @return the number of items this item represents
|
||||
*/
|
||||
uint32_t GetCount() const;
|
||||
|
||||
/**
|
||||
* Sets the slot this item is stored in
|
||||
* @param value the slot this item is stored in
|
||||
*/
|
||||
void SetSlot(uint32_t value);
|
||||
|
||||
/**
|
||||
* Returns the slot this item is in
|
||||
* @return the slot this item is in
|
||||
*/
|
||||
uint32_t GetSlot() const;
|
||||
|
||||
/**
|
||||
* Returns current config info for this item, e.g. for rockets
|
||||
* @return current config info for this item
|
||||
*/
|
||||
std::vector<LDFBaseData*>& GetConfig();
|
||||
|
||||
/**
|
||||
* Returns the database info for this item
|
||||
* @return the database info for this item
|
||||
*/
|
||||
const CDItemComponent& GetInfo() const;
|
||||
|
||||
/**
|
||||
* Sets if the item is bound
|
||||
* @param value if the item is bound
|
||||
*/
|
||||
void SetBound(bool value);
|
||||
|
||||
/**
|
||||
* Returns if the item is bound
|
||||
* @return if the item is bound
|
||||
*/
|
||||
bool GetBound() const;
|
||||
|
||||
/**
|
||||
* Sets the inventory this item belongs to
|
||||
* @param value the inventory this item belongs to
|
||||
*/
|
||||
void SetInventory(Inventory* value);
|
||||
|
||||
/**
|
||||
* Returns the inventory this item belongs to
|
||||
* @return the inventory this item belongs to
|
||||
*/
|
||||
Inventory* GetInventory() const;
|
||||
|
||||
/**
|
||||
* Returns the parent of this item, e.g. for proxy items
|
||||
* @return the parent of this item
|
||||
*/
|
||||
LWOOBJID GetParent() const;
|
||||
|
||||
/**
|
||||
* Sets the subkey for this item, e.g. for pets
|
||||
* @param value the subkey for this item
|
||||
*/
|
||||
void SetSubKey(LWOOBJID value);
|
||||
|
||||
/**
|
||||
* Returns the sub key this item has, e.g. for pets
|
||||
* @return the sub key this item has
|
||||
*/
|
||||
LWOOBJID GetSubKey() const;
|
||||
|
||||
/**
|
||||
* Returns the preconditions that must be met before this item may be used
|
||||
* @return the preconditions that must be met before this item may be used
|
||||
*/
|
||||
PreconditionExpression* GetPreconditionExpression() const;
|
||||
|
||||
/**
|
||||
* Equips this item into the linked inventory
|
||||
* @param skipChecks skips equip checks for special items like rockets and cars
|
||||
*/
|
||||
void Equip(bool skipChecks = false);
|
||||
|
||||
/**
|
||||
* Unequps the item from the linked inventory
|
||||
*/
|
||||
void UnEquip();
|
||||
|
||||
/**
|
||||
* Returns if the item is equipped in the linked inventory
|
||||
* @return if the item is equipped
|
||||
*/
|
||||
bool IsEquipped() const;
|
||||
|
||||
/**
|
||||
* Attempts to consume one of this item, applying its skills
|
||||
* @return whether the consumption was successful, e.g. the skill was cast
|
||||
*/
|
||||
bool Consume();
|
||||
|
||||
/**
|
||||
* Uses this item if its non equip, essentially an interface for the linked GM
|
||||
* @return whether the use was successful, e.g. the skill was cast
|
||||
*/
|
||||
bool UseNonEquip();
|
||||
|
||||
/**
|
||||
* Disassembles the part LOTs of this item back into the inventory, if it has any
|
||||
* @param inventoryType the inventory to dissassemble into
|
||||
*/
|
||||
void Disassemble(eInventoryType inventoryType = INVALID);
|
||||
|
||||
/**
|
||||
* Disassembles this item into bricks
|
||||
*/
|
||||
void DisassembleModel();
|
||||
|
||||
/**
|
||||
* Removes the item from the linked inventory
|
||||
*/
|
||||
void RemoveFromInventory();
|
||||
|
||||
private:
|
||||
/**
|
||||
* The object ID of this item
|
||||
*/
|
||||
LWOOBJID id;
|
||||
|
||||
/**
|
||||
* The LOT of this item
|
||||
*/
|
||||
LOT lot;
|
||||
|
||||
/**
|
||||
* The number of items this represents
|
||||
*/
|
||||
uint32_t count;
|
||||
|
||||
/**
|
||||
* The slot this item is stored in
|
||||
*/
|
||||
uint32_t slot;
|
||||
|
||||
/**
|
||||
* If this item is bound
|
||||
*/
|
||||
bool bound;
|
||||
|
||||
/**
|
||||
* A potential parent of this item, if this item is a subitem
|
||||
*/
|
||||
LWOOBJID parent;
|
||||
|
||||
/**
|
||||
* A potential subkey of this item, e.g. for pets
|
||||
*/
|
||||
LWOOBJID subKey;
|
||||
|
||||
/**
|
||||
* Config data for this item, e.g. for rocket parts and car parts
|
||||
*/
|
||||
std::vector<LDFBaseData*> config;
|
||||
|
||||
/**
|
||||
* The inventory this item belongs to
|
||||
*/
|
||||
Inventory* inventory;
|
||||
|
||||
/**
|
||||
* The database information of this item
|
||||
*/
|
||||
const CDItemComponent* info;
|
||||
|
||||
/**
|
||||
* A precondition to using this item
|
||||
*/
|
||||
PreconditionExpression* preconditions = nullptr;
|
||||
};
|
||||
|
235
dGame/dInventory/ItemSet.cpp
Normal file
235
dGame/dInventory/ItemSet.cpp
Normal file
@@ -0,0 +1,235 @@
|
||||
#include "ItemSet.h"
|
||||
|
||||
#include "InventoryComponent.h"
|
||||
#include "Entity.h"
|
||||
#include "SkillComponent.h"
|
||||
#include "CDClientDatabase.h"
|
||||
#include "Game.h"
|
||||
#include "MissionComponent.h"
|
||||
#include <algorithm>
|
||||
|
||||
ItemSet::ItemSet(const uint32_t id, InventoryComponent* inventoryComponent)
|
||||
{
|
||||
this->m_ID = id;
|
||||
this->m_InventoryComponent = inventoryComponent;
|
||||
|
||||
this->m_PassiveAbilities = ItemSetPassiveAbility::FindAbilities(id, m_InventoryComponent->GetParent(), this);
|
||||
|
||||
std::stringstream query;
|
||||
|
||||
query << "SELECT skillSetWith2, skillSetWith3, skillSetWith4, skillSetWith5, skillSetWith6, itemIDs FROM ItemSets WHERE setID = " << std::to_string(id);
|
||||
|
||||
auto result = CDClientDatabase::ExecuteQuery(query.str());
|
||||
|
||||
if (result.eof())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto i = 0; i < 5; ++i)
|
||||
{
|
||||
if (result.fieldIsNull(i))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
std::stringstream skillQuery;
|
||||
|
||||
skillQuery << "SELECT SkillID FROM ItemSetSkills WHERE SkillSetID = " << std::to_string(result.getIntField(i));
|
||||
|
||||
auto skillResult = CDClientDatabase::ExecuteQuery(skillQuery.str());
|
||||
|
||||
if (skillResult.eof())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
while (!skillResult.eof())
|
||||
{
|
||||
if (skillResult.fieldIsNull(0))
|
||||
{
|
||||
skillResult.nextRow();
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto skillId = skillResult.getIntField(0);
|
||||
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
m_SkillsWith2.push_back(skillId);
|
||||
break;
|
||||
case 1:
|
||||
m_SkillsWith3.push_back(skillId);
|
||||
break;
|
||||
case 2:
|
||||
m_SkillsWith4.push_back(skillId);
|
||||
break;
|
||||
case 3:
|
||||
m_SkillsWith5.push_back(skillId);
|
||||
break;
|
||||
case 4:
|
||||
m_SkillsWith6.push_back(skillId);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
skillResult.nextRow();
|
||||
}
|
||||
}
|
||||
|
||||
std::string ids = result.getStringField(5);
|
||||
|
||||
ids.erase(std::remove_if(ids.begin(), ids.end(), ::isspace), ids.end());
|
||||
|
||||
std::istringstream stream(ids);
|
||||
std::string token;
|
||||
|
||||
result.finalize();
|
||||
|
||||
m_Items = {};
|
||||
|
||||
while (std::getline(stream, token, ','))
|
||||
{
|
||||
int32_t value;
|
||||
if (GeneralUtils::TryParse(token, value))
|
||||
{
|
||||
m_Items.push_back(value);
|
||||
}
|
||||
}
|
||||
|
||||
m_Equipped = {};
|
||||
|
||||
for (const auto item : m_Items)
|
||||
{
|
||||
if (inventoryComponent->IsEquipped(item))
|
||||
{
|
||||
m_Equipped.push_back(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ItemSet::Contains(const LOT lot)
|
||||
{
|
||||
return std::find(m_Items.begin(), m_Items.end(), lot) != m_Items.end();
|
||||
}
|
||||
|
||||
void ItemSet::OnEquip(const LOT lot)
|
||||
{
|
||||
if (!Contains(lot))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& index = std::find(m_Equipped.begin(), m_Equipped.end(), lot);
|
||||
|
||||
if (index != m_Equipped.end())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_Equipped.push_back(lot);
|
||||
|
||||
const auto& skillSet = GetSkillSet(m_Equipped.size());
|
||||
|
||||
if (skillSet.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto* skillComponent = m_InventoryComponent->GetParent()->GetComponent<SkillComponent>();
|
||||
auto* missionComponent = m_InventoryComponent->GetParent()->GetComponent<MissionComponent>();
|
||||
|
||||
for (const auto skill : skillSet)
|
||||
{
|
||||
auto* skillTable = CDClientManager::Instance()->GetTable<CDSkillBehaviorTable>("SkillBehavior");
|
||||
|
||||
const auto behaviorId = skillTable->GetSkillByID(skill).behaviorID;
|
||||
|
||||
missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_SKILL, skill);
|
||||
|
||||
skillComponent->HandleUnmanaged(behaviorId, m_InventoryComponent->GetParent()->GetObjectID());
|
||||
}
|
||||
}
|
||||
|
||||
void ItemSet::OnUnEquip(const LOT lot)
|
||||
{
|
||||
if (!Contains(lot))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& index = std::find(m_Equipped.begin(), m_Equipped.end(), lot);
|
||||
|
||||
if (index == m_Equipped.end())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& skillSet = GetSkillSet(m_Equipped.size());
|
||||
|
||||
m_Equipped.erase(index);
|
||||
|
||||
if (skillSet.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& skillComponent = m_InventoryComponent->GetParent()->GetComponent<SkillComponent>();
|
||||
|
||||
for (const auto skill : skillSet)
|
||||
{
|
||||
auto* skillTable = CDClientManager::Instance()->GetTable<CDSkillBehaviorTable>("SkillBehavior");
|
||||
|
||||
const auto behaviorId = skillTable->GetSkillByID(skill).behaviorID;
|
||||
|
||||
skillComponent->HandleUnCast(behaviorId, m_InventoryComponent->GetParent()->GetObjectID());
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t ItemSet::GetEquippedCount() const
|
||||
{
|
||||
return m_Equipped.size();
|
||||
}
|
||||
|
||||
uint32_t ItemSet::GetID() const
|
||||
{
|
||||
return m_ID;
|
||||
}
|
||||
|
||||
void ItemSet::Update(float deltaTime)
|
||||
{
|
||||
for (auto& passiveAbility : m_PassiveAbilities)
|
||||
{
|
||||
passiveAbility.Update(deltaTime);
|
||||
}
|
||||
}
|
||||
|
||||
void ItemSet::TriggerPassiveAbility(PassiveAbilityTrigger trigger)
|
||||
{
|
||||
for (auto& passiveAbility : m_PassiveAbilities)
|
||||
{
|
||||
passiveAbility.Trigger(trigger);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<uint32_t> ItemSet::GetSkillSet(const uint32_t itemCount) const
|
||||
{
|
||||
switch (itemCount)
|
||||
{
|
||||
case 2:
|
||||
return m_SkillsWith2;
|
||||
case 3:
|
||||
return m_SkillsWith3;
|
||||
case 4:
|
||||
return m_SkillsWith4;
|
||||
case 5:
|
||||
return m_SkillsWith5;
|
||||
case 6:
|
||||
return m_SkillsWith6;
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
}
|
114
dGame/dInventory/ItemSet.h
Normal file
114
dGame/dInventory/ItemSet.h
Normal file
@@ -0,0 +1,114 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "dCommonVars.h"
|
||||
|
||||
#include "ItemSetPassiveAbility.h"
|
||||
|
||||
class InventoryComponent;
|
||||
|
||||
/**
|
||||
* A set of items that can be worn together for special bonuses, for example faction gear.
|
||||
*/
|
||||
class ItemSet
|
||||
{
|
||||
public:
|
||||
explicit ItemSet(uint32_t id, InventoryComponent* inventoryComponent);
|
||||
void Update(float deltaTime);
|
||||
|
||||
/**
|
||||
* Returns if this item set contains the LOT specified
|
||||
* @param lot the lot to check for
|
||||
* @return if this item set contains the LOT specified
|
||||
*/
|
||||
bool Contains(LOT lot);
|
||||
|
||||
/**
|
||||
* Equips the item set skill for this LOT (if it's in the item set)
|
||||
* @param lot the LOT of the item to equip skills for
|
||||
*/
|
||||
void OnEquip(LOT lot);
|
||||
|
||||
/**
|
||||
* Unequips the item set skill for this LOT (if it's in the item set)
|
||||
* @param lot the LOT of the item to unequip skills for
|
||||
*/
|
||||
void OnUnEquip(LOT lot);
|
||||
|
||||
/**
|
||||
* Returns the number of items in the item set that are currently equipped
|
||||
* @return the number of items in the item set that are currently equipped
|
||||
*/
|
||||
uint32_t GetEquippedCount() const;
|
||||
|
||||
/**
|
||||
* Returns the ID of this item set
|
||||
* @return the ID of this item set
|
||||
*/
|
||||
uint32_t GetID() const;
|
||||
|
||||
/**
|
||||
* Triggers all the passive abilities in this item set that match this trigger
|
||||
* @param trigger the trigger to use to trigger passive abilities
|
||||
*/
|
||||
void TriggerPassiveAbility(PassiveAbilityTrigger trigger);
|
||||
|
||||
/**
|
||||
* Returns the skills that can be equipped for a specified amount of equipped items
|
||||
* @param itemCount the amount of items equipped to check for
|
||||
* @return the skills that can be equipped for a specified amount of equipped items
|
||||
*/
|
||||
std::vector<uint32_t> GetSkillSet(uint32_t itemCount) const;
|
||||
|
||||
private:
|
||||
/**
|
||||
* The ID of this skill set
|
||||
*/
|
||||
uint32_t m_ID;
|
||||
|
||||
/**
|
||||
* The inventory this skill set belongs to
|
||||
*/
|
||||
InventoryComponent* m_InventoryComponent;
|
||||
|
||||
/**
|
||||
* The items in the skill set that are currently equipped
|
||||
*/
|
||||
std::vector<LOT> m_Equipped;
|
||||
|
||||
/**
|
||||
* The total list of items in this skill set
|
||||
*/
|
||||
std::vector<LOT> m_Items;
|
||||
|
||||
/**
|
||||
* The skills that can be triggered when 2 items are equipped
|
||||
*/
|
||||
std::vector<uint32_t> m_SkillsWith2;
|
||||
|
||||
/**
|
||||
* The skills that can be triggered when 3 items are equipped
|
||||
*/
|
||||
std::vector<uint32_t> m_SkillsWith3;
|
||||
|
||||
/**
|
||||
* The skills that can be triggered when 4 items are equipped
|
||||
*/
|
||||
std::vector<uint32_t> m_SkillsWith4;
|
||||
|
||||
/**
|
||||
* The skills that can be triggered when 5 items are equipped
|
||||
*/
|
||||
std::vector<uint32_t> m_SkillsWith5;
|
||||
|
||||
/**
|
||||
* The skills that can be triggered when 6 items are equipped
|
||||
*/
|
||||
std::vector<uint32_t> m_SkillsWith6;
|
||||
|
||||
/**
|
||||
* The passive abilities associated with this skill set
|
||||
*/
|
||||
std::vector<ItemSetPassiveAbility> m_PassiveAbilities;
|
||||
};
|
327
dGame/dInventory/ItemSetPassiveAbility.cpp
Normal file
327
dGame/dInventory/ItemSetPassiveAbility.cpp
Normal file
@@ -0,0 +1,327 @@
|
||||
#include "ItemSetPassiveAbility.h"
|
||||
|
||||
#include "DestroyableComponent.h"
|
||||
#include "SkillComponent.h"
|
||||
#include "ItemSet.h"
|
||||
#include "ItemSetPassiveAbilityID.h"
|
||||
|
||||
ItemSetPassiveAbility::ItemSetPassiveAbility(PassiveAbilityTrigger trigger, Entity* parent, ItemSet* itemSet)
|
||||
{
|
||||
m_Trigger = trigger;
|
||||
m_Parent = parent;
|
||||
m_ItemSet = itemSet;
|
||||
|
||||
m_Cooldown = 0.0f;
|
||||
}
|
||||
|
||||
ItemSetPassiveAbility::~ItemSetPassiveAbility()
|
||||
{
|
||||
}
|
||||
|
||||
void ItemSetPassiveAbility::Trigger(PassiveAbilityTrigger trigger)
|
||||
{
|
||||
if (m_Trigger != trigger || m_Cooldown > 0.0f)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Activate();
|
||||
}
|
||||
|
||||
void ItemSetPassiveAbility::Update(float deltaTime)
|
||||
{
|
||||
if (m_Cooldown > 0.0f)
|
||||
{
|
||||
m_Cooldown -= deltaTime;
|
||||
}
|
||||
}
|
||||
|
||||
void ItemSetPassiveAbility::Activate()
|
||||
{
|
||||
if (m_Trigger == PassiveAbilityTrigger::EnemySmashed)
|
||||
{
|
||||
OnEnemySmshed();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
auto* destroyableComponent = m_Parent->GetComponent<DestroyableComponent>();
|
||||
auto* skillComponent = m_Parent->GetComponent<SkillComponent>();
|
||||
|
||||
if (destroyableComponent == nullptr || skillComponent == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
EntityManager::Instance()->SerializeEntity(m_Parent);
|
||||
|
||||
const auto id = static_cast<ItemSetPassiveAbilityID>(m_ItemSet->GetID());
|
||||
const auto parentID = m_Parent->GetObjectID();
|
||||
const auto equippedCount = m_ItemSet->GetEquippedCount();
|
||||
|
||||
switch (id)
|
||||
{
|
||||
// Assembly
|
||||
case ItemSetPassiveAbilityID::InventorRank1:
|
||||
case ItemSetPassiveAbilityID::SummonerRank1:
|
||||
case ItemSetPassiveAbilityID::EngineerRank1: {
|
||||
if (equippedCount < 4) return;
|
||||
m_Cooldown = 11.0f;
|
||||
skillComponent->CalculateBehavior(394, 4401, parentID);
|
||||
break;
|
||||
}
|
||||
case ItemSetPassiveAbilityID::InventorRank2:
|
||||
case ItemSetPassiveAbilityID::SummonerRank2:
|
||||
case ItemSetPassiveAbilityID::EngineerRank2: {
|
||||
if (equippedCount < 4) return;
|
||||
m_Cooldown = 11.0f;
|
||||
skillComponent->CalculateBehavior(581, 9433, parentID);
|
||||
break;
|
||||
}
|
||||
case ItemSetPassiveAbilityID::InventorRank3:
|
||||
case ItemSetPassiveAbilityID::SummonerRank3:
|
||||
case ItemSetPassiveAbilityID::EngineerRank3: {
|
||||
if (equippedCount < 4) return;
|
||||
m_Cooldown = 11.0f;
|
||||
skillComponent->CalculateBehavior(582, 9435, parentID);
|
||||
break;
|
||||
}
|
||||
|
||||
// Sentinel
|
||||
case ItemSetPassiveAbilityID::KnightRank1: {
|
||||
if (equippedCount < 4) return;
|
||||
m_Cooldown = 11.0f;
|
||||
skillComponent->CalculateBehavior(559, 8884, parentID);
|
||||
break;
|
||||
}
|
||||
case ItemSetPassiveAbilityID::KnightRank2: {
|
||||
if (equippedCount < 4) return;
|
||||
m_Cooldown = 11.0f;
|
||||
skillComponent->CalculateBehavior(560, 8885, parentID);
|
||||
break;
|
||||
}
|
||||
case ItemSetPassiveAbilityID::KnightRank3: {
|
||||
if (equippedCount < 4) return;
|
||||
m_Cooldown = 11.0f;
|
||||
skillComponent->CalculateBehavior(561, 8890, parentID);
|
||||
break;
|
||||
}
|
||||
|
||||
case ItemSetPassiveAbilityID::SpaceRangerRank1: {
|
||||
if (equippedCount < 4) return;
|
||||
m_Cooldown = 11.0f;
|
||||
skillComponent->CalculateBehavior(1101, 24612, parentID);
|
||||
break;
|
||||
}
|
||||
case ItemSetPassiveAbilityID::SpaceRangerRank2: {
|
||||
if (equippedCount < 4) return;
|
||||
m_Cooldown = 11.0f;
|
||||
skillComponent->CalculateBehavior(1102, 24617, parentID);
|
||||
break;
|
||||
}
|
||||
case ItemSetPassiveAbilityID::SpaceRangerRank3: {
|
||||
if (equippedCount < 4) return;
|
||||
m_Cooldown = 11.0f;
|
||||
skillComponent->CalculateBehavior(1103, 24622, parentID);
|
||||
break;
|
||||
}
|
||||
|
||||
case ItemSetPassiveAbilityID::SamuraiRank1: {
|
||||
if (equippedCount < 4) return;
|
||||
m_Cooldown = 11.0f;
|
||||
skillComponent->CalculateBehavior(562, 8899, parentID);
|
||||
break;
|
||||
}
|
||||
case ItemSetPassiveAbilityID::SamuraiRank2: {
|
||||
if (equippedCount < 4) return;
|
||||
m_Cooldown = 11.0f;
|
||||
skillComponent->CalculateBehavior(563, 8904, parentID);
|
||||
break;
|
||||
}
|
||||
case ItemSetPassiveAbilityID::SamuraiRank3: {
|
||||
if (equippedCount < 4) return;
|
||||
m_Cooldown = 11.0f;
|
||||
skillComponent->CalculateBehavior(564, 8909, parentID);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<ItemSetPassiveAbility> ItemSetPassiveAbility::FindAbilities(uint32_t itemSetID, Entity* parent, ItemSet* itemSet)
|
||||
{
|
||||
std::vector<ItemSetPassiveAbility> abilities;
|
||||
|
||||
switch (static_cast<ItemSetPassiveAbilityID>(itemSetID)) {
|
||||
// Assembly
|
||||
case ItemSetPassiveAbilityID::SummonerRank1:
|
||||
case ItemSetPassiveAbilityID::SummonerRank2:
|
||||
case ItemSetPassiveAbilityID::SummonerRank3:
|
||||
case ItemSetPassiveAbilityID::InventorRank1:
|
||||
case ItemSetPassiveAbilityID::InventorRank2:
|
||||
case ItemSetPassiveAbilityID::InventorRank3:
|
||||
case ItemSetPassiveAbilityID::EngineerRank1:
|
||||
case ItemSetPassiveAbilityID::EngineerRank2:
|
||||
case ItemSetPassiveAbilityID::EngineerRank3: {
|
||||
abilities.emplace_back(PassiveAbilityTrigger::AssemblyImagination, parent, itemSet);
|
||||
|
||||
break;
|
||||
}
|
||||
// Sentinel
|
||||
case ItemSetPassiveAbilityID::KnightRank1:
|
||||
case ItemSetPassiveAbilityID::KnightRank2:
|
||||
case ItemSetPassiveAbilityID::KnightRank3:
|
||||
case ItemSetPassiveAbilityID::SpaceRangerRank1:
|
||||
case ItemSetPassiveAbilityID::SpaceRangerRank2:
|
||||
case ItemSetPassiveAbilityID::SpaceRangerRank3:
|
||||
case ItemSetPassiveAbilityID::SamuraiRank1:
|
||||
case ItemSetPassiveAbilityID::SamuraiRank2:
|
||||
case ItemSetPassiveAbilityID::SamuraiRank3: {
|
||||
abilities.emplace_back(PassiveAbilityTrigger::SentinelArmor, parent, itemSet);
|
||||
abilities.emplace_back(PassiveAbilityTrigger::EnemySmashed, parent, itemSet);
|
||||
|
||||
break;
|
||||
}
|
||||
// Paradox
|
||||
case ItemSetPassiveAbilityID::SpaceMarauderRank1:
|
||||
case ItemSetPassiveAbilityID::SpaceMarauderRank2:
|
||||
case ItemSetPassiveAbilityID::SpaceMarauderRank3:
|
||||
case ItemSetPassiveAbilityID::SorcererRank1:
|
||||
case ItemSetPassiveAbilityID::SorcererRank2:
|
||||
case ItemSetPassiveAbilityID::SorcererRank3:
|
||||
case ItemSetPassiveAbilityID::ShinobiRank1:
|
||||
case ItemSetPassiveAbilityID::ShinobiRank2:
|
||||
case ItemSetPassiveAbilityID::ShinobiRank3: {
|
||||
abilities.emplace_back(PassiveAbilityTrigger::EnemySmashed, parent, itemSet);
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return abilities;
|
||||
}
|
||||
|
||||
void ItemSetPassiveAbility::OnEnemySmshed()
|
||||
{
|
||||
auto* destroyableComponent = m_Parent->GetComponent<DestroyableComponent>();
|
||||
auto* skillComponent = m_Parent->GetComponent<SkillComponent>();
|
||||
|
||||
if (destroyableComponent == nullptr || skillComponent == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
EntityManager::Instance()->SerializeEntity(m_Parent);
|
||||
|
||||
const auto id = static_cast<ItemSetPassiveAbilityID>(m_ItemSet->GetID());
|
||||
const auto parentID = m_Parent->GetObjectID();
|
||||
const auto equippedCount = m_ItemSet->GetEquippedCount();
|
||||
|
||||
switch (id)
|
||||
{
|
||||
// Sentinel
|
||||
case ItemSetPassiveAbilityID::KnightRank1: {
|
||||
if (equippedCount < 5) return;
|
||||
destroyableComponent->Repair(1);
|
||||
break;
|
||||
}
|
||||
case ItemSetPassiveAbilityID::KnightRank2: {
|
||||
if (equippedCount < 5) return;
|
||||
destroyableComponent->Repair(1);
|
||||
break;
|
||||
}
|
||||
case ItemSetPassiveAbilityID::KnightRank3: {
|
||||
if (equippedCount < 5) return;
|
||||
destroyableComponent->Repair(1);
|
||||
break;
|
||||
}
|
||||
|
||||
case ItemSetPassiveAbilityID::SpaceRangerRank1: {
|
||||
if (equippedCount < 5) return;
|
||||
destroyableComponent->Repair(1);
|
||||
break;
|
||||
}
|
||||
case ItemSetPassiveAbilityID::SpaceRangerRank2: {
|
||||
if (equippedCount < 5) return;
|
||||
destroyableComponent->Repair(1);
|
||||
break;
|
||||
}
|
||||
case ItemSetPassiveAbilityID::SpaceRangerRank3: {
|
||||
if (equippedCount < 5) return;
|
||||
destroyableComponent->Repair(1);
|
||||
break;
|
||||
}
|
||||
|
||||
case ItemSetPassiveAbilityID::SamuraiRank1: {
|
||||
if (equippedCount < 5) return;
|
||||
destroyableComponent->Repair(1);
|
||||
break;
|
||||
}
|
||||
case ItemSetPassiveAbilityID::SamuraiRank2: {
|
||||
if (equippedCount < 5) return;
|
||||
destroyableComponent->Repair(1);
|
||||
break;
|
||||
}
|
||||
case ItemSetPassiveAbilityID::SamuraiRank3: {
|
||||
if (equippedCount < 5) return;
|
||||
destroyableComponent->Repair(1);
|
||||
break;
|
||||
}
|
||||
|
||||
// Paradox
|
||||
case ItemSetPassiveAbilityID::SpaceMarauderRank1: {
|
||||
if (equippedCount < 4) return;
|
||||
destroyableComponent->Imagine(1);
|
||||
break;
|
||||
}
|
||||
case ItemSetPassiveAbilityID::SpaceMarauderRank2: {
|
||||
if (equippedCount < 4) return;
|
||||
destroyableComponent->Imagine(2);
|
||||
break;
|
||||
}
|
||||
case ItemSetPassiveAbilityID::SpaceMarauderRank3: {
|
||||
if (equippedCount < 4) return;
|
||||
destroyableComponent->Imagine(3);
|
||||
break;
|
||||
}
|
||||
|
||||
case ItemSetPassiveAbilityID::ShinobiRank1: {
|
||||
if (equippedCount < 4) return;
|
||||
destroyableComponent->Imagine(1);
|
||||
break;
|
||||
}
|
||||
case ItemSetPassiveAbilityID::ShinobiRank2: {
|
||||
if (equippedCount < 4) return;
|
||||
destroyableComponent->Imagine(2);
|
||||
break;
|
||||
}
|
||||
case ItemSetPassiveAbilityID::ShinobiRank3: {
|
||||
if (equippedCount < 4) return;
|
||||
destroyableComponent->Imagine(3);
|
||||
break;
|
||||
}
|
||||
|
||||
case ItemSetPassiveAbilityID::SorcererRank1: {
|
||||
if (equippedCount < 4) return;
|
||||
destroyableComponent->Imagine(1);
|
||||
break;
|
||||
}
|
||||
case ItemSetPassiveAbilityID::SorcererRank2: {
|
||||
if (equippedCount < 4) return;
|
||||
destroyableComponent->Imagine(2);
|
||||
break;
|
||||
}
|
||||
case ItemSetPassiveAbilityID::SorcererRank3: {
|
||||
if (equippedCount < 4) return;
|
||||
destroyableComponent->Imagine(3);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
71
dGame/dInventory/ItemSetPassiveAbility.h
Normal file
71
dGame/dInventory/ItemSetPassiveAbility.h
Normal file
@@ -0,0 +1,71 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "dCommonVars.h"
|
||||
|
||||
class Entity;
|
||||
class ItemSet;
|
||||
|
||||
enum class PassiveAbilityTrigger
|
||||
{
|
||||
AssemblyImagination, // Less than 1 imagination
|
||||
ParadoxHealth, // Less or equal to 1 health
|
||||
SentinelArmor, // Less than 1 armor
|
||||
VentureHealth, // Less than 3 health
|
||||
EnemySmashed, // Enemy is smashed
|
||||
};
|
||||
|
||||
/**
|
||||
* Passive abilities that belong to an item set, activated when a PassiveAbilityTrigger condition is met
|
||||
*/
|
||||
class ItemSetPassiveAbility
|
||||
{
|
||||
public:
|
||||
ItemSetPassiveAbility(PassiveAbilityTrigger trigger, Entity* parent, ItemSet* itemSet);
|
||||
~ItemSetPassiveAbility();
|
||||
void Update(float deltaTime);
|
||||
|
||||
/**
|
||||
* Attempts to trigger a passive ability for this item set, if this is the wrong trigger this is a no-op
|
||||
* @param trigger the trigger to attempt to fire
|
||||
*/
|
||||
void Trigger(PassiveAbilityTrigger trigger);
|
||||
|
||||
/**
|
||||
* Activates the passive ability
|
||||
*/
|
||||
void Activate();
|
||||
|
||||
/**
|
||||
* Finds all the passive abilities associated with a certain item set
|
||||
* @param itemSetID the item set to find abilities for
|
||||
* @param parent the parent to add to the passive abilities
|
||||
* @param itemSet the item set to add to the passive abilities
|
||||
* @return the passive abilities for the provided item set
|
||||
*/
|
||||
static std::vector<ItemSetPassiveAbility> FindAbilities(uint32_t itemSetID, Entity* parent, ItemSet* itemSet);
|
||||
|
||||
private:
|
||||
void OnEnemySmshed();
|
||||
|
||||
/**
|
||||
* The means of triggering this ability
|
||||
*/
|
||||
PassiveAbilityTrigger m_Trigger;
|
||||
|
||||
/**
|
||||
* The owner of this ability
|
||||
*/
|
||||
Entity* m_Parent;
|
||||
|
||||
/**
|
||||
* The item set this ability belongs to
|
||||
*/
|
||||
ItemSet* m_ItemSet;
|
||||
|
||||
/**
|
||||
* The cooldown on this ability until it can be activated again
|
||||
*/
|
||||
float m_Cooldown;
|
||||
};
|
105
dGame/dInventory/ItemSetPassiveAbilityID.h
Normal file
105
dGame/dInventory/ItemSetPassiveAbilityID.h
Normal file
@@ -0,0 +1,105 @@
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
2 Engineer (Rank 1) Item Set
|
||||
3 Engineer (Rank 2) Item Set
|
||||
4 Engineer (Rank 3) Item Set
|
||||
7 Knight (Rank 1) Item Set
|
||||
8 Knight (Rank 2) Item Set
|
||||
9 Knight (Rank 3) Item Set
|
||||
10 Space Ranger (Rank 1) Item Set
|
||||
11 Space Ranger (Rank 2) Item Set
|
||||
12 Space Ranger (Rank 3) Item Set
|
||||
13 Samurai (Rank 1) Item Set
|
||||
14 Samurai (Rank 2) Item Set
|
||||
15 Samurai (Rank 3) Item Set
|
||||
16 Sorcerer (Rank 1) Item Set
|
||||
17 Sorcerer (Rank 2) Item Set
|
||||
18 Sorcerer (Rank 3) Item Set
|
||||
19 Space Marauder (Rank 1) Item Set
|
||||
20 Space Marauder (Rank 2) Item Set
|
||||
21 Space Marauder (Rank 3) Item Set
|
||||
22 Shinobi (Rank 1) Item Set
|
||||
23 Shinobi (Rank 2) Item Set
|
||||
24 Shinobi (Rank 3) Item Set
|
||||
25 Inventor (Rank 1) Item Set
|
||||
26 Inventor (Rank 2) Item Set
|
||||
27 Inventor (Rank 3) Item Set
|
||||
28 Summoner (Rank 1) Item Set
|
||||
29 Summoner (Rank 2) Item Set
|
||||
30 Summoner (Rank 3) Item Set
|
||||
31 Adventurer (Rank 1) Item Set
|
||||
32 Adventurer (Rank 2) Item Set
|
||||
33 Adventurer (Rank 3) Item Set
|
||||
34 Daredevil (Rank 1) Item Set
|
||||
35 Daredevil (Rank 2) Item Set
|
||||
36 Daredevil (Rank 3) Item Set
|
||||
37 Buccaneer (Rank 1) Item Set
|
||||
38 Buccaneer (Rank 2) Item Set
|
||||
39 Buccaneer (Rank 3) Item Set
|
||||
40 Bone Suit Item Set
|
||||
41 Imagination Spinjitzu Item Set
|
||||
42 Bat Lord Item Set
|
||||
43 Mosaic Jester Item Set
|
||||
44 Explorien Bot Item Set
|
||||
45 [Unnamed] Item Set
|
||||
46 [Unnamed] Item Set
|
||||
47 [Unnamed] Item Set
|
||||
48 Earth Spinjitzu Item Set
|
||||
49 [Unnamed] Item Set
|
||||
50 Fire Spinjitzu Item Set
|
||||
51 Ice Spinjitzu Item Set
|
||||
52 Lightning Spinjitzu Item Set
|
||||
*/
|
||||
enum class ItemSetPassiveAbilityID
|
||||
{
|
||||
EngineerRank1 = 2,
|
||||
EngineerRank2 = 3,
|
||||
EngineerRank3 = 4,
|
||||
KnightRank1 = 7,
|
||||
KnightRank2 = 8,
|
||||
KnightRank3 = 9,
|
||||
SpaceRangerRank1 = 10,
|
||||
SpaceRangerRank2 = 11,
|
||||
SpaceRangerRank3 = 12,
|
||||
SamuraiRank1 = 13,
|
||||
SamuraiRank2 = 14,
|
||||
SamuraiRank3 = 15,
|
||||
SorcererRank1 = 16,
|
||||
SorcererRank2 = 17,
|
||||
SorcererRank3 = 18,
|
||||
SpaceMarauderRank1 = 19,
|
||||
SpaceMarauderRank2 = 20,
|
||||
SpaceMarauderRank3 = 21,
|
||||
ShinobiRank1 = 22,
|
||||
ShinobiRank2 = 23,
|
||||
ShinobiRank3 = 24,
|
||||
InventorRank1 = 25,
|
||||
InventorRank2 = 26,
|
||||
InventorRank3 = 27,
|
||||
SummonerRank1 = 28,
|
||||
SummonerRank2 = 29,
|
||||
SummonerRank3 = 30,
|
||||
AdventurerRank1 = 31,
|
||||
AdventurerRank2 = 32,
|
||||
AdventurerRank3 = 33,
|
||||
DaredevilRank1 = 34,
|
||||
DaredevilRank2 = 35,
|
||||
DaredevilRank3 = 36,
|
||||
BuccaneerRank1 = 37,
|
||||
BuccaneerRank2 = 38,
|
||||
BuccaneerRank3 = 39,
|
||||
BoneSuit = 40,
|
||||
ImaginationSpinjitzu = 41,
|
||||
BatLord = 42,
|
||||
MosaicJester = 43,
|
||||
ExplorienBot = 44,
|
||||
Unnamed1 = 45,
|
||||
Unnamed2 = 46,
|
||||
Unnamed3 = 47,
|
||||
EarthSpinjitzu = 48,
|
||||
Unnamed4 = 49,
|
||||
FireSpinjitzu = 50,
|
||||
IceSpinjitzu = 51,
|
||||
LightningSpinjitzu = 52
|
||||
};
|
Reference in New Issue
Block a user