primerib1 Posted January 21 Share Posted January 21 (edited) I'm making a "gift giver" that will handout items in its inventory, but not all items; just those that matches one (or more) regexes. So I made the following: list EMPL; DeleteKeys(string pattern) { // Try trigger GC llSleep(0.01); list lsd_keys = llLinksetDataFindKeys(pattern, 0, 0); integer idx = -(lsd_keys != EMPL); if (idx) do { llLinksetDataDelete(llList2String(lsd_keys, idx)); } while (++idx); } BuildGiftSet() { // Pre-build cleanup DeleteKeys("^_item:"); DeleteKeys("^_gift:"); // Try trigger GC llSleep(0.01); // First we make a set of all our inventories integer j = llGetInventoryNumber(INVENTORY_ALL); // llGetInventoryName() does not support negative indexing, so we are forced to use standard for() loop integer i; for (;i<j;++i) { llLinksetDataWrite("_item:" + llGetInventoryName(INVENTORY_ALL, i), "."); } list gift_keys; list regexes_k = llLinksetDataFindKeys("^_regex-"); i = -(regexes_k != EMPL); if (i) do { // Grab a regex and use the regex to find matching items gift_keys = llLinksetDataFindKeys("^_item:" + llLinksetDataRead(llList2String(regexes_k, i))); j = -(gift_keys != EMPL); // Record the items. Dupes will get merged if (j) do { // llGetSubString used to remove the "_item:" prefix llLinksetDataWrite("_gift:" + llGetSubString(llList2String(gift_keys, j), 6, -1), "."); } while(++j) } while (++i) // Now the set of gifts are all in LSD, with keys prefixed by "_gift:" } // regexes are read from the notecard, they will be saved in LSD like so: // "_regex-0": "Gift Item .*" // "_regex-1": "Older Gifts .*" // "_regex-3": "some_other_regex" // "_regex-4": "yet_more_regex" // The number after the "_regex-" part means nothing; they are just to make unique keys. // The easiest way is to just use the global var containing the line number to read from the notecard // Like notice "_regex-2" does not exist because line 2 of the notecard is empty // To grab the gifts and give it out to someone: list gift_keys = llLinksetDataFindKeys("^_gift:", 0, 0); integer count = -(gift_keys != EMPL); if (!count) { llSleep(1); llRegionSayTo(toucher, 0, "Giver has nothing to give.\nIf you think this is an error, please inform a manager."); return; } list gifts; do { gifts += llGetSubString(llList2String(gift_keys, count), 6, -1); } while (++count); // Define target and folder_name somewhere, of course. // You might want to filter the target, e.g. based on active group. llGiveInventoryList(target, folder_name, llListSort(gifts, 1, TRUE)); Critiques & suggestions welcome! Edited January 21 by primerib1 Trigger GC? Link to comment Share on other sites More sharing options...
primerib1 Posted January 21 Author Share Posted January 21 Am I overthinking this? Can't I just simplify things like prefixing items to exclude with, say "~~"? Why YES of course, to both questions! I just like seeing how much I can push LSL to do some code acrobatics 😎 Link to comment Share on other sites More sharing options...
Quistess Alpha Posted January 21 Share Posted January 21 5 hours ago, primerib1 said: llGetInventoryName() does not support negative indexing, so we are forced to use standard for() loop ~--index doesn't depend on negative indexes, although looping backwards is "interesting" in some cases (not this one I don't think) Otherwise, interesting strategy. If it were me though, I'd probably write a CSV list of inventory items to the key of the regex that they match. Also at te scale where these sorts of acrobatics become a reasonable thing to do (rather than say, a manually curated list of category+item read from the notecard) the most likely case to handle is one or two items being added or removed from inventory at a time. It'd be better to try and optimize for the differential case rather than building the indexing from scratch after any change. 1 Link to comment Share on other sites More sharing options...
Lucia Nightfire Posted January 22 Share Posted January 22 Unrelated, but I suggest doing your LSDFindKeys in blocks instead of puting the entire list into script memory when doing cleanup, else, you easily risk crashing a script. 2 Link to comment Share on other sites More sharing options...
Recommended Posts
Please sign in to comment
You will be able to leave a comment after signing in
Sign In Now