include("memorytable.lua"); include("inventoryitem.lua"); -- Tooltip parser keywords ITEM_TOOLTIP_DURABILITY = { DE = "Haltbarkeit", FR = "Structure", ENEU = "Durability", ENUS = "Durability", PH = "Durability", RU = "\143\224\174\231\173\174\225\226\236", PL = "Trwa\136o\152\143", ES = "Durabilidad", SA = "Durabilidad", ENAR = "Durability", }; CInventory = class( function (self) RoMScript("ToggleBackpack(), BagFrame:Hide()"); -- Make sure the client loads the tables first. RoMScript("GoodsFrame:Show(), GoodsFrame:Hide()"); -- Make sure the client loads the tables first. self.MaxSlots = 240; self.BagSlot = {}; self.Money = memoryReadInt( getProc(), addresses.moneyPtr ); local timeStart = getTime(); for slotNumber = 1, self.MaxSlots, 1 do self.BagSlot[slotNumber] = CInventoryItem( slotNumber ); end if( settings.profile.options.DEBUG_INV ) then printf( "Inventory update took: %d\n", deltaTime( getTime(), timeStart ) ); end; self.NextItemToUpdate = 1; end ); function CInventory:update( _maxslot ) self.Money = memoryReadInt( getProc(), addresses.moneyPtr ); if( not _maxslot ) then _maxslot = self.MaxSlots; end; for slotNumber = 1, _maxslot, 1 do self.BagSlot[slotNumber]:update(); end end; -- update x slots until given time in ms is gone function CInventory:updateSlotsByTime(_ms) local start_update = getTime(); keyboardSetDelay(0); while ( deltaTime(getTime(), start_update ) < _ms ) do self:updateNextSlot(); end keyboardSetDelay(50); end -- update x slots function CInventory:updateNextSlot(_times) if(not _times) then _times = 1; end for i = 1, _times do local item = self.BagSlot[self.NextItemToUpdate]; -- if( settings.profile.options.DEBUG_INV) then -- local msg = ""; -- msg = "DEBUG updateNextSlot(): Slot #"..self.NextItemToUpdate..": "; -- if(item.Name) then -- msg = msg.." name "..item.Name; -- else -- msg = msg.." name ".." "; -- end; -- if(item.ItemCount) then msg = msg.." ItemCount:"..item.ItemCount; end; -- cprintf(cli.lightblue, "%s\n", msg); -- end; self.BagSlot[self.NextItemToUpdate]:update(); self.NextItemToUpdate = self.NextItemToUpdate + 1; if (self.NextItemToUpdate > self.MaxSlots) then self.NextItemToUpdate = 1; end; end; end; -- return is true or false. false if there was no ammunition in the bag, type is "thrown" or "arrow" function CInventory:reloadAmmunition(type) local item = self:bestAvailableConsumable(type); -- if theres no ammunition, open a ammunition bag if not item then local openItem if type == "arrow" then openItem = self:bestAvailableConsumable("arrow_quiver"); elseif type == "thrown" then openItem = self:bestAvailableConsumable("thrown_bag"); end if not openItem then return false; end local checkItemName = openItem.Name; yrest(300); item = self:bestAvailableConsumable(type); if( item and checkItemName ~= item.Name ) then cprintf(cli.yellow, language[18], tostring(checkItemName), tostring(item.Name)); -- NOTICE: Item mismatch openItem:update(); else openItem:use(); yrest( 500 ); --give time to server to respond with the opened item end item = self:bestAvailableConsumable(type); end if item then -- use it -- local unused,unused,checkItemName = RoMScript("GetBagItemInfo(" .. item.SlotNumber .. ")"); local checkItemName = item.Name; item:update(); if( checkItemName ~= item.Name ) then cprintf(cli.yellow, language[18], tostring(checkItemName), tostring(item.Name)); -- NOTICE: Item mismatch item:update(); else item:use(); end end end; -- Here for compatibility reasons function CInventory:getItemCount(itemId, range) if(itemId == nil) then cprintf(cli.yellow, "Inventory:getItemCount with itemId=nil, please (do not) inform the developers.\n" ); return 0; end return self:itemTotalCount( itemId, range ); end; -- No longer uses cached information, it updates before checking function CInventory:itemTotalCount(itemNameOrId, range) local first, last, location = getInventoryRange(range) -- get bag slot range if location and location ~= "inventory" then print("inventory:itemTotalCount() only supports ranges in the inventory, eg. \"bags\",\"bag1\",\"bag2\",etc.") return end if first == nil then -- Default values - 1-240 for items, 61-240 for empties. if itemNameOrId == "" or itemNameOrId == 0 then first = 61 else first = 1 end last = 240 -- default, search only bags end local item local totalCount = 0; for slot = first, last do item = inventory.BagSlot[slot] item:update() if item.Available and (item.Id == itemNameOrId or item.Name == itemNameOrId) then if itemNameOrId == "" or itemNameOrId == 0 then -- so you can count empty slots totalCount = totalCount + 1 else totalCount = totalCount + item.ItemCount; end end; end; return totalCount; end; function CInventory:findItem( itemNameOrId, range) local first, last, location = getInventoryRange(range) -- get bag slot range if location ~= "inventory" and location ~= nil then printf("You can only use inventory ranges with 'inventory:findItem'. You cannot use '%s' which is in %s\n", range, location) end if first == nil then first , last = 1, 240 -- default, search all end local smallestStack = nil local item for slot = first, last do item = self.BagSlot[slot] item:update() if item.Available and (not item.InUse) and (item.Name == itemNameOrId or item.Id == itemNameOrId) then if (os.clock() - item.LastMovedTime) > ITEM_REUSE_DELAY then if item.ItemCount > 1 then -- find smallest stack if smallestStack == nil or smallestStack.ItemCount > item.ItemCount then smallestStack = item end else return item end end end; end; return smallestStack end function CInventory:useItem(itemNameOrId) local item = self:findItem(itemNameOrId) if item then item:use(); return true, item.Id, item.Name; end; return false; end; -- Make a full update -- or update slot 1 to _maxslot -- Returns item name or false, takes in type, example: "hot" or "mot" or "arrow" or "thrown" function CInventory:bestAvailableConsumable(type) local bestLevel = 0; -- required player level of a potion local bestPotency = 0; -- power of a potion local bestItem = false; local bestSmallStack = 999; local select_strategy; local select_strategy_best = "best"; local select_strategy_minstack = "minstack"; local select_strategy_default = "best"; -- set select strategy if( type == "mot" ) then if( settings.profile.options.USE_MANA_POTION == select_strategy_minstack ) then select_strategy = select_strategy_minstack; else select_strategy = select_strategy_default; end elseif(type == "hot" ) then if( settings.profile.options.USE_HP_POTION == select_strategy_minstack ) then select_strategy = select_strategy_minstack; else select_strategy = select_strategy_default; end else select_strategy = select_strategy_default; -- default = 'best' end self:update(); -- check item slots slot by slot for slot,item in pairs(self.BagSlot) do local consumable = database.consumables[item.Id]; if( consumable and -- item in database consumable.Type == type and -- right type (mana, arrow, ...) consumable.Level <= player.Level and -- level ok item.ItemCount > 0 and -- use only if some available item.Available) then -- not in unrented bag if( select_strategy == select_strategy_minstack ) then -- select smallest stack if item.ItemCount < bestSmallStack then bestSmallStack = item.ItemCount; bestItem = item; end else -- select best available consumable (& smallest stack by default) -- select better level if( consumable.Level > bestLevel ) then bestLevel = consumable.Level; bestPotency = consumable.Potency; bestSmallStack = item.ItemCount; bestItem = item; -- same level but select better potency elseif( consumable.Level == bestLevel and consumable.Potency > bestPotency) then bestLevel = consumable.Level; bestPotency = consumable.Potency; bestSmallStack = item.ItemCount; bestItem = item; -- same/same but select smaller stack elseif( consumable.Level == bestLevel and consumable.Potency == bestPotency and item.ItemCount < bestSmallStack ) then bestLevel = consumable.Level; bestPotency = consumable.Potency; bestSmallStack = item.ItemCount; bestItem = item; end end end end return bestItem; end -- Kept for backward compatibility. Use store:buyItem(nameIdOrIndex, quantity) instead function CInventory:storeBuyItem(nameIdOrIndex, quantity) return store:buyItem(nameIdOrIndex, quantity) end -- Kept for backward compatibility. Use store:buyConsumable(type, quantity) instead function CInventory:storeBuyConsumable(type, quantity) return store:buyConsumable(type, quantity) end function CInventory:deleteItemInSlot(slot) self.BagSlot[slot]:delete(); end function CInventory:autoSell(evalfunc) if( settings.profile.options.INV_AUTOSELL_ENABLE ~= true ) then return false end -- warning if not all inventory slots are updated if( settings.profile.options.INV_AUTOSELL_TOSLOT > self.MaxSlots ) then cprintf(cli.yellow, language[1003], self.MaxSlots, settings.profile.options.INV_AUTOSELL_TOSLOT); end -- warning if igf addon is missing if( bot.IgfAddon == false and ( settings.profile.options.INV_AUTOSELL_NOSELL_DURA > 0 or settings.profile.options.INV_AUTOSELL_STATS_NOSELL ~= nil ) ) then cprintf(cli.yellow, language[1004]); -- Ingamefunctions addon (igf) is not installed return false; end if evalfunc == nil or type(evalfunc) ~= "function" then -- Set up default eval function -- move color settings into table local hf_quality = string.gsub (settings.profile.options.INV_AUTOSELL_QUALITY, "%s*[;,]%s*", "\n"); -- replace ; with linefeed local hf_quality_table = explode( hf_quality, "\n" ); -- move colors to table local hf_ignore_table; -- move ignore list into table if( settings.profile.options.INV_AUTOSELL_IGNORE ) then local hf_explode = string.gsub (settings.profile.options.INV_AUTOSELL_IGNORE, "%s*[;,]%s*", "\n"); -- replace ; with linefeed hf_ignore_table = explode( hf_explode, "\n" ); -- move ignore list for i,v in pairs(hf_ignore_table) do local m = string.match(v,"^'(.*)'$") if m then hf_ignore_table[i] = m end end -- remove quotes end local hf_stats_nosell; -- move ignore stats list into table if( settings.profile.options.INV_AUTOSELL_STATS_NOSELL ) then local hf_explode = string.gsub (settings.profile.options.INV_AUTOSELL_STATS_NOSELL, "[;,]", "\n"); -- replace ; with linefeed/ no trim hf_stats_nosell = explode( hf_explode, "\n" ); -- move ignore list for i,v in pairs(hf_stats_nosell) do local m = string.match(v,"^'(.*)'$") if m then hf_stats_nosell[i] = m end end -- remove quotes end local hf_stats_sell; -- move stats list into table if( settings.profile.options.INV_AUTOSELL_STATS_SELL ) then local hf_explode = string.gsub (settings.profile.options.INV_AUTOSELL_STATS_SELL, "[;,]", "\n"); -- replace ; with linefeed/ no trim hf_stats_sell = explode( hf_explode, "\n" ); -- move ignore list for i,v in pairs(hf_stats_sell) do local m = string.match(v,"^'(.*)'$") if m then hf_stats_sell[i] = m end end -- remove quotes end local hf_type_sell; -- move type list into table if( settings.profile.options.INV_AUTOSELL_TYPES ) then local hf_explode = string.gsub(settings.profile.options.INV_AUTOSELL_TYPES, "[;,]", "\n"); -- replace ; with linefeed/ no trim hf_type_sell = explode( hf_explode, "\n" ); end local hf_type_nosell; -- move type list into table if( settings.profile.options.INV_AUTOSELL_TYPES_NOSELL ) then local hf_explode = string.gsub(settings.profile.options.INV_AUTOSELL_TYPES_NOSELL, "[;,]", "\n"); -- replace ; with linefeed/ no trim hf_type_nosell = explode( hf_explode, "\n" ); end -- ITEMCOLORS table is defined in item.lua local function sellColor(_itemcolor) for i,v in pairs(hf_quality_table) do if( ITEMCOLOR[string.upper(v)] == _itemcolor ) then return true end end return false end local function isInTypeSell(_slotitem) if ( not hf_type_sell ) then return true end for i,v in pairs(hf_type_sell) do if _slotitem:isType(v) then return true end end return false end local function isInTypeNosell(_slotitem) if ( not hf_type_nosell ) then return false end for i,v in pairs(hf_type_nosell) do if _slotitem:isType(v) then return true end end return false end -- check if itemname or itemid is in the ignorelist local function isInIgnorelist(_item) if ( not hf_ignore_table ) then return false end for i,ignorelistitem in pairs(hf_ignore_table) do if( string.find( string.lower(_item.Name), string.lower(ignorelistitem), 1, true) or _item.ItemId == ignorelistitem ) then debugMsg(settings.profile.options.DEBUG_AUTOSELL, "Itemname/id is in ignore list INV_AUTOSELL_IGNORE:", _item.ItemId, _item.Name, "=>", "'"..ignorelistitem.."'"); return true end end return false end local function isInStatsNoSell(_item) if ( not hf_stats_nosell ) then return false end for i1,stat in pairs(_item.Stats) do for i2,nosellstat in pairs(hf_stats_nosell) do debugMsg(settings.profile.options.DEBUG_AUTOSELL, "Check nosellstat line:", i1, tooltipline, "=>", nosellstat); if( string.find( string.lower(stat.Name), string.lower(nosellstat), 1, true) ) then debugMsg(settings.profile.options.DEBUG_AUTOSELL, "Not to sell stat found:", stat.Name); return true end end end return false end local function isInStatsSell(_item) if ( not hf_stats_sell ) then return false end for i,stat in pairs(_item.Stats) do for i,sellstat in pairs(hf_stats_sell) do if( string.find( string.lower(stat.Name), string.lower(sellstat), 1, true) ) then debugMsg(settings.profile.options.DEBUG_AUTOSELL, "Allways sell stat found:", stat.Name); return true end end end return false end function evalfunc(slotitem) debugMsg(settings.profile.options.DEBUG_AUTOSELL, "Check item so sell:", slotitem.SlotNumber, slotitem.Id, slotitem.Name); -- Check if can be sold if slotitem.CannotBeSold then debugMsg(settings.profile.options.DEBUG_AUTOSELL, "Item can not be sold"); return false end -- check item quality color if( sellColor(slotitem.Color) == false ) then debugMsg(settings.profile.options.DEBUG_AUTOSELL, "Itemcolor not in option INV_AUTOSELL_QUALITY:", slotitem:getColorString() ); return false end -- check if on type sell lists if (isInTypeSell(slotitem) == false ) then debugMsg(settings.profile.options.DEBUG_AUTOSELL, "Item is not in type option INV_AUTOSELL_TYPE:", settings.profile.options.INV_AUTOSELL_TYPE); return false elseif (isInTypeNosell(slotitem) == true ) then debugMsg(settings.profile.options.DEBUG_AUTOSELL, "Item is in type option INV_AUTOSELL_TYPE_NOSELL:", settings.profile.options.INV_AUTOSELL_TYPE_NOSELL); return false end -- check itemname against ignore list if( isInIgnorelist(slotitem) == true ) then return false end -- check number of named stats if #slotitem.Stats >= settings.profile.options.INV_AUTOSELL_NOSELL_STATSNUMBER then debugMsg(settings.profile.options.DEBUG_AUTOSELL, "Number of stats not less than INV_AUTOSELL_NOSELL_STATSNUMBER", settings.profile.options.INV_AUTOSELL_NOSELL_STATSNUMBER ); return false end -- check max durability value if( settings.profile.options.INV_AUTOSELL_NOSELL_DURA > 0 and slotitem.MaxDurability > 0 and slotitem.MaxDurability > settings.profile.options.INV_AUTOSELL_NOSELL_DURA )then debugMsg(settings.profile.options.DEBUG_AUTOSELL, "Don't sell, durability > INV_AUTOSELL_NOSELL_DURA:", settings.profile.options.INV_AUTOSELL_NOSELL_DURA ); return false end -- check if stats / text strings are on the ingnore list if( isInStatsNoSell(slotitem) == true ) then -- check if in sell always stats if( isInStatsSell(slotitem) == true ) then -- don't change the sell flag else return false end end return true end end local sellstartstring = "} local U=UseBagItem; if StoreFrame:IsVisible() then a={true};" local sellendstring = "end;z={" local sellstring = sellstartstring local hf_wesell = false; -- check the given slot numbers to autosell for slotNumber = settings.profile.options.INV_AUTOSELL_FROMSLOT + 60, settings.profile.options.INV_AUTOSELL_TOSLOT + 60, 1 do local slotitem = self.BagSlot[slotNumber]; if( slotitem and tonumber(slotitem.Id) > 0 and slotitem.Available and slotitem.CanBeSold) then if evalfunc(slotitem) == true then -- Passed eval function. Then sell the item sellstring = sellstring .. "U("..slotitem.BagId..");" -- max length 7 if #sellstring >= (254 - 7 - #sellendstring) then -- Can't fit more sellstring = sellstring .. sellendstring if RoMScript(sellstring) then yrest(100) hf_wesell = true; sellstring = sellstartstring -- Reset for more else return hf_wesell end end end end -- end of: if( slotitem and slotitem.Id > 0 ) end -- Sell any left over in list if #sellstring > #sellstartstring then sellstring = sellstring .. sellendstring if RoMScript(sellstring) then yrest(100) hf_wesell = true; end end if( hf_wesell == true ) then return true; else return false; end end function CInventory:getMount() mounts = { -- Id of all mounts -- Add single mounts or ranges of mounts. {first = 200876, last = 200879}, 201130, 201468, 201482, {first = 201488, last = 201490}, 201698, {first = 201927, last = 201928}, {first = 201965, last = 201966}, 202095, {first = 202217, last = 202218}, {first = 202226, last = 202232}, {first = 202245, last = 202248}, {first = 202450, last = 202486}, 202821, {first = 202931, last = 202936}, {first = 203285, last = 203290}, {first = 203296, last = 203341}, {first = 203553, last = 203573}, {first = 203669, last = 203678}, {first = 203913, last = 203915}, {first = 203968, last = 203971}, 204072, {first = 204083, last = 204085}, {first = 204142, last = 204151}, {first = 204276, last = 204295}, {first = 204929, last = 204948}, {first = 204950, last = 204979}, {first = 204982, last = 204999}, {first = 205748, last = 205749}, {first = 206016, last = 206020}, {first = 206196, last = 206207}, {first = 206212, last = 206215}, {first = 206234, last = 206239}, {first = 206275, last = 206292}, {first = 206314, last = 206319}, {first = 206326, last = 206329}, {first = 206352, last = 206361}, {first = 206556, last = 206573}, {first = 206594, last = 206596}, {first = 206705, last = 206710}, {first = 206715, last = 206720}, {first = 206904, last = 206906}, {first = 206934, last = 206936}, {first = 206939, last = 206941}, {first = 206944, last = 206946}, {first = 207501, last = 207503}, {first = 207515, last = 207536}, {first = 207546, last = 207551}, {first = 207558, last = 207560}, {first = 207566, last = 207571}, 207624, {first = 208159, last = 208161}, {first = 208570, last = 208572}, 208691, {first = 208693, last = 208695}, {first = 208697, last = 208700}, 208702, {first = 208704, last = 208707}, {first = 208910, last = 208912}, {first = 209485, last = 209487}, 209490, {first = 209500, last = 209502}, {first = 209505, last = 209508}, {first = 209601, last = 209602}, {first = 209961, last = 209966}, {first = 240036, last = 240038}, {first = 240081, last = 240083}, {first = 240086, last = 240088}, {first = 240928, last = 240930}, {first = 240933, last = 240935}, 241101, {first = 241103, last = 241104}, {first = 241316, last = 241318}, {first = 241620, last = 241622}, {first = 241632, last = 241634}, {first = 241772, last = 241774}, {first = 241777, last = 241779}, {first = 241786, last = 241788}, {first = 241791, last = 241793}, 241805, {first = 241997, last = 241999}, -- Temp mounts 505113,494474, }; for slot,item in pairs(self.BagSlot) do if item.Available then for i, mount in ipairs(mounts) do if type(mount) == "number" then if item.Id == mount then return item; end else -- table if item.Id >= mount.first and item.Id <= mount.last then return item end end end end end return false; end function getInventoryRange(range) if range == nil then return end local rangeLower = string.lower(range) if rangeLower == "all" then return 1, 240, "inventory" elseif rangeLower == "itemshop" then return 1, 50, "inventory" elseif rangeLower == "magicbox" then return 51, 60, "inventory" elseif rangeLower == "bag1" then return 61, 90, "inventory" elseif rangeLower == "bag2" then return 91, 120, "inventory" elseif rangeLower == "bag3" then return 121, 150, "inventory" elseif rangeLower == "bag4" then return 151, 180, "inventory" elseif rangeLower == "bag5" then return 181, 210, "inventory" elseif rangeLower == "bag6" then return 211, 240, "inventory" elseif rangeLower == "bag" or rangeLower == "bags" then return 61, 240, "inventory" elseif rangeLower == "bank1" then return 1, 40, "bank" elseif rangeLower == "bank2" then return 41, 80, "bank" elseif rangeLower == "bank3" then return 81, 120, "bank" elseif rangeLower == "bank4" then return 121, 160, "bank" elseif rangeLower == "bank5" then return 161, 200, "bank" elseif rangeLower == "isbank" then return 201, 300, "bank" elseif rangeLower == "bank" or rangeLower == "banks" then return 1, 200, "bank" elseif rangeLower == "equipment" then return 0, 21, "equipment" elseif rangeLower == "head" then return 0, 0, "equipment" elseif rangeLower == "hands" then return 1, 1, "equipment" elseif rangeLower == "feet" then return 2, 2, "equipment" elseif rangeLower == "chest" then return 3, 3, "equipment" elseif rangeLower == "legs" then return 4, 4, "equipment" elseif rangeLower == "cape" then return 5, 5, "equipment" elseif rangeLower == "belt" then return 6, 6, "equipment" elseif rangeLower == "shoulders" then return 7, 7, "equipment" elseif rangeLower == "necklace" then return 8, 8, "equipment" elseif rangeLower == "ammunition" then return 9, 9, "equipment" elseif rangeLower == "ranged weapon" then return 10, 10, "equipment" elseif rangeLower == "left ring" then return 11, 11, "equipment" elseif rangeLower == "right ring" then return 12, 12, "equipment" elseif rangeLower == "left earring" then return 13, 13, "equipment" elseif rangeLower == "right earring" then return 14, 14, "equipment" elseif rangeLower == "main hand" then return 15, 15, "equipment" elseif rangeLower == "off hand" then return 16, 16, "equipment" elseif rangeLower == "unknown" then return 17, 17, "equipment" elseif rangeLower == "amulets" then return 18, 20, "equipment" elseif rangeLower == "amulet1" then return 18, 18, "equipment" elseif rangeLower == "amulet2" then return 19, 19, "equipment" elseif rangeLower == "amulet3" then return 20, 20, "equipment" elseif rangeLower == "wings" then return 21, 21, "equipment" elseif rangeLower == "guildbank" or rangeLower == "guild" then guildbank:updatePageAddresses() return 1, #guildbank.PageAddresses*100, "guildbank" elseif string.match(rangeLower, "guild") then local page = string.match(rangeLower,"^guildbank(%d%d?)$") or string.match(rangeLower,"^guild(%d%d?)$") page = tonumber(page) if page and page > 0 and page <= 10 then return (page-1)*100+1, page*100, "guildbank" end end end -- Returns item name or false, takes in type, example: "hot" or "mot" or "arrow" or "thrown" function CInventory:bestAvailablePhirius(type) local bestPer = 0; -- power of a potion local bestItem = false; local select_strategy = "best"; self:update(); -- check item slots slot by slot for slot,item in pairs(self.BagSlot) do local consumable = database.consumables[item.Id]; if consumable and -- item in database (consumable.Type == type and -- right type (mana, hp, both) item.ItemCount > 0 and -- use only if some available item.Available) then -- not in unrented bag if( consumable.Potency > bestPer) then bestPer = consumable.Potency; bestSmallStack = item.ItemCount; bestItem = item; -- same/same but select smaller stack elseif( consumable.Potency == bestPer and item.ItemCount < bestSmallStack ) then bestPer = consumable.Potency; bestSmallStack = item.ItemCount; bestItem = item; end end end if bestItem == false then for slot,item in pairs(self.BagSlot) do local consumable = database.consumables[item.Id]; if consumable and -- item in database (consumable.Type == "phirusboth" and -- right type (mana, hp, both) item.ItemCount > 0 and -- use only if some available item.Available) then -- not in unrented bag if( consumable.Potency > bestPer) then bestPer = consumable.Potency; bestSmallStack = item.ItemCount; bestItem = item; -- same/same but select smaller stack elseif( consumable.Potency == bestPer and item.ItemCount < bestSmallStack ) then bestPer = consumable.Potency; bestSmallStack = item.ItemCount; bestItem = item; end end end end return bestItem; end -- Returns item name or false, takes in type, example: "hot" or "mot" or "arrow" or "thrown" function CInventory:bestAvailablepotion(type) local bestLevel = 0; -- required player level of a potion local bestPotency = 0; -- power of a potion local bestItem = false; local bestSmallStack = 999; local select_strategy; local select_strategy_best = "best"; local select_strategy_minstack = "minstack"; local select_strategy_default = "best"; -- set select strategy if( type == "mana" ) then if( settings.profile.options.USE_MANA_POTION == select_strategy_minstack ) then select_strategy = select_strategy_minstack; else select_strategy = select_strategy_default; end elseif(type == "heal" ) then if( settings.profile.options.USE_HP_POTION == select_strategy_minstack ) then select_strategy = select_strategy_minstack; else select_strategy = select_strategy_default; end else select_strategy = select_strategy_default; -- default = 'best' end self:update(); -- check item slots slot by slot for slot,item in pairs(self.BagSlot) do local consumable = database.consumables[item.Id]; if( consumable and -- item in database consumable.Type == type and -- right type (mana, arrow, ...) consumable.Level <= player.Level and -- level ok item.ItemCount > 0 and -- use only if some available item.Available) then -- not in unrented bag if( select_strategy == select_strategy_minstack ) then -- select smallest stack if item.ItemCount < bestSmallStack then bestSmallStack = item.ItemCount; bestItem = item; end else -- select best available consumable (& smallest stack by default) -- select better level if( consumable.Level > bestLevel ) then bestLevel = consumable.Level; bestPotency = consumable.Potency; bestSmallStack = item.ItemCount; bestItem = item; -- same level but select better potency elseif( consumable.Level == bestLevel and consumable.Potency > bestPotency) then bestLevel = consumable.Level; bestPotency = consumable.Potency; bestSmallStack = item.ItemCount; bestItem = item; -- same/same but select smaller stack elseif( consumable.Level == bestLevel and consumable.Potency == bestPotency and item.ItemCount < bestSmallStack ) then bestLevel = consumable.Level; bestPotency = consumable.Potency; bestSmallStack = item.ItemCount; bestItem = item; end end end end return bestItem; end --== Superseded Functions ==-- -- Obsolete. Kept for backward compatability function CInventory:updateEquipment() if equipment then equipment:update() end end; -- Obsolete. Kept for backward compatability function CInventory:getAmmunitionCount() if equipment then return equipment:getAmmunitionCount() end end; -- Obsolete. Kept for backward compatability function CInventory:isEquipped( __space ) if equipment then return equipment:isEquipped( __space ) end end; -- Obsolete. Kept for backward compatability function CInventory:getDurability( _slot ) if equipment then return equipment:getDurability( _slot ) else return 0 end end; -- Obsolete. Kept for backward compatability function CInventory:getMainHandDurability() -- return values in percent from 0 - 100 if equipment then return equipment:getDurability( 15 ); -- 15=Main Hand end end;