--*********************************************************** --** LEMMY/ROBERT JOHNSON ** --*********************************************************** require "ISUI/ISPanel" require "ISUI/ISButton" require "ISUI/ISMouseDrag" require "TimedActions/ISTimedActionQueue" require "TimedActions/ISEatFoodAction" ISInventoryPane = ISPanel:derive("ISInventoryPane"); ISInventoryPane.MAX_ITEMS_IN_STACK_TO_RENDER = 50 --************************************************************************-- --** ISInventoryPane:initialise --** --************************************************************************-- function ISInventoryPane:initialise() ISPanel.initialise(self); end --************************************************************************-- --** ISPanel:instantiate --** --************************************************************************-- function ISInventoryPane:createChildren() local fontHgtSmall = getTextManager():getFontHeight(UIFont.Small) self.minimumHeight = 50; self.minimumWidth = 256; self.expandAll = ISButton:new(0, 0, 15, 17, "", self, ISInventoryPane.expandAll); self.expandAll:initialise(); self.expandAll.borderColor.a = 0.0; -- self.expandAll.backgroundColorMouseOver.a = 0; self.expandAll:setImage(self.expandicon); self:addChild(self.expandAll); self.column2 = 48; --math.ceil(self.column2*self.zoom); self.column3 = math.ceil(self.column3*self.zoom); self.column3 = self.column3 + 100; local categoryWid = math.max(100,self.column4-self.column3-1) if self.column3 - 1 + categoryWid > self.width then self.column3 = self.width - categoryWid + 1 end self.collapseAll = ISButton:new(15, 0, 15, 17, "", self, ISInventoryPane.collapseAll); self.collapseAll:initialise(); self.collapseAll.borderColor.a = 0.0; -- self.collapseAll.backgroundColorMouseOver.a = 0; self.collapseAll:setImage(self.collapseicon); self:addChild(self.collapseAll); self.filterMenu = ISButton:new(30, 0, 15, 17, "", self, ISInventoryPane.onFilterMenu); self.filterMenu:initialise(); self.filterMenu.borderColor.a = 0.0; -- self.collapseAll.backgroundColorMouseOver.a = 0; self.filterMenu:setImage(self.filtericon); self:addChild(self.filterMenu); self.headerHgt = fontHgtSmall + 1 self.nameHeader = ISResizableButton:new(self.column2, 0, (self.column3 - self.column2), self.headerHgt, getText("IGUI_invpanel_Type"), self, ISInventoryPane.sortByName); self.nameHeader:initialise(); self.nameHeader.borderColor.a = 0.2; self.nameHeader.minimumWidth = 100 self.nameHeader.onresize = { ISInventoryPane.onResizeColumn, self, self.nameHeader } self:addChild(self.nameHeader); self.typeHeader = ISResizableButton:new(self.column3-1, 0, self.column4 - self.column3 + 1, self.headerHgt, getText("IGUI_invpanel_Category"), self, ISInventoryPane.sortByType); self.typeHeader.borderColor.a = 0.2; self.typeHeader.anchorRight = true; self.typeHeader.minimumWidth = 100 self.typeHeader.resizeLeft = true self.typeHeader.onresize = { ISInventoryPane.onResizeColumn, self, self.typeHeader } self.typeHeader:initialise(); self:addChild(self.typeHeader); local btnWid = 10 -- proper width set by setWidthToTitle() later local btnHgt = self.itemHgt self.contextButton1 = ISButton:new(0, 0, btnWid, btnHgt, getText("ContextMenu_Grab"), self, ISInventoryPane.onContext); self.contextButton1:initialise(); self:addChild(self.contextButton1); self.contextButton1:setFont(self.font) self.contextButton1:setVisible(false); self.contextButton1.borderColor.a = 0.3; self.contextButton2 = ISButton:new(0, 0, btnWid, btnHgt, getText("IGUI_invpanel_Pack"), self, ISInventoryPane.onContext); self.contextButton2:initialise(); self:addChild(self.contextButton2); self.contextButton2:setFont(self.font) self.contextButton2:setVisible(false); self.contextButton2.borderColor.a = 0.3; self.contextButton3 = ISButton:new(0, 0, btnWid, btnHgt, getText("IGUI_invpanel_Pack"), self, ISInventoryPane.onContext); self.contextButton3:initialise(); self:addChild(self.contextButton3); self.contextButton3:setFont(self.font) self.contextButton3:setVisible(false); self.contextButton3.borderColor.a = 0.3; self:addScrollBars(); end function ISInventoryPane:onResizeColumn(button) if button == self.nameHeader then self.column3 = self.nameHeader.x + self.nameHeader.width self.typeHeader:setX(self.column3 - 1) self.typeHeader:setWidth(self.width - self.typeHeader.x) end if button == self.typeHeader then self.nameHeader:setWidth(self.typeHeader.x - self.column2 + 1) self.column3 = self.typeHeader.x end end function ISInventoryPane:onResize() ISPanel.onResize(self) if self.typeHeader:getWidth() == self.typeHeader.minimumWidth then self.column3 = self.width - self.typeHeader:getWidth() + 1 self.nameHeader:setWidth(self.column3 - self.column2) self.typeHeader:setX(self.column3 - 1) end self.column4 = self.width end function ISInventoryPane:onContext(button) local playerObj = getSpecificPlayer(self.player) local playerInv = playerObj:getInventory(); local lootInv = getPlayerLoot(self.player).inventory; if button.mode == "unpack" then local k = self.items[self.buttonOption]; local items = ISInventoryPane.getActualItems({k}) ISInventoryPaneContextMenu.onMoveItemsTo(items, playerInv, self.player) end if button.mode == "grab" then local k = self.items[self.buttonOption]; local items = ISInventoryPane.getActualItems({k}) if isForceDropHeavyItem(items[1]) then ISInventoryPaneContextMenu.equipHeavyItem(playerObj, items[1]) return end ISInventoryPaneContextMenu.onGrabItems(items, self.player) end if button.mode == "grab1" then local k = self.items[self.buttonOption]; local items = ISInventoryPane.getActualItems({k}) ISInventoryPaneContextMenu.onGrabOneItems(items, self.player) end if button.mode == "drop" then local k = self.items[self.buttonOption]; local items = ISInventoryPane.getActualItems({k}) ISInventoryPaneContextMenu.onDropItems(items, self.player) end if button.mode == "drop1" then local k = self.items[self.buttonOption]; local items = ISInventoryPane.getActualItems({k}) ISInventoryPaneContextMenu.onDropItems({items[1]}, self.player) end if button.mode == "place" then local k = self.items[self.buttonOption]; local items = ISInventoryPane.getActualItems({k}) local mo = ISMoveableCursor:new(getSpecificPlayer(self.player)) getCell():setDrag(mo, mo.player) mo:setMoveableMode("place") mo:tryInitialItem(items[1]) end getPlayerLoot(self.player).inventoryPane.selected = {}; getPlayerInventory(self.player).inventoryPane.selected = {}; end function ISInventoryPane:collapseAll(button) for k, v in pairs(self.collapsed) do self.collapsed[k] = true; end self:refreshContainer(); end function ISInventoryPane:expandAll(button) for k, v in pairs(self.collapsed) do self.collapsed[k] = false; end self:refreshContainer(); end function ISInventoryPane:onFilterMenu(button) local playerObj = getSpecificPlayer(self.player) local playerInv = playerObj:getInventory() if playerObj:isAsleep() then return end local x = button:getAbsoluteX(); local y = button:getAbsoluteY(); local context = ISContextMenu.get(self.player, x, y); getCell():setDrag(nil, self.player); local weight = context:addOption(getText("IGUI_invpanel_weight"), nil, nil); local subMenuWeight = ISContextMenu:getNew(context); context:addSubMenu(weight, subMenuWeight); subMenuWeight:addOption(getText("IGUI_invpanel_ascending"), self, ISInventoryPane.sortByWeight, true); subMenuWeight:addOption(getText("IGUI_invpanel_descending"), self, ISInventoryPane.sortByWeight, false); end function ISInventoryPane:sortByWeight(_isAscending) if _isAscending and self.itemSortFunc ~= ISInventoryPane.itemSortByWeightAsc then self.itemSortFunc = ISInventoryPane.itemSortByWeightAsc; self:refreshContainer(); end if (not _isAscending) and self.itemSortFunc ~= ISInventoryPane.itemSortByWeightDesc then self.itemSortFunc = ISInventoryPane.itemSortByWeightDesc; self:refreshContainer(); end end ISInventoryPane.itemSortByWeightAsc = function(a,b) if a.equipped and not b.equipped then return false end if b.equipped and not a.equipped then return true end --if a.cat == b.cat then return not string.sort(a.name, b.name) end --return not string.sort(a.cat, b.cat); return a.weight < b.weight; end ISInventoryPane.itemSortByWeightDesc = function(a,b) if a.equipped and not b.equipped then return false end if b.equipped and not a.equipped then return true end --if a.cat == b.cat then return not string.sort(a.name, b.name) end --return string.sort(a.cat, b.cat); return a.weight > b.weight; end ISInventoryPane.itemSortByNameInc = function(a,b) if a.equipped and not b.equipped then return false end if b.equipped and not a.equipped then return true end if a.inHotbar and not b.inHotbar then return true end if b.inHotbar and not a.inHotbar then return false end return not string.sort(a.name, b.name); end ISInventoryPane.itemSortByNameDesc = function(a,b) if a.equipped and not b.equipped then return false end if b.equipped and not a.equipped then return true end if a.inHotbar and not b.inHotbar then return true end if b.inHotbar and not a.inHotbar then return false end return string.sort(a.name, b.name); end ISInventoryPane.itemSortByCatInc = function(a,b) if a.equipped and not b.equipped then return false end if b.equipped and not a.equipped then return true end if a.cat == b.cat then return not string.sort(a.name, b.name) end return not string.sort(a.cat, b.cat); end ISInventoryPane.itemSortByCatDesc = function(a,b) if a.equipped and not b.equipped then return false end if b.equipped and not a.equipped then return true end if a.cat == b.cat then return not string.sort(a.name, b.name) end return string.sort(a.cat, b.cat); end function ISInventoryPane:sortByName(button) if self.itemSortFunc == ISInventoryPane.itemSortByNameInc then self.itemSortFunc = ISInventoryPane.itemSortByNameDesc; else self.itemSortFunc = ISInventoryPane.itemSortByNameInc; end self:refreshContainer(); end function ISInventoryPane:sortByType(button) if self.itemSortFunc == ISInventoryPane.itemSortByCatInc then self.itemSortFunc = ISInventoryPane.itemSortByCatDesc; else self.itemSortFunc = ISInventoryPane.itemSortByCatInc; end self:refreshContainer(); end function ISInventoryPane:SaveLayout(name, layout) layout.column2 = self.nameHeader.width if self.itemSortFunc == self.itemSortByNameInc then layout.sortBy = "nameInc" end if self.itemSortFunc == self.itemSortByNameDesc then layout.sortBy = "nameDesc" end if self.itemSortFunc == self.itemSortByCatInc then layout.sortBy = "catInc" end if self.itemSortFunc == self.itemSortByCatDesc then layout.sortBy = "catDesc" end end function ISInventoryPane:RestoreLayout(name, layout) if layout.column2 and tonumber(layout.column2) then self.nameHeader:setWidth(tonumber(layout.column2)) self:onResizeColumn(self.nameHeader) end if layout.sortBy == "nameInc" then self.itemSortFunc = self.itemSortByNameInc end if layout.sortBy == "nameDesc" then self.itemSortFunc = self.itemSortByNameDesc end if layout.sortBy == "catInc" then self.itemSortFunc = self.itemSortByCatInc end if layout.sortBy == "catDesc" then self.itemSortFunc = self.itemSortByCatDesc end self:refreshContainer() end function ISInventoryPane:rowAt(x, y) local rowCount = math.floor((self:getScrollHeight() - self.headerHgt) / self.itemHgt) if rowCount > 0 then return math.floor((y) / self.itemHgt) + 1 end return -1 end function ISInventoryPane:topOfItem(index) local rowCount = math.floor((self:getScrollHeight() - self.headerHgt) / self.itemHgt) if rowCount > 0 then return (index - 1) * self.itemHgt end return -1 end function ISInventoryPane:onMouseWheel(del) if self.inventoryPage.isCollapsed then return false; end local yScroll = self.smoothScrollTargetY or self:getYScroll() local topRow = self:rowAt(0, -yScroll) if self.items[topRow] then if not self.smoothScrollTargetY then self.smoothScrollY = self:getYScroll() end local y = self:topOfItem(topRow) if del < 0 then if yScroll == -y and topRow > 1 then y = self:topOfItem(topRow - 1) end self.smoothScrollTargetY = -y; else self.smoothScrollTargetY = -(y + self.itemHgt); end else self:setYScroll(self:getYScroll() - (del*9)); end return true; end function ISInventoryPane:selectIndex(index) local listItem = self.items[index] if not listItem then return end self.selected[index] = listItem if not instanceof(listItem, "InventoryItem") and not self.collapsed[listItem.name] then for i=2,#listItem.items do self.selected[index+i-1] = listItem.items[i] if i == ISInventoryPane.MAX_ITEMS_IN_STACK_TO_RENDER + 1 then break end end end end function ISInventoryPane:onMouseMoveOutside(dx, dy) local x = self:getMouseX(); local y = self:getMouseY(); self.buttonOption = 0; self.contextButton1:setVisible(false); self.contextButton2:setVisible(false); self.contextButton3:setVisible(false); self.mouseOverOption = 0 if(self.draggingMarquis) then local x2 = self.draggingMarquisX; local y2 = self.draggingMarquisY; if(self:getMouseY() + self:getYScroll() > self:getHeight()) then self:setYScroll(self:getYScroll() - (9)); end if(self:getMouseY() + self:getYScroll() < 0) then self:setYScroll(self:getYScroll() + (9)); end if (x2 < x) then local xt = x; x = x2; x2 = xt; end if (y2 < y) then local yt = y; y = y2; y2 = yt; end if x > self.column3 then return; end local startY = math.floor((y-self.headerHgt) / self.itemHgt) + 1; local endY = math.floor((((y2)-self.headerHgt) / self.itemHgt)) + 1; if(startY < 1) then startY = 1; end self.selected = {} for i=startY, endY do self:selectIndex(i) end end if self.dragging and not self.dragStarted and (math.abs(x - self.draggingX) > 4 or math.abs(y - self.draggingY) > 4) then self.dragStarted = true end end function ISInventoryPane:hideButtons() self.contextButton1:setVisible(false); self.contextButton2:setVisible(false); self.contextButton3:setVisible(false); end function ISInventoryPane:doButtons(y) self.contextButton1:setVisible(false); self.contextButton2:setVisible(false); self.contextButton3:setVisible(false); if UIManager.getSpeedControls():getCurrentGameSpeed() == 0 or getPlayerContextMenu(self.player):isAnyVisible() or getSpecificPlayer(self.player):isAsleep() then return end if ISMouseDrag.dragging and #ISMouseDrag.dragging > 0 then return end local count = 1; local item = self.items[y] if not instanceof(item, "InventoryItem") then count = item.count-1; item = item.items[1] end local isNoDropMoveable = instanceof(item, "Moveable") and not item:CanBeDroppedOnFloor() local mode1,mode2,mode3 = nil,nil,nil local label1,label2,label3 = nil,nil,nil if self.inventory:isInCharacterInventory(getSpecificPlayer(self.player)) and self.inventory ~= getSpecificPlayer(self.player):getInventory() then -- unpack, drop mode1,label1 = "unpack", getText("IGUI_invpanel_unpack") if isNoDropMoveable then -- No 'Drop' option elseif count == 1 then mode2,label2 = "drop", getText("ContextMenu_Drop") else mode2,label2 = "drop", getText("IGUI_invpanel_drop_all") mode3,label3 = "drop1", getText("IGUI_invpanel_drop_one") end if not instanceof(self.items[y], "InventoryItem") then local fav = true; local firstFav = true; for i,v in ipairs(self.items[y].items) do if i == 1 then firstFav = v:isFavorite() end; if not v:isFavorite() then fav = false; end end if fav then mode2 = nil mode3 = nil elseif count > 1 and firstFav then mode3 = nil end else if self.items[y]:isFavorite() then mode2 = nil mode3 = nil end end elseif self.inventory == getSpecificPlayer(self.player):getInventory() then if isNoDropMoveable then -- No 'Drop' option elseif count == 1 then mode1,label1 = "drop", getText("ContextMenu_Drop") else mode1,label1 = "drop", getText("IGUI_invpanel_drop_all") mode2,label2 = "drop1", getText("IGUI_invpanel_drop_one") end if not instanceof(self.items[y], "InventoryItem") then local fav = true; local firstFav = true; for i,v in ipairs(self.items[y].items) do if i == 1 then firstFav = v:isFavorite() end; if not v:isFavorite() then fav = false; end end if fav then mode1 = nil mode2 = nil elseif count > 1 and firstFav then mode2 = nil end else if self.items[y]:isFavorite() then mode1 = nil mode2 = nil end end if instanceof(item, "Moveable") then if mode1 and mode2 then mode3,label3 = "place", getText("IGUI_Place") elseif mode1 then mode2,label2 = "place", getText("IGUI_Place") else mode1,label1 = "place", getText("IGUI_Place") end end else if count == 1 then mode1,label1 = "grab",getText("ContextMenu_Grab") else mode1,label1 = "grab",getText("ContextMenu_Grab_all") mode2,label2 = "grab1",getText("ContextMenu_Grab_one") end end local ypos = ((y-1)*self.itemHgt) + self.headerHgt; ypos = ypos + self:getYScroll(); if getCore():getGameMode() ~= "Tutorial" then if mode1 then self.contextButton1:setTitle(label1) self.contextButton1.mode = mode1 self.contextButton1:setWidthToTitle() self.contextButton1:setX(self.column3) self.contextButton1:setY(ypos) self.contextButton1:setVisible(true) end if mode2 then self.contextButton2:setTitle(label2) self.contextButton2.mode = mode2 self.contextButton2:setWidthToTitle() self.contextButton2:setX(self.contextButton1:getRight() + 1) self.contextButton2:setY(ypos) self.contextButton2:setVisible(true) end if mode3 then self.contextButton3:setTitle(label3) self.contextButton3.mode = mode3 self.contextButton3:setWidthToTitle() self.contextButton3:setX(self.contextButton2:getRight() + 1) self.contextButton3:setY(ypos) self.contextButton3:setVisible(true) end end self.buttonOption = y; end function ISInventoryPane:toggleStove() local stove = self.inventory:getParent(); stove:Toggle(); return stove:Activated(); end function ISInventoryPane:sortItemsByType(items) table.sort(items, function(a,b) if a:getContainer() and a:getContainer() == b:getContainer() and a:getDisplayName() == b:getDisplayName() then return a:getContainer():getItems():indexOf(a) < b:getContainer():getItems():indexOf(b) end return not string.sort(a:getType(), b:getType()) end) end function ISInventoryPane:sortItemsByWeight(items) table.sort(items, function(a,b) if a:getContainer() and a:getContainer() == b:getContainer() and a:getDisplayName() == b:getDisplayName() then return a:getContainer():getItems():indexOf(a) < b:getContainer():getItems():indexOf(b) end return a:getUnequippedWeight() < b:getUnequippedWeight() end) end function ISInventoryPane:sortItemsByTypeAndWeight(items) local indexMap = {} local containers = {} local allIndexMap = {} for index,item in ipairs(items) do local container = item:getContainer() if container and not containers[container] then containers[container] = true local containerItems = container:getItems() for i=1,containerItems:size() do indexMap[containerItems:get(i-1)] = i end end allIndexMap[item] = index end local itemsByName = {} for _,item in ipairs(items) do local key = item:getDisplayName() itemsByName[key] = itemsByName[key] or {} table.insert(itemsByName[key], item) end local sorted = {} for _,itemList in pairs(itemsByName) do timSort(itemList, function(a,b) if a:getContainer() and (a:getContainer() == b:getContainer()) then return indexMap[a] < indexMap[b] end return allIndexMap[a] < allIndexMap[b] end) table.insert(sorted, itemList) end timSort(sorted, function(a,b) local wa = a[1]:getUnequippedWeight() local wb = b[1]:getUnequippedWeight() if wa < wb then return true end if wa == wb then return allIndexMap[a[1]] < allIndexMap[b[1]] end return false end) table.wipe(items) local count = 1 for _,itemList in ipairs(sorted) do for _,item in ipairs(itemList) do items[count] = item count = count + 1 end end end function ISInventoryPane:transferItemsByWeight(items, container) local playerObj = getSpecificPlayer(self.player) if true then self:sortItemsByTypeAndWeight(items) else self:sortItemsByType(items) self:sortItemsByWeight(items) end for _,item in ipairs(items) do if not container:isItemAllowed(item) then -- elseif container:getType() == "floor" then ISInventoryPaneContextMenu.dropItem(item, self.player) else ISTimedActionQueue.add(ISInventoryTransferAction:new(playerObj, item, item:getContainer(), container)) end end end function ISInventoryPane:removeAll(player) if self.removeAllDialog then self.removeAllDialog:destroy() end local width = 350; local x = getPlayerScreenLeft(player) + (getPlayerScreenWidth(player) - width) / 2 local height = 120; local y = getPlayerScreenTop(player) + (getPlayerScreenHeight(player) - height) / 2 local modal = ISModalDialog:new(x,y, width, height, getText("IGUI_ConfirmDeleteItems"), true, self, ISInventoryPane.onConfirmDelete, player); modal:initialise() self.removeAllDialog = modal modal:addToUIManager() if JoypadState.players[player+1] then modal.prevFocus = JoypadState.players[player+1].focus setJoypadFocus(player, modal) end end function ISInventoryPane:onConfirmDelete(button) if button.internal == "YES" then local object = self.inventory:getParent() local playerObj = getSpecificPlayer(self.player) local args = { x = object:getX(), y = object:getY(), z = object:getZ(), index = object:getObjectIndex() } sendClientCommand(playerObj, 'object', 'emptyTrash', args) end self.removeAllDialog = nil end function ISInventoryPane:lootAll() local playerObj = getSpecificPlayer(self.player) local playerInv = getPlayerInventory(self.player).inventory local items = {} local it = self.inventory:getItems(); local heavyItem = nil if luautils.walkToContainer(self.inventory, self.player) then for i = 0, it:size()-1 do local item = it:get(i); if isForceDropHeavyItem(item) then heavyItem = item else table.insert(items, item) end end if heavyItem and it:size() == 1 then ISInventoryPaneContextMenu.equipHeavyItem(playerObj, heavyItem) return end self:transferItemsByWeight(items, playerInv) end self.selected = {}; getPlayerLoot(self.player).inventoryPane.selected = {}; getPlayerInventory(self.player).inventoryPane.selected = {}; end function ISInventoryPane:transferAll() local playerObj = getSpecificPlayer(self.player) local playerLoot = getPlayerLoot(self.player).inventory local hotBar = getPlayerHotbar(self.player) local it = self.inventory:getItems(); local items = {} if luautils.walkToContainer(self.inventory, self.player) then local toFloor = getPlayerLoot(self.player).inventory:getType() == "floor" for i = 0, it:size()-1 do local item = it:get(i); local ok = not item:isEquipped() and item:getType() ~= "KeyRing" and not hotBar:isInHotbar(item) if item:isFavorite() then ok = false end if toFloor and instanceof(item, "Moveable") and item:getSpriteGrid() == nil and not item:CanBeDroppedOnFloor() then ok = false end if ok then table.insert(items, item) end end self:transferItemsByWeight(items, playerLoot) end self.selected = {}; getPlayerLoot(self.player).inventoryPane.selected = {}; getPlayerInventory(self.player).inventoryPane.selected = {}; end function ISInventoryPane:onMouseMove(dx, dy) if self.player ~= 0 then return end local x = self:getMouseX(); local y = self:getMouseY(); self.contextButton1:setVisible(false); self.contextButton2:setVisible(false); self.contextButton3:setVisible(false); if(self.draggingMarquis) then local x2 = self.draggingMarquisX; local y2 = self.draggingMarquisY; if (x2 < x) then local xt = x; x = x2; x2 = xt; end if (y2 < y) then local yt = y; y = y2; y2 = yt; end if x > self.column3 then return; end local startY = math.floor((y-self.headerHgt) / self.itemHgt) + 1; local endY = math.floor((((y2)-self.headerHgt) / self.itemHgt)) + 1; if(startY < 1) then startY = 1; end self.selected = {} for i=startY, endY do self:selectIndex(i); end else if self.dragging == nil and x >= 0 and y >= 0 and x >= self.column3 and not isShiftKeyDown() then y = y - self.headerHgt; y = y / self.itemHgt; y = math.floor(y + 1); local topOfRow = ((y - 1) * self.itemHgt) + self:getYScroll() + self.headerHgt if self.items[y] and topOfRow >= self.headerHgt then self:doButtons(y); end end if self.dragging == nil and x >= 0 and y >= 0 and x < self.column3 then y = y - self.headerHgt; y = y / self.itemHgt; y = math.floor(y + 1); self.mouseOverOption = y; else self.mouseOverOption = 0; end end if self.dragging and not self.dragStarted and (math.abs(x - self.draggingX) > 4 or math.abs(y - self.draggingY) > 4) then self.dragStarted = true end end function ISInventoryPane:updateTooltip() if not self:isReallyVisible() then return -- in the main menu end local item = nil if self.doController and self.joyselection then if self.joyselection < 0 then self.joyselection = #self.items - 1 end if self.joyselection >= #self.items then self.joyselection = 0 end item = self.items[self.joyselection+1] end if not self.doController and not self.dragging and not self.draggingMarquis and self:isMouseOver() then local x = self:getMouseX() local y = self:getMouseY() if x < self.column3 and y + self:getYScroll() >= self.headerHgt then y = y - self.headerHgt y = y / self.itemHgt self.mouseOverOption = math.floor(y + 1) item = self.items[self.mouseOverOption] end end local weightOfStack = 0.0 if item and not instanceof(item, "InventoryItem") then if #item.items > 2 then weightOfStack = item.weight end item = item.items[1] end if getPlayerContextMenu(self.player):isAnyVisible() then item = nil end if item and self.toolRender and (item == self.toolRender.item) and (weightOfStack == self.toolRender.tooltip:getWeightOfStack()) and self.toolRender:isVisible() then return end if item then if self.toolRender then self.toolRender:setItem(item) self.toolRender:setVisible(true) self.toolRender:addToUIManager() self.toolRender:bringToTop() else self.toolRender = ISToolTipInv:new(item) self.toolRender:initialise() self.toolRender:addToUIManager() self.toolRender:setVisible(true) self.toolRender:setOwner(self) self.toolRender:setCharacter(getSpecificPlayer(self.player)) -- self.toolRender:setX(getPlayerScreenLeft(self.player) + 60) -- self.toolRender:setY(getPlayerScreenTop(self.player) + 60) self.toolRender.anchorBottomLeft = { x = self:getAbsoluteX() + self.column2, y = self:getParent():getAbsoluteY() } end self.toolRender.followMouse = not self.doController self.toolRender.tooltip:setWeightOfStack(weightOfStack) if not self.doController then -- self.toolRender:setX(getMouseX()) -- self.toolRender:setY(getMouseY()) end elseif self.toolRender then self.toolRender:removeFromUIManager() self.toolRender:setVisible(false) -- self.toolRender = nil end -- Hack for highlighting doors when a Key tooltip is displayed. if self.parent.onCharacter then if not self.toolRender or not self.toolRender:getIsVisible() then item = nil end Key.setHighlightDoors(self.player, item) end local inventoryPage = getPlayerInventory(self.player) local inventoryTooltip = inventoryPage and inventoryPage.inventoryPane.toolRender local lootPage = getPlayerLoot(self.player) local lootTooltip = lootPage and lootPage.inventoryPane.toolRender UIManager.setPlayerInventoryTooltip(self.player, inventoryTooltip and inventoryTooltip.javaObject or nil, lootTooltip and lootTooltip.javaObject or nil) end --************************************************************************-- --** ISInventoryPane:onMouseUpOutside --** --************************************************************************-- function ISInventoryPane:onMouseDownOutside(x, y) self.dragging = nil; self.draggedItems:reset() if self:isMouseOverScrollBar() then self.clickedScrollBar = true; else self.clickedScrollBar = false; self.selected = {}; end end function ISInventoryPane:onMouseUpOutside(x, y) self.previousMouseUp = self.mouseOverOption; if self.draggingMarquis then self:onMouseUp(x, y); elseif not self.clickedScrollBar then self.selected = {}; end; self.draggingMarquis = false; self.clickedScrollBar = false; end function ISInventoryPane.getActualItems(items) local ret = {} local contains = {} for _,item in ipairs(items) do if instanceof(item, "InventoryItem") then if not contains[item] then -- The top-level group and its children might both be selected. table.insert(ret, item) contains[item] = true end else -- The first item is a dummy duplicate, skip it. for i=2,#item.items do local item2 = item.items[i] if not contains[item2] then table.insert(ret, item2) contains[item2] = true end end end end return ret end function ISInventoryPane:doContextualDblClick(item) local playerObj = getSpecificPlayer(self.player); if instanceof(item, "HandWeapon") then if playerObj:isHandItem(item) then ISInventoryPaneContextMenu.unequipItem(item, self.player); elseif item:getCondition() > 0 then ISInventoryPaneContextMenu.equipWeapon(item, true, item:isTwoHandWeapon(), self.player); end end if instanceof(item, "Clothing") then if playerObj:isEquipped(item) then ISInventoryPaneContextMenu.onUnEquip({item}, self.player); else ISInventoryPaneContextMenu.onWearItems({item}, self.player); end end if instanceof(item, "InventoryContainer") and item:canBeEquipped() ~= nil and item:canBeEquipped() ~= "" then if playerObj:isEquipped(item) then ISInventoryPaneContextMenu.onUnEquip({item}, self.player); else ISInventoryPaneContextMenu.onWearItems({item}, self.player); end elseif instanceof (item, "InventoryContainer") and item:getItemReplacementSecondHand() ~= nil then if playerObj:isEquipped(item) then ISInventoryPaneContextMenu.onUnEquip({item}, self.player); else ISInventoryPaneContextMenu.equipWeapon(item, false, false, self.player); end end if instanceof(item, "Food") and item:getHungChange() < 0 and not item:getScriptItem():isCantEat() then if playerObj:getMoodles():getMoodleLevel(MoodleType.FoodEaten) < 3 or playerObj:getNutrition():getCalories() < 1000 then ISInventoryPaneContextMenu.onEatItems({item}, 1, self.player); end end end function ISInventoryPane:onMouseDoubleClick(x, y) if self.items and self.mouseOverOption and self.previousMouseUp == self.mouseOverOption then if getCore():getGameMode() == "Tutorial" then if TutorialData.chosenTutorial.doubleClickInventory(self, x, y, self.mouseOverOption) then return end end local playerObj = getSpecificPlayer(self.player) local playerInv = getPlayerInventory(self.player).inventory; local lootInv = getPlayerLoot(self.player).inventory; local item = self.items[self.mouseOverOption]; local doWalk = true local shiftHeld = isShiftKeyDown() if item and not instanceof(item, "InventoryItem") then -- expand or collapse... if x < self.column2 then self.collapsed[item.name] = not self.collapsed[item.name]; self:refreshContainer(); return; end if item.items then for k, v in ipairs(item.items) do if k ~= 1 and v:getContainer() ~= playerInv then if isForceDropHeavyItem(v) then ISInventoryPaneContextMenu.equipHeavyItem(playerObj, v) break end if doWalk then if not luautils.walkToContainer(v:getContainer(), self.player) then break end doWalk = false end ISTimedActionQueue.add(ISInventoryTransferAction:new(playerObj, v, v:getContainer(), playerInv)) if instanceof(v, "Clothing") and shiftHeld then ISTimedActionQueue.add(ISWearClothing:new(playerObj, v, 50)) end elseif k ~= 1 and v:getContainer() == playerInv then local tItem = v; self:doContextualDblClick(tItem); break end end end elseif item and item:getContainer() ~= playerInv then if isForceDropHeavyItem(item) then ISInventoryPaneContextMenu.equipHeavyItem(playerObj, item) elseif luautils.walkToContainer(item:getContainer(), self.player) then ISTimedActionQueue.add(ISInventoryTransferAction:new(playerObj, item, item:getContainer(), playerInv)) end elseif item and item:getContainer() == playerInv then -- double click do some basic action, equip weapon/wear clothing... self:doContextualDblClick(item); end self.previousMouseUp = nil; end end function ISInventoryPane:onMouseUp(x, y) if self.player ~= 0 then return end local playerObj = getSpecificPlayer(self.player) self.previousMouseUp = self.mouseOverOption; if (not isShiftKeyDown()and not isCtrlKeyDown() and x >= self.column2 and x == self.downX and y == self.downY) and self.mouseOverOption ~= 0 and self.items[self.mouseOverOption] ~= nil then self.selected = {}; self:selectIndex(self.mouseOverOption); end if ISMouseDrag.dragging ~= nil and ISMouseDrag.draggingFocus ~= self and ISMouseDrag.draggingFocus ~= nil then if getCore():getGameMode() ~= "Tutorial" then if self:canPutIn() then local doWalk = true local items = {} local dragging = ISInventoryPane.getActualItems(ISMouseDrag.dragging) for i,v in ipairs(dragging) do local transfer = v:getContainer() and not self.inventory:isInside(v) if v:isFavorite() and not self.inventory:isInCharacterInventory(playerObj) then transfer = false end if transfer then -- only walk for the first item if doWalk then if not luautils.walkToContainer(self.inventory, self.player) then break end doWalk = false end table.insert(items, v) end end self:transferItemsByWeight(items, self.inventory) self.selected = {}; getPlayerLoot(self.player).inventoryPane.selected = {}; getPlayerInventory(self.player).inventoryPane.selected = {}; end end if ISMouseDrag.draggingFocus then ISMouseDrag.draggingFocus:onMouseUp(0,0); end ISMouseDrag.draggingFocus = nil; ISMouseDrag.dragging = nil; return; end self.dragging = nil; self.draggedItems:reset(); ISMouseDrag.dragging = nil; ISMouseDrag.draggingFocus = nil; if x >= 0 and y >= 0 and x < self.column3 then y = y - self.headerHgt; y = y / self.itemHgt; y = math.floor(y + 1); self.mouseOverOption = y; end self.draggingMarquis = false; return true; end function ISInventoryPane:canPutIn() local playerObj = getSpecificPlayer(self.player) if self.inventory == nil then return false; end if self.inventory:getType() == "floor" then return true; end if self.inventory:getParent() == playerObj then return true; end local items = {} -- If the lightest item fits, allow the transfer. local minWeight = 100000 local dragging = ISInventoryPane.getActualItems(ISMouseDrag.dragging) for i,v in ipairs(dragging) do local itemOK = true if v:isFavorite() and not self.inventory:isInCharacterInventory(playerObj) then itemOK = false end -- you can't draw the container in himself if (self.inventory:isInside(v)) then itemOK = false; end if self.inventory:getType() == "floor" and v:getWorldItem() then itemOK = false end if v:getContainer() == self.inventory then itemOK = false end local inv = self.inventory; -- if self.mouseOverButton and self.mouseOverButton.inventory then -- inv = self.mouseOverButton.inventory; -- end if not inv:isItemAllowed(v) then itemOK = false; end if itemOK then table.insert(items, v) end if v:getUnequippedWeight() < minWeight then minWeight = v:getUnequippedWeight() end end if #items == 1 then return self.inventory:hasRoomFor(playerObj, items[1]) end return self.inventory:hasRoomFor(playerObj, minWeight) end ----- ISInventoryPaneDraggedItems = {} local DraggedItems = ISInventoryPaneDraggedItems function DraggedItems:getDropContainer() local playerInv = getPlayerInventory(self.playerNum) local playerLoot = getPlayerLoot(self.playerNum) if not playerInv or not playerLoot then return nil end if playerInv.mouseOverButton then return playerInv.mouseOverButton.inventory, "button" end if playerInv.inventoryPane:isMouseOver() then return playerInv.inventoryPane.inventory, "inventory" end if playerLoot.mouseOverButton then return playerLoot.mouseOverButton.inventory, "button" end if playerLoot.inventoryPane:isMouseOver() then return playerLoot.inventoryPane.inventory, "loot" end local mx = getMouseX() local my = getMouseY() local uis = UIManager.getUI() local mouseOverUI = nil for i=0,uis:size()-1 do local ui = uis:get(i) if ui:isPointOver(mx, my) then mouseOverUI = ui break end end if not mouseOverUI then return ISInventoryPage.GetFloorContainer(self.playerNum), "floor" end return nil end function DraggedItems:update() self.playerNum = self.inventoryPane.player local playerObj = getSpecificPlayer(self.playerNum) if not self.items then self.items = ISInventoryPane.getActualItems(ISMouseDrag.dragging) self.inventoryPane:sortItemsByTypeAndWeight(self.items) end -- Try to detect changes to the destination container. if self.mouseOverContainer and (self.mouseOverItemCount ~= self.mouseOverContainer:getItems():size()) then self.mouseOverContainer = nil end local container, what = self:getDropContainer() if (container == self.mouseOverContainer) and (what == self.mouseOverWhat) then return end self.mouseOverContainer = container self.mouseOverWhat = what self.mouseOverItemCount = container and container:getItems():size() or 0 table.wipe(self.itemNotOK) if #self.items == 0 then return end if not container then return end local containerInInventory = container:isInCharacterInventory(playerObj) -- Items may always be dragged to the floor (except favorited items). if container:getType() == "floor" then for _,item in ipairs(self.items) do if item:isFavorite() and not containerInInventory then self.itemNotOK[item] = true end if what ~= "loot" and item:getWorldItem() then self.itemNotOK[item] = true end end return end -- Dragging from ourself to ourself does nothing, but don't show as prevented. if what ~= "button" and container == self.inventoryPane.inventory then return end local totalWeight = 0 local overWeight = false local validItems = {} for _,item in ipairs(self.items) do local itemOK = true if container:isInside(item) then itemOK = false end if item:isFavorite() and not containerInInventory then itemOK = false end if item:getContainer() == container then itemOK = false end if not container:isItemAllowed(item) then itemOK = false end -- Items are sorted by weight (see above) if itemOK then totalWeight = totalWeight + item:getUnequippedWeight() end if overWeight then itemOK = false else if not container:hasRoomFor(playerObj, totalWeight) then itemOK = false overWeight = true end end if itemOK then table.insert(validItems, item) else self.itemNotOK[item] = true end end -- Hack: Allow any single item on a vehicle seat regardless of weight (ex, Generator) if #validItems == 1 then local item = validItems[1] self.itemNotOK[item] = not container:hasRoomFor(playerObj, item) end end function DraggedItems:cannotDropItem(item) if not item then return false end return self.itemNotOK[item] == true end function DraggedItems:reset() self.mouseOverContainer = nil self.mouseOverWhat = nil self.items = nil table.wipe(self.itemNotOK) end function DraggedItems:new(inventoryPane) local o = {} setmetatable(o, self) self.__index = self o.inventoryPane = inventoryPane o.mouseOverContainer = nil o.mouseOverWhat = nil o.items = nil o.itemNotOK = {} return o end ----- function ISInventoryPane:doJoypadExpandCollapse() if not self.joyselection then return end if not self.items or not self.items[self.joyselection+1] then return end if not instanceof(self.items[self.joyselection+1], "InventoryItem") then self.collapsed[self.items[self.joyselection+1].name] = not self.collapsed[self.items[self.joyselection+1].name] self:refreshContainer() end end function ISInventoryPane:doGrabOnJoypadSelected() if self.joyselection == nil then return end if not self.doController then return end local playerObj = getSpecificPlayer(self.player) if playerObj:isAsleep() then return end if #self.items == 0 then return end self.selected = {}; self:selectIndex(self.joyselection+1); local items = {} for k, v in ipairs(self.items) do if self.selected[k] ~= nil then if instanceof(v, "InventoryItem") then if not self.parent.onCharacter and isForceDropHeavyItem(v) then ISInventoryPaneContextMenu.equipHeavyItem(playerObj, v) return end table.insert(items, v); elseif self.collapsed[v.name] then if not self.parent.onCharacter and isForceDropHeavyItem(v.items[1]) then ISInventoryPaneContextMenu.equipHeavyItem(playerObj, v.items[1]) return end table.insert(items, v); end end end if self.parent.onCharacter then ISInventoryPaneContextMenu.onPutItems(items, self.player); else ISInventoryPaneContextMenu.onGrabItems(items, self.player); end end function ISInventoryPane:doContextOnJoypadSelected() if JoypadState.disableInvInteraction then return; end if UIManager.getSpeedControls() and UIManager.getSpeedControls():getCurrentGameSpeed() == 0 then return; end local playerObj = getSpecificPlayer(self.player) if playerObj:isAsleep() then return end local isInInv = self.inventory:isInCharacterInventory(playerObj) if #self.items == 0 then local menu = ISInventoryPaneContextMenu.createMenuNoItems(self.player, not isInInv, self:getAbsoluteX()+64, self:getAbsoluteY()+64) if menu then menu.origin = self.inventoryPage menu.mouseOver = 1 setJoypadFocus(self.player, menu) end return end if self.joyselection == nil then return end if not self.doController then return end self:selectIndex(self.joyselection+1); local item = self.items[self.joyselection+1]; local contextMenuItems = {} for k, v in ipairs(self.items) do if self.selected[k] ~= nil then if instanceof(v, "InventoryItem") or self.collapsed[v.name] then table.insert(contextMenuItems, v); end end end local menu = nil; if getCore():getGameMode() == "Tutorial" then menu = Tutorial1.createInventoryContextMenu(self.player, isInInv, contextMenuItems, self:getAbsoluteX()+64, self:getAbsoluteY()+8+(self.joyselection*self.itemHgt)+self:getYScroll()); else menu = ISInventoryPaneContextMenu.createMenu(self.player, isInInv, contextMenuItems, self:getAbsoluteX()+64, self:getAbsoluteY()+8+(self.joyselection*self.itemHgt)+self:getYScroll()); end menu.origin = self.inventoryPage; menu.mouseOver = 1; if menu.numOptions > 1 then setJoypadFocus(self.player, menu) end end function ISInventoryPane:onRightMouseUp(x, y) if self.player ~= 0 then return end local isInInv = self.inventory:isInCharacterInventory(getSpecificPlayer(self.player)) if #self.items == 0 then local menu = ISInventoryPaneContextMenu.createMenuNoItems(self.player, not isInInv, self:getAbsoluteX()+x, self:getAbsoluteY()+y+self:getYScroll()) if menu and menu.numOptions > 1 and JoypadState.players[self.player+1] then menu.origin = self.inventoryPage menu.mouseOver = 1 setJoypadFocus(self.player, menu) end return end if self.selected == nil then self.selected = {} end if self.mouseOverOption ~= 0 and self.items[self.mouseOverOption] ~= nil and self.selected[self.mouseOverOption] == nil then self.selected = {}; self:selectIndex(self.mouseOverOption); end local contextMenuItems = {} for k, v in ipairs(self.items) do if self.selected[k] ~= nil then if instanceof(v, "InventoryItem") or self.collapsed[v.name] then table.insert(contextMenuItems, v); end end end if self.toolRender then self.toolRender:setVisible(false) end local menu = ISInventoryPaneContextMenu.createMenu(self.player, isInInv, contextMenuItems, self:getAbsoluteX()+x, self:getAbsoluteY()+y+self:getYScroll()); if menu and menu.numOptions > 1 and JoypadState.players[self.player+1] then menu.origin = self.inventoryPage menu.mouseOver = 1 setJoypadFocus(self.player, menu) end return true; end function ISInventoryPane:onMouseDown(x, y) if self.player ~= 0 then return true end getSpecificPlayer(self.player):nullifyAiming(); local count = 0; self.downX = x; self.downY = y; if self.selected == nil then self.selected = {} end if self.mouseOverOption ~= 0 and self.items[self.mouseOverOption] ~= nil then -- expand or collapse... if x < self.column2 then if not instanceof(self.items[self.mouseOverOption], "InventoryItem") then self.collapsed[self.items[self.mouseOverOption].name] = not self.collapsed[self.items[self.mouseOverOption].name]; self:refreshContainer(); self.selected = {}; return; end end if not isShiftKeyDown() and not isCtrlKeyDown() and self.selected[self.mouseOverOption] == nil then self.selected = {}; self.firstSelect = nil; end if not isShiftKeyDown() then self.firstSelect = self.mouseOverOption; if isCtrlKeyDown() then if self.selected[self.mouseOverOption] then self.selected[self.mouseOverOption] = nil; else self.selected[self.mouseOverOption] = self.items[self.mouseOverOption]; end else self.selected[self.mouseOverOption] = self.items[self.mouseOverOption]; end end if isShiftKeyDown() then if self.firstSelect then self.selected = {}; if self.firstSelect < self.mouseOverOption then for i=self.firstSelect, self.mouseOverOption do self.selected[i] = self.items[i]; end else for i=self.mouseOverOption, self.firstSelect do self.selected[i] = self.items[i]; end end else self.firstSelect = self.mouseOverOption; self.selected[self.mouseOverOption] = self.items[self.mouseOverOption]; end end local listItem = self.items[self.mouseOverOption]; if listItem and self.selected[self.mouseOverOption] and not instanceof(listItem, "InventoryItem") and not self.collapsed[listItem.name] then for i=2,#listItem.items do self.selected[self.mouseOverOption+i-1] = listItem.items[i]; if i == ISInventoryPane.MAX_ITEMS_IN_STACK_TO_RENDER + 1 then break end end end self.dragging = self.mouseOverOption; self.draggingX = x; self.draggingY = y; self.dragStarted = false --print ("Dragging "..self.selected); ISMouseDrag.dragging = {} ----print(self.selected[self.mouseOverOption]); for i,v in ipairs(self.items) do if self.selected[count+1] ~= nil then table.insert(ISMouseDrag.dragging, v); end count = count + 1; end ISMouseDrag.draggingFocus = self; return; end if not isShiftKeyDown() and not isCtrlKeyDown() then self.selected = {}; self.firstSelect = nil; end if self.dragging == nil and x >= 0 and y >= 0 and (x<=self.column3 and y <= self:getScrollHeight() - self.itemHgt) then elseif count == 0 then self.draggingMarquis = true; self.draggingMarquisX = x; self.draggingMarquisY = y; self.dragging = nil; self.draggedItems:reset() ISMouseDrag.dragging = nil; ISMouseDrag.draggingFocus = nil; end if x < self.column2 and y < self.headerHgt then return false; end return true; end function ISInventoryPane:updateSmoothScrolling() if not self.smoothScrollTargetY or #self.items == 0 then return end local dy = self.smoothScrollTargetY - self.smoothScrollY local maxYScroll = self:getScrollHeight() - self:getHeight() local frameRateFrac = UIManager.getMillisSinceLastRender() / 33.3 local itemHeightFrac = 160 / (self:getScrollHeight() / #self.items) local targetY = self.smoothScrollY + dy * math.min(0.5, 0.25 * frameRateFrac * itemHeightFrac) if frameRateFrac > 1 then targetY = self.smoothScrollY + dy * math.min(1.0, math.min(0.5, 0.25 * frameRateFrac * itemHeightFrac) * frameRateFrac) end if targetY > 0 then targetY = 0 end if targetY < -maxYScroll then targetY = -maxYScroll end if math.abs(targetY - self.smoothScrollY) > 0.1 then self:setYScroll(targetY) self.smoothScrollY = targetY else self:setYScroll(self.smoothScrollTargetY) self.smoothScrollTargetY = nil self.smoothScrollY = nil end end function ISInventoryPane:isMouseOverScrollBar() return self:isVScrollBarVisible() and self.vscroll:isMouseOver() end --************************************************************************-- --** ISInventoryPane:prerender --** --************************************************************************-- function ISInventoryPane:prerender() local mouseY = self:getMouseY() self:updateSmoothScrolling() if mouseY ~= self:getMouseY() and self:isMouseOver() then self:onMouseMove(0, self:getMouseY() - mouseY) end self.nameHeader.maximumWidth = self.width - self.typeHeader.minimumWidth - self.column2 self.typeHeader.maximumWidth = self.width - self.nameHeader.minimumWidth - self.column2 + 1 --self:drawRectStatic(0, 0, self.width, self.height, self.backgroundColor.a, self.backgroundColor.r, self.backgroundColor.g, self.backgroundColor.b); -- self:drawRectStatic(0, 0, self.width, 1, self.borderColor.a, self.borderColor.r, self.borderColor.g, self.borderColor.b); -- self:drawRectStatic(0, self.height-1, self.width, 1, self.borderColor.a, self.borderColor.r, self.borderColor.g, self.borderColor.b); -- self:drawRectStatic(0, 0, 1, self.height, self.borderColor.a, self.borderColor.r, self.borderColor.g, self.borderColor.b); -- self:drawRectStatic(0+self.width-1, 0, 1, self.height, self.borderColor.a, self.borderColor.r, self.borderColor.g, self.borderColor.b); self:setStencilRect(0,0,self.width-1, self.height-1); if self.mode == "icons" then self:rendericons(); elseif self.mode == "details" then self:renderdetails(false); end self:updateScrollbars(); end function ISInventoryPane:rendericons() local xpad = 10; local ypad = 10; local iw = 40; local ih = 40; local xmax = math.floor((self.width - (xpad * 2)) / iw); local ymax = math.floor((self.height - (ypad * 2)) / ih); local xcount = 0; local ycount = 0; local it = self.inventory:getItems(); for i = 0, it:size()-1 do local item = it:get(i); self:drawTexture(item:getTex(), (xcount * iw) + xpad + 4, (ycount * ih) + ypad + 4, 1, 1, 1, 1); xcount = xcount + 1; if xcount >= xmax then xcount= 0; ycount = ycount + 1; end end end local function isSelectAllPossible(page) if not page then return false end if not page:isVisible() then return false end if page.isCollapsed then return false end if not page:isMouseOver() then return false end for _,v in pairs(page.inventoryPane.selected) do return true end return false end function ISInventoryPane:update() local playerObj = getSpecificPlayer(self.player) if self.doController then --print("do controller!") if (self.player ~= 0) or (wasMouseActiveMoreRecentlyThanJoypad() == false) then table.wipe(self.selected) end if self.joyselection == nil then self.joyselection = 0; end end self:updateTooltip() local remove = nil for i,v in pairs(self.selected) do if instanceof(v, "InventoryItem") then if v:getContainer() ~= self.inventory then if remove == nil then remove = {} end remove[i] = i; end end end if remove ~= nil then for i,v in pairs(remove) do self.selected[v] = nil; end end -- Make it select the header if all sub items in expanded item are selected. for i,v in ipairs(self.items) do if not instanceof(v, "InventoryItem") and self.selected[i] == nil and not self.collapsed[v.name] then local anyNot = false; for j=2,#v.items do if self.selected[i+j-1] == nil then anyNot = true; break; end end if not anyNot then self.selected[i] = v; end end end -- If the user was dragging items from this pane and the mouse wasn't released over a valid drop location, -- then we must clear the drag info. Additionally, if the mouse was released outside any UIElement, then -- we will drop the items onto the floor (unless this pane is displaying the floor container). -- NOTE: This only works because update() is called after all the mouse-event handling, so other UIElements -- have already had a chance to accept the drag. if ISMouseDrag.dragging ~= nil and ISMouseDrag.draggingFocus == self and not isMouseButtonDown(0) then if getCore():getGameMode() == "Tutorial" then if ISMouseDrag.draggingFocus then ISMouseDrag.draggingFocus:onMouseUp(0,0); end ISMouseDrag.draggingFocus = nil; ISMouseDrag.dragging = nil; return; end local dragContainsMovables = false; local dragContainsNonMovables = false; local mx = getMouseX() local my = getMouseY() local uis = UIManager.getUI() local mouseOverUI for i=0,uis:size()-1 do local ui = uis:get(i) if ui:isPointOver(mx, my) then mouseOverUI = ui break end end local noVehicle = true local vehicleNoWindow = true local vehicleWindowDestroyed = true local vehicleWindowOpen = true local vehicle = playerObj:getVehicle() if vehicle ~= nil then noVehicle = false local seat = vehicle:getSeat(playerObj) local door = vehicle:getPassengerDoor(seat) local windowPart = VehicleUtils.getChildWindow(door) if windowPart and (not windowPart:getItemType() or windowPart:getInventoryItem()) then vehicleNoWindow = false local window = windowPart:getWindow() if window:isOpenable() and not window:isOpen() then vehicleWindowOpen = false end end end if self.inventory:getType() ~= "floor" and not mouseOverUI and (noVehicle or vehicleNoWindow or vehicleWindowOpen) then local dragging = ISInventoryPane.getActualItems(ISMouseDrag.dragging) local dropit = false; -- for i,v in ipairs(dragging) do -- if not self.inventory:isInside(v) and not v:isFavorite() then -- if not instanceof(v, "Moveable") or v:CanBeDroppedOnFloor() then -- if self.inventoryPage.selectedSqDrop and self.inventoryPage.render3DItems and #self.inventoryPage.render3DItems > 0 then -- ISWorldObjectContextMenu.transferIfNeeded(playerObj, v) -- end -- end -- end -- end -- if self.inventoryPage.selectedSqDrop and luautils.walkAdj(playerObj, self.inventoryPage.selectedSqDrop, true) then -- if self.inventoryPage.selectedSqDrop then -- dropit = true; -- end for i,v in ipairs(dragging) do if not self.inventory:isInside(v) and not v:isFavorite() then if not instanceof(v, "Moveable") or v:CanBeDroppedOnFloor() then -- if self.inventoryPage.selectedSqDrop and self.inventoryPage.render3DItems and #self.inventoryPage.render3DItems > 0 then -- if dropit then -- if playerObj:isEquipped(v) then -- ISTimedActionQueue.add(ISUnequipAction:new(playerObj, v, 1)); -- end -- ISTimedActionQueue.add(ISDropWorldItemAction:new (playerObj, v, self.inventoryPage.selectedSqDrop, self.inventoryPage.render3DItemXOffset, self.inventoryPage.render3DItemYOffset, self.inventoryPage.render3DItemZOffset, self.inventoryPage.render3DItemRot)); -- end -- else ISInventoryPaneContextMenu.dropItem(v, self.player) -- end dragContainsNonMovables = true else dragContainsMovables = dragContainsMovables or v end end end self.selected = {} getPlayerLoot(self.player).inventoryPane.selected = {} getPlayerInventory(self.player).inventoryPane.selected = {} end self.inventoryPage.selectedSqDrop = nil; self.inventoryPage.render3DItems = {}; self.dragging = nil self.draggedItems:reset() ISMouseDrag.dragging = nil ISMouseDrag.draggingFocus = nil if dragContainsMovables and not dragContainsNonMovables then local mo = ISMoveableCursor:new(getSpecificPlayer(self.player)); getCell():setDrag(mo, mo.player); mo:setMoveableMode("place"); mo:tryInitialItem(dragContainsMovables); end end -- If the user was draggingMarquis from this pane and the mouse wasn't released over a valid location, -- then we must clear the drag info. if self.draggingMarquis and not isMouseButtonDown(0) then self.draggingMarquis = false; end; if self.doController then return end local page1 = getPlayerInventory(0) local page2 = getPlayerLoot(0) if not page1 or not page2 then return end if isCtrlKeyDown() and (isSelectAllPossible(page1) or isSelectAllPossible(page2)) then getCore():setIsSelectingAll(true) else getCore():setIsSelectingAll(false) end if isCtrlKeyDown() and isKeyDown(Keyboard.KEY_A) and isSelectAllPossible(self.parent) then table.wipe(self.selected) for k,v in ipairs(self.items) do self.selected[k] = v end end end function ISInventoryPane:saveSelection(selected) for _,v in pairs(self.selected) do if instanceof(v, "InventoryItem") then selected[v] = selected[v] or "item" else selected[v.items[1]] = "group" end end -- Hack for the selection being cleared while dragging items. if ISMouseDrag.dragging and (ISMouseDrag.draggingFocus == self) then for _,v in ipairs(ISMouseDrag.dragging) do if instanceof(v, "InventoryItem") then selected[v] = selected[v] or "item" else selected[v.items[1]] = "group" end end end return selected end function ISInventoryPane:restoreSelection(selected) local row = 1 for _,v in ipairs(self.itemslist) do local item = v.items[1] if selected[item] == "group" then self.selected[row] = item end row = row + 1 if not self.collapsed[v.name] then for j=2,#v.items do local item2 = v.items[j] if selected[item2] then self.selected[row] = item2 end row = row + 1 end end end end function ISInventoryPane:refreshContainer() self.itemslist = {} self.itemindex = {} if self.collapsed == nil then self.collapsed = {} end if self.selected == nil then self.selected = {} end local selected = self:saveSelection({}) table.wipe(self.selected) local playerObj = getSpecificPlayer(self.player) if not self.hotbar then self.hotbar = getPlayerHotbar(self.player); end local isEquipped = {} local isInHotbar = {} if self.parent.onCharacter then local wornItems = playerObj:getWornItems() for i=1,wornItems:size() do local wornItem = wornItems:get(i-1) isEquipped[wornItem:getItem()] = true end local item = playerObj:getPrimaryHandItem() if item then isEquipped[item] = true end item = playerObj:getSecondaryHandItem() if item then isEquipped[item] = true end if self.hotbar and self.hotbar.attachedItems then for _,item in pairs(self.hotbar.attachedItems) do isInHotbar[item] = true end end end local it = self.inventory:getItems(); for i = 0, it:size()-1 do local item = it:get(i); local add = true; -- don't add the ZedDmg category, they are just equipped models if item:isHidden() then add = false; end if add then local itemName = item:getName(); if item:IsFood() and item:getHerbalistType() and item:getHerbalistType() ~= "" then if playerObj:isRecipeKnown("Herbalist") then if item:getHerbalistType() == "Berry" then itemName = (item:getPoisonPower() > 0) and getText("IGUI_PoisonousBerry") or getText("IGUI_Berry") end if item:getHerbalistType() == "Mushroom" then itemName = (item:getPoisonPower() > 0) and getText("IGUI_PoisonousMushroom") or getText("IGUI_Mushroom") end else if item:getHerbalistType() == "Berry" then itemName = getText("IGUI_UnknownBerry") end if item:getHerbalistType() == "Mushroom" then itemName = getText("IGUI_UnknownMushroom") end end if itemName ~= item:getDisplayName() then item:setName(itemName); end itemName = item:getName() end local equipped = false local inHotbar = false if self.parent.onCharacter then if isEquipped[item] then itemName = "equipped:"..itemName equipped = true elseif item:getType() == "KeyRing" and playerObj:getInventory():contains(item) then itemName = "keyring:"..itemName equipped = true end if self.hotbar then inHotbar = isInHotbar[item]; if inHotbar and not equipped then itemName = "hotbar:"..itemName end end end if self.itemindex[itemName] == nil then self.itemindex[itemName] = {}; self.itemindex[itemName].items = {} self.itemindex[itemName].count = 0 end local ind = self.itemindex[itemName]; ind.equipped = equipped ind.inHotbar = inHotbar; ind.count = ind.count + 1 ind.items[ind.count] = item; end end for k, v in pairs(self.itemindex) do if v ~= nil then table.insert(self.itemslist, v); local count = 1; local weight = 0; for k2, v2 in ipairs(v.items) do if v2 == nil then table.remove(v.items, k2); else count = count + 1; weight = weight + v2:getUnequippedWeight(); end end v.count = count; v.invPanel = self; v.name = k -- v.items[1]:getName(); v.cat = v.items[1]:getDisplayCategory() or v.items[1]:getCategory(); v.weight = weight; if self.collapsed[v.name] == nil then self.collapsed[v.name] = true; end end end --print("Preparing to sort inv items"); table.sort(self.itemslist, self.itemSortFunc ); -- Adding the first item in list additionally at front as a dummy at the start, to be used in the details view as a header. for k, v in ipairs(self.itemslist) do local item = v.items[1]; table.insert(v.items, 1, item); end self:restoreSelection(selected); table.wipe(selected); self:updateScrollbars(); self.inventory:setDrawDirty(false); -- Update the buttons if self:isMouseOver() then self:onMouseMove(0, 0) end end ISInventoryPane.highlightItem = nil; function ISInventoryPane:renderdetails(doDragged) self:updateScrollbars(); if doDragged == false then table.wipe(self.items) if self.inventory:isDrawDirty() then self:refreshContainer() end end local player = getSpecificPlayer(self.player) local checkDraggedItems = false if doDragged and self.dragging ~= nil and self.dragStarted then self.draggedItems:update() checkDraggedItems = true end if not doDragged then -- background of item icon self:drawRectStatic(0, 0, self.column2, self.height, 0.6, 0, 0, 0); end local y = 0; local alt = false; if self.itemslist == nil then self:refreshContainer(); end local MOUSEX = self:getMouseX() local MOUSEY = self:getMouseY() local YSCROLL = self:getYScroll() local HEIGHT = self:getHeight() local equippedLine = false local all3D = true; -- self.inventoryPage.render3DItems = {}; -- Go through all the stacks of items. for k, v in ipairs(self.itemslist) do local count = 1; -- Go through each item in stack.. for k2, v2 in ipairs(v.items) do -- print("trace:a"); local item = v2; local doIt = true; local xoff = 0; local yoff = 0; if doDragged == false then -- if it's the first item, then store the category, otherwise the item if count == 1 then table.insert(self.items, v); else table.insert(self.items, item); end if instanceof(item, 'InventoryItem') then item:updateAge() end if instanceof(item, 'Clothing') then item:updateWetness() end end -- print("trace:b"); local isDragging = false if self.dragging ~= nil and self.selected[y+1] ~= nil and self.dragStarted then xoff = MOUSEX - self.draggingX; yoff = MOUSEY - self.draggingY; if not doDragged then doIt = false; else self:suspendStencil(); isDragging = true -- if dragging and item with a 3D model outside of inventory, ready to render it -- if not item:getWorldStaticItem() and not instanceof(item, "HandWeapon") and not instanceof(item, "Clothing") then -- all3D = false; -- end -- if all3D and instanceof(item, "Clothing") then -- all3D = item:canBe3DRender(); -- end -- if all3D and not self.inventoryPage.mouseOver and not getPlayerLoot(self.player).mouseOver and not getPlayerInventory(self.player).mouseOver then -- if xoff > self.width or xoff < 0 or yoff < 0 or yoff > self.height then -- doIt = false; -- multiple selection of a single item, first is dummy -- if self.selected[y+1].items and #self.selected[y+1].items > 2 then -- for i,v in ipairs(self.selected[y+1].items) do -- if i > 1 then -- local add = true; -- for x,testItem in ipairs(self.inventoryPage.render3DItems) do -- if testItem == v then -- add = false; -- break; -- end -- end -- if add and self.inventory:getType() ~= "floor" then -- table.insert(self.inventoryPage.render3DItems, v) -- end -- print("add multiple table item ", v, #self.inventoryPage.render3DItems) -- end -- end -- elseif(self.inventory:getType() ~= "floor") then -- print("add single item table", item) -- table.insert(self.inventoryPage.render3DItems, item) -- end -- self.inventoryPage.render3DItem = item; -- else -- self.inventoryPage.render3DItems = {}; -- end -- else -- self.inventoryPage.render3DItems = {}; -- end end else if doDragged then doIt = false; end end local topOfItem = y * self.itemHgt + YSCROLL if not isDragging and ((topOfItem + self.itemHgt < 0) or (topOfItem > HEIGHT)) then doIt = false end -- print("trace:c"); if doIt == true then -- print("trace:cc"); -- print(count); if count == 1 then -- rect over the whole item line -- self:drawRect(1+xoff, (y*self.itemHgt)+self.headerHgt+yoff, self:getWidth(), 1, 0.3, 0.0, 0.0, 0.0); end -- print("trace:d"); -- do controller selection. if self.joyselection ~= nil and self.doController then -- if self.joyselection < 0 then self.joyselection = (#self.itemslist) - 1; end -- if self.joyselection >= #self.itemslist then self.joyselection = 0; end if self.joyselection == y then self:drawRect(1+xoff, (y*self.itemHgt)+self.headerHgt+yoff, self:getWidth()-1, self.itemHgt, 0.2, 0.2, 1.0, 1.0); end end -- print("trace:e"); -- only do icon if header or dragging sub items without header. local tex = item:getTex(); if tex ~= nil then local texDY = 1 local texWH = math.min(self.itemHgt-2,32) local auxDXY = math.ceil(20 * self.texScale) if count == 1 then self:drawTextureScaledAspect(tex, 10+xoff, (y*self.itemHgt)+self.headerHgt+texDY+yoff, texWH, texWH, 1, item:getR(), item:getG(), item:getB()); if player:isEquipped(item) then self:drawTexture(self.equippedItemIcon, (10+auxDXY+xoff), (y*self.itemHgt)+self.headerHgt+auxDXY+yoff, 1, 1, 1, 1); end if not self.hotbar then self.hotbar = getPlayerHotbar(self.player); end if not player:isEquipped(item) and self.hotbar and self.hotbar:isInHotbar(item) then self:drawTexture(self.equippedInHotbar, (10+auxDXY+xoff), (y*self.itemHgt)+self.headerHgt+auxDXY+yoff, 1, 1, 1, 1); end if item:isBroken() then self:drawTexture(self.brokenItemIcon, (10+auxDXY+xoff), (y*self.itemHgt)+self.headerHgt+auxDXY-1+yoff, 1, 1, 1, 1); end if instanceof(item, "Food") and item:isFrozen() then self:drawTexture(self.frozenItemIcon, (10+auxDXY+xoff), (y*self.itemHgt)+self.headerHgt+auxDXY-1+yoff, 1, 1, 1, 1); end if (item:isTaintedWater() and getSandboxOptions():getOptionByName("EnableTaintedWaterText"):getValue()) or player:isKnownPoison(item) then self:drawTexture(self.poisonIcon, (10+auxDXY+xoff), (y*self.itemHgt)+self.headerHgt+auxDXY-1+yoff, 1, 1, 1, 1); end if item:isFavorite() then self:drawTexture(self.favoriteStar, (13+auxDXY+xoff), (y*self.itemHgt)+self.headerHgt-1+yoff, 1, 1, 1, 1); end elseif v.count > 2 or (doDragged and count > 1 and self.selected[(y+1) - (count-1)] == nil) then self:drawTextureScaledAspect(tex, 10+16+xoff, (y*self.itemHgt)+self.headerHgt+texDY+yoff, texWH, texWH, 0.3, item:getR(), item:getG(), item:getB()); if player:isEquipped(item) then self:drawTexture(self.equippedItemIcon, (10+auxDXY+16+xoff), (y*self.itemHgt)+self.headerHgt+auxDXY+yoff, 1, 1, 1, 1); end if item:isBroken() then self:drawTexture(self.brokenItemIcon, (10+auxDXY+16+xoff), (y*self.itemHgt)+self.headerHgt+auxDXY-1+yoff, 1, 1, 1, 1); end if instanceof(item, "Food") and item:isFrozen() then self:drawTexture(self.frozenItemIcon, (10+auxDXY+16+xoff), (y*self.itemHgt)+self.headerHgt+auxDXY-1+yoff, 1, 1, 1, 1); end if item:isFavorite() then self:drawTexture(self.favoriteStar, (13+auxDXY+16+xoff), (y*self.itemHgt)+self.headerHgt-1+yoff, 1, 1, 1, 1); end end end -- print("trace:f"); if count == 1 then if not doDragged then if not self.collapsed[v.name] then self:drawTexture( self.treeexpicon, 2, (y*self.itemHgt)+self.headerHgt+5+yoff, 1, 1, 1, 0.8); -- self:drawText("+", 2, (y*18)+16+1+yoff, 0.7, 0.7, 0.7, 0.5); else self:drawTexture( self.treecolicon, 2, (y*self.itemHgt)+self.headerHgt+5+yoff, 1, 1, 1, 0.8); end end end -- print("trace:g"); if self.selected[y+1] ~= nil and not self.highlightItem then -- clicked/dragged item if checkDraggedItems and self.draggedItems:cannotDropItem(item) then self:drawRect(1+xoff, (y*self.itemHgt)+self.headerHgt+yoff, self:getWidth()-1, self.itemHgt, 0.20, 1.0, 0.0, 0.0); elseif false and (((instanceof(item,"Food") or instanceof(item,"DrainableComboItem")) and item:getHeat() ~= 1) or item:getItemHeat() ~= 1) then if (((instanceof(item,"Food") or instanceof(item,"DrainableComboItem")) and item:getHeat() > 1) or item:getItemHeat() > 1) then self:drawRect(1+xoff, (y*self.itemHgt)+self.headerHgt+yoff, self.column4, self.itemHgt, 0.5, math.abs(item:getInvHeat()), 0.0, 0.0); else self:drawRect(1+xoff, (y*self.itemHgt)+self.headerHgt+yoff, self.column4, self.itemHgt, 0.5, 0.0, 0.0, math.abs(item:getInvHeat())); end else self:drawRect(1+xoff, (y*self.itemHgt)+self.headerHgt+yoff, self:getWidth()-1, self.itemHgt, 0.20, 1.0, 1.0, 1.0); end elseif self.mouseOverOption == y+1 and not self.highlightItem then -- called when you mose over an element if(((instanceof(item,"Food") or instanceof(item,"DrainableComboItem")) and item:getHeat() ~= 1) or item:getItemHeat() ~= 1) then if (((instanceof(item,"Food") or instanceof(item,"DrainableComboItem")) and item:getHeat() > 1) or item:getItemHeat() > 1) then self:drawRect(1+xoff, (y*self.itemHgt)+self.headerHgt+yoff, self.column4, self.itemHgt, 0.3, math.abs(item:getInvHeat()), 0.0, 0.0); else self:drawRect(1+xoff, (y*self.itemHgt)+self.headerHgt+yoff, self.column4, self.itemHgt, 0.3, 0.0, 0.0, math.abs(item:getInvHeat())); end else self:drawRect(1+xoff, (y*self.itemHgt)+self.headerHgt+yoff, self:getWidth()-1, self.itemHgt, 0.05, 1.0, 1.0, 1.0); end else if count == 1 then -- normal background (no selected, no dragging..) -- background of item line if self.highlightItem and self.highlightItem == item:getType() then if not self.blinkAlpha then self.blinkAlpha = 0.5; end self:drawRect(1+xoff, (y*self.itemHgt)+self.headerHgt+yoff, self.column4, self.itemHgt, self.blinkAlpha, 1, 1, 1); if not self.blinkAlphaIncrease then self.blinkAlpha = self.blinkAlpha - 0.05 * (UIManager.getMillisSinceLastRender() / 33.3); if self.blinkAlpha < 0 then self.blinkAlpha = 0; self.blinkAlphaIncrease = true; end else self.blinkAlpha = self.blinkAlpha + 0.05 * (UIManager.getMillisSinceLastRender() / 33.3); if self.blinkAlpha > 0.5 then self.blinkAlpha = 0.5; self.blinkAlphaIncrease = false; end end else if (((instanceof(item,"Food") or instanceof(item,"DrainableComboItem")) and item:getHeat() ~= 1) or item:getItemHeat() ~= 1) then if (((instanceof(item,"Food") or instanceof(item,"DrainableComboItem")) and item:getHeat() > 1) or item:getItemHeat() > 1) then if alt then self:drawRect(1+xoff, (y*self.itemHgt)+self.headerHgt+yoff, self.column4, self.itemHgt, 0.15, math.abs(item:getInvHeat()), 0.0, 0.0); else self:drawRect(1+xoff, (y*self.itemHgt)+self.headerHgt+yoff, self.column4, self.itemHgt, 0.2, math.abs(item:getInvHeat()), 0.0, 0.0); end else if alt then self:drawRect(1+xoff, (y*self.itemHgt)+self.headerHgt+yoff, self.column4, self.itemHgt, 0.15, 0.0, 0.0, math.abs(item:getInvHeat())); else self:drawRect(1+xoff, (y*self.itemHgt)+self.headerHgt+yoff, self.column4, self.itemHgt, 0.2, 0.0, 0.0, math.abs(item:getInvHeat())); end end else if alt then self:drawRect(self.column2+xoff, (y*self.itemHgt)+self.headerHgt+yoff, self.column4, self.itemHgt, 0.02, 1.0, 1.0, 1.0); else self:drawRect(self.column2+xoff, (y*self.itemHgt)+self.headerHgt+yoff, self.column4, self.itemHgt, 0.2, 0.0, 0.0, 0.0); end end end else if (((instanceof(item,"Food") or instanceof(item,"DrainableComboItem")) and item:getHeat() ~= 1) or item:getItemHeat() ~= 1) then if (((instanceof(item,"Food") or instanceof(item,"DrainableComboItem")) and item:getHeat() > 1) or item:getItemHeat() > 1) then self:drawRect(1+xoff, (y*self.itemHgt)+self.headerHgt+yoff, self.column4, self.itemHgt, 0.2, math.abs(item:getInvHeat()), 0.0, 0.0); else self:drawRect(1+xoff, (y*self.itemHgt)+self.headerHgt+yoff, self.column4, self.itemHgt, 0.2, 0.0, 0.0, math.abs(item:getInvHeat())); end else self:drawRect(1+xoff, (y*self.itemHgt)+self.headerHgt+yoff, self.column4, self.itemHgt, 0.4, 0.0, 0.0, 0.0); end end end -- print("trace:h"); -- divider between equipped and unequipped items if v.equipped then if not doDragged and not equippedLine and y > 0 then self:drawRect(1, ((y+1)*self.itemHgt)+self.headerHgt-1-self.itemHgt, self.column4, 1, 0.2, 1, 1, 1); end equippedLine = true end if item:getJobDelta() > 0 and (count > 1 or self.collapsed[v.name]) then local scrollBarWid = self:isVScrollBarVisible() and 13 or 0 local displayWid = self.column4 - scrollBarWid self:drawRect(1+xoff, (y*self.itemHgt)+self.headerHgt+yoff, displayWid * item:getJobDelta(), self.itemHgt, 0.2, 0.4, 1.0, 0.3); end -- print("trace:i"); local textDY = (self.itemHgt - self.fontHgt) / 2 --~ local redDetail = false; local itemName = item:getName(); if count == 1 then -- if we're dragging something and want to put it in a container wich is full if doDragged and ISMouseDrag.dragging and #ISMouseDrag.dragging > 0 then local red = false; if red then if v.count > 2 then self:drawText(itemName.." ("..(v.count-1)..")", self.column2+8+xoff, (y*self.itemHgt)+self.headerHgt+textDY+yoff, 0.7, 0.0, 0.0, 1.0, self.font); else self:drawText(itemName, self.column2+8+xoff, (y*self.itemHgt)+self.headerHgt+textDY+yoff, 0.7, 0.0, 0.0, 1.0, self.font); end else if v.count > 2 then self:drawText(itemName.." ("..(v.count-1)..")", self.column2+8+xoff, (y*self.itemHgt)+self.headerHgt+textDY+yoff, 0.7, 0.7, 0.7, 1.0, self.font); else self:drawText(itemName, self.column2+8+xoff, (y*self.itemHgt)+self.headerHgt+textDY+yoff, 0.7, 0.7, 0.7, 1.0, self.font); end end else local clipX = math.max(0, self.column2+xoff) local clipY = math.max(0, (y*self.itemHgt)+self.headerHgt+yoff+self:getYScroll()) local clipX2 = math.min(clipX + self.column3-self.column2, self.width) local clipY2 = math.min(clipY + self.itemHgt, self.height) if clipX < clipX2 and clipY < clipY2 then self:setStencilRect(clipX, clipY, clipX2 - clipX, clipY2 - clipY) if v.count > 2 then self:drawText(itemName.." ("..(v.count-1)..")", self.column2+8+xoff, (y*self.itemHgt)+self.headerHgt+textDY+yoff, 0.7, 0.7, 0.7, 1.0, self.font); else self:drawText(itemName, self.column2+8+xoff, (y*self.itemHgt)+self.headerHgt+textDY+yoff, 0.7, 0.7, 0.7, 1.0, self.font); end self:clearStencilRect() self:repaintStencilRect(clipX, clipY, clipX2 - clipX, clipY2 - clipY) end end end -- print("trace:j"); --~ if self.mouseOverOption == y+1 and self.dragging and not self.parent:canPutIn(item) then --~ self:drawText(item:getName(), self.column2+8+xoff, (y*18)+16+1+yoff, 0.7, 0.0, 0.0, 1.0); --~ else if item:getJobDelta() > 0 then if (count > 1 or self.collapsed[v.name]) then if self.dragging == count then self:drawText(item:getJobType(), self.column3+8+xoff, (y*self.itemHgt)+self.headerHgt+textDY+yoff, 0.7, 0.0, 0.0, 1.0, self.font); else self:drawText(item:getJobType(), self.column3+8+xoff, (y*self.itemHgt)+self.headerHgt+textDY+yoff, 0.7, 0.7, 0.7, 1.0, self.font); end end else if count == 1 then if doDragged then -- Don't draw the category when dragging elseif item:getDisplayCategory() then -- display the custom category set in items.txt self:drawText(getText("IGUI_ItemCat_" .. item:getDisplayCategory()), self.column3+8+xoff, (y*self.itemHgt)+self.headerHgt+textDY+yoff, 0.6, 0.6, 0.8, 1.0, self.font); else self:drawText(getText("IGUI_ItemCat_" .. item:getCategory()), self.column3+8+xoff, (y*self.itemHgt)+self.headerHgt+textDY+yoff, 0.6, 0.6, 0.8, 1.0, self.font); end else local redDetail = false; self:drawItemDetails(item, y, xoff, yoff, redDetail); end end if self.selected ~= nil and self.selected[y+1] ~= nil then self:resumeStencil(); end end if count == 1 then if alt == nil then alt = false; end alt = not alt; end y = y + 1; if count == 1 and self.collapsed ~= nil and v.name ~= nil and self.collapsed[v.name] then if instanceof(item, "Food") then -- Update all food items in a collapsed stack so they separate when freshness changes. for k3,v3 in ipairs(v.items) do v3:updateAge() end end break end if count == ISInventoryPane.MAX_ITEMS_IN_STACK_TO_RENDER + 1 then break end count = count + 1; -- print("trace:zz"); end end self:setScrollHeight((y+1)*self.itemHgt); self:setScrollWidth(0); if self.draggingMarquis then local w = self:getMouseX() - self.draggingMarquisX; local h = self:getMouseY() - self.draggingMarquisY; self:drawRectBorder(self.draggingMarquisX, self.draggingMarquisY, w, h, 0.4, 0.9, 0.9, 1); end if not doDragged then self:drawRectStatic(1, 0, self.width-2, self.headerHgt, 1, 0, 0, 0); end end function ISInventoryPane:drawProgressBar(x, y, w, h, f, fg) if f < 0.0 then f = 0.0 end if f > 1.0 then f = 1.0 end local done = math.floor(w * f) if f > 0 then done = math.max(done, 1) end self:drawRect(x, y, done, h, fg.a, fg.r, fg.g, fg.b); local bg = {r=0.25, g=0.25, b=0.25, a=1.0}; self:drawRect(x + done, y, w - done, h, bg.a, bg.r, bg.g, bg.b); end function ISInventoryPane:drawTextAndProgressBar(text, fraction, xoff, top, fgText, fgBar) self:drawText(text, 40 + 30 + xoff, top + (self.itemHgt - self.fontHgt) / 2, fgText.a, fgText.r, fgText.g, fgText.b, self.font) local textWid = getTextManager():MeasureStringX(self.font, text) self:drawProgressBar(40 + math.max(120, 30 + textWid + 20) + xoff, top+(self.itemHgt/2)-1, 100, 2, fraction, fgBar) end function ISInventoryPane:drawItemDetails(item, y, xoff, yoff, red) if item == nil then return; end --~ print("renderdetail"); --~ print(red); local hdrHgt = self.headerHgt local top = hdrHgt + y * self.itemHgt + yoff local hc = getCore():getGoodHighlitedColor() local fgBar = {r=hc:getR(), g=hc:getG(), b=hc:getB(), a=1} local fgText = {r=0.6, g=0.8, b=0.5, a=0.6} if red then fgText = {r=0.0, g=0.0, b=0.5, a=0.7} end if instanceof(item, "HandWeapon") then local text = getText("IGUI_invpanel_Condition") .. ":" self:drawTextAndProgressBar(text, item:getCondition() / item:getConditionMax(), xoff, top, fgText, fgBar) elseif instanceof(item, "Drainable") then local text = getText("IGUI_invpanel_Remaining") .. ":" self:drawTextAndProgressBar(text, item:getUsedDelta(), xoff, top, fgText, fgBar) elseif item:getMeltingTime() > 0 then local text = getText("IGUI_invpanel_Melting") .. ":" self:drawTextAndProgressBar(text, item:getMeltingTime() / 100, xoff, top, fgText, fgBar) elseif instanceof(item, "Food") then if item:isIsCookable() and not item:isFrozen() and item:getHeat() > 1.6 then local ct = item:getCookingTime() local mtc = item:getMinutesToCook() local mtb = item:getMinutesToBurn() local f = ct / mtc; local s = getText("IGUI_invpanel_Cooking") .. ":" if ct > mtb then s = getText("IGUI_invpanel_Burnt") .. ":" elseif ct > mtc then s = getText("IGUI_invpanel_Burning") .. ":" f = (ct - mtc) / (mtb - mtc); fgBar.r = getCore():getBadHighlitedColor():getR() fgBar.g = getCore():getBadHighlitedColor():getG() fgBar.b = getCore():getBadHighlitedColor():getB() end self:drawText(s, 40 + 30 + xoff, top + (self.itemHgt - self.fontHgt) / 2, fgText.a, fgText.r, fgText.g, fgText.b, self.font); if item:isBurnt() then return end local textWid = getTextManager():MeasureStringX(self.font, s) self:drawProgressBar(40 + math.max(120, 30 + textWid + 20) + xoff, top+(self.itemHgt/2)-1, 100, 2, f, fgBar); elseif item:getFreezingTime() > 0 then local text = getText("IGUI_invpanel_FreezingTime") .. ":" self:drawTextAndProgressBar(text, item:getFreezingTime() / 100, xoff, top, fgText, fgBar) else local hunger = item:getHungerChange(); if(hunger ~= 0) then local text = getText("IGUI_invpanel_Nutrition") .. ":" self:drawTextAndProgressBar(text, (-hunger) / 1.0, xoff, top, fgText, fgBar) else self:drawText(item:getName(), 40 + 30 + xoff, top + (self.itemHgt - self.fontHgt) / 2, fgText.a, fgText.r, fgText.g, fgText.b, self.font); end end else self:drawText(item:getName(), 40 + 30 + xoff, top + (self.itemHgt - self.fontHgt) / 2, fgText.a, fgText.r, fgText.g, fgText.b, self.font); end end function ISInventoryPane:render() if self.mode == "icons" then self:rendericons(); elseif self.mode == "details" then self:renderdetails(true); end self:clearStencilRect(); --self:clearStencilRect(); local resize = self.nameHeader.resizing or self.nameHeader.mouseOverResize if not resize then resize = self.typeHeader.resizing or self.typeHeader.mouseOverResize end if resize then self:repaintStencilRect(self.nameHeader:getRight() - 1, self.nameHeader.y, 2, self.height) self:drawRectStatic(self.nameHeader:getRight() - 1, self.nameHeader.y, 2, self.height, 0.5, 1, 1, 1) end end function ISInventoryPane:setMode(mode) self.mode = mode; end function ISInventoryPane:onInventoryFontChanged() local font = getCore():getOptionInventoryFont() if font == "Large" then self.font = UIFont.Large elseif font == "Small" then self.font = UIFont.Small else self.font = UIFont.Medium end self.fontHgt = getTextManager():getFontFromEnum(self.font):getLineHeight() self.itemHgt = math.ceil(math.max(18, self.fontHgt) * self.zoom) self.texScale = math.min(32, (self.itemHgt - 2)) / 32 self.contextButton1:setFont(self.font) self.contextButton2:setFont(self.font) self.contextButton3:setFont(self.font) self.contextButton1:setHeight(self.itemHgt) self.contextButton2:setHeight(self.itemHgt) self.contextButton3:setHeight(self.itemHgt) end --************************************************************************-- --** ISInventoryPane:new --** --************************************************************************-- function ISInventoryPane:new (x, y, width, height, inventory, zoom) local o = {} --o.data = {} o = ISPanel:new(x, y, width, height); setmetatable(o, self) self.__index = self o.x = x; o.y = y; o.borderColor = {r=0.4, g=0.4, b=0.4, a=1}; o.backgroundColor = {r=0, g=0, b=0, a=0.5}; o.width = width; o.height = height; o.anchorLeft = true; o.anchorRight = false; o.anchorTop = true; o.anchorBottom = false; o.inventory = inventory; o.zoom = zoom; o.mode = "details"; o.column2 = 30; o.column3 = 140; o.column4 = o.width; o.items = {} o.selected = {} o.previousMouseUp = nil; local font = getCore():getOptionInventoryFont() if font == "Large" then o.font = UIFont.Large elseif font == "Small" then o.font = UIFont.Small else o.font = UIFont.Medium end if zoom > 1.5 then o.font = UIFont.Large; end o.fontHgt = getTextManager():getFontFromEnum(o.font):getLineHeight() o.itemHgt = math.ceil(math.max(18, o.fontHgt) * o.zoom) o.texScale = math.min(32, (o.itemHgt - 2)) / 32 o.draggedItems = DraggedItems:new(o) o.treeexpicon = getTexture("media/ui/TreeExpanded.png"); o.treecolicon = getTexture("media/ui/TreeCollapsed.png"); o.expandicon = getTexture("media/ui/TreeExpandAll.png"); o.filtericon = getTexture("media/ui/TreeFilter.png"); o.collapseicon = getTexture("media/ui/TreeCollapseAll.png"); o.equippedItemIcon = getTexture("media/ui/icon.png"); o.equippedInHotbar = getTexture("media/ui/iconInHotbar.png"); o.brokenItemIcon = getTexture("media/ui/icon_broken.png"); o.frozenItemIcon = getTexture("media/ui/icon_frozen.png"); o.poisonIcon = getTexture("media/ui/SkullPoison.png"); o.itemSortFunc = ISInventoryPane.itemSortByNameInc; -- how to sort the items... o.favoriteStar = getTexture("media/ui/FavoriteStar.png"); return o end