Files
DarkflameServer/dDatabase/CDClientDatabase/CDClientTables/CDDeletionRestrictionsTable.cpp
Aaron Kimbrell 02108055e7 feat(inventory): enforce DeletionRestrictions when deleting items
Deleting an item now follows its ItemComponent delResIndex row in the
DeletionRestrictions table, the way the client's shared inventory code
decides it (LWOInventoryComponent_Common::CanRemoveFromInventory @
0x00ce0d20, CheckDeletionRestrictionIndex @ 0x00c94c20):
- missing, unrestricted, unknown-type or empty rows allow it;
- LOTS_INCLUDED: another item of any listed LOT must remain;
- LOTS_EXCLUDED: other items of every listed LOT must remain;
- ANY_RESTRICTION / ALL_RESTRICTIONS: any / all listed rows allow it;
- ZONE: only in the listed maps; ALWAYS_RESTRICTED: never.
Operators (GM level 9) may delete anything, as in the client. A refused
delete is logged and the item stays.

ItemComponent.minNumRequired is not used: the client never reads it, so
its meaning can't be verified.

Issue 960: the rocket (6416, row 8) and the classic rocket parts (rows 1-3)
have rows that keep at least one rocket or part, so the last rocket can
no longer be deleted and strand the player.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 22:31:04 -05:00

23 lines
841 B
C++

#include "CDDeletionRestrictionsTable.h"
void CDDeletionRestrictionsTable::LoadValuesFromDatabase() {
auto& entries = GetEntriesMutable();
auto tableData = CDClientDatabase::ExecuteQuery("SELECT id, restricted, ids, checkType FROM DeletionRestrictions;");
while (!tableData.eof()) {
CDDeletionRestriction entry;
entry.restricted = tableData.getIntField("restricted", 0) != 0;
entry.ids = tableData.getStringField("ids", "");
entry.checkType = tableData.getIntField("checkType", 0);
entries.insert_or_assign(tableData.getIntField("id", -1), std::move(entry));
tableData.nextRow();
}
tableData.finalize();
}
const CDDeletionRestriction* CDDeletionRestrictionsTable::Get(const int32_t id) const {
const auto& entries = GetEntries();
const auto it = entries.find(id);
return it == entries.end() ? nullptr : &it->second;
}