--*********************************************************** --** ROBERT JOHNSON ** --*********************************************************** require "ISUI/ISPanel" require "ISUI/ISButton" require "ISUI/ISInventoryPane" require "ISUI/ISResizeWidget" require "ISUI/ISMouseDrag" require "defines" ModSelector = ISPanelJoypad:derive("ModSelector"); local FONT_HGT_TITLE = getTextManager():getFontHeight(UIFont.Title) local FONT_HGT_SMALL = getTextManager():getFontHeight(UIFont.Small) local FONT_HGT_MEDIUM = getTextManager():getFontHeight(UIFont.Medium) local FONT_HGT_LARGE = getTextManager():getFontHeight(UIFont.Large) ----- ModListBox = ISScrollingListBox:derive("ModListbox") function ModListBox:onMouseDown(x, y) -- stop you from changing mods while in mod order UI if not self.parent.modorderui or not self.parent.modorderui:isVisible() then if #self.items == 0 then return end local row = self:rowAt(x, y) if row > #self.items then row = #self.items end if row < 1 then row = 1 end getSoundManager():playUISound("UISelectListItem") if self.mouseOverButton then self.parent:forceActivateMods(self.mouseOverButton.item.modInfo, not self.parent:isModActive(self.mouseOverButton.item.modInfo)); else self.selected = row end end end function ModListBox:doDrawItem(y, item, alt) local modInfo = item.item.modInfo local tex = nil; local isMouseOver = self.mouseoverselected == item.index if self.selected == item.index then self:drawRect(0, (y), self:getWidth(), item.height-1, 0.3, 0.7, 0.35, 0.15); elseif isMouseOver and not self:isMouseOverScrollBar() then self:drawRect(1, y + 1, self:getWidth() - 2, item.height - 2, 0.95, 0.05, 0.05, 0.05); end -- border over text and description self:drawRectBorder(0, (y), self:getWidth(), item.height-1, 0.5, self.borderColor.r, self.borderColor.g, self.borderColor.b); local r,g,b,a = 0.9, 0.9, 0.9, 0.9 if not modInfo:isAvailable() then g = 0.0 b = 0.0 end self:drawText(modInfo:getName(), 10, y + 10, r, g, b, a, UIFont.Medium); local itemHgt = 10 + FONT_HGT_MEDIUM + 10 local textDisabled = getText("UI_mods_ModDisabled") local textEnabled = getText("UI_mods_ModEnabled") local textDisabledWid = getTextManager():MeasureStringX(UIFont.Small, textDisabled) local textEnabledWid = getTextManager():MeasureStringX(UIFont.Small, textEnabled) local buttonWid = 8 + math.max(textEnabledWid, textDisabledWid) + 8 local buttonHgt = FONT_HGT_MEDIUM local scrollBarWid = self:isVScrollBarVisible() and 13 or 0 local buttonX = self.width - 16 - scrollBarWid - buttonWid local buttonY = y + 10 local isMouseOverButton = isMouseOver and ((self:getMouseX() > buttonX - 16) and (self:getMouseX() < self.width - scrollBarWid) and (self:getMouseY() < buttonY + buttonHgt + 16)) local isJoypadSelected = self.joyfocus and (self.selected == item.index) if self.parent:isModActive(modInfo) then if isMouseOverButton then self:drawRect(buttonX, buttonY, buttonWid, buttonHgt, 1, 0, 0.85, 0) self.mouseOverButton = item else self:drawRect(buttonX, buttonY, buttonWid, buttonHgt, 1, 0, 0.70, 0) end self:drawTextCentre(textEnabled, buttonX + buttonWid / 2, buttonY + (buttonHgt - FONT_HGT_SMALL) / 2 , 0, 0, 0, 1) elseif (isMouseOver and not self:isMouseOverScrollBar() or isJoypadSelected) and modInfo:isAvailable() then local rgb = (isMouseOverButton or isJoypadSelected) and 0.5 or 0.2 self:drawRect(buttonX, buttonY, buttonWid, buttonHgt, 1, rgb, rgb, rgb) self:drawTextCentre(textDisabled, buttonX + buttonWid / 2, buttonY + (buttonHgt - FONT_HGT_SMALL) / 2 , 0, 0, 0, 1) self.mouseOverButton = isMouseOverButton and item or nil end if not modInfo:isAvailable() then local tex = ModSelector.instance.cantTexture self:drawTexture(tex, self.width - 16 - scrollBarWid - tex:getWidth(), y + (item.height - tex:getHeight()) / 2, 1, 1, 1, 1); end if self.joyfocus and modInfo:isAvailable() and (self.selected == item.index) then local fontHgt = FONT_HGT_SMALL local tex = self.parent.abutton self:drawTextureScaled(tex, buttonX - 8 - buttonHgt, buttonY, buttonHgt, buttonHgt, 1,1,1,1) end y = y + itemHgt; return y; end function ModListBox:onJoypadDirRight(joypadData) self:setJoypadFocused(false, joypadData) joypadData.focus = self.parent.infoPanel updateJoypadFocus(joypadData) end function ModListBox:onJoypadBeforeDeactivate(joypadData) self.parent:onJoypadBeforeDeactivate(joypadData) end function ModListBox:new(x, y, width, height) local o = ISScrollingListBox.new(self, x, y, width, height) return o end ----- ModThumbnailPanel = ISPanelJoypad:derive("ModThumbnailPanel") function ModThumbnailPanel:render() ISPanelJoypad.render(self) if self.modInfo and (self.modInfo:getPosterCount() > 0) then self.index = math.max(self.index, 1) self.index = math.min(self.index, self.modInfo:getPosterCount()) local left = 1 local top = 1 local alpha = 1.0 local width = self.thumbnailWidth local height = self.thumbnailHeight local x = 0 local y = 0 for i=1,self.modInfo:getPosterCount() do local tex = getTexture(self.modInfo:getPoster(i-1)) or Texture:getWhite() if tex == Texture.getWhite() then alpha = 0.1 end self:drawRect(x + self.padX, y + self.padY, width, height, 1, 0.1, 0.1, 0.1) self:drawTextureScaledAspect(tex, x + self.padX, y + (self.height - height) / 2, width, height, alpha, 1, 1, 1) if not self.pressed and self:isMouseOver() and self:getIndexAt(self:getMouseX(), self:getMouseY()) + 1 == i then self:drawRectBorder(x + self.padX - 2, y + self.padY - 2, width + 4, height + 4, 1, 0.5, 0.5, 0.5) end x = x + self.padX + width end if x > self.width then self:setXScroll(math.min(self:getXScroll(), 0)) self:setXScroll(math.max(self:getXScroll(), -(x - self.width))) else self:setXScroll(0) end end end function ModThumbnailPanel:onMouseDown(x, y) self.index = self:getIndexAt(x, y) + 1 self.pressed = true end function ModThumbnailPanel:onMouseUp(x, y) self.pressed = false end function ModThumbnailPanel:onMouseUpOutside(x, y) self.pressed = false end function ModThumbnailPanel:onMouseMove(dx, dy) if self.pressed then self:setXScroll(self:getXScroll() + dx) end end function ModThumbnailPanel:onMouseMoveOutside(dx, dy) if self.pressed then self:onMouseMove(dx, dy) end end function ModThumbnailPanel:getIndexAt(x, y) if not self.modInfo or self.modInfo:getPosterCount() == 0 then return -1 end local index = (x - 5) / (self.thumbnailWidth + 10) index = math.floor(index) if index >= self.modInfo:getPosterCount() then return -1 end return index end function ModThumbnailPanel:setJoypadFocused(focused) end function ModThumbnailPanel:setModInfo(modInfo) self.modInfo = modInfo end function ModThumbnailPanel:new(x, y, width, height) local o = ISPanelJoypad.new(self, x, y, width, height) o.padX = 10 o.padY = 8 o.thumbnailWidth = 116 o.thumbnailHeight = height - o.padY * 2 -- 64 o.index = 1 return o end ----- ModPosterPanel = ISPanelJoypad:derive("ModPosterPanel") function ModPosterPanel:render() ISPanelJoypad.render(self) if self.modInfo and (self.modInfo:getPosterCount() > 0) then local index = self.parent.thumbnailPanel.index index = math.max(index, 1) index = math.min(index, self.modInfo:getPosterCount()) local texName = self.modInfo:getPoster(index - 1) local tex = getTexture(texName) or Texture.getWhite() local left = 1 local top = 1 local alpha = 1.0 if tex == Texture.getWhite() then alpha = 0.1 end local scrollBarWid = (self:getScrollHeight() > self.height) and self.vscroll:getWidth() or 0 self:drawTextureScaledAspect(tex, left, top, self.width - scrollBarWid - left, self.height - 1 - top, alpha, 1, 1, 1) end end function ModPosterPanel:setJoypadFocused(focused) end function ModPosterPanel:setModInfo(modInfo) self.modInfo = modInfo end function ModPosterPanel:new(x, y, width, height) local o = ISPanelJoypad.new(self, x, y, width, height) return o end ----- ModInfoPanel = ISPanelJoypad:derive("ModInfoPanel") function ModInfoPanel:createChildren() local scrollBarWid = 13 local panel = ModPosterPanel:new(0, 0, self.width - scrollBarWid, 360) panel:setAnchorRight(true) self:addChild(panel) self.posterPanel = panel panel = ModThumbnailPanel:new(0, self.posterPanel:getBottom() - 1, self.width - scrollBarWid, 80) panel:setAnchorRight(true) self:addChild(panel) self.thumbnailPanel = panel local buttonHgt = math.max(25, FONT_HGT_SMALL + 3 * 2) local buttonWid = 150 local button1 = ISButton:new(self.width - scrollBarWid - 16 - buttonWid, panel:getBottom() + 24, buttonWid, buttonHgt, getText("UI_mods_ModEnable"), ModSelector.instance, ModSelector.onOptionMouseDown) button1.internal = "TOGGLE" button1:initialise() button1:instantiate() button1:setAnchorLeft(false) button1:setAnchorRight(true) button1:setAnchorTop(false) button1:setAnchorBottom(false) button1.borderColor = {r=1, g=1, b=1, a=0.1} -- button1:setFont(UIFont.Small) self:addChild(button1) self.buttonToggle = button1 local button2 = ISButton:new(button1.x - 20 - buttonWid, button1.y, buttonWid, buttonHgt, getText("UI_mods_ModOptions"), ModSelector.instance, ModSelector.onOptionMouseDown) button2.internal = "OPTIONS" button2:initialise() button2:instantiate() button2:setAnchorLeft(false) button2:setAnchorRight(true) button2:setAnchorTop(false) button2:setAnchorBottom(false) button2.borderColor = {r=1, g=1, b=1, a=0.1} -- button2:setFont(UIFont.Small) button2:setEnable(false) button2:setVisible(false) self:addChild(button2) self.buttonOptions = button2 local richText = ISRichTextLayout:new(self.width - scrollBarWid) self.richText = richText self.urlButton = ISButton:new(16, 0, self.width - scrollBarWid - 16 * 2, buttonHgt, getText("UI_mods_OpenWebBrowser"), ModSelector.instance, ModSelector.onOptionMouseDown) self.urlButton.internal = "URL" self.urlButton.url = "" self.urlButton:initialise() self.urlButton:instantiate() self.urlButton:setAnchorLeft(true) self.urlButton:setAnchorRight(true) self.urlButton:setAnchorTop(false) self.urlButton:setAnchorBottom(false) self.urlButton.borderColor = {r=1, g=1, b=1, a=0.1} -- self.urlButton:setFont(UIFont.Small) self.urlButton:setEnable(false) self:addChild(self.urlButton) local label = ISLabel:new(richText.marginLeft, 0, FONT_HGT_SMALL + 2 * 2, getText("UI_mods_Location"), 1.0, 1.0, 1.0, 1.0, UIFont.Small, true) label:setColor(0.7, 0.7, 0.7) self:addChild(label) self.locationLabel = label local entryX = label:getRight() + 6 local entry = ISTextEntryBox:new("", entryX, 0, self.width - scrollBarWid - 16 - entryX, FONT_HGT_SMALL + 2 * 2) entry:setAnchorRight(true) self:addChild(entry) entry:setEditable(false) entry:setSelectable(true) self.locationEntry = entry local y = self.buttonToggle:getBottom() + 16 self.locationLabel:setY(y) self.locationEntry:setY(y) self.urlButton:setY(self.locationEntry:getBottom() + 24) self:setScrollHeight(self.urlButton:getBottom() + 20) -- self:insertNewLineOfButtons(self.posterPanel) -- self:insertNewLineOfButtons(self.thumbnailPanel) self:insertNewLineOfButtons(self.buttonToggle) self.joypadIndexY = 1 self.joypadIndex = 1 end function ModInfoPanel:onMouseWheel(del) self:setYScroll(self:getYScroll() - (del * 40)) return true end function ModInfoPanel:prerender() local scrollBarWid = 13 if self.width - scrollBarWid ~= self.richText.width then self.richText:setWidth(self.width - scrollBarWid) self.richText:paginate() end self:doRightJoystickScrolling(20, 20) self:setStencilRect(0, 0, self:getWidth(), self:getHeight()) ISPanelJoypad.prerender(self) end function ModInfoPanel:render() ISPanelJoypad.render(self) local x = 0 local y = self.buttonToggle:getBottom() + 16 self.richText:render(x, y, self) self:clearStencilRect() self:drawRectBorderStatic(0, 0, self.width, self.height, self.borderColor.a, self.borderColor.r, self.borderColor.g, self.borderColor.b) if self.joyfocus then self:drawRectBorder(0, -self:getYScroll(), self:getWidth(), self:getHeight(), 0.4, 0.2, 1.0, 1.0); self:drawRectBorder(1, 1-self:getYScroll(), self:getWidth()-2, self:getHeight()-2, 0.4, 0.2, 1.0, 1.0); end end function ModInfoPanel:setModInfo(modInfo) if modInfo == self.modInfo then return end self.modInfo = modInfo self.posterPanel:setModInfo(modInfo) self.thumbnailPanel:setModInfo(modInfo) local description = "

