diff --git a/aard_inventory.xml b/aard_inventory.xml index 9c9700f..55b457f 100644 --- a/aard_inventory.xml +++ b/aard_inventory.xml @@ -88,7 +88,7 @@ dbot.version : Module to track version and changelog information and update the save_state="y" date_written="2017-08-12 08:45:15" requires="4.98" - version="2.0025" + version="2.0026" > dinv reset [list | confirm] dinv forget + dinv ignore [on | off] dinv notify [none | light | standard | all] dinv cache [reset | size] [recent | frequent | custom | all] <# entries> dinv tags [on | off] @@ -314,6 +315,16 @@ Feature Wishlist > + + + @w") +end -- inv.cli.ignore.usage + + +function inv.cli.ignore.examples() + dbot.print("@W\nUsage:\n") + inv.cli.ignore.usage() + + dbot.print( +[[@W +The @Cignore@W mode allows you to specify one or more containers that the plugin should ignore. +Any ignored container and any items in an ignored container are not included when the plugin is +searching, getting, putting, storing, organizing, and creating or wearing equipment sets. + +Examples: + 1) Ignore "3.bag" in your main inventory + @Gdinv ignore on 3.bag@W + + 2) Stop ignoring "3.bag" + @Gdinv ignore off 3.bag@W + + 3) Do you really need another example? :p +]]) + +end -- inv.cli.ignore.examples + + inv.cli.reset = {} function inv.cli.reset.fn(name, line, wildcards) local command = wildcards[1] or "" @@ -4706,6 +4767,9 @@ end -- inv.cli.debug.fn -- inv.items.remove -- inv.items.forget -- inv.items.forgetCR +-- inv.items.ignore +-- inv.items.ignoreCR +-- inv.items.isIgnored(objId) -- -- inv.items.discoverCR(maxNumItems, refreshLocations) -- inv.items.discoverLocation @@ -5371,6 +5435,109 @@ function inv.items.forgetCR() end -- inv.items.forgetCR +inv.items.ignorePkg = nil +inv.items.ignoreFlag = "dinvIgnore" +function inv.items.ignore(mode, container, endTag) + + if (inv.items.ignorePkg ~= nil) then + dbot.note("Skipping ignore request: another ignore request is in progress") + return inv.tags.stop(invTagsIgnore, endTag, DRL_RET_BUSY) + end -- if + + inv.items.ignorePkg = {} + inv.items.ignorePkg.mode = mode or "" + inv.items.ignorePkg.container = container or "" + inv.items.ignorePkg.endTag = endTag + + wait.make(inv.items.ignoreCR) + + return DRL_RET_SUCCESS +end -- inv.items.ignore + + +function inv.items.ignoreCR() + + if (inv.items.ignorePkg == nil) then + dbot.error("inv.items.ignoreCR: Aborting ignore request -- ignore package is nil!") + return DRL_RET_INTERNAL_ERROR + end -- if + + local endTag = inv.items.ignorePkg.endTag + + local idArray, retval = inv.items.searchCR("rname " .. inv.items.ignorePkg.container, true) + if (retval ~= DRL_RET_SUCCESS) then + dbot.warn("inv.items.ignoreCR: failed to search inventory table: " .. dbot.retval.getString(retval)) + + -- Let the user know if no items matched their container relative name + elseif (idArray == nil) or (#idArray == 0) then + dbot.info("No match found for ignore container: \"" .. inv.items.ignorePkg.container .. "\"") + retval = DRL_MISSING_ENTRY + + elseif (#idArray > 1) then + dbot.warn("inv.items.ignoreCR: More than one item matched container \"" .. + inv.items.ignorePkg.container .. "\"") + retval = DRL_INTERNAL_ERROR + + -- Set or clear the ignore flag for the specified container + else + local mode + local objId = idArray[1] + + dbot.debug("Setting ignore to \"" .. inv.items.ignorePkg.mode .. "\" for item " .. objId) + + if (inv.items.getStatField(objId, invStatFieldType) ~= invmon.typeStr[invmonTypeContainer]) then + mode = "@MINVALID@W" + dbot.warn("inv.items.ignoreCR: item \"" .. inv.items.ignorePkg.container .. "\" is not a container") + retval = DRL_INVALID_PARAM + + elseif (inv.items.ignorePkg.mode == "on") then + mode = "@GON@W" + retval = inv.items.keyword(inv.items.ignoreFlag, invKeywordOpAdd, "id " .. objId, true, nil) + + elseif (inv.items.ignorePkg.mode == "off") then + mode = "@ROFF@W" + retval = inv.items.keyword(inv.items.ignoreFlag, invKeywordOpRemove, "id " .. objId, true, nil) + + else + mode = "@MINVALID@W" + dbot.warn("inv.items.ignoreCR: Invalid ignore mode \"" .. inv.items.ignorePkg.mode .. "\"") + retval = DRL_INVALID_PARAM + end -- if + + dbot.info("Ignore mode for container \"" .. inv.items.ignorePkg.container .. "\" is " .. mode) + end -- if + + -- Save our changes so that they don't get picked up again accidentally if we reload the plugin + inv.items.save() + + inv.items.ignorePkg = nil + + return inv.tags.stop(invTagsIgnore, endTag, retval) +end -- inv.items.ignoreCR + + +-- An item is "ignored" if it has the inv.items.ignoreFlag or if it is in a container that has +-- the inv.items.ignoreFlag +function inv.items.isIgnored(objId) + if (objId == nil) or (tonumber(objId or "") == nil) then + return false + end -- if + + local keywords = inv.items.getStatField(objId, invStatFieldKeywords) or "" + + if dbot.isWordInString(inv.items.ignoreFlag, keywords) then + -- If the the item has the ignore flag, it is ignored + return true + + else + -- Check if the object is in a container and, if so, if that container is ignored + return inv.items.isIgnored(tonumber(inv.items.getField(objId, invFieldObjLoc) or "")) + + end -- if + +end -- inv.items.isIgnored + + function inv.items.discoverCR(maxNumItems, refreshLocations) local retval @@ -7392,7 +7559,7 @@ function inv.items.keywordCR() doCacheItem = true end -- if - idArray, retval = inv.items.searchCR(inv.items.keywordPkg.queryString) + idArray, retval = inv.items.searchCR(inv.items.keywordPkg.queryString, true) if (retval ~= DRL_RET_SUCCESS) then dbot.warn("inv.items.keywordCR: failed to search inventory table: " .. dbot.retval.getString(retval)) @@ -7484,7 +7651,7 @@ end -- inv.items.keywordCR -- { { { invStatFieldType, "weapon" }, { "minlevel", "100" } }, -- { { invStatFieldWearable, "shield" }, { "minlevel", "100" } } -- } -function inv.items.search(arrayOfQueryArrays) +function inv.items.search(arrayOfQueryArrays, allowIgnored) local retval = DRL_RET_SUCCESS local idArray = {} @@ -7504,6 +7671,14 @@ function inv.items.search(arrayOfQueryArrays) return nil, DRL_RET_MISSING_ENTRY end -- if + -- Check if the item is ignored (it either has the ignored flag or is in a container that is ignored). + -- If it is ignored, don't include the item in search results unless the caller specifically said + -- to include ignored items. + local ignoreItem = false + if inv.items.isIgnored(itemId) and (allowIgnored ~= true) then + ignoreItem = true + end -- if + -- Check if the item already matches the query. This could happen if we have something of the -- form "query1 or query2" and the item matches both query1 and query2. If the item is already -- known to match, then we don't want to waste time checking other query clauses and we don't @@ -7519,7 +7694,7 @@ function inv.items.search(arrayOfQueryArrays) local itemMatches = false local objLoc = itemObj[invFieldObjLoc] local stats = itemObj[invFieldStats] - if (stats ~= nil) and (idAlreadyMatches == false) then + if (stats ~= nil) and (idAlreadyMatches == false) and (ignoreItem == false) then itemMatches = true -- start by assuming we have a match and halt if we find any non-conforming query -- If we have an empty query (query == "") and the item is equipped, we don't match it. The @@ -7704,7 +7879,7 @@ end -- inv.items.search -- name bob -- keyword shardblade -- Note: This must be called from within a co-routine because inv.items.convertRelative() can block -function inv.items.searchCR(queryString) +function inv.items.searchCR(queryString, allowIgnored) local retval = DRL_RET_SUCCESS local arrayOfKvArrays = {} local kvArray = {} @@ -7804,7 +7979,7 @@ function inv.items.searchCR(queryString) table.insert(arrayOfKvArrays, kvArray) -- Convert the series of queries in an array of object IDs that match the queries - local idArray, retval = inv.items.search(arrayOfKvArrays) + local idArray, retval = inv.items.search(arrayOfKvArrays, allowIgnored) return idArray, retval @@ -13345,12 +13520,18 @@ function inv.set.createWithHandicap(priorityName, level, handicap) dbot.debug("Skipping item: align=" .. (dbot.gmcp.getAlign() or "nil") .. ", flags=\"" .. (objFlags or "nil") .. "\"") + -- Check if we are ignoring this item (it is flagged as "ignored" or is in a container + -- that is flagged as "ignored) + elseif inv.items.isIgnored(objId) then + dbot.debug("Ignoring item " .. objId .. " for set") + -- Check if the item is a weapon with a disallowed damage type elseif (objDamType ~= nil) and (objDamType ~= "") and (not inv.priority.damTypeIsAllowed(objDamType, priorityName, level)) then -- Skip the current object because it is a weapon with a damtype we don't want - -- The alignment is acceptable. Check the other requirements... + -- The alignment is acceptable, the item isn't ignored, and it doesn't use a disallowed + -- damage type. Whew. Check the other requirements... elseif (objWearable ~= nil) and (objWearable ~= "") and (inv.wearables[objWearable] ~= nil) then score, offhandScore = inv.score.item(objId, priorityName, handicap, level) local nextBest = { id = objId, score = score }