From 83aa532a644f632c20990b7dc70e4a80c17a4a74 Mon Sep 17 00:00:00 2001 From: Logg-y <49533518+Logg-y@users.noreply.github.com> Date: Tue, 26 Nov 2024 01:39:02 +0000 Subject: [PATCH] Support updating name/description and searching for items to update by resref --- src/nss/inc_itemupdate.nss | 21 ++++++++- src/nss/inc_loot.nss | 2 +- src/nss/inc_treasure.nss | 91 +++++++++++++++++++++++++++++++++++--- src/nss/on_mod_load.nss | 2 +- 4 files changed, 107 insertions(+), 9 deletions(-) diff --git a/src/nss/inc_itemupdate.nss b/src/nss/inc_itemupdate.nss index bab085d1..d8d4a1a7 100644 --- a/src/nss/inc_itemupdate.nss +++ b/src/nss/inc_itemupdate.nss @@ -24,6 +24,8 @@ struct ItemPropertyUpdateInfo const int ITEM_UPDATE_ITEMPROPERTIES = 1; const int ITEM_UPDATE_ADDITIONALGOLDCOST = 2; const int ITEM_UPDATE_TAG = 4; +const int ITEM_UPDATE_DESCRIPTION = 8; +const int ITEM_UPDATE_NAME = 16; // Update oItem to its "newer" form. // Returns a Json object saying what was updated. @@ -315,11 +317,28 @@ int GetIdentifiedGoldCost(object oItem) struct ItemPropertyUpdateInfo UpdateItemProperties(object oItem) { struct ItemPropertyUpdateInfo sRet; - object oTreasureStorage = GetTFNEquipmentByName(oItem); + object oTreasureStorage = GetTFNStagedEquipmentForItem(oItem); if (!GetIsObjectValid(oTreasureStorage)) { return sRet; } + if (GetDescription(oItem) != GetDescription(oTreasureStorage)) + { + SetDescription(oItem, GetDescription(oTreasureStorage)); + sRet.nUpdateFlags |= ITEM_UPDATE_DESCRIPTION; + } + if (GetIdentified(oItem)) + { + int bOldIdentified = GetIdentified(oTreasureStorage); + SetIdentified(oTreasureStorage, 1); + string sNewName = GetName(oTreasureStorage); + SetIdentified(oTreasureStorage, bOldIdentified); + if (GetName(oItem) != sNewName) + { + SetName(oItem, sNewName); + sRet.nUpdateFlags |= ITEM_UPDATE_NAME; + } + } int nThisHash = GetItemPropertiesHash(oItem); int nTreasureHash = GetItemPropertiesHash(oTreasureStorage); diff --git a/src/nss/inc_loot.nss b/src/nss/inc_loot.nss index 24c6a088..94b45864 100644 --- a/src/nss/inc_loot.nss +++ b/src/nss/inc_loot.nss @@ -758,7 +758,7 @@ json _AddToDroppableLootArray(json jItems, object oLootOrigin, object oItem, int { json jBlacklist = GetLocalJson(oLootOrigin, "OwnDroppableLootBlacklist"); - object oTFN = GetTFNEquipmentByName(oItem); + object oTFN = GetTFNStagedEquipmentForItem(oItem); if (GetLocalInt(oItem, "creature_drop_only")) { oTFN = oItem; diff --git a/src/nss/inc_treasure.nss b/src/nss/inc_treasure.nss index 65c4656b..9de2446e 100644 --- a/src/nss/inc_treasure.nss +++ b/src/nss/inc_treasure.nss @@ -313,7 +313,7 @@ location GetTreasureStagingLocation() {return Location(GetObjectByTag("_TREASURE // Also, some creatures add itemprops to them on spawn, which isn't ideal // To get around that we can map the generic names to the TFN object // ... which this DB can do for us happily -void BuildItemNamesToObjectsDB() +void BuildTreasureStagingToObjectsDB() { object oMod = GetModule(); sqlquery sql = SqlPrepareQueryObject(GetModule(), @@ -321,12 +321,18 @@ void BuildItemNamesToObjectsDB() "itemname TEXT PRIMARY KEY ON CONFLICT FAIL, " + "oid TEXT);"); SqlStep(sql); + sql = SqlPrepareQueryObject(GetModule(), + "CREATE TABLE IF NOT EXISTS item_resref_lookup (" + + "resref TEXT PRIMARY KEY ON CONFLICT FAIL, " + + "oid TEXT);"); + SqlStep(sql); int nTier; int nItemType; int nUniqueness; int nRarity; string sRarity; string sItemType; + json jResrefMappingsWithConflicts = JsonArray(); for (nTier=1; nTier<=5; nTier++) { // Armor, Melee, Range, Apparel @@ -358,8 +364,9 @@ void BuildItemNamesToObjectsDB() SetIdentified(oTest, 1); // As of right now there are about four items who conflict // including base item name resolves them all + // If that ever changes, this will throw full blown sqlite errors string sName = GetName(oTest) + IntToString(GetBaseItemType(oTest)); - SetIdentified(oTest, bIdentified); + sql = SqlPrepareQueryObject(GetModule(), "INSERT INTO item_name_lookup " + "(itemname, oid) VALUES (@itemname, @oid);");// + @@ -373,6 +380,38 @@ void BuildItemNamesToObjectsDB() { WriteTimestampedLogEntry("Error while writing item name: " + sName); } + + // Resref mapping: we can expect to have conflicts here + // It is nice not to spam the server log with them. + + sName = GetResRef(oTest) + "_baseitem_" + IntToString(GetBaseItemType(oTest)); + sql = SqlPrepareQueryObject(GetModule(), + "SELECT EXISTS(SELECT 1 FROM item_resref_lookup WHERE resref = @resref);"); + SqlBindString(sql, "@resref", sName); + SqlStep(sql); + if (SqlGetInt(sql, 0)) + { + WriteTimestampedLogEntry("Resref lookup for " + GetName(oTest) + " has conflicts with something that came before it using key " + sName); + if (JsonFind(jResrefMappingsWithConflicts, JsonString(sName)) == JsonNull()) + { + JsonArrayInsertInplace(jResrefMappingsWithConflicts, JsonString(sName)); + } + } + else + { + sql = SqlPrepareQueryObject(GetModule(), + "INSERT INTO item_resref_lookup " + + "(resref, oid) VALUES (@resref, @oid);"); + SqlBindString(sql, "@resref", sName); + SqlBindString(sql, "@oid", ObjectToString(oTest)); + SqlStep(sql); + sError = SqlGetError(sql); + if (sError != "") + { + WriteTimestampedLogEntry("Error while writing item resref mapping: " + sName); + } + } + SetIdentified(oTest, bIdentified); oTest = GetNextItemInInventory(oChest); } } @@ -380,6 +419,40 @@ void BuildItemNamesToObjectsDB() } } } + // Drop the records that had conflicts + int i; + for (i=0; i " + GetName(oRet)); + return oRet; + } + //WriteTimestampedLogEntry("GetTFNEquipmentByResref: " + sName + " -> invalid"); + + return OBJECT_INVALID; } object GetTFNEquipmentFromName(string sItemName, int nBaseItemType) @@ -392,15 +465,15 @@ object GetTFNEquipmentFromName(string sItemName, int nBaseItemType) if (SqlStep(sql)) { object oRet = StringToObject(SqlGetString(sql, 0)); - //WriteTimestampedLogEntry("GetTFNEquipmentByName: " + GetName(oItem) + " -> " + GetName(oRet)); + //WriteTimestampedLogEntry("GetTFNEquipmentFromName: " + sName+ " -> " + GetName(oRet)); return oRet; } - //WriteTimestampedLogEntry("GetTFNEquipmentByName: " + GetName(oItem) + " -> invalid"); + //WriteTimestampedLogEntry("GetTFNEquipmentFromName: " + sName + " -> invalid"); return OBJECT_INVALID; } -object GetTFNEquipmentByName(object oItem) +object GetTFNStagedEquipmentForItem(object oItem) { if (GetIsObjectValid(oItem)) { @@ -413,7 +486,13 @@ object GetTFNEquipmentByName(object oItem) } SetIdentified(oItem, bIdentified); - return GetTFNEquipmentFromName(sName, GetBaseItemType(oItem)); + object oRet = GetTFNEquipmentFromName(sName, GetBaseItemType(oItem)); + if (GetIsObjectValid(oRet)) + { + return oRet; + } + + return GetTFNEquipmentByResref(GetResRef(oItem), GetBaseItemType(oItem)); } return OBJECT_INVALID; } diff --git a/src/nss/on_mod_load.nss b/src/nss/on_mod_load.nss index fe2967bd..6a05594d 100644 --- a/src/nss/on_mod_load.nss +++ b/src/nss/on_mod_load.nss @@ -749,7 +749,7 @@ void main() } } - BuildItemNamesToObjectsDB(); + BuildTreasureStagingToObjectsDB(); SetLocalInt(GetModule(), "treasure_ready", 1); CalculatePlaceableLootValues();