" .. modInfo:getName() .. " " description = description .. " " description = description .. " " if modInfo:getDescription() ~= "" then description = description .. modInfo:getDescription() description = description .. " " description = description .. " " end local needBlank = false local gameVersion = getCore():getGameVersion() if modInfo:getVersionMin() and modInfo:getVersionMin():isGreaterThan(gameVersion) then description = description .. " " .. getText("UI_mods_RequiredVersionMin", modInfo:getVersionMin():toString()) description = description .. " " needBlank = true end if modInfo:getVersionMax() and modInfo:getVersionMax():isLessThan(gameVersion) then description = description .. " " .. getText("UI_mods_RequiredVersionMax", modInfo:getVersionMax():toString()) description = description .. " " needBlank = true end if modInfo:getRequire() and not modInfo:getRequire():isEmpty() then if needBlank then description = description .. " " end description = description .. " " .. getText("UI_mods_require") description = description .. " " for i=1,modInfo:getRequire():size() do local modID = modInfo:getRequire():get(i-1) local modInfo1 = getModInfoByID(modID) if modInfo1 == nil then description = description .. " " .. modID elseif not modInfo1:isAvailable() then description = description .. " " .. modInfo1:getName() else description = description .. " " .. modInfo1:getName() end description = description .. " " end description = description .. " " needBlank = true end if needBlank then description = description .. " " end description = description .. " " .. getText("UI_mods_ID", modInfo:getId()) description = description .. " " if getSteamModeActive() and modInfo:getWorkshopID() then description = description .. getText("UI_WorkshopSubmit_ItemID") .. " " .. modInfo:getWorkshopID() description = description .. " " end self.richText:setText(description) self.richText:paginate() local y = self.buttonToggle:getBottom() + 16 + self.richText:getHeight() self.locationLabel:setY(y) self.locationEntry:setY(y) self.locationEntry:setText(modInfo:getDir()) self.urlButton:setY(self.locationEntry:getBottom() + 24) self:setScrollHeight(self.urlButton:getBottom() + 20) end function ModInfoPanel:onJoypadDirLeft(joypadData) self.parent.listbox:setJoypadFocused(true, joypadData) end function ModInfoPanel:onGainJoypadFocus(joypadData) ISPanelJoypad.onGainJoypadFocus(self, joypadData) self:restoreJoypadFocus() end function ModInfoPanel:onLoseJoypadFocus(joypadData) self:clearJoypadFocus() ISPanelJoypad.onLoseJoypadFocus(self, joypadData) end function ModInfoPanel:onJoypadBeforeDeactivate(joypadData) self.parent:onJoypadBeforeDeactivate(joypadData) end function ModInfoPanel:new(x, y, width, height) local o = ISPanelJoypad.new(self, x, y, width, height) o.backgroundColor.a = 1.0 return o end ----- function ModSelector:initialise() ISPanelJoypad.initialise(self); end function ModSelector:getActiveMods() if self.loadGameFolder then return ActiveMods.getById("currentGame") end return ActiveMods.getById(self.isNewGame and "currentGame" or "default") end function ModSelector:isModActive(modInfo) return self:getActiveMods():isModActive(modInfo:getId()) end function ModSelector:onDblClickMap(item) if not self.modorderui or not self.modorderui:isVisible() then local joypadData = JoypadState.getMainMenuJoypad() if not joypadData or wasMouseActiveMoreRecentlyThanJoypad() then if self.listbox:isMouseOverScrollBar() then return end if self.listbox.mouseOverButton then item = self.listbox.mouseOverButton.item end end self:forceActivateMods(item.modInfo, not self:isModActive(item.modInfo)); end end function ModSelector:forceActivateMods(modInfo, activate) if modInfo:isAvailable() then self:getActiveMods():setModActive(modInfo:getId(), activate); -- we also activate the required mod if needed if self:isModActive(modInfo) and modInfo:getRequire() then for l=0,modInfo:getRequire():size() - 1 do for i,k in ipairs(self.listbox.items) do local modInfo2 = k.item.modInfo if modInfo2:getId() and modInfo2:getId():trim() == modInfo:getRequire():get(l):trim() then self:forceActivateMods(modInfo2, self:isModActive(modInfo)); end end end end end -- check the "parents" mod to disable if not self:isModActive(modInfo) then for i,activatedMod in ipairs(self.listbox.items) do local modInfo2 = activatedMod.item.modInfo if self:isModActive(modInfo2) and modInfo2:getRequire() then for l=0,modInfo2:getRequire():size() - 1 do if modInfo:getId() == modInfo2:getRequire():get(l):trim() then self:forceActivateMods(modInfo2, false); end end end end end self.mapGroups:createGroups(self:getActiveMods(), false) self.mapConflicts = self.mapGroups:checkMapConflicts() end function ModSelector:onModsEnabledTick(option, selected) getCore():setOptionModsEnabled(selected) end --************************************************************************-- --** ModSelector:instantiate --** --************************************************************************-- function ModSelector:instantiate() self.javaObject = UIElement.new(self); self.javaObject:setX(self.x); self.javaObject:setY(self.y); self.javaObject:setHeight(self.height); self.javaObject:setWidth(self.width); self.javaObject:setAnchorLeft(self.anchorLeft); self.javaObject:setAnchorRight(self.anchorRight); self.javaObject:setAnchorTop(self.anchorTop); self.javaObject:setAnchorBottom(self.anchorBottom); end function ModSelector:populateListBox(directories) self.listbox:clear(); local modIDs = {} for _,directory in ipairs(directories) do local modInfo = getModInfo(directory) -- Display the first mod with a given ID. -- There may be mods in User\Zomboid\mods, User\Zomboid\Workshop\, -- and steamapps\workshop\content\108600\. The order can be changed -- using the -modfolders commandline option. if modInfo and not modIDs[modInfo:getId()] then local item = {} item.modInfo = modInfo self.listbox:addItem("", item) modIDs[modInfo:getId()] = true end end for i,k in ipairs(self.listbox.items) do local modInfo = k.item.modInfo if self:isModActive(modInfo) and not modInfo:isAvailable() then self:getActiveMods():setModActive(modInfo:getId(), false) end end self.ModsEnabled = getCore():getOptionModsEnabled() table.sort(self.listbox.items, function(a,b) return not string.sort(a.item.modInfo:getName(), b.item.modInfo:getName()) end) self.mapGroups:createGroups(self:getActiveMods(), false) self.mapConflicts = self.mapGroups:checkMapConflicts() end function ModSelector:setExistingSavefile(folder) self.loadGameFolder = folder local info = getSaveInfo(folder) local activeMods = info.activeMods or ActiveMods.getById("default") ActiveMods.getById("currentGame"):copyFrom(activeMods) -- Remember the list of map directories. The user isn't allowed to change -- these by enabling/disabling mods. self.loadGameMapName = info.mapName or 'Muldraugh, KY' end function ModSelector:create() local labelHgt = FONT_HGT_SMALL self.smallFontHgt = labelHgt local buttonHgt = math.max(25, FONT_HGT_SMALL + 3 * 2) self.topRect = {} self.topRect.x = 16 self.topRect.y = 10 + FONT_HGT_TITLE + 10 self.topRect.h = 8 + buttonHgt + 8 local listY = self.topRect.y + self.topRect.h + 10 local listHgt = self.height-(5 + buttonHgt + 10)-listY self.listbox = ModListBox:new(16, listY, self.width/2-16, listHgt); self.listbox:initialise(); self.listbox:instantiate(); self.listbox:setAnchorLeft(true); self.listbox:setAnchorRight(true); self.listbox:setAnchorTop(true); self.listbox:setAnchorBottom(true); self.listbox.itemheight = 128; self.listbox.drawBorder = true self.listbox:setOnMouseDoubleClick(self, ModSelector.onDblClickMap); self:addChild(self.listbox); self.backButton = ISButton:new(16, self.height-buttonHgt - 5, 100, buttonHgt, getText("UI_btn_back"), self, ModSelector.onOptionMouseDown); self.backButton.internal = "DONE"; self.backButton:initialise(); self.backButton:instantiate(); self.backButton:setAnchorLeft(true); self.backButton:setAnchorRight(false); self.backButton:setAnchorTop(false); self.backButton:setAnchorBottom(true); self.backButton.borderColor = {r=1, g=1, b=1, a=0.1}; self.backButton:setFont(UIFont.Small); self.backButton:ignoreWidthChange(); self.backButton:ignoreHeightChange(); self:addChild(self.backButton); local size = getTextManager():MeasureStringX(UIFont.Small, getText("UI_mods_GetModsHere")); local size = math.max(size + 10 * 2, 100) self.getModButton = ISButton:new(self.width - 16 - 16 - size, self.topRect.y + 8, size, buttonHgt, getText("UI_mods_GetModsHere"), self, ModSelector.onOptionMouseDown); self.getModButton.internal = "GETMOD"; self.getModButton:initialise(); self.getModButton:instantiate(); self.getModButton:setAnchorLeft(false); self.getModButton:setAnchorRight(true); self.getModButton:setAnchorTop(true); self.getModButton:setAnchorBottom(false); self.getModButton.borderColor = {r=1, g=1, b=1, a=1}; self.getModButton.backgroundColor = {r=0, g=0.5, b=0.75, a=1.0}; self.getModButton.backgroundColorMouseOver = {r=0, g=0.65, b=0.85, a=1.0}; self.getModButton:setFont(UIFont.Small); self.getModButton:ignoreWidthChange(); self.getModButton:ignoreHeightChange(); if not getSteamModeActive() then self.getModButton.tooltip = getText("UI_mods_WorkshopRequiresSteam") end self:addChild(self.getModButton); self.modOrderbtn = ISButton:new(self.width - 16, self.height - buttonHgt - 5, 100, buttonHgt, getText("UI_mods_ModsOrder"), self, ModSelector.onOptionMouseDown); self.modOrderbtn.internal = "MODSORDER"; self.modOrderbtn:initialise(); self.modOrderbtn:instantiate(); self.modOrderbtn:setAnchorLeft(false); self.modOrderbtn:setAnchorRight(true); self.modOrderbtn:setAnchorTop(false); self.modOrderbtn:setAnchorBottom(true); self.modOrderbtn.borderColor = {r=1, g=1, b=1, a=0.1}; self.modOrderbtn:setFont(UIFont.Small); self.modOrderbtn:ignoreWidthChange(); self.modOrderbtn:ignoreHeightChange(); self:addChild(self.modOrderbtn); self.modOrderbtn:setWidthToTitle() self.modOrderbtn:setX(self.width - 16 - self.modOrderbtn.width) --[[ local checkBox = ISTickBox:new(16, self.height - 30, 200, 30, "Enable mods", self, ModSelector.onModsEnabledTick) checkBox:initialise() checkBox:setAnchorTop(false) checkBox:setAnchorBottom(true) checkBox:addOption("Enable mods", nil) checkBox.leftMargin = 0 checkBox.selected[1] = getCore():getOptionModsEnabled() self:addChild(checkBox) --]] local left = self.listbox:getRight() + 16 local top = self.listbox:getY() local panel = ModInfoPanel:new(left, top, self.width - 16 - left, self.listbox.height) panel:setAnchorBottom(true) self:addChild(panel) panel:addScrollBars() panel:setScrollChildren(true) self.infoPanel = panel self.urlButton = self.infoPanel.urlButton end function ModSelector:prerender() ModSelector.instance = self self:updateButtons(); self.listbox.mouseOverButton = nil ISPanelJoypad.prerender(self); if self.listbox.items and self.listbox.items[self.listbox.selected] then self.infoPanel:setModInfo(self.listbox.items[self.listbox.selected].item.modInfo) end self:drawTextCentre(getText("UI_mods_SelectMods"), self.width / 2, 10, 1, 1, 1, 1, UIFont.Title); self:drawRect(self.topRect.x, self.topRect.y, self.width - 16 * 2, self.topRect.h, 1, 0.0, 0.5, 0.75) local labelY = self.topRect.y + (self.topRect.h - FONT_HGT_SMALL) / 2 local text = getText("UI_mods_Explanation") .. Core.getMyDocumentFolder() .. getFileSeparator() .. "mods" .. getFileSeparator() self:drawText(text, self.topRect.x + 16, labelY, 1, 1, 1, 1, UIFont.Small); end function ModSelector:updateButtons() local item = self.listbox.items[self.listbox.selected] if item then local modInfo = item.item.modInfo self.infoPanel.buttonToggle:setEnable(modInfo:isAvailable()) self.infoPanel.buttonToggle:setTitle(getText(self:isModActive(modInfo) and "UI_mods_ModDisable" or "UI_mods_ModEnable")) self.infoPanel.buttonOptions:setEnable(false) if modInfo:getWorkshopID() and isSteamOverlayEnabled() then self.urlButton:setEnable(true); self.urlButton.workshopID = modInfo:getWorkshopID() self.urlButton:setTitle(getText("UI_WorkshopSubmit_OverlayButton")) elseif modInfo:getUrl() and modInfo:getUrl() ~= "" then self.urlButton:setVisible(true); self.urlButton.workshopID = nil self.urlButton.url = modInfo:getUrl(); -- self.urlButton:setTitle("URL : " .. modInfo:getUrl()); self.urlButton:setEnable(true); self.urlButton:setTitle(getText("UI_mods_OpenWebBrowser")) else self.urlButton:setTitle(getText("UI_mods_OpenWebBrowser")) self.urlButton:setEnable(false); end else self.infoPanel.buttonToggle:setEnable(false) self.infoPanel.buttonOptions:setEnable(false) end self.modOrderbtn.enable = self.mapConflicts if self.modorderui and self.modorderui:isReallyVisible() then self.modOrderbtn.blinkBG = false self.modOrderbtn.tooltip = nil else self.modOrderbtn.blinkBG = self.mapConflicts self.modOrderbtn.tooltip = self.mapConflicts and getText("UI_mods_ConflictDetected") or nil end end function ModSelector:onAccept() if self.modorderui then self.modorderui:removeFromUIManager() end self:setVisible(false) local activeMods = self:getActiveMods() -- Remove mod IDs for missing mods from ActiveMods.mods activeMods:checkMissingMods() -- Remove unused map directories from ActiveMods.mapOrder activeMods:checkMissingMaps() if self.loadGameFolder then local saveFolder = self.loadGameFolder self.loadGameFolder = nil manipulateSavefile(saveFolder, "WriteModsDotTxt") -- Setting 'currentGame' to 'default' in case other places forget to set it -- before starting a game (DebugScenarios.lua, etc). local defaultMods = ActiveMods.getById("default") local currentMods = ActiveMods.getById("currentGame") currentMods:copyFrom(defaultMods) LoadGameScreen.instance:onSavefileModsChanged(saveFolder) LoadGameScreen.instance:setVisible(true, self.joyfocus) return end if self.isNewGame then NewGameScreen.instance:setVisible(true, self.joyfocus) else saveModsFile() -- Setting 'currentGame' to 'default' in case other places forget to set it -- before starting a game (DebugScenarios.lua, etc). local defaultMods = ActiveMods.getById("default") local currentMods = ActiveMods.getById("currentGame") currentMods:copyFrom(defaultMods) MainScreen.instance.bottomPanel:setVisible(true) if self.joyfocus then self.joyfocus.focus = MainScreen.instance updateJoypadFocus(self.joyfocus) end end local reset = self.ModsEnabled ~= getCore():getOptionModsEnabled() if ActiveMods.requiresResetLua(activeMods) then reset = true end if reset then if self.isNewGame then getCore():ResetLua("currentGame", "NewGameMods") else getCore():ResetLua("default", "modsChanged") end end end function ModSelector:onOptionMouseDown(button, x, y) if button.internal == "DONE" then self:onAccept() elseif button.internal == "TOGGLE" then local item = self.listbox.items[self.listbox.selected].item self:forceActivateMods(item.modInfo, not self:isModActive(item.modInfo)) elseif button.internal == "URL" then if button.workshopID then activateSteamOverlayToWorkshopItem(button.workshopID) else openUrl(button.url); end elseif button.internal == "GETMOD" then if getSteamModeActive() then if isSteamOverlayEnabled() then activateSteamOverlayToWorkshop() else openUrl("steam://url/SteamWorkshopPage/108600") end else openUrl("http://theindiestone.com/forums/index.php/forum/58-mods/"); end elseif button.internal == "MODSORDER" then self:setVisible(false) self.modorderui = ModOrderUI:new(0, 0, 700, 400); self.modorderui:initialise(); self.modorderui:addToUIManager(); end end function ModSelector:onGainJoypadFocus(joypadData) ISPanelJoypad.onGainJoypadFocus(self, joypadData); self.listbox:setISButtonForB(self.backButton); self.infoPanel:setISButtonForB(self.backButton); self.listbox:setJoypadFocused(true, joypadData); -- joypadData.focus = self.listbox; end function ModSelector:onResolutionChange(oldw, oldh, neww, newh) self.listbox:setWidth(self:getWidth() / 2 - self.listbox:getX()) self.listbox:recalcSize() self.listbox.vscroll:setX(self.listbox:getWidth() - 16) local urlX = self:getWidth() / 2 + 16 self.infoPanel:setWidth(self.width - 20 - urlX) self.infoPanel:setX(urlX) end function ModSelector:onJoypadBeforeDeactivate(joypadData) self.backButton:clearJoypadButton() -- focus is on listbox or infoPanel self.joyfocus = nil end function ModSelector:new(x, y, width, height) local o = {} --o.data = {} o = ISPanelJoypad:new(x, y, width, height); ModSelector.instance = o; setmetatable(o, self) self.__index = self o.x = x; o.y = y; o.backgroundColor = {r=0, g=0, b=0, a=0.3}; o.borderColor = {r=1, g=1, b=1, a=0.2}; o.width = width; o.height = height; o.anchorLeft = true; o.anchorRight = false; o.anchorTop = true; o.anchorBottom = false; o.itemheightoverride = {} o.tickTexture = getTexture("Quest_Succeed"); o.cantTexture = getTexture("Quest_Failed"); o.abutton = Joypad.Texture.AButton; o.selected = 1; o.mapGroups = MapGroups.new() return o end function ModSelector_onModsModified() local self = ModSelector.instance if self and self.listbox and self:isReallyVisible() then local index = self.listbox.selected self:populateListBox(getModDirectoryTable()) if self.listbox.items[index] then self.listbox.selected = index end end end Events.OnModsModified.Add(ModSelector_onModsModified) ----- function ModSelector.showNagPanel() if getCore():isModsPopupDone() or getDebug() and getDebugOptions():getBoolean("UI.DisableWelcomeMessage") then return end getCore():setModsPopupDone(true) ModSelector.instance:setVisible(false) local width = 650 local height = 400 local nagPanel = ISModsNagPanel:new( (getCore():getScreenWidth() - width)/2, (getCore():getScreenHeight() - height)/2, width, height) nagPanel:initialise() nagPanel:addToUIManager() nagPanel:setAlwaysOnTop(true) local joypadData = JoypadState.getMainMenuJoypad() if joypadData then joypadData.focus = nagPanel updateJoypadFocus(joypadData) end end