diff --git a/dDatabase/CDClientDatabase/CDClientTables/CDDeletionRestrictionsTable.cpp b/dDatabase/CDClientDatabase/CDClientTables/CDDeletionRestrictionsTable.cpp index 1e7f87c2..cf66b832 100644 --- a/dDatabase/CDClientDatabase/CDClientTables/CDDeletionRestrictionsTable.cpp +++ b/dDatabase/CDClientDatabase/CDClientTables/CDDeletionRestrictionsTable.cpp @@ -1,10 +1,16 @@ #include "CDDeletionRestrictionsTable.h" #include "GeneralUtils.h" +#include "eDeletionRestrictionsCheckType.h" + +CDDeletionRestriction CDDeletionRestrictionsTable::Default = { + .id = 0, + .restricted = false, + .ids = {}, + .checkType = eDeletionRestrictionsCheckType::MAX +}; -//! Constructor void CDDeletionRestrictionsTable::LoadValuesFromDatabase() { - // First, get the size of the table uint32_t size = 0; auto tableSize = CDClientDatabase::ExecuteQuery("SELECT COUNT(*) FROM CurrencyTable"); while (!tableSize.eof()) { @@ -15,14 +21,11 @@ void CDDeletionRestrictionsTable::LoadValuesFromDatabase() { tableSize.finalize(); - // Reserve the size auto& entries = GetEntriesMutable(); - entries.reserve(size); - // Now get the data auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM DeletionRestrictions"); while (!tableData.eof()) { - CDDeletionRestrictions entry; + CDDeletionRestriction entry; entry.id = tableData.getIntField("id", -1); if (entry.id == -1) continue; entry.restricted = tableData.getIntField("restricted", -1); @@ -37,17 +40,18 @@ void CDDeletionRestrictionsTable::LoadValuesFromDatabase() { } entry.checkType = static_cast(tableData.getIntField("checkType", 6)); // MAX - entries.push_back(entry); + entries.insert(std::make_pair(entry.id, entry)); tableData.nextRow(); } tableData.finalize(); } -std::vector CDDeletionRestrictionsTable::Query(std::function predicate) { - std::vector data = cpplinq::from(GetEntries()) - >> cpplinq::where(predicate) - >> cpplinq::to_vector(); - - return data; +const CDDeletionRestriction& CDDeletionRestrictionsTable::GetByID(uint32_t id) { + auto& entries = GetEntries(); + const auto& it = entries.find(id); + if (it != entries.end()) { + return it->second; + } + return Default; } diff --git a/dDatabase/CDClientDatabase/CDClientTables/CDDeletionRestrictionsTable.h b/dDatabase/CDClientDatabase/CDClientTables/CDDeletionRestrictionsTable.h index 718e7bab..a09ee60d 100644 --- a/dDatabase/CDClientDatabase/CDClientTables/CDDeletionRestrictionsTable.h +++ b/dDatabase/CDClientDatabase/CDClientTables/CDDeletionRestrictionsTable.h @@ -4,15 +4,17 @@ enum class eDeletionRestrictionsCheckType : uint32_t; -struct CDDeletionRestrictions { +struct CDDeletionRestriction { uint32_t id; bool restricted; std::vector ids; eDeletionRestrictionsCheckType checkType; }; -class CDDeletionRestrictionsTable : public CDTable> { +class CDDeletionRestrictionsTable : public CDTable> { public: void LoadValuesFromDatabase(); - std::vector Query(std::function predicate); + const CDDeletionRestriction& GetByID(uint32_t id); + + static CDDeletionRestriction Default; }; diff --git a/dGame/dInventory/Item.cpp b/dGame/dInventory/Item.cpp index 32603761..9ef81663 100644 --- a/dGame/dInventory/Item.cpp +++ b/dGame/dInventory/Item.cpp @@ -21,11 +21,13 @@ #include "eUseItemResponse.h" #include "dZoneManager.h" #include "ChatPackets.h" +#include "eDeletionRestrictionsCheckType.h" #include "CDBrickIDTableTable.h" #include "CDObjectSkillsTable.h" #include "CDComponentsRegistryTable.h" #include "CDPackageComponentTable.h" +#include "CDDeletionRestrictionsTable.h" namespace { const std::map ExtraSettingAbbreviations = { @@ -568,3 +570,43 @@ void Item::LoadConfigXml(const tinyxml2::XMLElement& i) { config.push_back(LDFBaseData::DataFromString(value)); } } + +bool Item::CanDeleteItem(Item* item) { + if (!item) return false; + // TODO: + // Check if item is being possessed + // Check if the owner is mounting item? (how is this different than the above) + // Allow GM 9 to freely delete + // Finally, check Deletion Restriction + const auto& itemComponent = item->inventory->FindItemComponent(item->lot); + if (itemComponent.delResIndex == -1) return true; + return CheckDeletionRestriction(itemComponent.delResIndex, item->lot); +} + +bool Item::CheckDeletionRestriction(uint32_t delResIndex, LOT item) { + auto* delresTable = CDClientManager::GetTable(); + const auto restriction = delresTable->GetByID(delResIndex); + + switch(restriction.checkType) { + case eDeletionRestrictionsCheckType::INCLUDE_LOTS: + if (std::ranges::find(restriction.ids, item) != restriction.ids.end()) return false; + else return true; + case eDeletionRestrictionsCheckType::EXCLUDE_LOTS: + if (std::ranges::find(restriction.ids, item) != restriction.ids.end()) return true; + else return false; + case eDeletionRestrictionsCheckType::ANY_OF_THESE: + // TODO: Implement + return true; + case eDeletionRestrictionsCheckType::ALL_OF_THESE: + // TODO: Implement + return true; + case eDeletionRestrictionsCheckType::WHILE_IN_ZONE: + if (std::ranges::find(restriction.ids, Game::zoneManager->GetZoneID().GetMapID()) != restriction.ids.end()) return false; + else return true; + case eDeletionRestrictionsCheckType::ALWAYS_RESTRICTED: + return false; + case eDeletionRestrictionsCheckType::MAX: + default: + return true; + } +} diff --git a/dGame/dInventory/Item.h b/dGame/dInventory/Item.h index 72ff264c..b5e4e9f2 100644 --- a/dGame/dInventory/Item.h +++ b/dGame/dInventory/Item.h @@ -228,6 +228,13 @@ public: void LoadConfigXml(const tinyxml2::XMLElement& i); + bool CanDeleteItem(Item* item); + + bool CheckDeletionRestriction(uint32_t delResIndex, LOT item); + + bool CheckDeletionRestrictionRecursion(std::set& delResIndexs, uint32_t delResIndex); + + private: /** * The object ID of this item