From d9f4c8bd13f363481298df6d2da3eeccfd0fbc6b Mon Sep 17 00:00:00 2001 From: davidh Date: Wed, 11 May 2022 03:16:11 -0500 Subject: [PATCH] Update CARM SUI-Inv and add SUI-Rads --- .../media/lua/client/ClothingActions.lua | 45 +- .../lua/client/ClothingActionsRadialMenu.lua | 57 +- .../TimedActions/CARM_ClothingExtraAction.lua | 4 +- .../media/lua/shared/Translate/EN/UI_EN.txt | 5 +- .../Contents/mods/ClothingActions/mod.info | 2 +- ClothingActions/README.md | 8 +- ClothingActions/workshop.txt | 18 +- .../media/lua/client/!SpiffUI-Inv.lua | 31 +- .../lua/client/SUI/SUI_ISInventoryPage.lua | 15 +- .../media/lua/client/SpiffUI-Inventory.lua | 10 +- .../media/lua/shared/Translate/EN/UI_EN.txt | 2 + .../media/lua/shared/Translate/RU/UI_RU.txt | 31 + SpiffUI-Inventory/README.md | 36 +- SpiffUI-Inventory/workshop.txt | 57 +- .../SpiffUI-Radials/media/SpiffUI/1-2.png | Bin 0 -> 1550 bytes .../SpiffUI-Radials/media/SpiffUI/1-4.png | Bin 0 -> 1476 bytes .../mods/SpiffUI-Radials/media/SpiffUI/1.png | Bin 0 -> 480 bytes .../SpiffUI-Radials/media/SpiffUI/ALL.png | Bin 0 -> 1549 bytes .../SpiffUI-Radials/media/SpiffUI/FULL.png | Bin 0 -> 782 bytes .../media/SpiffUI/crafting.png | Bin 0 -> 2451 bytes .../media/SpiffUI/inventory.png | Bin 0 -> 2539 bytes .../media/SpiffUI/nextpage.png | Bin 0 -> 2229 bytes .../media/SpiffUI/prevpage.png | Bin 0 -> 2102 bytes .../media/lua/client/!SpiffUI-Rads.lua | 596 +++++++++++++++++ .../ISUI/SpiffUI_ISFirearmRadialMenu.lua | 15 + .../lua/client/ISUI/SpiffUI_ISRadialMenu.lua | 435 +++++++++++++ .../client/Radials/SpiffUI-ARadialMenu.lua | 247 +++++++ .../client/Radials/SpiffUI_CraftingRadial.lua | 186 ++++++ .../client/Radials/SpiffUI_DrinkRadial.lua | 246 +++++++ .../lua/client/Radials/SpiffUI_EatRadial.lua | 199 ++++++ .../Radials/SpiffUI_EquipmentRadial.lua | 607 ++++++++++++++++++ .../client/Radials/SpiffUI_FirstAidCraft.lua | 130 ++++ .../lua/client/Radials/SpiffUI_OneRadial.lua | 121 ++++ .../client/Radials/SpiffUI_PillsRadial.lua | 212 ++++++ .../client/Radials/SpiffUI_RepairRadial.lua | 234 +++++++ .../Radials/SpiffUI_SmokeCraftRadial.lua | 168 +++++ .../client/Radials/SpiffUI_SmokeRadial.lua | 263 ++++++++ .../media/lua/client/SpiffUI-Radials.lua | 599 +++++++++++++++++ .../SpiffUI_ISClothingExtraAction.lua | 22 + .../TimedActions/SpiffUI_ISFixAction.lua | 11 + .../TimedActions/SpiffUI_ISWearClothing.lua | 15 + .../media/lua/shared/Translate/EN/UI_EN.txt | 119 ++++ .../media/lua/shared/Translate/RU/UI_RU.txt | 122 ++++ .../Contents/mods/SpiffUI-Radials/mod.info | 10 + .../Contents/mods/SpiffUI-Radials/poster.png | Bin 0 -> 192721 bytes SpiffUI-Radials/README.md | 306 +++++++++ SpiffUI-Radials/preview.png | Bin 0 -> 28706 bytes SpiffUI-Radials/workshop.txt | 136 ++++ 48 files changed, 5225 insertions(+), 95 deletions(-) create mode 100644 SpiffUI-Inventory/Contents/mods/SpiffUI-Inventory/media/lua/shared/Translate/RU/UI_RU.txt create mode 100644 SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/SpiffUI/1-2.png create mode 100644 SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/SpiffUI/1-4.png create mode 100644 SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/SpiffUI/1.png create mode 100644 SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/SpiffUI/ALL.png create mode 100644 SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/SpiffUI/FULL.png create mode 100644 SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/SpiffUI/crafting.png create mode 100644 SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/SpiffUI/inventory.png create mode 100644 SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/SpiffUI/nextpage.png create mode 100644 SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/SpiffUI/prevpage.png create mode 100644 SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/!SpiffUI-Rads.lua create mode 100644 SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/ISUI/SpiffUI_ISFirearmRadialMenu.lua create mode 100644 SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/ISUI/SpiffUI_ISRadialMenu.lua create mode 100644 SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/Radials/SpiffUI-ARadialMenu.lua create mode 100644 SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/Radials/SpiffUI_CraftingRadial.lua create mode 100644 SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/Radials/SpiffUI_DrinkRadial.lua create mode 100644 SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/Radials/SpiffUI_EatRadial.lua create mode 100644 SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/Radials/SpiffUI_EquipmentRadial.lua create mode 100644 SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/Radials/SpiffUI_FirstAidCraft.lua create mode 100644 SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/Radials/SpiffUI_OneRadial.lua create mode 100644 SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/Radials/SpiffUI_PillsRadial.lua create mode 100644 SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/Radials/SpiffUI_RepairRadial.lua create mode 100644 SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/Radials/SpiffUI_SmokeCraftRadial.lua create mode 100644 SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/Radials/SpiffUI_SmokeRadial.lua create mode 100644 SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/SpiffUI-Radials.lua create mode 100644 SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/TimedActions/SpiffUI_ISClothingExtraAction.lua create mode 100644 SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/TimedActions/SpiffUI_ISFixAction.lua create mode 100644 SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/TimedActions/SpiffUI_ISWearClothing.lua create mode 100644 SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/shared/Translate/EN/UI_EN.txt create mode 100644 SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/shared/Translate/RU/UI_RU.txt create mode 100644 SpiffUI-Radials/Contents/mods/SpiffUI-Radials/mod.info create mode 100644 SpiffUI-Radials/Contents/mods/SpiffUI-Radials/poster.png create mode 100644 SpiffUI-Radials/README.md create mode 100644 SpiffUI-Radials/preview.png create mode 100644 SpiffUI-Radials/workshop.txt diff --git a/ClothingActions/Contents/mods/ClothingActions/media/lua/client/ClothingActions.lua b/ClothingActions/Contents/mods/ClothingActions/media/lua/client/ClothingActions.lua index cf03c28..c000c37 100644 --- a/ClothingActions/Contents/mods/ClothingActions/media/lua/client/ClothingActions.lua +++ b/ClothingActions/Contents/mods/ClothingActions/media/lua/client/ClothingActions.lua @@ -2,9 +2,19 @@ -- Clothing Actions ------------------------------------------ +local CARM = require("ClothingActionsRadialMenu") + +local spiff +if getActivatedMods():contains('SpiffUI-Rads') then + -- Register our Radials + spiff = SpiffUI:Register("radials") + if not spiff.radials then spiff.radials = {} end +end + CARMconfig = { filter = false, - delay = false + delay = false, + spiff = true } local function ClothingActions() @@ -25,14 +35,6 @@ local function ClothingActions() end end - if ModKey then - local CARMMODbindings = { - name = 'CARMMK', - key = 0 - } - ModKey:AddBinding(CARMMODbindings) - end - if ModOptions and ModOptions.getInstance then local function apply(data) local player = getSpecificPlayer(0) @@ -40,6 +42,16 @@ local function ClothingActions() CARMconfig.filter = values.filter CARMconfig.delay = values.delay + CARMconfig.spiff = values.spiff + + -- Register our Radial to SpiffUI + if spiff then + if CARMconfig.spiff then + spiff.radials[9] = CARM + else + spiff.radials[9] = nil + end + end end local CARMCONFIG = { @@ -62,6 +74,15 @@ local function ClothingActions() mod_fullname = getText("UI_optionscreen_binding_ClothingActionsRM") } + if spiff then + CARMCONFIG.options_data.spiff = { + default = true, + name = getText("UI_ModOptions_CARMtoSpiff"), + OnApplyMainMenu = apply, + OnApplyInGame = apply + } + end + local optionsInstance = ModOptions:getInstance(CARMCONFIG) ModOptions:loadFile() @@ -69,8 +90,14 @@ local function ClothingActions() apply({settings = CARMCONFIG}) end) end + + Events.OnGameBoot.Add(function() + print("Clothing Actions Boot!") + end) print(getText("UI_Init_ClothingActionsRM")) end + + ClothingActions() \ No newline at end of file diff --git a/ClothingActions/Contents/mods/ClothingActions/media/lua/client/ClothingActionsRadialMenu.lua b/ClothingActions/Contents/mods/ClothingActions/media/lua/client/ClothingActionsRadialMenu.lua index bfe2808..41abcac 100644 --- a/ClothingActions/Contents/mods/ClothingActions/media/lua/client/ClothingActionsRadialMenu.lua +++ b/ClothingActions/Contents/mods/ClothingActions/media/lua/client/ClothingActionsRadialMenu.lua @@ -1,8 +1,8 @@ ------------------------------------------ -- Clothing Actions Radial Menu ------------------------------------------ +local CARadialMenu = ISBaseObject:derive("CARadialMenu") -CARadialMenu = ISBaseObject:derive("CARadialMenu") activeMenu = nil ------------------------------------------ @@ -31,21 +31,6 @@ end ------------------------------------------ -function CARadialMenu:center() - local menu = getPlayerRadialMenu(self.playerNum) - - local x = getPlayerScreenLeft(self.playerNum) - local y = getPlayerScreenTop(self.playerNum) - local w = getPlayerScreenWidth(self.playerNum) - local h = getPlayerScreenHeight(self.playerNum) - - x = x + w / 2 - y = y + h / 2 - - menu:setX(x - menu:getWidth() / 2) - menu:setY(y - menu:getHeight() / 2) -end - local function checkClothes(item) -- If there's extra options if item and item:getClothingItemExtraOption() then @@ -70,6 +55,7 @@ function CARadialMenu:fillMenu() local action = item:getClothingItemExtraOption():get(i) local itemType = moduleDotType(item:getModule(), item:getClothingItemExtra():get(i)) table.insert(commands, CACommand:new(self, item, getText("ContextMenu_" .. action), itemType, action)) + self.hasCommands = true end end end @@ -84,8 +70,12 @@ function CARadialMenu:fillMenu() end function CARadialMenu:display() + self:fillMenu() + + if not self.hasCommands then return end + local menu = getPlayerRadialMenu(self.playerNum) - self:center() + menu:center() menu:addToUIManager() if JoypadState.players[self.playerNum+1] then menu:setHideWhenButtonReleased(Joypad.DPadUp) @@ -109,6 +99,10 @@ function CARadialMenu.checkKey(key) return false end + if ModKey and ModKey.isKeyDown() then + return false + end + if UIManager.getSpeedControls() and (UIManager.getSpeedControls():getCurrentGameSpeed() == 0) then return false end @@ -148,19 +142,22 @@ function CARadialMenu.showRadialMenu(player) end local menu = CARadialMenu:new(player) - menu:fillMenu() + --menu:fillMenu() menu:display() - activeMenu = menu + --activeMenu = menu end ----- Show the Radial Menu on the Up DPad when there's not a car around -local _ISDPadWheels_onDisplayUp = ISDPadWheels.onDisplayUp -function ISDPadWheels.onDisplayUp(joypadData) - local player = getSpecificPlayer(joypadData.player) - if not player:getVehicle() and not ISVehicleMenu.getVehicleToInteractWith(player) then - CARadialMenu.showRadialMenu(player) - else - _ISDPadWheels_onDisplayUp(joypadData) +-- Only do this if SpiffUI doesn't +if not SpiffUI then + ---- Show the Radial Menu on the Up DPad when there's not a car around + local _ISDPadWheels_onDisplayUp = ISDPadWheels.onDisplayUp + function ISDPadWheels.onDisplayUp(joypadData) + local player = getSpecificPlayer(joypadData.player) + if not player:getVehicle() and not ISVehicleMenu.getVehicleToInteractWith(player) then + CARadialMenu.showRadialMenu(player) + else + _ISDPadWheels_onDisplayUp(joypadData) + end end end ------------------------------------------ @@ -196,7 +193,7 @@ function CARadialMenu.onKeyHold(key) end if (getTimestampMs() - ticks >= delay) and not radialMenu:isReallyVisible() then local menu = CARadialMenu:new(getSpecificPlayer(0)) - menu:fillMenu() + --menu:fillMenu() menu:display() activeMenu = menu end @@ -206,4 +203,6 @@ end Events.OnGameStart.Add(function() Events.OnKeyStartPressed.Add(CARadialMenu.onKeyPress) Events.OnKeyKeepPressed.Add(CARadialMenu.onKeyHold) -end) \ No newline at end of file +end) + +return CARadialMenu \ No newline at end of file diff --git a/ClothingActions/Contents/mods/ClothingActions/media/lua/client/TimedActions/CARM_ClothingExtraAction.lua b/ClothingActions/Contents/mods/ClothingActions/media/lua/client/TimedActions/CARM_ClothingExtraAction.lua index a08fd3b..e70acb5 100644 --- a/ClothingActions/Contents/mods/ClothingActions/media/lua/client/TimedActions/CARM_ClothingExtraAction.lua +++ b/ClothingActions/Contents/mods/ClothingActions/media/lua/client/TimedActions/CARM_ClothingExtraAction.lua @@ -6,7 +6,9 @@ local _ISClothingExtraAction_new = ISClothingExtraAction.new function ISClothingExtraAction:new(...) local o = _ISClothingExtraAction_new(self, ...) - o.stopOnWalk = false + o.stopOnAim = false + o.stopOnWalk = false + o.stopOnRun = true o.maxTime = 25 o.useProgressBar = false if o.character:isTimedActionInstant() then diff --git a/ClothingActions/Contents/mods/ClothingActions/media/lua/shared/Translate/EN/UI_EN.txt b/ClothingActions/Contents/mods/ClothingActions/media/lua/shared/Translate/EN/UI_EN.txt index 9f6b894..3c7e8e1 100644 --- a/ClothingActions/Contents/mods/ClothingActions/media/lua/shared/Translate/EN/UI_EN.txt +++ b/ClothingActions/Contents/mods/ClothingActions/media/lua/shared/Translate/EN/UI_EN.txt @@ -1,8 +1,9 @@ UI_EN = { - UI_Init_ClothingActionsRM = "Hello from Clothing Actions - Radial Menu!", + UI_Init_ClothingActionsRM = "Hello: Clothing Actions - Radial Menu!", UI_optionscreen_binding_ClothingActionsRM = "Clothing Actions - Radial Menu", UI_optionscreen_binding_CARM = "Show Clothing Actions Radial Menu", UI_optionscreen_binding_CARMMK = "Show Clothing Actions Radial Menu", UI_ModOptions_CARMfilter = "Disable Clothing Filter (Shows bags, watches, etc)", - UI_ModOptions_CARMdelay = "Show Radial Menu Immediately on Key Press" + UI_ModOptions_CARMdelay = "Show Radial Menu Immediately on Key Press", + UI_ModOptions_CARMtoSpiff = "Add Clothing Actions Radial to SpiffUI Radial" } \ No newline at end of file diff --git a/ClothingActions/Contents/mods/ClothingActions/mod.info b/ClothingActions/Contents/mods/ClothingActions/mod.info index d5ddb7d..ffb0f3a 100644 --- a/ClothingActions/Contents/mods/ClothingActions/mod.info +++ b/ClothingActions/Contents/mods/ClothingActions/mod.info @@ -5,6 +5,6 @@ authors=dhert description=A Radial Menu for quick access to equipped clothing actions pzversion=41 -tags=Immersion;Realistic +tags=Interface;Realistic poster=poster.png diff --git a/ClothingActions/README.md b/ClothingActions/README.md index 0c8dee5..a24237c 100644 --- a/ClothingActions/README.md +++ b/ClothingActions/README.md @@ -33,7 +33,13 @@ Default keybind is to the "Z" key. Configurable in the "Keybinds" menu. ## Translations -This mod is currently only in English. If you would like to contribute a translation, please submit a pull request! I will happily credit here and on the Steam Workshop Page! +English + +Spanish - [ElDoktor](https://github.com/fcastro97) + +Thai - [radiusgreenhill](https://github.com/radiusgreenhill) + +If you would like to contribute a translation, please submit a pull request! I will happily credit here and on the Steam Workshop Page! ``` Workshop ID: 2786689104 diff --git a/ClothingActions/workshop.txt b/ClothingActions/workshop.txt index 75ba148..f6bd74c 100644 --- a/ClothingActions/workshop.txt +++ b/ClothingActions/workshop.txt @@ -16,6 +16,17 @@ description=[url=https://steamcommunity.com/sharedfiles/filedetails/?id=26842855 description= description=Should work with any other mods that add ExtraClothingOptions to item definitions too. description= +description=UPDATE 05/11/2022: +description=Added Spanish and Thai Translations +description= +description=UPDATE 05/03/2022: +description=Added integration for [url=https://steamcommunity.com/sharedfiles/filedetails/?id=2802525922]SpiffUI - Radials[/url] +description=[list] +description=[*]If SpiffUI - Radials is installed, a new configuration option is available to add this to the main SpiffUI Radial +description=[*][b]Note:[/b]The SpiffUI Radial will override the Controller binding! Use the SpiffUI Radial instead if its installed! +description=[/list] +description=Fixed an issue where the Radial could be given focus even if there were no items. +description= description=UPDATE 04/02/2022: Added support for controllers description=This RadialMenu is now bound to the UP-DPad; this cannot be changed. Select what you want with the right thumbstick and release to perform the action. description=Don't worry, when the player is near a car the Vehicle Menu will appear as expected. @@ -46,8 +57,13 @@ description=[/tr] description=[/table] description= description=[h2]Translations[/h2] +description=[list] +description=[*]English +description=[*]Spanish - [url=https://steamcommunity.com/id/deadinside11]ElDoktor[/url] +description=[*]Thai - radiusgreenhill +description=[/list] description= -description=This mod is currently only in English, but Actions in the Radial Menu will be translated (modded actions must include their own translations). +description=Actions in the Radial Menu will be translated (modded actions must include their own translations). description=If you would like to contribute a translation, please submit a pull request on [url=https://github.com/hlfstr/pz-mods]GitHub![/url] I will happily give credit! tags=Build 41;Interface;Realistic visibility=public diff --git a/SpiffUI-Inventory/Contents/mods/SpiffUI-Inventory/media/lua/client/!SpiffUI-Inv.lua b/SpiffUI-Inventory/Contents/mods/SpiffUI-Inventory/media/lua/client/!SpiffUI-Inv.lua index 5c1b988..6e1061a 100644 --- a/SpiffUI-Inventory/Contents/mods/SpiffUI-Inventory/media/lua/client/!SpiffUI-Inv.lua +++ b/SpiffUI-Inventory/Contents/mods/SpiffUI-Inventory/media/lua/client/!SpiffUI-Inv.lua @@ -25,7 +25,7 @@ ------------------------------------------ -- Set the SpiffUI lib version -local SPIFFUI_VERSION = 1 --<<< DO NOT CHANGE UNLESS YOU KNOW WHAT YOU'RE DOING +local SPIFFUI_VERSION = 2 --<<< DO NOT CHANGE UNLESS YOU KNOW WHAT YOU'RE DOING if SpiffUI then if SpiffUI.Version >= SPIFFUI_VERSION then return -- Don't do anything else @@ -155,6 +155,7 @@ SpiffUI.preCheck = function() end local function keyDown(key) + --print("Pressed: " .. getKeyName(key) .. " | " .. key) local player = SpiffUI.preCheck(key) if not player then return end for _,bind in ipairs(SpiffUI.KeyBinds) do @@ -488,13 +489,14 @@ function SpiffUI:ModOptions() end end --- Due to SpiffUI being loaded as one of the first mods, it will be one of the first to Boot ----- We don't want that, we want this to be last. So, this makes sure of that. +-- At first I had this run only once, but apparently when there's only 1 mod this breaks +---- So, OnPostBoot is added to run things last SpiffUI.firstBoot = function() Events.OnGameBoot.Add(function() - SpiffUI:OnGameBoot() + SpiffUI:OnPostBoot() end) - Events.OnGameBoot.Remove(SpiffUI.firstBoot) + --Events.OnGameBoot.Remove(SpiffUI.firstBoot) + SpiffUI:OnGameBoot() end function SpiffUI:OnGameBoot() @@ -513,7 +515,7 @@ function SpiffUI:OnGameBoot() for i = 1, #keyBinding do if keyBinding[i].value == name then table.remove(keyBinding, i) - print("Removed Keybind: " .. name) + --print("Removed Keybind: " .. name) found = true break end @@ -524,7 +526,7 @@ function SpiffUI:OnGameBoot() for i,bind in ipairs(SpiffUI.KeyBinds) do if bind.name == name then table.remove(SpiffUI.KeyBinds, i) - print("Removed SpiffUI Keybind: " .. name) + --print("Removed SpiffUI Keybind: " .. name) break end end @@ -547,6 +549,21 @@ function SpiffUI:OnGameBoot() end +function SpiffUI:OnPostBoot() + -- Let's Remove some keys possibly added by mods + for name,_ in pairs(SpiffUI.KeyDisables) do + local found = false + for i = 1, #keyBinding do + if keyBinding[i].value == name then + table.remove(keyBinding, i) + --print("Removed Keybind: " .. name) + found = true + break + end + end + end +end + function SpiffUI:OnCreatePlayer(id) for _,j in ipairs(SpiffUI) do local mod = SpiffUI[j] diff --git a/SpiffUI-Inventory/Contents/mods/SpiffUI-Inventory/media/lua/client/SUI/SUI_ISInventoryPage.lua b/SpiffUI-Inventory/Contents/mods/SpiffUI-Inventory/media/lua/client/SUI/SUI_ISInventoryPage.lua index ec9bdb3..3d54499 100644 --- a/SpiffUI-Inventory/Contents/mods/SpiffUI-Inventory/media/lua/client/SUI/SUI_ISInventoryPage.lua +++ b/SpiffUI-Inventory/Contents/mods/SpiffUI-Inventory/media/lua/client/SUI/SUI_ISInventoryPage.lua @@ -131,18 +131,18 @@ function ISInventoryPage:update() self.inventory:getParent():setHighlightColor(getCore():getObjectHighlitedColor()); self.coloredInv = self.inventory; end - - if not self.isCollapsed and self.inventoryPane.inventory:getType() == "floor" and self.inventoryPane.inventory:getItems():isEmpty() then - if self.autoHide and self.holdOpen and not self.prevMouse then - self:Collapse(true, "No Floor Items") - end - end end ------------------------------------------ self.collapseCounter = 0 self.wasVisible = not self.isCollapsed + if not self.onCharacter and not self.isCollapsed and self.inventoryPane.inventory:getType() == "floor" and self.inventoryPane.inventory:getItems():isEmpty() then + if self.autoHide and self.holdOpen and not self.prevMouse and not spiff.config.mouseHide then + self:Collapse(true, "No Floor Items") + end + end + if not self.isCollapsed then -- When we stop dragging, set panel to close after next mouseout or click, or set to tie with our friend if not self.fVisible and (not ISMouseDrag.dragging or #ISMouseDrag.dragging == 0) and self.fromDrag then @@ -173,7 +173,7 @@ function ISInventoryPage:update() --- prevmouse is to not have this happen immediately, we need a tick for other logic to kick in on state change --- holdOpen should prevent the window from closing if we click on an object --- We do this here so we can check the mouse location with our buffer - if not self.fVisible and self.autoHide and not self.prevMouse and not self.holdOpen and not self.fromDrag and not self.toDrag and not self.wasDrag and not self:isMouseInBuffer() then + if not self.fVisible and not spiff.config.mouseHide and self.autoHide and not self.prevMouse and not self.holdOpen and not self.fromDrag and not self.toDrag and not self.wasDrag and not self:isMouseInBuffer() then self:Collapse(true, "Autohide") end @@ -463,6 +463,7 @@ function ISInventoryPage:InitSUI() self.wasDrag = false self.wasVisible = false + --self.mouseHide = spiff.config.mouseHide end function ISInventoryPage:SUIReset() diff --git a/SpiffUI-Inventory/Contents/mods/SpiffUI-Inventory/media/lua/client/SpiffUI-Inventory.lua b/SpiffUI-Inventory/Contents/mods/SpiffUI-Inventory/media/lua/client/SpiffUI-Inventory.lua index 5399256..238a306 100644 --- a/SpiffUI-Inventory/Contents/mods/SpiffUI-Inventory/media/lua/client/SpiffUI-Inventory.lua +++ b/SpiffUI-Inventory/Contents/mods/SpiffUI-Inventory/media/lua/client/SpiffUI-Inventory.lua @@ -7,7 +7,8 @@ SpiffUI = SpiffUI or {} local spiff = SpiffUI:Register("inventory") spiff.config = { - enabled = true + enabled = true, + mouseHide = false } local function SpiffUIBoot() @@ -16,6 +17,7 @@ local function SpiffUIBoot() local options = data.settings.options -- Set options spiff.config.enabled = options.enableInv + spiff.config.mouseHide = options.mouseHide SpiffUI.equippedItem["Inventory"] = not options.hideInv end @@ -40,6 +42,12 @@ local function SpiffUIBoot() OnApplyMainMenu = apply, OnApplyInGame = applyGame, }, + mouseHide = { + name = "UI_ModOptions_SpiffUI_Inv_mouseHide", + default = false, + OnApplyMainMenu = apply, + OnApplyInGame = apply, + }, }, mod_id = "SpiffUI - Inventory", mod_shortname = "SpiffUI-Inv", diff --git a/SpiffUI-Inventory/Contents/mods/SpiffUI-Inventory/media/lua/shared/Translate/EN/UI_EN.txt b/SpiffUI-Inventory/Contents/mods/SpiffUI-Inventory/media/lua/shared/Translate/EN/UI_EN.txt index cebbaf4..e0e50f8 100644 --- a/SpiffUI-Inventory/Contents/mods/SpiffUI-Inventory/media/lua/shared/Translate/EN/UI_EN.txt +++ b/SpiffUI-Inventory/Contents/mods/SpiffUI-Inventory/media/lua/shared/Translate/EN/UI_EN.txt @@ -23,5 +23,7 @@ UI_EN = { UI_ModOptions_SpiffUI_Inv_hideInv = "Hide Inventory Button", + UI_ModOptions_SpiffUI_Inv_mouseHide = "Only Autohide on Mouse Click", + UI_optionscreen_binding_SpiffUI_Inv = "Toggle Inventory" } \ No newline at end of file diff --git a/SpiffUI-Inventory/Contents/mods/SpiffUI-Inventory/media/lua/shared/Translate/RU/UI_RU.txt b/SpiffUI-Inventory/Contents/mods/SpiffUI-Inventory/media/lua/shared/Translate/RU/UI_RU.txt new file mode 100644 index 0000000..4e1480a --- /dev/null +++ b/SpiffUI-Inventory/Contents/mods/SpiffUI-Inventory/media/lua/shared/Translate/RU/UI_RU.txt @@ -0,0 +1,31 @@ +UI_RU = { + + -- SpiffUI + UI_Hello_SpiffUI = "Hello SpiffUI!", + UI_Name_SpiffUI = "SpiffUI", + UI_optionscreen_binding_SpiffUI = "SpiffUI" + + UI_ModOptions_SpiffUI_applyNewKeybinds = "Установите рекомендуемые сочетания клавиш SpiffUI", + UI_ModOptions_SpiffUI_Modal_applyNewKeybinds = " Установить привязки клавиш SpiffUI Устанавливает следующие сочетания клавиш: ", + UI_ModOptions_SpiffUI_Modal_aNKChild = " %1 для: [%2] ", + + UI_ModOptions_SpiffUI_runAllResets = "Запустить полный сброс SpiffUI", + UI_ModOptions_SpiffUI_tooltip_runResets = "Работает только в игре!", + UI_ModOptions_SpiffUI_Modal_runResets = " Сброс SpiffUI Будут сброшены: ", + + + -- SpiffUI -- Inventory + UI_Hello_SpiffUI_Inv = "Hello SpiffUI - Инвентарь!", + + UI_Name_SpiffUI_Inv = "SpiffUI - Инвентарь", + + UI_ModOptions_SpiffUI_Inv_enable = "Включить инвентарь SpiffUI", + UI_ModOptions_SpiffUI_Inv_tooltip_enable = "Примечание. В игре требуется перезагрузка!", + + UI_ModOptions_SpiffUI_Inv_hideInv = "Скрыть кнопку инвентаря", + + UI_ModOptions_SpiffUI_Inv_mouseHide = "Только автоматическое скрытие по щелчку мыши", + + UI_optionscreen_binding_SpiffUI_Inv = "Переключить инвентарь", + +} \ No newline at end of file diff --git a/SpiffUI-Inventory/README.md b/SpiffUI-Inventory/README.md index 792312b..6645352 100644 --- a/SpiffUI-Inventory/README.md +++ b/SpiffUI-Inventory/README.md @@ -4,32 +4,33 @@ ## About SpiffUI -SpiffUI is an attempt to make the Project Zomboid in-game UI more player-friendly. The UI currently acts like a windowing system overtop a video game; similar in behavior to the Openbox/Fluxbox windowing system for a Linux Desktop. This is works as the complexity of the game warrants this, but with little tweaks it can be so much better. +SpiffUI (pronounced "Spiffy") is an attempt to make the Project Zomboid in-game UI more player-friendly. The UI currently acts like a windowing system overtop a video game; similar in behavior to the Openbox/Fluxbox windowing system for a Linux Desktop. This works as the complexity of the game warrants this, but with little tweaks it can be so much better. -There will be several independent modules released under the SpiffUI name that each change/add their own features. +There will be several independent modules released under the SpiffUI name that each change/add their own features. This allows me to make modifications to these independently, and allow you, the user, to choose which are active. **Supports B41+. Works in Multiplayer** ## SpiffUI - Inventory -Changes the default behavior of the Loot and Player Inventories in how they are displayed. +The goal of this mod is to change the default behavior of the Loot and Player Inventories in how they are displayed. The Inventory/Loot Panel rules should make sense in normal usage, but may take a small adjustment to your playstyle. Try it for yourself and let me know what you think! -For starters, the Inventory and Loot panels are hidden until the player triggers an interaction. +### Features -The Inventory is now bound to the "Tab" key by default. Pressing Tab will open/close both the inventory and loot panels for the player, the panels cannot be closed when open in this way until you press the key again. +- The Inventory and Loot panels are hidden until the player triggers an interaction. -Bringing the mouse to the top of the screen will show the inventory or loot panel allowing easy access; you can freely switch between which panel is open by moving the mouse. The panel is automatically hidden after losing mouse focus. +- The Inventory is now bound to the "Tab" key by default. Pressing Tab will open/close both the inventory and loot panels for the player, the panels cannot be closed when open in this way until you press the key again. -Panels are no longer able to be resized horizontally or moved around. They are instead locked to the top of the screen in the default location, and can only be resized vertically. The "Close", "Info", "Collapse", and "Pin" buttons are also hidden. +- Bringing the mouse to the top of the screen will show the inventory or loot panel allowing easy access; you can freely switch between which panel is open by moving the mouse. The panel is automatically hidden after losing mouse focus. -Clicking on a world container will show the loot panel and lock it open until the window is interacted with, an external mouse click, or if you walk away changing the loot panel to a blank floor. +- Panels are no longer able to be resized horizontally or moved around. They are instead locked to the top of the screen in the default location, and can only be resized vertically. The "Close", "Info", "Collapse", and "Pin" buttons are also hidden. -Even when "hidden", the panels are only a small mouse-movement or key-press away! +- Clicking on a world container will show the loot panel and lock it open until the window is interacted with, an external mouse click, or if you walk away changing the loot panel to a blank floor. -Option to Hide the "Inventory" button in the left panel. (I know the keybind, I don't need it) +- Option to Hide the "Inventory" button in the left panel. (I know the keybind, I don't need it) -The Inventory/Loot Panel rules should make sense in normal usage, but may take a small adjustment to your playstyle. Try it for yourself and let me know what you think! +### Controllers +If playing with a controller the new behavior will not apply and the inventory will behave like Vanilla. -If playing with a controller these rules will not apply. +**NOTE:** I HIGHLY recommend that you run both the "Set SpiffUI Recommended Keybinds" and "Run All SpiffUI Resets" after you first install and start the game! ## SpiffUI Configuration @@ -62,8 +63,15 @@ If ModOptions is installed (Recommended) SpiffUI will appear as a category. Thi ## Translations -This mod is currently only in English! If you would like to help with translations, please submit a Pull Request. +English + +Spanish - [ElDoktor](https://github.com/fcastro97) + +Thai - [radiusgreenhill](https://github.com/radiusgreenhill) + +If you would like to help with translations, please submit a Pull Request. ``` - +Workshop ID: 2799848602 +Mod ID: SpiffUI-Inv ``` \ No newline at end of file diff --git a/SpiffUI-Inventory/workshop.txt b/SpiffUI-Inventory/workshop.txt index e8f8131..9711d2d 100644 --- a/SpiffUI-Inventory/workshop.txt +++ b/SpiffUI-Inventory/workshop.txt @@ -6,33 +6,33 @@ description=[h3]A new save is not required[/h3] description= description=[h2]About SpiffUI[/h2] description= -description=SpiffUI is an attempt to make the Project Zomboid in-game UI more player-friendly. The UI currently acts like a windowing system overtop a video game; similar in behavior to the Openbox/Fluxbox windowing system for a Linux Desktop. This is works as the complexity of the game warrants this, but with little tweaks it can be so much better. +description=SpiffUI (pronounced "Spiffy") is an attempt to make the Project Zomboid in-game UI more player-friendly. The UI currently acts like a windowing system overtop a video game; similar in behavior to the Openbox/Fluxbox windowing system for a Linux Desktop. This works as the complexity of the game warrants this, but with little tweaks it can be so much better. description= description=There will be several independent modules released under the SpiffUI name that each change/add their own features. This allows me to make modifications to these independently, and allow you, the user, to choose which are active. description= -description=[h2]About SpiffUI[/h2] +description=[h2]About SpiffUI - Inventory[/h2] description= -description=Changes the default behavior of the Loot and Player Inventories in how they are displayed. +description=The goal of this mod is to change the default behavior of the Loot and Player Inventories in how they are displayed. The Inventory/Loot Panel rules should make sense in normal usage, but may take a small adjustment to your playstyle. Try it for yourself and let me know what you think! description= -description=For starters, the Inventory and Loot panels are hidden until the player triggers an interaction. +description=[b]Features[/b] +description=[list] +description=[*]The Inventory and Loot panels are hidden until the player triggers an interaction. +description=[*]The Inventory is now bound to the "Tab" key by default. Pressing Tab will open/close both the inventory and loot panels for the player. The panels cannot be closed when open in this way until you press the key again. +description=[*]Bringing the mouse to the top of the screen will show the inventory or loot panel allowing easy access; you can freely switch between which panel is open by moving the mouse. The panel is automatically hidden after losing mouse focus. +description=[*]Panels are no longer able to be resized horizontally or moved around. They are instead locked to the top of the screen in the default location, and can only be resized vertically. The "Close", "Info", "Collapse", and "Pin" buttons are also hidden. +description=[*]Clicking on a world container will show the loot panel and lock it open until the window is interacted with, an external mouse click, or if you walk away changing the loot panel to a blank floor. +description=[*]Option to Hide the "Inventory" button in the left panel. (I know the keybind, I don't need it) +description=[/list] description= -description=The Inventory is now bound to the "Tab" key by default. Pressing Tab will open/close both the inventory and loot panels for the player, the panels cannot be closed when open in this way until you press the key again. +description=[b]Update v2[/b] +description=[list] +description=[*]Added option to only autohide on External Mouse Click from windows +description=[/list] description= -description=Bringing the mouse to the top of the screen will show the inventory or loot panel allowing easy access; you can freely switch between which panel is open by moving the mouse. The panel is automatically hidden after losing mouse focus. +description=[h3] Controllers [/h3] +description=If playing with a controller the new behavior will not apply and the inventory will behave like Vanilla. description= -description=Panels are no longer able to be resized horizontally or moved around. They are instead locked to the top of the screen in the default location, and can only be resized vertically. The "Close", "Info", "Collapse", and "Pin" buttons are also hidden. -description= -description=Clicking on a world container will show the loot panel and lock it open until the window is interacted with, an external mouse click, or if you walk away changing the loot panel to a blank floor. -description= -description=Even when "hidden", the panels are only a small mouse-movement or key-press away! -description= -description=Option to Hide the "Inventory" button in the left panel. (I know the keybind, I don't need it) -description= -description=The Inventory/Loot Panel rules should make sense in normal usage, but may take a small adjustment to your playstyle. Try it for yourself and let me know what you think! -description= -description=If playing with a controller these rules will not apply. -description= -description=I HIGHLY recommend that you run both the "Set SpiffUI Recommended Keybinds" and "Run All SpiffUI Resets" after you first install and start the game! +description=[b]NOTE:[/b] I HIGHLY recommend that you run both the "Set SpiffUI Recommended Keybinds" and "Run All SpiffUI Resets" after you first install and start the game! description= description=[h2]SpiffUI Configuration[/h2] description= @@ -77,8 +77,21 @@ description=[td]Hides the Inventory button in the left sidemenu[/td] description=[/tr] description=[/table] description= -description=[h2]Translations[/h2] +description=[h2] Known Issues [/h2] +description=[list] +description=[*] The Dialog Box shown for the SpiffUI options will trigger the game to be unpaused if in-game. +description=[*] Controllers do not gain focus to the Settings Dialog; please use a mouse for now. +description=[*] Initiating a splitscreen game does not move Player 1's Inventory/Loot panels. This is vanilla behavior, but complicates things as you cannot move these panels with this mod. +description=[/list] description= -description=This mod is currently only in English. If you would like to contribute a translation, please submit a pull request on [url=https://github.com/hlfstr/pz-mods]GitHub![/url] I will happily give credit! +description= +description=[h2]Translations[/h2] +description=[list] +description=[*]English +description=[*]Russian - [url=https://steamcommunity.com/profiles/76561198433229952]fourteensix[/url] +description=[*]Spanish - [url=https://steamcommunity.com/id/deadinside11]ElDoktor[/url] +description=[*]Thai - radiusgreenhill +description=[/list] +description= If you would like to contribute a translation, please submit a pull request on [url=https://github.com/hlfstr/pz-mods]GitHub![/url] I will happily give credit! tags=Build 41;Framework;Interface;Misc -visibility=friendsOnly +visibility=public diff --git a/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/SpiffUI/1-2.png b/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/SpiffUI/1-2.png new file mode 100644 index 0000000000000000000000000000000000000000..f6b7d24f959dfa0f22674a9b8b968d2b01ca38fd GIT binary patch literal 1550 zcmV+p2J!icP)pF8FWQhbW?9;ba!ELWdL_~cP?peYja~^aAhuUa%Y?FJQ@H11)E7k zK~zYItyXJHQ)d`{P7BmRVc}W{a^G+n35(l=O%^Z;Y7;FK37HUN1&c0@Od2=-Eh8FP z!Uhbt5k!871PH>URHB6v2UF`H;FL)q$_i0Sxff`GBbKv2J@rs~8`+b5Y5HED_s#dc z?*aZ_5C8%IdSp+tk!FFBA$N0^mCE&O?)&<>lpduD-s0Q%uXFR4Vl`F)=^TIcSESUS3|`W@TkPQz#Tg zB9X|4nbpnB&2`6)9ijHx6&DwGCO9}a008uQ{o3{G*S|NZ4p&xIo{Eo;_p#%S$jC^K z%F4{Z0!a6D|N z2tJ=*kd&0<0{|37ZFF>W)B#ur@To*1VKa?KM@J30xw)cCmo5byJ$m$tUawzd>Jt(Y z0s#2408A(p3N}SiMtj8Uz%M;L{UDpob_0NW_wKC@4i5fk(((Cx{w88=ZEf1MwY6>l z8|&-q%?}eVaKNm2xh#rj+<7Mle! znd~nB&jC;X{=9niD(IrMTJ5Srp{QW^FE1@ES$&C{l9*0>U0vNX%U82^@7@}``6}5- zNlD|hO>L1nB)j=*UF6Iw{fq?--et!Pf6B84^0@$GC)-Jz8#KgpWwR7iAJ^+v; z`SQk%8>J2kIZ#kgP%o8AeZd$xw{PFpOQq5*olYl*MYp#?EIKe!V&1EAxx5X4!I~|A z!xt}JEEfm_Z;%3j3l}aN>F(}cT3J~!k|en?KR-X!)6-L|(P$d25i?qwW2QCbDHICR zU0q$d05CK(WVmzZP6=#W`tb1ZT!BE~XH5qHVPRpOd3kwE(ObQ}z12B6Ilo)G{4-Ni zQ*IVAN~_hr0FWV(NX!?swYBvh03)^%^LRW@TRK~ah=?EnY_~?t(ACv7#$4nomCEq+ z>C^U*kdT8xK|%fiFg-oJDwD~+vzKIKWaOGsshl+!3@d9+U}k1!xvHva8o=MSR!>l1 zVBj~=(a|3)E-t=!^ypD7Ns>w~ms?a`UVhfy-QA_Cs;X0^Qhf%-6So2aKpcQ*yk6e+ zFb$v!fWh8QWa=n}>^%S^fH63?ek@}-0tEp70zxx|Lm2q+`~Uy|07*qoM6N<$f>LJ7 AhX4Qo literal 0 HcmV?d00001 diff --git a/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/SpiffUI/1-4.png b/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/SpiffUI/1-4.png new file mode 100644 index 0000000000000000000000000000000000000000..25c6c1250b1c9716a484d9696b99b14d702f7c5e GIT binary patch literal 1476 zcmV;#1v~nQP)pF8FWQhbW?9;ba!ELWdL_~cP?peYja~^aAhuUa%Y?FJQ@H11yM;v zK~zYIwO4ISTU8i-Zf{vBEp7Q~nMQ<37plRKfdrC1HAhewYl? zgtewZq3Vfe!+W`YGQr3mnI3wOOXH%`vtc7B{-C6gOxGtRMb>HnhEzJJct+ z$vy9VKc4fRd*1UN;J=3iKnVc;|KK|c1b`d>3IH6IHcE=39#|}v`9p^e%>vlLA_f6K z2H?5%cUHtIs;a7P_V)J94-5==4jede1Au4?J5s4s&d@X+q-i=dI5@ZnAUlCRha}1R zhK7c}&YU^pId|^dLStj&GyrKLVmo*|UYlO8pQmX$6nFMdS074A9+=7CF?{qp{Dw87)hZB``4uDsh zo0~<6$N>P4$4lAd6T#>6k2W_FipmZT%!aKR=VLa}I#NhlhtNi;9X)tJP}b z@#Dwu`u+YVEbR#Z^+%2ziIC~D8-O z8%IV)>TNdL0!xC}vu96xety0b0G5}RS4T%jPcuzKEEb>Y?(UWm1i|(Bd@EY5_UF#d z&WBt1=Wcip&*-7Y<6&Evi<_I9Bb&!$GOf(b&GjKZI~5%r9h6KaO9ueGUOziAF;RQ} z{{0^Syp<>b6Omvr7-U0^$jZw4sHUbyygm+%j*boj@Wtp!_U+sE?ZJZwGXTJDw|o2g z`ZNGmT`t#ytvIpG6cf_bYPE{X;$xIXUb)2FKdcGT3= zv!iCMw-7rF%Jh#Tj$L+DocDsE(Ob%fFN!?DTGp^HcyWMjD>SE4a zkKgbAB>}mFn4O)S^85YE8)Y<2J2sA)2(Dhdc=3&DI4Ljl@o=RQh>!b@g~zS=m5J zN=hx(it`5sgJJ&s`SS~V_wM}(K+?Y;7)B<5{Q&B)c5#YAqFYq#x6rz5H`X%$Cs?*j eED(+r=kFhWj`g@ye2)nL0000pF8FWQhbW?9;ba!ELWdL_~cP?peYja~^aAhuUa%Y?FJQ@H10c}Y{ zK~y-6?UX-DLQxpTf9Gm{FbN|YLC8((>3@xI$#nq1>7_Ne|egg*~9Q*)|Elp0E zh)^_K3>?HP@9kbP>vmcUE_oGf?twF$m-qMZyzhbIV!i~h1?)}l#)4jU0)fC)Hk&o8 z)#`JxSTrM%NN#E}<9ZN_#U4AIj;X4u{5gd};SJbu+Zs=z(dcC|nLJ9RQtLtpm)$8G z4qJfV4Jg52u#(T`&*SmIR0^w zz!&fYTsNCdZC)nF?3QJHE(J&_R{R4jnoSwn5EC9<9&~^Rgcg-*i3A{Q2-EQ}G zGMT*DYmG)j0UlgVz<4~qZ?#$%9*>9Na5%2jYO-7|=QK^bnfV25S^;)}HQ)|-2jn** WUX~3~jpLsH0000_2` literal 0 HcmV?d00001 diff --git a/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/SpiffUI/ALL.png b/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/SpiffUI/ALL.png new file mode 100644 index 0000000000000000000000000000000000000000..e875be242c483c6feb97be7bbed464c71ea8daf4 GIT binary patch literal 1549 zcmV+o2J-odP)pF8FWQhbW?9;ba!ELWdL_~cP?peYja~^aAhuUa%Y?FJQ@H11)51j zK~z|U%~)+rQ&$*%?zy)gv=j8QFCMMRcRx9Ukw{G2fDVNJD5Pnjq%*@P(larGk zKCiE@ZwbH$QEXBGnjSrR=g4$kPU7bf!RKzS)R#q}nsnmcimaR}hQG}3&Lx&Cpl-)ab?z}v8>eP(e?Oyix z$z(FofddDc-?*2XM5v&MUavovoSZE8cdV?etX;l*`I~$9?iF3Xe%;L%E-x?7hOeS+ z8H5T-UsqQbQ1R~Hzwe!%p8gTQct=Oa2zZ;PUauGJ+`02}Y@sC>926y&%a0Zp7boyL zhlhus0GI~=o6UCHZnwK$D!WMp+}YU(!rS#nbk9z1aIWt2)~Tyb&n zS!|Id7?7!qjEu(I+}wb@$!4=L0H(n^p*tK7Yp^1gWj_Is5ZwPRzz<4gFc@|P?@c8o zB`7E;=mJm+phhSZes%o#@jbzc%FD|Isi~<(M93B)gaSZ^8;=HtVVLMrfM19rgf!IG z*L#BnBoc|Rv$L~oZf@>lj^nua_;^Mv7K?-B;^N{2rKP1`w70ka5YCuXDitb~$}GFx z9&;dkq^73sfN#guW&01^@sXhMiUtyVL&wY4IKVT3#iRZ>!N*lad`8O||^qKHbRN>r)-bqJ9G(49Vg z`sbdWp22YZq@*ONUat=|l#!R0_ftzti;@8#Vp+CYC=>=PtMT#i6{FF3*6DO!0}%YL zQ2;VbCey>4H*YHW#igpMN_6$=)e?`#6Ya_#5;-|JIXyi+10ifig;uMj0H_H7&Axs6 z0?u>G%gbx$&!6vdI-PCsJ$7(G%?n^+U|_)5+S(fMn4(Z9#CpBHZf0i2%5mJL9eeid znG?X2!{J!kEZ1hUQ2=Hc0Jh%V-dE}A=`Mz0FgG{Hw70iEF`LbwA^L3ndgaQMuNj8< zZtvc`9ssadEaI`Tv3|SVZo6>d!Y+fs0D(Xd)uHwEb!vEcnC|TCJPBZ^xw*Nisi}!1 zCMHJBILC3+B!sgarV909f4k7H)8pW8kg<_!Gci0Jy&aHj~&9^K7=}00000NkvXXu0mjf*}%@O literal 0 HcmV?d00001 diff --git a/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/SpiffUI/FULL.png b/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/SpiffUI/FULL.png new file mode 100644 index 0000000000000000000000000000000000000000..79272f89ab4da7d127da1b908402b9c8ec578c69 GIT binary patch literal 782 zcmV+p1M&QcP)pF8FWQhbW?9;ba!ELWdL_~cP?peYja~^aAhuUa%Y?FJQ@H10-H%h zK~zYIt(DDd8c`I*e=`%cBGD!jYZVz9j1e11BmE%IRkAUQLg*rGHd%DpMgM?6mtB=Y zcFCfPg1anB5gM1V=%x@26pR6tiqgTD8qzPnI$fwG)y7OsTe z2VB5cK+{{KCp@w&zgt;Z3EAy-VzF2ul}d$y!%H+cw28>h&d!f~KCk8TdF|lfpdAbb z<9ZqtbqGkav$Kz;r>Ctwz-%^);c)mqAR8gz@_N1Ieo#>q0IwkePN#DK>|!n>1g=d? zObmcyV`CaHn7E{X2;B7h{q_EYq9~f#Y@WG@Lprk;01My-rhq%ZgJ3ZDe0_c0DoN5m zL>7xhJUKbJySKL|0^{8!0S%yamK0!IlBAdO^Yf1bfq+exW!!EzilQ_^p^!-w#dEvN z<#LT|HanuKs&I64M6p_A&u1BSUA=L7dfHxFTRTjr z(=#IATUc1QXB0WW=;)}ly1E(w0wQqLX0sW^{WnY|6M$I+(y>_VbFEfu7)9Q0x3y?A zssfqbPrl`JI^QfVF3wF(PU3JlaJgJ9pU>A;6y?e=vRbXy%;j=gxm-4>s!FL;BAHBP zGnvd2AbHlT1Ui#>1F!?vf!j+VSrvzZ3I0A--q-Ctxtk{{R30 literal 0 HcmV?d00001 diff --git a/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/SpiffUI/crafting.png b/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/SpiffUI/crafting.png new file mode 100644 index 0000000000000000000000000000000000000000..01cb4370910d1fe92c8b9c6bb47deb7745acea7f GIT binary patch literal 2451 zcmV;E32gR>P)EX>4Tx04R}tkv&MmKpe$iQ;Q-M2aAX}WT>4ih>AFB6^c+H)C#RSm|Xe=O&XFE z7e~Rh;NZt%)xpJCR|i)?5c~jfbaGO3krMxx6k5c1aNLh~_a1le0HIM~n$AQI0q!?cMvh^IGg zgY!Odgq38K_?&pmqze*1a$WKGjdRgufoDd{OnRO;LM#?LSm|I^GBx5U;;5?WlrLmG zRyl8R)+#mDx+i~OIIpiPbDic0l32tNB#2N@Lm3s=h|{W*Vj)fY2_OHk>zBx-kgE(v zjs;YqL3aJ%fAG6ot1vm?C500}=*4k9MuF~KpjmgE?_j}uW_&m#wlq8gqEey01ZJ+6h!HVq9&zKsy40EPeo~~E>bELL0ch_C@Be1 zX-cZJ0g?#Qpp*t2V@$S!Z4AbE#xtJr?CYD`4;?DYY7N*XRV9verT3(J_0E0o{?9q@ z4|j1F|653tSR;?QF5YQ^@+3B7R1{@B@LM1Nh?|Vlz>LWfRBv~I#bS{xX0yJzxw*1+ zVXMvO^P#FLZnqn|-HzF8CXq-mI5Y5#bh!uFfhR0U+<%%qay^kZ}kDn6bTlA0&pJa^9KT( zRxDeJqNoHzA+p&lsZ@$|I*r9*p^(pW=ImKLFbbUcGzgBx1z@+YVm20w4Ovx?Bncq| z`Fx&%fdK-60Qp>A9u5ZA0ukW7Pm>_PZoAoxtmu#x8KcPrKr|YqzrUY&JdW4v#bh)x zc>VfX;D^9+;9#lZr~M3$g%L=vTDFv2L7+Dosi>$xk|d(hC_)IVRx56|o2I5Fs^(SG z-rmlhJ$t(2@%U$e?6k2y(DRYgrr4Rv*Ow6wHf zvY2UYZN+Rh6OYHIPX{Nc=C3VktRou;U??vqlSwl?Je(7-#~<*o35Ub;T`m_cmy2L9 zNTg?!ef#zi2n57rAG#6y3IU{m)um%p4#a#upZNB! zUE;^j{7BT*)d}DtFl#d8J_lrcRkdQvle@%>m;+9g1Clopc)9d~^rdlo1V8!sL($oF4lSEN z(X!YKI__V-nx$WU66>t$3gFLWW~1b?87VUedi*iYT~7nNUh?UiMX^OXovy=ZGAgDrx$0L11*;^8OTuXEJM-KoazY?$!HgWFZ?%6 z8v{3R+}AL_VZ+w#v##{_&q~K5-vjc%saqjf1dbt!?!Z9b{fY!twe^@C9#mB&c(s>n z7cby-+tCUI{DC1p3Z`?wBS7Cx$jt!$zgPFiNKXhZNRf*-~L28 zr~%u7;)k85zp0vSln;f8MuH6YeZ&llg4tvu8H+NK(IW)$(x;jTF5pdSB;#=s$t1Z#j&x3Q zf$#$z|4H;ENjmAPZkV-s+fMAW>xmU~T({^Q)=PLy1u3#bE* z&GyxLR;+srrL2N6I|5GWKV6q3CC{4WTNjD|{@d48&a zbr$e+OH-pHm-5|6I7~1SC8tSL&TGJ8F`*ib)HE+*W<{-JGh39o^P1$v>$c#S+eoe` z)7ANRELwuU{^0KZ8)i)(-r)7JWsWf_OvPAZ)ykxUT^hY>9K(I89)gOLA~l&=A{ z3D(R5u9z)$;dFb2B*_AJ{!X>uBw*&adAU+&U?Nz7rZM-Or4Gbh+{OPL{t4Ti8mHbX RvaSFC002ovPDHLkV1m2>aN+;} literal 0 HcmV?d00001 diff --git a/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/SpiffUI/inventory.png b/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/SpiffUI/inventory.png new file mode 100644 index 0000000000000000000000000000000000000000..66e38c9923d91f830518592fc5e0636ba81110d0 GIT binary patch literal 2539 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 DOT8Kt literal 0 HcmV?d00001 diff --git a/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/SpiffUI/prevpage.png b/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/SpiffUI/prevpage.png new file mode 100644 index 0000000000000000000000000000000000000000..3a14028437938877b311d9a85af6c42c9474737a GIT binary patch literal 2102 zcmV-62+8+}P)pF8FWQhbW?9;ba!ELWdL_~cP?peYja~^aAhuUa%Y?FJQ@H12g6B3 zK~z|U?U-F?9M=`c|L4xf-PxIyw7aq`TWwq!1P-y{kFs^*hvKBrmZT8dL1}6XwI6H} z#cdi0l+w*P21ER!x&);*acL=(;FcC@;W{|fQt^YD_(4#dVymLEypFWmncexg zrw=lxhy~3^(PB62{%xPxs+_PuT(Y0&WUbSs|)-Vj;FbrQx>7~=@ ziLG0=o;`c^>`rEGW9B3?Yo9cn#>}ainVHV6uCCu2hT&V56{gc^Zf|erj*brQ=;+|} z>(}$DRjW9aN=3S^huLiQA16+n_y#k#GP4nTpw3q8;`rM)_4f9DbzorNOwJu)~U={A*!Gn8;hK5e0(`nstoZ9;!qD8L( zKq-aE$;oKlx^-8sUAy))fPVo9s*qv@a0I{_7#R5S(9qC{*4EZKH~=6b2qB>B`uw^Z zPzZtc_I7P@a&p_IO`8S*w4jn?l`}pj7yuXmK9@`;#~jB=I*wC!mZoWtQo^zssZ+lIFh@ja#G z)o0eMSyPvVQc5&8H^Xrpn5GF$tK3#fAq+#fu8WzO8Mv;CD2ggd5usQtVs>`6=y~2I z024$M+>?uAI1@nYmpVI-ZEA1t2hcV)HuiKjn{9y0X0ym-GH@IRQp$Pvnx+ZMve44f zg4WhnIF17$?jYE<4FHMm?(V$+Bs0^pfHiP!yLRsE_dfivC!I`o9zJ|{w-7?B%~oC4 z(cIjOrlzKOx87|;1YOtRI1XA`S|Fta5rLVjklOI@@bds{080Z_;Yy{_+TD*o{<<0+ zedd)gG;PPR&!0cPOG+u?=jH)z+g=o|)`Sp9CX=vjdp-mJpsA?|g+ieXKnj4iC}1tz z-Y1`YJscU?{ryr&21L*d!((h!RV$OpAd|_|!Bk6-5TZ_T zP1AUAaPXny$B+N50dOI>9^W^o5()T32$&%ZL+|S98o6=fMyC)$5D`UDq(xCAip3(` zbsmBsNK8#lS-D(}q?8SUEEEo!rYWFOG8To4Mn;~h!p$TSFqA^V_c8v#2ODiEy*6f0 zTqXdJs=V#ac}nqZ-^b=hAN|Y7$jDBmR0F(H3d~&hE2EU6TrM{Wfc2V(8{nSzeRjSd_JIySrZ!%rKS0N!u>vHEqF+3BwSc=OL_wO)WTgcXwZ( z2V4s7wq+qOO)wFBX5307P&5o^ym$*o0E{R?bGZx_Lg)*04oWGwu8TsUFkh?z!1Fvv zDdzyp0*I;`4FIdZ^~4iDRimR%_4vM=s)dUKTj@GHAyB$2BO8nvi6DRxMV0osrj4q) z)AKwO3I&wQ<+`nfLP2fZxbb%Y<^U+2nFRp*>yJG0ntcELT`!i)a?-N!Q6e!9cc=Fu zK-0k5()}edBT@<~ER)wr$(nZEbD; zL}eU+0HF5m+c)*?Lx)~|DU~V)QH16oK*IN-MG>eb)+pXU%n(Z~ikCper9y}(2m(w` zPvh3DTX0>s0WP1TU6qQbH%>b zB%+X+Z};{0zYV3tkyEFB)aSa%Z2XWbB_bi91p%5o4^9w3XI`|KBmlZnXbMAUh5^>~ zU?DKy_c1*^9XXCOaq;5CCpT=^a1B7Yw&kx){}4dFZ(!gI3qieugRk|uZW6JZJkx|8 zhG;66vD)_`mjDDRp`bGZQ53nZ>oMPvyjUz^Zf-6Lf>l8B%CldbZR4T8OQoMw#nVEwqDt)0)_`BzM z+V$(#BO>BtGMV4Lefuwmhlfw1;?g33aH09QL4>$w=>W1Xz3{@pcTb;wrO)%MIm3V_ z1aA92e!qG1=sWMd*JBt)9+iIz7UYZXl`mboq>qn}w;ecezylDVQsauK4Dr$3sx52G zO!1uB_Pw5-qhCy=+&^d<|Isk`XPU-edHCUXUDs`o2X%d!rNzsLpEu&`m5sc$kl%go zxmR= SPIFFUI_VERSION then + return -- Don't do anything else + else + -- We only want the newest version, and this is it + Events.OnGameBoot.Remove(SpiffUI.firstBoot) + SpiffUI = nil + end +end + +------------------------------------------ +-- Start SpiffUI +SpiffUI = {} +SpiffUI.Version = SPIFFUI_VERSION + +------------------------------------------ +-- Register Module +function SpiffUI:Register(name) + if not SpiffUI[name] then + -- Add Key for our module + table.insert(SpiffUI, name) + + -- Add module + SpiffUI[name] = {} + end + return SpiffUI[name] +end + +------------------------------------------ +-- Overrides for already-defined keys +SpiffUI.KeyDefaults = {} + +-- Add a new Key Default +function SpiffUI:AddKeyDefault(name, key) + SpiffUI.KeyDefaults[name] = tonumber(key) +end + +-- Add an array of keys +---- Expected: +---- binds { +---- ["Name"] = key, +---- } +function SpiffUI:AddKeyDefaults(binds) + for i,j in pairs(binds) do + self:AddKeyDefault(i,j) + end +end + +------------------------------------------ +-- Keys that will be removed from the binds +SpiffUI.KeyDisables = {} + +-- Add a new Key Disable +function SpiffUI:AddKeyDisable(name) + -- We do it where the name is the index to avoid dupes + SpiffUI.KeyDisables[name] = true +end + +-- Add an array of keys +---- Expected: +---- binds { +---- ["Name"] = true, +---- } +function SpiffUI:AddKeyDisables(binds) + for i,_ in pairs(binds) do + self:AddKeyDisable(i) + end +end + +------------------------------------------ +-- New Keys to Add +SpiffUI.KeyBinds = { + { + name = '[SpiffUI]', -- Title + } +} + +-- Add a new Key Bind +---- Expected: +---- bind = { +---- name = 'KeyBind', -- Name of Key +---- key = Keyboard.KEY, -- Key +---- qBlock = true, -- Don't perform key action with queue +---- Down = actionDown, -- Action on Down -- Receives playerObj -- Optional +---- Hold = actionHold, -- Action on Hold -- Receives playerObj -- Optional +---- Up = actionUp -- Action on Up -- Receives playerObj -- Optional +---- } +function SpiffUI:AddKeyBind(bind) + --SpiffUI.KeyDefaults[name] = tonumber(key) + table.insert(SpiffUI.KeyBinds, bind) +end + +-- Add an array of keys +---- Expected: +---- binds = { +---- { +---- name = 'KeyBind', -- Name of Key +---- key = Keyboard.KEY, -- Key +---- qBlock = true, -- Don't perform key action with queue +---- Down = actionDown, -- Action on Down -- Receives playerObj -- Optional +---- Hold = actionHold, -- Action on Hold -- Receives playerObj -- Optional +---- Up = actionUp -- Action on Up -- Receives playerObj -- Optional +---- }, +---- } +function SpiffUI:AddKeyBinds(binds) + for _,j in ipairs(binds) do + self:AddKeyBind(j) + end +end + +------------------------------------------ +-- Key Handlers +-- Common things to check for when checking a key +---- Returns the player object if successful +SpiffUI.preCheck = function() + local player = getSpecificPlayer(0) + + if not player or player:isDead() or player:isAsleep() then + return nil + end + + if UIManager.getSpeedControls() and (UIManager.getSpeedControls():getCurrentGameSpeed() == 0) then + return nil + end + + return player +end + +local function keyDown(key) + --print("Pressed: " .. getKeyName(key) .. " | " .. key) + local player = SpiffUI.preCheck(key) + if not player then return end + for _,bind in ipairs(SpiffUI.KeyBinds) do + if key == getCore():getKey(bind.name) then + if bind.Down then + local queue = ISTimedActionQueue.queues[player] + if bind.qBlock and queue and #queue.queue > 0 then + return + end + bind.Down(player) + end + break + end + end +end + +local function keyHold(key) + local player = SpiffUI.preCheck(key) + if not player then return end + + for _,bind in ipairs(SpiffUI.KeyBinds) do + if key == getCore():getKey(bind.name) then + if bind.Hold then + local queue = ISTimedActionQueue.queues[player] + if bind.qBlock and queue and #queue.queue > 0 then + return + end + bind.Hold(player) + end + break + end + end +end + +local function keyRelease(key) + local player = SpiffUI.preCheck(key) + if not player then return end + + for _,bind in ipairs(SpiffUI.KeyBinds) do + if key == getCore():getKey(bind.name) then + if bind.Up then + local queue = ISTimedActionQueue.queues[player] + if bind.qBlock and queue and #queue.queue > 0 then + return + end + bind.Up(player) + end + break + end + end +end + +------------------------------------------ +-- Key Action Handlers +---- used mostly for radials +SpiffUI.action = { + ticks = 0, + delay = 500, + ready = true, + wasVisible = false +} + +-- onKeyDown starts an action +SpiffUI.onKeyDown = function(player) + -- The radial menu will also close without updating me + ---- So we need to catch this + local radialMenu = getPlayerRadialMenu(0) + if SpiffUI.action.ready and (not radialMenu:isReallyVisible() and SpiffUI.action.wasVisible) then + SpiffUI.action.ready = true + end + + -- True means we're not doing another action + if SpiffUI.action.ready then + -- Hide Radial Menu on Press if applicable + if radialMenu:isReallyVisible() and getCore():getOptionRadialMenuKeyToggle() then + radialMenu:removeFromUIManager() + setJoypadFocus(player:getPlayerNum(), nil) + SpiffUI.action.wasVisible = false + SpiffUI.action.ready = true + return + end + SpiffUI.action.ticks = getTimestampMs() + SpiffUI.action.ready = false + SpiffUI.action.wasVisible = false + end +end + +-- We check here and set our state if true on hold +SpiffUI.holdTime = function() + if SpiffUI.action.ready then return false end + SpiffUI.action.ready = (getTimestampMs() - SpiffUI.action.ticks) >= SpiffUI.action.delay + return SpiffUI.action.ready +end + +-- We check here and set our state if true on release +SpiffUI.releaseTime = function() + if SpiffUI.action.ready then return false end + SpiffUI.action.ready = (getTimestampMs() - SpiffUI.action.ticks) < SpiffUI.action.delay + return SpiffUI.action.ready +end + +SpiffUI.resetKey = function() + SpiffUI.action.ready = true +end + +------------------------------------------ +-- ISEquippedItem Buttons +SpiffUI.equippedItem = { + ["Inventory"] = true, + ["Health"] = true, + ["Craft"] = true, + ["Movable"] = true, + ["Search"] = true, + ["Map"] = true, + ["MiniMap"] = true, + ["Debug"] = true, + ["Client"] = true, + ["Admin"] = true +} + +function SpiffUI:updateEquippedItem() + -- Redo the ISEquippedItem tree based on what we set + local player = getPlayerData(0) + local y = player.equipped.invBtn:getY() + for i,v in pairs(SpiffUI.equippedItem) do + if i == "Inventory" then + player.equipped.invBtn:setVisible(v) + if v then + y = player.equipped.invBtn:getY() + player.equipped.inventoryTexture:getHeightOrig() + 5 + end + elseif i == "Health" then + player.equipped.healthBtn:setVisible(v) + player.equipped.healthBtn:setY(y) + if v then + y = player.equipped.healthBtn:getY() + player.equipped.heartIcon:getHeightOrig() + 5 + end + elseif i == "Craft" then + player.equipped.craftingBtn:setVisible(v) + player.equipped.craftingBtn:setY(y) + if v then + y = player.equipped.craftingBtn:getY() + player.equipped.craftingIcon:getHeightOrig() + 5 + end + elseif i == "Movable" then + player.equipped.movableBtn:setVisible(v) + player.equipped.movableBtn:setY(y) + player.equipped.movableTooltip:setY(y) + player.equipped.movablePopup:setY(y) + if v then + y = player.equipped.movableBtn:getBottom() + 5 + end + elseif i == "Search" then + player.equipped.searchBtn:setVisible(v) + player.equipped.searchBtn:setY(y) + if v then + y = player.equipped.searchBtn:getY() + player.equipped.searchIconOff:getHeightOrig() + 5 + end + elseif i == "Map" then + if ISWorldMap.IsAllowed() then + player.equipped.mapBtn:setVisible(v) + player.equipped.mapBtn:setY(y) + + if ISMiniMap.IsAllowed() then + player.equipped.mapPopup:setY(10 + y) + end + + if v then + y = player.equipped.mapBtn:getBottom() + 5 + end + end + elseif i == "Debug" then + if getCore():getDebug() or (ISDebugMenu.forceEnable and not isClient()) then + player.equipped.debugBtn:setVisible(v) + player.equipped.debugBtn:setY(y) + if v then + y = player.equipped.debugBtn:getY() + player.equipped.debugIcon:getHeightOrig() + 5 + end + end + elseif i == "Client" then + if isClient() then + player.equipped.clientBtn:setVisible(v) + player.equipped.clientBtn:setY(y) + if v then + y = player.equipped.clientBtn:getY() + player.equipped.clientIcon:getHeightOrig() + 5 + end + end + elseif i == "Admin" then + if isClient() then + player.equipped.adminBtn:setVisible(v) + player.equipped.adminBtn:setY(y) + end + end + end +end + +------------------------------------------ + +function SpiffUI:OnGameStart() + for _,j in ipairs(SpiffUI) do + local mod = SpiffUI[j] + if mod and mod.Start then + mod.Start() + end + end + + Events.OnKeyStartPressed.Add(keyDown) + Events.OnKeyKeepPressed.Add(keyHold) + Events.OnKeyPressed.Add(keyRelease) + + self:updateEquippedItem() +end + +function SpiffUI:ModOptions() + SpiffUI.config = {} + + if ModOptions and ModOptions.getInstance then + local function apply(data) + local options = data.settings.options + -- Set options + end + + local SPIFFCONFIG = { + options_data = { + applyNewKeybinds = { + name = "UI_ModOptions_SpiffUI_applyNewKeybinds", + default = false + }, + runAllResets = { + name = "UI_ModOptions_SpiffUI_runAllResets", + default = false, + tooltip = "UI_ModOptions_SpiffUI_tooltip_runResets" + } + }, + mod_id = "SpiffUI", + mod_shortname = "SpiffUI", + mod_fullname = getText("UI_Name_SpiffUI") + } + + local optionsInstance = ModOptions:getInstance(SPIFFCONFIG) + ModOptions:loadFile() + + -- Modal for our Apply Defaults key + local applyKeys = optionsInstance:getData("applyNewKeybinds") + + function applyKeys:buildString(text,h) + for name,key in pairs(SpiffUI.KeyDefaults) do + text = text .. getText("UI_ModOptions_SpiffUI_Modal_aNKChild", getText("UI_optionscreen_binding_" .. name), getKeyName(key)) + h = h + 20 + end + return text,h + end + + function applyKeys:onUpdate(newValue) + if newValue then + applyKeys:set(false) + local w,h = 350,120 + local text = getText("UI_ModOptions_SpiffUI_Modal_applyNewKeybinds") + text,h = self:buildString(text,h) + SpiffUI.settingsModal(w, h, text, self, applyKeys.apply) + end + end + + function applyKeys:apply(button) + self.modal = nil + if button.internal == "NO" then + return + end + for name,key in pairs(SpiffUI.KeyDefaults) do + for i,v in ipairs(MainOptions.keyText) do + if not v.value then + if v.txt:getName() == name then + v.keyCode = key + v.btn:setTitle(getKeyName(key)) + break + end + end + end + end + getCore():saveOptions() + MainOptions.instance.gameOptions.changed = false + end + + local runResets = optionsInstance:getData("runAllResets") + + function runResets:buildString(text,h) + for _,j in ipairs(SpiffUI) do + local mod = SpiffUI[j] + if mod and mod.Reset then + if mod.resetDesc then + text = text .. mod.resetDesc + else + text = text .. " " .. j + end + h = h + 20 + end + end + return text,h + end + + function runResets:onUpdate(newValue) + if newValue then + runResets:set(false) + -- quick check if we're in game + local player = getPlayerData(0) + if not player then return end + local w,h = 350,120 + local text = getText("UI_ModOptions_SpiffUI_Modal_runResets") + text,h = self:buildString(text,h) + SpiffUI.settingsModal(w, h, text, self, runResets.apply) + end + end + + function runResets:apply(button) + self.modal = nil + if button.internal == "NO" then + return + end + for _,j in ipairs(SpiffUI) do + local mod = SpiffUI[j] + if mod and mod.Reset then + mod.Reset() + end + end + MainOptions.instance.gameOptions.changed = false + end + + + Events.OnPreMapLoad.Add(function() + apply({settings = SPIFFCONFIG}) + end) + + end +end + +-- At first I had this run only once, but apparently when there's only 1 mod this breaks +---- So, OnPostBoot is added to run things last +SpiffUI.firstBoot = function() + Events.OnGameBoot.Add(function() + SpiffUI:OnPostBoot() + end) + --Events.OnGameBoot.Remove(SpiffUI.firstBoot) + SpiffUI:OnGameBoot() +end + +function SpiffUI:OnGameBoot() + self:ModOptions() + + for _,j in ipairs(SpiffUI) do + local mod = SpiffUI[j] + if mod and mod.Boot then + mod.Boot() + end + end + + -- Let's Remove some keys + for name,_ in pairs(SpiffUI.KeyDisables) do + local found = false + for i = 1, #keyBinding do + if keyBinding[i].value == name then + table.remove(keyBinding, i) + --print("Removed Keybind: " .. name) + found = true + break + end + end + + -- We may have a SpiffUI key we want to remove + if not found then + for i,bind in ipairs(SpiffUI.KeyBinds) do + if bind.name == name then + table.remove(SpiffUI.KeyBinds, i) + --print("Removed SpiffUI Keybind: " .. name) + break + end + end + end + end + + -- Now let's add ours! + for _, bind in ipairs(SpiffUI.KeyBinds) do + table.insert(keyBinding, { value = bind.name, key = bind.key }) + end + + -- Events + Events.OnGameStart.Add(function() + SpiffUI:OnGameStart() + end) + + Events.OnCreatePlayer.Add(function(id) + SpiffUI:OnCreatePlayer(id) + end) + +end + +function SpiffUI:OnPostBoot() + -- Let's Remove some keys possibly added by mods + for name,_ in pairs(SpiffUI.KeyDisables) do + local found = false + for i = 1, #keyBinding do + if keyBinding[i].value == name then + table.remove(keyBinding, i) + --print("Removed Keybind: " .. name) + found = true + break + end + end + end +end + +function SpiffUI:OnCreatePlayer(id) + for _,j in ipairs(SpiffUI) do + local mod = SpiffUI[j] + if mod and mod.CreatePlayer then + mod.CreatePlayer(id) + end + end +end + +------------------------------------------ + +SpiffUI.settingsModal = function(w, h, text, key, callback) + key.modal = ISModalRichText:new((getCore():getScreenWidth() / 2) - w / 2, + (getCore():getScreenHeight() / 2) - h / 2, w, h, + text, true, MainOptions.instance, callback) + key.modal:initialise() + key.modal:setCapture(true) + key.modal:setAlwaysOnTop(true) + key.modal:addToUIManager() + if MainOptions.joyfocus then + MainOptions.joyfocus.focus = key.modal + updateJoypadFocus(key.joyfocus) + end +end + +------------------------------------------ +Events.OnGameBoot.Add(SpiffUI.firstBoot) + +-- Hello SpiffUI :) +print(getText("UI_Hello_SpiffUI")) \ No newline at end of file diff --git a/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/ISUI/SpiffUI_ISFirearmRadialMenu.lua b/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/ISUI/SpiffUI_ISFirearmRadialMenu.lua new file mode 100644 index 0000000..2aec24f --- /dev/null +++ b/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/ISUI/SpiffUI_ISFirearmRadialMenu.lua @@ -0,0 +1,15 @@ +------------------------------------------ +-- SpiffUI Radials +---- ISFirearmRadialMenu getWeapon hack +------------------------------------------ + +-- This lets us set call the radial without having the wepaon in-hand +---- You must have the weapon equipped in primary in order to do an action though +---- Useful as we can inject a weapon to show +local _ISFirearmRadialMenu_getWeapon = ISFirearmRadialMenu.getWeapon +function ISFirearmRadialMenu:getWeapon() + if not self.weapon then + return _ISFirearmRadialMenu_getWeapon(self) + end + return self.weapon +end \ No newline at end of file diff --git a/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/ISUI/SpiffUI_ISRadialMenu.lua b/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/ISUI/SpiffUI_ISRadialMenu.lua new file mode 100644 index 0000000..47cae57 --- /dev/null +++ b/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/ISUI/SpiffUI_ISRadialMenu.lua @@ -0,0 +1,435 @@ +------------------------------------------ +-- SpiffUI Radials +---- Add tooltip to Radial +------------------------------------------ + +SpiffUI = SpiffUI or {} + +-- Register our inventory +local spiff = SpiffUI:Register("radials") + +local SpiffUIRadialRecipeTooltip = ISRecipeTooltip:derive("SpiffUIRadialRecipeTooltip") + +function SpiffUIRadialRecipeTooltip:new() + return ISRecipeTooltip.new(self) +end + +-- Taken from the base game's ISInventoryPaneContextMenu.lua +---- CraftTooltip:layoutContents(x, y) +----- This fixes the lag spike by limiting the number of sources we parse +------ We also force-add our item if missing to ensure it shows :) +function SpiffUIRadialRecipeTooltip:layoutContents(x, y) + if self.contents then + return self.contentsWidth, self.contentsHeight + end + + self:getContainers() + self:getAvailableItemsType() + + local FONT_HGT_SMALL = getTextManager():getFontHeight(UIFont.Small) + local IMAGE_SIZE = 20 + + self.contents = {} + local marginLeft = 20 + local marginTop = 10 + local marginBottom = 10 + local y1 = y + marginTop + local lineHeight = math.max(FONT_HGT_SMALL, 20 + 2) + local textDY = (lineHeight - FONT_HGT_SMALL) / 2 + local imageDY = (lineHeight - IMAGE_SIZE) / 2 + local singleSources = {} + local multiSources = {} + local allSources = {} + + for j=0,self.recipe:getSource():size()-1 do + local source = self.recipe:getSource():get(j) + if source:getItems():size() == 1 then + table.insert(singleSources, source) + else + table.insert(multiSources, source) + end + end + + -- Display singleSources before multiSources + for _,source in ipairs(singleSources) do + table.insert(allSources, source) + end + + for _,source in ipairs(multiSources) do + table.insert(allSources, source) + end + + local maxSingleSourceLabelWidth = 0 + for _,source in ipairs(singleSources) do + local txt = self:getSingleSourceText(source) + local width = getTextManager():MeasureStringX(UIFont.Small, txt) + maxSingleSourceLabelWidth = math.max(maxSingleSourceLabelWidth, width) + end + + for scount,source in ipairs(allSources) do + local txt = "" + local x1 = x + marginLeft + if source:getItems():size() > 1 then + if source:isDestroy() then + txt = getText("IGUI_CraftUI_SourceDestroyOneOf") + elseif source:isKeep() then + txt = getText("IGUI_CraftUI_SourceKeepOneOf") + else + txt = getText("IGUI_CraftUI_SourceUseOneOf") + end + self:addText(x1, y1 + textDY, txt) + y1 = y1 + lineHeight + else + txt = self:getSingleSourceText(source) + self:addText(x1, y1 + textDY, txt) + x1 = x1 + maxSingleSourceLabelWidth + 10 + end + + local itemDataList = {} + + local searching = {} + + -- Get 10 more items from our item's recipe + ---- This should cover all of the required items + ----- And give us some candy for the UI. :) + ------ Why 10? The UI stops at 10 sooooooooo....... + local loopLength = 10 + if source:getItems():size() < loopLength then + loopLength = source:getItems():size() + end + + -- on our first run + ---- The first iteration will be the item itself ("use one item", etc) + if scount == 1 then + local found = false + -- We first need to check if our item is part of the 10 + for s=0,loopLength - 1 do + found = (source:getItems():get(s) == self.item:getFullType()) + end + -- if our item was not part of the 10 then we add it first + if not found then + searching[self.item:getFullType()] = true + end + end + + -- Add our items + for s=0,loopLength - 1 do + searching[source:getItems():get(s)] = true + end + + for fType,_ in pairs(searching) do + local itemData = {} + itemData.fullType = fType + itemData.available = true + local item = nil + if itemData.fullType == "Water" then + item = ISInventoryPaneContextMenu.getItemInstance("Base.WaterDrop") + else + if instanceof(self.recipe, "MovableRecipe") and (itemData.fullType == "Base."..self.recipe:getWorldSprite()) then + item = ISInventoryPaneContextMenu.getItemInstance("Moveables.Moveable") + else + item = ISInventoryPaneContextMenu.getItemInstance(itemData.fullType) + end + --this reads the worldsprite so the generated item will have correct icon + if instanceof(item, "Moveable") and instanceof(self.recipe, "MovableRecipe") then + item:ReadFromWorldSprite(self.recipe:getWorldSprite()); + end + end + itemData.texture = "" + if item then + itemData.texture = item:getTex():getName() + if itemData.fullType == "Water" then + if source:getCount() == 1 then + itemData.name = getText("IGUI_CraftUI_CountOneUnit", getText("ContextMenu_WaterName")) + else + itemData.name = getText("IGUI_CraftUI_CountUnits", getText("ContextMenu_WaterName"), source:getCount()) + end + elseif source:getItems():size() > 1 then -- no units + itemData.name = item:getDisplayName() + elseif not source:isDestroy() and item:IsDrainable() then + if source:getCount() == 1 then + itemData.name = getText("IGUI_CraftUI_CountOneUnit", item:getDisplayName()) + else + itemData.name = getText("IGUI_CraftUI_CountUnits", item:getDisplayName(), source:getCount()) + end + elseif not source:isDestroy() and source:getUse() > 0 then -- food + if source:getUse() == 1 then + itemData.name = getText("IGUI_CraftUI_CountOneUnit", item:getDisplayName()) + else + itemData.name = getText("IGUI_CraftUI_CountUnits", item:getDisplayName(), source:getUse()) + end + elseif source:getCount() > 1 then + itemData.name = getText("IGUI_CraftUI_CountNumber", item:getDisplayName(), source:getCount()) + else + itemData.name = item:getDisplayName() + end + else + itemData.name = itemData.fullType + end + local countAvailable = self.typesAvailable[itemData.fullType] or 0 + if countAvailable < source:getCount() and itemData.fullType ~= self.item:getFullType() then + itemData.available = false + itemData.r = 0.54 + itemData.g = 0.54 + itemData.b = 0.54 + end + table.insert(itemDataList, itemData) + end + + -- Hack for "Dismantle Digital Watch" and similar recipes. + -- Recipe sources include both left-hand and right-hand versions of the same item. + -- We only want to display one of them. + ---[[ + for j=1,#itemDataList do + local item = itemDataList[j] + for k=#itemDataList,j+1,-1 do + local item2 = itemDataList[k] + if self:isExtraClothingItemOf(item, item2) then + table.remove(itemDataList, k) + end + end + end + --]] + + for i,itemData in ipairs(itemDataList) do + local x2 = x1 + if source:getItems():size() > 1 then + x2 = x2 + 20 + if source:getCount() > 1 then + itemData.name = getText("IGUI_CraftUI_CountNumber", itemData.name, source:getCount()) + end + end + if itemData.texture ~= "" then + self:addImage(x2, y1 + imageDY, itemData.texture) + x2 = x2 + IMAGE_SIZE + 6 + end + self:addText(x2, y1 + textDY, itemData.name, itemData.r, itemData.g, itemData.b) + y1 = y1 + lineHeight + + if i == 10 and i < source:getItems():size() then + self:addText(x2, y1 + textDY, getText("Tooltip_AndNMore", source:getItems():size() - i)) + y1 = y1 + lineHeight + break + end + end + end + + if self.recipe:getTooltip() then + local x1 = x + marginLeft + local tooltip = getText(self.recipe:getTooltip()) + self:addText(x1, y1 + 8, tooltip) + end + + self.contentsX = x + self.contentsY = y + self.contentsWidth = 0 + self.contentsHeight = 0 + for _,v in ipairs(self.contents) do + self.contentsWidth = math.max(self.contentsWidth, v.x + v.width - x) + self.contentsHeight = math.max(self.contentsHeight, v.y + v.height + marginBottom - y) + end + return self.contentsWidth, self.contentsHeight +end + +function ISRadialMenu:makeToolTip() + local player = getSpecificPlayer(self.playerNum) + + self.toolRender = ISToolTipInv:new() + self.toolRender:initialise() + self.toolRender:setCharacter(player) + + self.craftRender = SpiffUIRadialRecipeTooltip:new() + self.craftRender:initialise() + self.craftRender.character = player + + self.invRender = ISToolTip:new() + self.invRender:initialise() + + if JoypadState.players[self.playerNum+1] then + local x = getPlayerScreenLeft(self.playerNum) + 60 + local y = getPlayerScreenTop(self.playerNum) + 60 + self.invRender.followMouse = false + self.invRender.desiredX = x + self.invRender.desiredY = y + + self.toolRender.followMouse = false + self.toolRender:setX(x) + self.toolRender:setY(y) + + self.craftRender.followMouse = false + self.craftRender.desiredX = x + self.craftRender.desiredY = y + end +end + +function ISRadialMenu:getSliceTooltipJoyPad() + if not self.joyfocus or not self.joyfocus.id then return nil end + + local sliceIndex = self.javaObject:getSliceIndexFromJoypad(self.joyfocus.id) + if sliceIndex == -1 then return nil end + + local command = self:getSliceCommand(sliceIndex + 1) + + if command and command[2] and command[2].tooltip then + return command[2].tooltip + end + return nil +end + +function ISRadialMenu:getSliceTooltipMouse(x, y) + local sliceIndex = self.javaObject:getSliceIndexFromMouse(x, y) + local command = self:getSliceCommand(sliceIndex + 1) + + if command and command[2] and command[2].tooltip then + return command[2].tooltip + end + return nil +end + +function ISRadialMenu:showTooltip(item) + if item and spiff.config.showTooltips then + if self.prev == item and (self.toolRender:getIsVisible() + or self.craftRender:getIsVisible() + or self.invRender:getIsVisible()) then return end + + if self.toolRender:getIsVisible() then + self.toolRender:removeFromUIManager() + self.toolRender:setVisible(false) + end + + if self.craftRender:getIsVisible() then + self.craftRender:removeFromUIManager() + self.craftRender:setVisible(false) + end + + if self.invRender:getIsVisible() then + self.invRender:removeFromUIManager() + self.invRender:setVisible(false) + end + + self.prev = item + + if instanceof(item, "InventoryItem") then + + self.toolRender:setItem(item) + + self.toolRender:setVisible(true) + self.toolRender:addToUIManager() + self.toolRender:bringToTop() + + elseif item.isRecipe then + -- We have to run the reset so the recipe is updated + self.craftRender:reset() + + -- Reset annoyingly changes this stuff.. + if JoypadState.players[self.playerNum+1] then + self.craftRender.followMouse = false + self.craftRender.desiredX = getPlayerScreenLeft(self.playerNum) + 60 + self.craftRender.desiredY = getPlayerScreenTop(self.playerNum) + 60 + end + + self.craftRender.recipe = item.recipe + self.craftRender.item = item.item + self.craftRender:setName(item.recipe:getName()) + + if item.item:getTexture() and item.item:getTexture():getName() ~= "Question_On" then + self.craftRender:setTexture(item.item:getTexture():getName()) + end + + self.craftRender:setVisible(true) + self.craftRender:addToUIManager() + self.craftRender:bringToTop() + + elseif item.isFix then + + self.invRender:setName(item.name) + self.invRender.texture = item.texture + self.invRender.description = item.description + + self.invRender:setVisible(true) + self.invRender:addToUIManager() + self.invRender:bringToTop() + + end + else + if self.toolRender and self.toolRender:getIsVisible() then + self.toolRender:removeFromUIManager() + self.toolRender:setVisible(false) + end + if self.craftRender and self.craftRender:getIsVisible() then + self.craftRender:removeFromUIManager() + self.craftRender:setVisible(false) + end + if self.invRender and self.invRender:getIsVisible() then + self.invRender:removeFromUIManager() + self.invRender:setVisible(false) + end + end +end + +-- Derived from ISPanelJoypad +function ISRadialMenu:onMouseMove(dx, dy) + if self.playerNum ~= 0 then return end + ISPanelJoypad.onMouseMove(self, dx, dy) + + local x = self:getMouseX() + local y = self:getMouseY() + + self:showTooltip(self:getSliceTooltipMouse(x, y)) +end + +-- Derived from ISPanelJoypad +function ISRadialMenu:onMouseMoveOutside(dx, dy) + if self.playerNum ~= 0 then return end + ISPanelJoypad.onMouseMoveOutside(self, dx, dy) + + if self.toolRender and self.toolRender:getIsVisible() then + self.toolRender:removeFromUIManager() + self.toolRender:setVisible(false) + end + if self.craftRender and self.craftRender:getIsVisible() then + self.craftRender:removeFromUIManager() + self.craftRender:setVisible(false) + end + if self.invRender and self.invRender:getIsVisible() then + self.invRender:removeFromUIManager() + self.invRender:setVisible(false) + end +end + +local _ISRadialMenu_undisplay = ISRadialMenu.undisplay +function ISRadialMenu:undisplay() + _ISRadialMenu_undisplay(self) + + if self.toolRender and self.toolRender:getIsVisible() then + self.toolRender:removeFromUIManager() + self.toolRender:setVisible(false) + end + if self.craftRender and self.craftRender:getIsVisible() then + self.craftRender:removeFromUIManager() + self.craftRender:setVisible(false) + end + if self.invRender and self.invRender:getIsVisible() then + self.invRender:removeFromUIManager() + self.invRender:setVisible(false) + end +end + +function ISRadialMenu:RadialTick() + if self:isReallyVisible() then + self:showTooltip(self:getSliceTooltipJoyPad()) + end +end + +local _ISRadialMenu_new = ISRadialMenu.new +function ISRadialMenu:new(...) + local o = _ISRadialMenu_new(self, ...) + o:makeToolTip() + if JoypadState.players[o.playerNum+1] then + Events.OnRenderTick.Add(function() + o:RadialTick() + end) + end + return o +end + diff --git a/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/Radials/SpiffUI-ARadialMenu.lua b/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/Radials/SpiffUI-ARadialMenu.lua new file mode 100644 index 0000000..ac244e6 --- /dev/null +++ b/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/Radials/SpiffUI-ARadialMenu.lua @@ -0,0 +1,247 @@ +------------------------------------------ +-- SpiffUI Radials +---- Radial Menu Functions +------------------------------------------ + +SpiffUI = SpiffUI or {} + +-- Register our Radials +local spiff = SpiffUI:Register("radials") + +-- Base SpiffUI Radial Menu +local SpiffUIRadialMenu = ISBaseObject:derive("SpiffUIRadialMenu") + +-- Base Radial Command +local SpiffUIRadialCommand = ISBaseObject:derive("SpiffUIRadialCommand") + +-- Radial Command for asking amount +local SpiffUIRadialCommandAsk = SpiffUIRadialCommand:derive("SpiffUIRadialCommandAsk") + +-- Radial Command for Next Page +local SpiffUIRadialCommandNext = SpiffUIRadialCommand:derive("SpiffUIRadialCommandNext") + +-- Radial Command for Prev Page +local SpiffUIRadialCommandPrev = SpiffUIRadialCommand:derive("SpiffUIRadialCommandPrev") + +------------------------------------------ +function SpiffUIRadialCommand:new(menu, text, texture, tooltip) + local o = ISBaseObject.new(self) + o.menu = menu + o.rmenu = menu.rmenu + o.player = menu.player + o.playerNum = menu.playerNum + + o.tooltip = tooltip + + o.text = text + o.texture = texture + + o.shouldAsk = 0 + o.amount = 0 + + return o +end + +function SpiffUIRadialCommand:fillMenu() + if spiff.config.showTooltips and self.tooltip then + if self.forceText then + self.rmenu:addSlice(self.text, self.texture, self.invoke, self) + else + self.rmenu:addSlice("", self.texture, self.invoke, self) + end + else + self.rmenu:addSlice(self.text, self.texture, self.invoke, self) + end +end + +function SpiffUIRadialCommand:Action() + print("Base SpiffUIRadialCommand Action -- Override me!") +end + +function SpiffUIRadialCommand:invoke() + if self.shouldAsk > 0 then + self.menu.command = self + self.menu:askAmount() + return + end + self:Action() +end + +-- Add Definition +spiff.radialcommand = SpiffUIRadialCommand + +------------------------------------------ + +function SpiffUIRadialCommandAsk:invoke() + self.menu.command.amount = self.amount + self.menu.command:Action() +end + +function SpiffUIRadialCommandAsk:new(menu, text, texture, amount) + local o = spiff.radialcommand.new(self, menu, text, texture, nil) + o.amount = amount + return o +end + +------------------------------------------ + +function SpiffUIRadialCommandNext:invoke() + self.menu.page = self.menu.page + 1 + self.menu:show() +end + +function SpiffUIRadialCommandNext:new(menu, text, texture) + return spiff.radialcommand.new(self, menu, text, texture, nil) +end + +------------------------------------------ + +function SpiffUIRadialCommandPrev:invoke() + self.menu.page = self.menu.page - 1 + if self.menu.pageReset then + self.menu.maxPage = self.menu.page + end + self.menu:show() +end + +function SpiffUIRadialCommandPrev:new(menu, text, texture) + return spiff.radialcommand.new(self, menu, text, texture, nil) +end + +------------------------------------------ + +function SpiffUIRadialMenu:build() + print("Base SpiffUIRadialMenu build -- Override me!") +end + +function SpiffUIRadialMenu:askAmount() + self.rmenu:clear() + --table.wipe(self.commands) + + local askCommands = {} + + if self.command.shouldAsk == 1 then -- Consume: 1 (all), 1/2, 1/4, Dieter + table.insert(askCommands, SpiffUIRadialCommandAsk:new(self, self.command.item:getName(), spiff.icons[4], 1)) + table.insert(askCommands, SpiffUIRadialCommandAsk:new(self, self.command.item:getName(), spiff.icons[2], 0.5)) + table.insert(askCommands, SpiffUIRadialCommandAsk:new(self, self.command.item:getName(), spiff.icons[3], 0.25)) + table.insert(askCommands, SpiffUIRadialCommandAsk:new(self, self.command.item:getName(), spiff.icons[5], -1)) + elseif self.command.shouldAsk == 2 then -- Crafting, all or 1 + table.insert(askCommands, SpiffUIRadialCommandAsk:new(self, self.command.recipe:getName(), spiff.icons[4], true)) + table.insert(askCommands, SpiffUIRadialCommandAsk:new(self, self.command.recipe:getName(), spiff.icons[1], false)) + end + + for _,command in ipairs(askCommands) do + local count = #self.rmenu.slices + command:fillMenu() + if count == #self.rmenu.slices then + self.rmenu:addSlice(nil, nil, nil) + end + end + + self.rmenu:center() + self.rmenu:addToUIManager() + self.rmenu:setVisible(true) + SpiffUI.action.wasVisible = true + if JoypadState.players[self.playerNum+1] then + self.rmenu:setHideWhenButtonReleased(Joypad.DPadUp) + setJoypadFocus(self.playerNum, self.rmenu) + self.player:setJoypadIgnoreAimUntilCentered(true) + end +end + +function SpiffUIRadialMenu:display() + self:build() + self.page = 1 + + self:show() +end + +function SpiffUIRadialMenu:show() + self.rmenu:clear() + + local hasCommands = false + + -- Add the next page + if self.maxPage > 1 and self.page < self.maxPage then + local nextp = SpiffUIRadialCommandNext:new(self, "Next", self.nextTex) + local count = #self.rmenu.slices + nextp:fillMenu() + if count == #self.rmenu.slices then + self.rmenu:addSlice(nil, nil, nil) + end + end + + if self.commands[self.page] then + for _,command in ipairs(self.commands[self.page]) do + local count = #self.rmenu.slices + command:fillMenu() + if count == #self.rmenu.slices then + self.rmenu:addSlice(nil, nil, nil) + end + hasCommands = true + end + end + + -- Add the previous page + if self.maxPage > 1 and self.page > 1 then + local nextp = SpiffUIRadialCommandPrev:new(self, "Previous", self.prevTex) + local count = #self.rmenu.slices + nextp:fillMenu() + if count == #self.rmenu.slices then + self.rmenu:addSlice(nil, nil, nil) + end + end + + if hasCommands then + self.rmenu:center() + self.rmenu:addToUIManager() + self.rmenu:setVisible(true) + SpiffUI.action.wasVisible = true + if JoypadState.players[self.playerNum+1] then + self.rmenu:setHideWhenButtonReleased(Joypad.DPadUp) + setJoypadFocus(self.playerNum, self.rmenu) + self.player:setJoypadIgnoreAimUntilCentered(true) + end + else + -- If no commands, just close the radial + self.rmenu:undisplay() + end +end + +function SpiffUIRadialMenu:AddCommand(command) + if self.cCount == self.cMax then + --print("Adding New Page: " .. self.cCount) + self.cCount = 0 + self.page = self.page + 1 + self.maxPage = self.page + end + + if not self.commands[self.page] then + self.commands[self.page] = {} + end + table.insert(self.commands[self.page], command) + self.cCount = self.cCount + 1 + --print("Count: " .. self.cCount) +end + +function SpiffUIRadialMenu:new(player) + local o = ISBaseObject.new(self) + + o.player = player + o.playerNum = player:getPlayerNum() + + o.rmenu = getPlayerRadialMenu(o.playerNum) + + o.commands = {} + o.cCount = 0 + o.cMax = 16 + o.page = 1 + o.maxPage = 1 + + o.nextTex = getTexture("media/SpiffUI/nextpage.png") + o.prevTex = getTexture("media/SpiffUI/prevpage.png") + + return o +end + +spiff.radialmenu = SpiffUIRadialMenu \ No newline at end of file diff --git a/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/Radials/SpiffUI_CraftingRadial.lua b/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/Radials/SpiffUI_CraftingRadial.lua new file mode 100644 index 0000000..2d0bb2c --- /dev/null +++ b/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/Radials/SpiffUI_CraftingRadial.lua @@ -0,0 +1,186 @@ +------------------------------------------ +-- SpiffUI Crafting Radial Actions +---- Radial Menu for Crafting +------------------------------------------ + +SpiffUI = SpiffUI or {} + +-- Register our Radials +local spiff = SpiffUI:Register("radials") + +local SpiffUICraftingRadial = spiff.radialmenu:derive("SpiffUICraftingRadial") +if not spiff.radials then spiff.radials = {} end +spiff.radials[0] = SpiffUICraftingRadial + +------------------------------------------ + +local SpiffUICraftingRadialCommand = spiff.radialcommand:derive("SpiffUICraftingRadialCommand") + +function SpiffUICraftingRadialCommand:Action() + ISInventoryPaneContextMenu.OnCraft(self.item, self.recipe, self.player:getPlayerNum(), self.amount) +end + +function SpiffUICraftingRadialCommand:new(menu, recipe) + local texture = InventoryItemFactory.CreateItem(recipe.recipe:getResult():getFullType()):getTexture() + + local tooltip = { + recipe = recipe.recipe, + item = recipe.item, + isRecipe = true + } + local o = spiff.radialcommand.new(self, menu, recipe.recipe:getName(), texture, tooltip) + + o.recipe = recipe.recipe + o.item = recipe.item + + if spiff.config.craftAmount == -1 and recipe.num > 1 then + -- Ask + o.shouldAsk = 2 + elseif spiff.config.craftAmount == 1 then + -- Craft All + o.amount = true + end + + return o +end + +local function getRecipes(packs, player) + local items = {} + local recipes = {} + for p = 0, packs:size() - 1 do + local pack = packs:get(p) + local ps = pack:getAllEval(function(item) + return instanceof(item, "InventoryItem") + end) + if ps and ps:size() > 0 then + for i = 0, ps:size() - 1 do + local item = ps:get(i) + if item then + if not items[item:getType()] then + items[item:getType()] = item + end + end + end + end + end + + if not spiff.config.craftShowSmokeables then + for i,item in pairs(items) do + if spiff.filters.smokeables[item:getType()] or item:getCustomMenuOption() == "Smoke" then + items[item:getType()] = nil + end + end + end + + if not spiff.config.craftShowMedical then + for i,item in pairs(items) do + if spiff.filters.firstAidCraft[item:getType()] or item:getStringItemType() == "Medical" then + items[item:getType()] = nil + end + end + end + + if not spiff.config.craftShowEquipped then + for i,item in pairs(items) do + if player:isEquipped(item) and (player:getPrimaryHandItem() ~= item and player:getSecondaryHandItem() ~= item) then + items[item:getType()] = nil + end + end + end + + local count = 0 + for _,item in pairs(items) do + local recs = RecipeManager.getUniqueRecipeItems(item, player, packs) + for i = 0, recs:size() - 1 do + local recipe = recs:get(i) + local key + if spiff.config.craftFilterUnique then + key = recipe:getName() + else + key = count + end + if not recipes[key] then + recipes[key] = { + recipe = recipe, + num = RecipeManager.getNumberOfTimesRecipeCanBeDone(recipe, player, packs, item), + item = item + } + count = count + 1 + end + end + end + + return recipes +end + +------------------------------------------ + +function SpiffUICraftingRadial:build() + local bags = ISInventoryPaneContextMenu.getContainers(self.player) + local recipes = getRecipes(bags, self.player) + + local hasRecipes = false + for i,j in pairs(recipes) do + self:AddCommand(SpiffUICraftingRadialCommand:new(self, j)) + hasRecipes = true + end + + if not hasRecipes then + self.player:Say(getText("UI_character_SpiffUI_noCraft")) + end +end + +function SpiffUICraftingRadial:new(player) + return spiff.radialmenu.new(self, player) +end + +local function SpiffUICraftDown(player) + SpiffUI.onKeyDown(player) + if not SpiffUI.action.ready then + local ui = getPlayerCraftingUI(player:getPlayerNum()) + if ui:getIsVisible() then + ui:setVisible(false) + ui:removeFromUIManager() + -- Ready for another action + SpiffUI.action.ready = true + end + end +end + +local function SpiffUICraftHold(player) + if SpiffUI.holdTime() then + if spiff.config.craftSwitch then + ISCraftingUI.toggleCraftingUI() + else + -- Create Menu + local menu = SpiffUICraftingRadial:new(player) + menu:display() + end + end +end + +local function SpiffUICraftRelease(player) + if SpiffUI.releaseTime() then + if spiff.config.craftSwitch then + -- Create Menu + local menu = SpiffUICraftingRadial:new(player) + menu:display() + else + ISCraftingUI.toggleCraftingUI() + end + end +end + +local function actionInit() + local bind = { + name = 'SpiffUICraftWheel', + key = Keyboard.KEY_B, + queue = false, + Down = SpiffUICraftDown, + Hold = SpiffUICraftHold, + Up = SpiffUICraftRelease + } + SpiffUI:AddKeyBind(bind) +end + +actionInit() \ No newline at end of file diff --git a/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/Radials/SpiffUI_DrinkRadial.lua b/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/Radials/SpiffUI_DrinkRadial.lua new file mode 100644 index 0000000..afc1a44 --- /dev/null +++ b/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/Radials/SpiffUI_DrinkRadial.lua @@ -0,0 +1,246 @@ +------------------------------------------ +-- SpiffUI Drink Actions +---- Radial Menu for drinks +------------------------------------------ + +SpiffUI = SpiffUI or {} + +-- Register our Radials +local spiff = SpiffUI:Register("radials") + +local SpiffUIDrinkRadial = spiff.radialmenu:derive("SpiffUIDrinkRadial") +if not spiff.radials then spiff.radials = {} end +spiff.radials[1] = SpiffUIDrinkRadial + +------------------------------------------ + +local SpiffUIDrinkThirstRadialCommand = spiff.radialcommand:derive("SpiffUIDrinkThirstRadialCommand") + +function SpiffUIDrinkThirstRadialCommand:Action() + ISInventoryPaneContextMenu.onDrinkForThirst(self.item, self.player) + + -- Return from whence it came... + if self.item:getContainer() ~= self.player:getInventory() then + ISTimedActionQueue.add(ISInventoryTransferAction:new(self.player, self.item, self.player:getInventory(), self.item:getContainer())) + end +end + +function SpiffUIDrinkThirstRadialCommand:new(menu, item) + local o = spiff.radialcommand.new(self, menu, item:getName(), item:getTexture(), item) + + o.item = item + return o +end + +------------------------------------------ + +local SpiffUIDrinkRadialCommand = spiff.radialcommand:derive("SpiffUIDrinkRadialCommand") + +-- Code below is adapted from the "Dieter" feature of the excellent ExtraSauce Quality of Life mod by MonsterSauce +local function round(num) + return math.floor(num * 100 + 0.5) / 100; +end + +local function doDrink(item, player, amount) + -- If we don't specify an amount, then figure it out + if amount == -1 then + local itemThirst = 0 + if (item.getThirstChange and item:getThirstChange()) then + itemThirst = round(item:getThirstChange()) + end + local charThirst = round(player:getStats():getThirst()) + + if itemThirst < 0 and charThirst >= 0.1 then + + local percentage = 1 + + if (charThirst + itemThirst < 0) then + percentage = -1 * round(charThirst / itemThirst) + if (percentage > 0.95) then percentage = 1.0 end + end + amount = percentage + end + end + + if amount ~= -1 then + ISInventoryPaneContextMenu.eatItem(item, amount, player:getPlayerNum()) + else + player:Say(getText("UI_character_SpiffUI_notThirsty")) + end +end + +function SpiffUIDrinkRadialCommand:Action() + doDrink(self.item, self.player, self.amount) + --ISInventoryPaneContextMenu.eatItem(self.item, self.amount, self.playerNum) + + -- Return from whence it came... + if self.item:getContainer() ~= self.player:getInventory() then + ISTimedActionQueue.add(ISInventoryTransferAction:new(self.player, self.item, self.player:getInventory(), self.item:getContainer())) + end +end + +function SpiffUIDrinkRadialCommand:new(menu, item) + local o = spiff.radialcommand.new(self, menu, item:getName(), item:getTexture(), item) + + o.amount = spiff.config.drinkAmount + + o.item = item + + if spiff.config.drinkAmount == 0 then + o.shouldAsk = 1 + end + + return o +end + +local function getItems(packs, player) + local items = {} + for p = 0, packs:size() - 1 do + local pack = packs:get(p) + local ps = pack:getAllEval(function(item) + return not player:isKnownPoison(item) and (item:getCustomMenuOption() and item:getCustomMenuOption() == "Drink") or item:isWaterSource() + end) + if ps and ps:size() > 0 then + for i = 0, ps:size() - 1 do + local item = ps:get(i) + if item then + if item:isWaterSource() then + if not items[item:getType()] or items[item:getType()]:getUsedDelta() > item:getUsedDelta() then + items[item:getType()] = item + end + else + if not items[item:getType()] or items[item:getType()]:getThirstChange() < item:getThirstChange() then + items[item:getType()] = item + end + end + + end + end + end + end + + local drinks = nil + + for _,j in pairs(items) do + if not drinks then drinks = {} end + table.insert(drinks, j) + end + + if drinks then + table.sort(drinks, function(a,b) + if a:isWaterSource() then + return true + end + if b:isWaterSource() then + return false + end + return a:getThirstChange() > b:getThirstChange() + end) + end + + return drinks +end + +------------------------------------------ + +function SpiffUIDrinkRadial:build() + local packs = ISInventoryPaneContextMenu.getContainers(self.player) + local drinks = getItems(packs, self.player) + + if not drinks then + self.player:Say(getText("UI_character_SpiffUI_noDrinks")) + return + end + + local hasCmd = false + + -- Build + for _,j in ipairs(drinks) do + if j:isWaterSource() then + if self.player:getStats():getThirst() > 0.1 then + self:AddCommand(SpiffUIDrinkThirstRadialCommand:new(self, j)) + hasCmd = true + end + else + self:AddCommand(SpiffUIDrinkRadialCommand:new(self, j)) + hasCmd = true + end + end + + if not hasCmd then + self.player:Say(getText("UI_character_SpiffUI_noDrinks")) + end +end + +function SpiffUIDrinkRadial:new(player) + return spiff.radialmenu.new(self, player) +end + +local function quickDrink(player) + if player:getStats():getThirst() < 0.1 then + player:Say(getText("UI_character_SpiffUI_notThirsty")) + return + end + local packs = ISInventoryPaneContextMenu.getContainers(player) + local items = getItems(packs, player) + + if items then + for _,item in ipairs(items) do + if item:isWaterSource() then + ISInventoryPaneContextMenu.onDrinkForThirst(item, player) + else + local amount = spiff.config.drinkQuickAmount + if amount == 0 then amount = -1 end + doDrink(item, player, amount) + end + -- Return from whence it came... + if item:getContainer() ~= player:getInventory() then + ISTimedActionQueue.add(ISInventoryTransferAction:new(player, item, player:getInventory(), item:getContainer())) + end + -- Just do the first + return + end + else + player:Say(getText("UI_character_SpiffUI_noDrinks")) + end +end + +local function DrinksDown(player) + SpiffUI.onKeyDown(player) + -- If showNow and we're doing an action, do it now + if spiff.config.drinkShowNow and not SpiffUI.action.ready then + -- Create Menu + local menu = SpiffUIDrinkRadial:new(player) + menu:display() + -- Ready for another action + SpiffUI.action.ready = true + end +end + +local function DrinksHold(player) + if SpiffUI.holdTime() then + -- Create Menu + local menu = SpiffUIDrinkRadial:new(getSpecificPlayer(0)) + menu:display() + end +end + +local function DrinksRelease(player) + if SpiffUI.releaseTime() then + quickDrink(player) + end +end + +local function actionInit() + local bind = { + name = 'SpiffUIDrinkWheel', + key = 26, -- { + queue = true, + Down = DrinksDown, + Hold = DrinksHold, + Up = DrinksRelease + } + SpiffUI:AddKeyBind(bind) +end + +actionInit() \ No newline at end of file diff --git a/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/Radials/SpiffUI_EatRadial.lua b/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/Radials/SpiffUI_EatRadial.lua new file mode 100644 index 0000000..c269904 --- /dev/null +++ b/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/Radials/SpiffUI_EatRadial.lua @@ -0,0 +1,199 @@ +------------------------------------------ +-- SpiffUI Eat Actions +---- Radial Menu for food +------------------------------------------ + +SpiffUI = SpiffUI or {} + +-- Register our Radials +local spiff = SpiffUI:Register("radials") + +local SpiffUIEatRadial = spiff.radialmenu:derive("SpiffUIEatRadial") +if not spiff.radials then spiff.radials = {} end +spiff.radials[2] = SpiffUIEatRadial +------------------------------------------ + +local SpiffUIEatRadialCommand = spiff.radialcommand:derive("SpiffUIEatRadialCommand") + +-- Code below is adapted from the excellent ExtraSauce Quality of Life mod by MonsterSauce +local function round(num) + return math.floor(num * 100 + 0.5) / 100; +end + +local function doEat(item, player, amount) + -- If we don't specify an amount, then figure it out + if amount == -1 then + local itemHunger = 0 + if (item.getBaseHunger and item:getBaseHunger()) then + itemHunger = round(item:getBaseHunger()) + end + + local charHunger = round(player:getStats():getHunger()) + + if itemHunger < 0 and charHunger >= 0.1 then + + local percentage = 1 + + if (charHunger + itemHunger < 0) then + percentage = -1 * round(charHunger / itemHunger) + if (percentage > 0.95) then percentage = 1.0 end + end + amount = percentage + end + end + + if amount ~= -1 then + ISInventoryPaneContextMenu.eatItem(item, amount, player:getPlayerNum()) + else + player:Say(getText("UI_character_SpiffUI_notHungry")) + end +end + +------------------------------------------ + +function SpiffUIEatRadialCommand:Action() + doEat(self.item, self.player, self.amount) + + -- Return from whence it came... + if self.item:getContainer() ~= self.player:getInventory() then + ISTimedActionQueue.add(ISInventoryTransferAction:new(self.player, self.item, self.player:getInventory(), self.item:getContainer())) + end +end + +function SpiffUIEatRadialCommand:new(menu, item) + local o = spiff.radialcommand.new(self, menu, item:getName(), item:getTexture(), item) + + o.amount = spiff.config.eatAmount + + o.item = item + + if spiff.config.eatAmount == 0 then + o.shouldAsk = 1 + end + + return o +end + +local function getItems(packs) + local items = {} + for p = 0, packs:size() - 1 do + local pack = packs:get(p) + local ps = pack:getAllEval(function(item) + return instanceof(item, "Food") and item:getHungChange() < 0 and not item:getScriptItem():isCantEat() and not item:getCustomMenuOption() + end) + if ps and ps:size() > 0 then + for i = 0, ps:size() - 1 do + local item = ps:get(i) + if item then + if not items then items = {} end + if not items[item:getType()] or items[item:getType()]:getHungChange() < item:getHungChange() then + items[item:getType()] = item + end + end + end + end + end + local food = nil + + for _,j in pairs(items) do + if not food then food = {} end + table.insert(food, j) + end + + if food then + table.sort(food, function(a,b) + return a:getHungChange() > b:getHungChange() + end) + end + + return food +end + +------------------------------------------ + +function SpiffUIEatRadial:build() + local packs = ISInventoryPaneContextMenu.getContainers(self.player) + local food = getItems(packs) + + if not food then + self.player:Say(getText("UI_character_SpiffUI_noFood")) + return + end + + -- Build + for _,j in ipairs(food) do + self:AddCommand(SpiffUIEatRadialCommand:new(self, j)) + end +end + +function SpiffUIEatRadial:new(player) + return spiff.radialmenu.new(self, player) +end + +local function quickEat(player) + if player:getStats():getHunger() < 0.1 then + player:Say(getText("UI_character_SpiffUI_notHungry")) + return + end + local packs = ISInventoryPaneContextMenu.getContainers(player) + local food = getItems(packs) + + if not food then + player:Say(getText("UI_character_SpiffUI_noFood")) + return + end + + for _,item in ipairs(food) do + -- Just do the first thing + local amount = spiff.config.eatQuickAmount + if amount == 0 then amount = -1 end + doEat(item, player, amount) + --ISInventoryPaneContextMenu.eatItem(item, spiff.config.eatQuickAmount, player:getPlayerNum()) + + -- Return from whence it came... + if item:getContainer() ~= player:getInventory() then + ISTimedActionQueue.add(ISInventoryTransferAction:new(player, item, player:getInventory(), item:getContainer())) + end + return + end +end + +local function EatDown(player) + SpiffUI.onKeyDown(player) + -- If showNow and we're doing an action, do it now + if spiff.config.eatShowNow and not SpiffUI.action.ready then + -- Create Menu + local menu = SpiffUIEatRadial:new(player) + menu:display() + -- Ready for another action + SpiffUI.action.ready = true + end +end + +local function EatHold(player) + if SpiffUI.holdTime() then + -- Create Menu + local menu = SpiffUIEatRadial:new(getSpecificPlayer(0)) + menu:display() + end +end + +local function EatRelease(player) + if SpiffUI.releaseTime() then + quickEat(player) + end +end + +local function actionInit() + local bind = { + name = 'SpiffUIEatWheel', + key = 27, -- } + queue = true, + Down = EatDown, + Hold = EatHold, + Up = EatRelease + } + SpiffUI:AddKeyBind(bind) +end + +actionInit() \ No newline at end of file diff --git a/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/Radials/SpiffUI_EquipmentRadial.lua b/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/Radials/SpiffUI_EquipmentRadial.lua new file mode 100644 index 0000000..db286aa --- /dev/null +++ b/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/Radials/SpiffUI_EquipmentRadial.lua @@ -0,0 +1,607 @@ +------------------------------------------ +-- SpiffUI Equipment Actions +---- Radial Menu for Equipment +------------------------------------------ + +SpiffUI = SpiffUI or {} + +-- Register our Radials +local spiff = SpiffUI:Register("radials") + +local SpiffUIEquipmentRadial = spiff.radialmenu:derive("SpiffUIEquipmentRadial") +if not spiff.radials then spiff.radials = {} end +spiff.radials[3] = SpiffUIEquipmentRadial +------------------------------------------ + +local SpiffUIEquipmentRadialCommand = spiff.radialcommand:derive("SpiffUIEquipmentRadialCommand") +local SpiffUIEquipmentItemRadialCommand = spiff.radialcommand:derive("SpiffUIEquipmentItemRadialCommand") + +local function returnItem(item, player) + if item:getContainer() ~= player:getInventory() then + ISTimedActionQueue.add(ISInventoryTransferAction:new(player, item, player:getInventory(), item:getContainer())) + end +end + +local function returnItems(items, player) + for i=0,items:size() - 1 do + local item = items:get(i) + returnItem(item, player) + end +end + +------------------------------------------ + +function SpiffUIEquipmentItemRadialCommand:Action() + if self.mode == 0 then -- "Inspect" + ISInventoryPaneContextMenu.onInspectClothing(self.player, self.item.item) + elseif self.mode == 1 then -- "Unequip" + if self.item.inHotbar then + -- We Detach it + ISTimedActionQueue.add(ISDetachItemHotbar:new(self.player, self.item.item)) + end + ISInventoryPaneContextMenu.unequipItem(self.item.item, self.playerNum) + elseif self.mode == 2 then -- "Transfer To" + ISTimedActionQueue.add(ISInventoryTransferAction:new(self.player, self.item.item, self.player:getInventory(), self.item.inv)) + elseif self.mode == 3 then -- "Drop" + ISInventoryPaneContextMenu.dropItem(self.item.item, self.playerNum) + elseif self.mode == 4 then -- Clothing Items Extra + ISTimedActionQueue.add(ISClothingExtraAction:new(self.player, self.item.item, self.item.itype)) + elseif self.mode == 5 then --Recipes + ISInventoryPaneContextMenu.OnCraft(self.item.item, self.item.recipe, self.playerNum, false) + elseif self.mode == 6 then -- Item Repairs + if not self.item.unavailable then + local items = self.item.fixing:getRequiredItems(self.player, self.item.fixer, self.item.item) + ISInventoryPaneContextMenu.onFix(self.item.item, self.playerNum, self.item.fixing, self.item.fixer) + returnItems(items, self.player) + else + self.player:Say(getText("UI_character_SpiffUI_noRepairItems")) + end + elseif self.mode == 7 then -- Guns! + if self.item.item ~= self.player:getPrimaryHandItem() then + -- The gun has to be equipped in order for the radial menu to work + ISInventoryPaneContextMenu.equipWeapon(self.item.item, true, self.item.item:isTwoHandWeapon(), self.playerNum) + end + local frm = ISFirearmRadialMenu:new(self.player) + frm.weapon = self.item.item + frm:fillMenu() + frm:display() + else + self.player:Say("OOPS! I don't know how to do that. That's not supposed to happen!") + end +end + +function SpiffUIEquipmentItemRadialCommand:new(menu, stuff) + local o = spiff.radialcommand.new(self, menu, stuff.label, stuff.texture, stuff.tooltip) + o.item = stuff + o.mode = stuff.mode + o.forceText = true + + return o +end +------------------------------------------ + +function SpiffUIEquipmentRadialCommand:Action() + self.menu.page = self.menu.page + 1 + self.menu.maxPage = self.menu.page + if self.mode == 0 then + -- base menu, show item + self.menu:itemOptions(self.item) + elseif self.mode == 1 then + -- show accessories + self.menu:accessories() + elseif self.mode == 2 then + -- show accessories + self.menu:hotbar() + end +end + +function SpiffUIEquipmentRadialCommand:new(menu, item, mode) + local o + if mode == 0 then + o = spiff.radialcommand.new(self, menu, item:getName(), item:getTexture(), item) + else + o = spiff.radialcommand.new(self, menu, item.label, item.texture, nil) + end + + o.item = item + o.mode = mode + return o +end + +------------------------------------------ + +local clothesSort = { + ["Hat"] = 0, + ["FullHat"] = 1, + ["FullHelmet"] = 2, + ["FullSuit"] = 3, + ["FullSuitHead"] = 4, + ["FullTop"] = 5, + ["JacketHat"] = 6, + ["SweaterHat"] = 7, + ["Ears"] = 108, + ["EarTop"] = 109, + ["Eyes"] = 110, + ["MakeUp_Eyes"] = 111, + ["MakeUp_EyesShadow"] = 112, + ["MaskEyes"] = 113, + ["RightEye"] = 114, + ["LeftEye"] = 115, + ["Nose"] = 116, + ["MakeUp_Lips"] = 117, + ["MakeUp_FullFace"] = 118, + ["Mask"] = 119, + ["MaskFull"] = 120, + ["Neck"] = 121, + ["Necklace"] = 122, + ["Necklace_Long"] = 123, + ["Scarf"] = 24, + ["Jacket"] = 25, + ["Sweater"] = 26, + ["JacketHat"] = 27, + ["SweaterHat"] = 28, + ["Dress"] = 29, + ["BathRobe"] = 30, + ["Shirt"] = 31, + ["TankTop"] = 32, + ["TorsoExtra"] = 33, + ["Tshirt"] = 34, + ["ShortSleeveShirt"] = 35, + ["Sweater"] = 36, + ["AmmoStrap"] = 137, + ["BellyButton"] = 138, + ["Belt"] = 39, + ["Holster"] = 139, + ["BeltExtra"] = 140, + ["FannyPackBack"] = 41, + ["FannyPackFront"] = 42, + ["Hands"] = 43, + ["Left_MiddleFinger"] = 144, + ["Left_RingFinger"] = 145, + ["LeftWrist"] = 146, + ["Right_MiddleFinger"] = 147, + ["Right_RingFinger"] = 148, + ["RightWrist"] = 149, + ["Tail"] = 150, + ["Underwear"] = 51, + ["UnderwearBottom"] = 52, + ["UnderwearExtra1"] = 53, + ["UnderwearExtra2"] = 54, + ["UnderwearInner"] = 55, + ["UnderwearTop"] = 56, + ["Skirt"] = 57, + ["Torso1Legs1"] = 58, + ["Legs1"] = 59, + ["Pants"] = 60, + ["Socks"] = 61, + ["Shoes"] = 62, + [""] = 99 +} + +local clothesFilter = { + ["Bandage"] = true, + ["Wound"] = true, + ["ZedDmg"] = true +} + +local function getItems(packs, player) + local items = nil + + -- First get worn items + local clothes = player:getWornItems() + for i=0, clothes:size() - 1 do + if not items then items = {} end + local item = clothes:get(i):getItem() + if item and not clothesFilter[item:getBodyLocation()] then + table.insert(items, item) + end + end + + -- Add any equipped items in our hands too + local primary = player:getPrimaryHandItem() + local secondary = player:getSecondaryHandItem() + if primary then + if not items then items = {} end + table.insert(items, primary) + end + if secondary and secondary ~= primary then + if not items then items = {} end + table.insert(items, secondary) + end + + if items then + -- order our clothes from head to toe + table.sort(items, function(a,b) + if not clothesSort[a:getBodyLocation()] or not clothesSort[b:getBodyLocation()] then return false end + return clothesSort[a:getBodyLocation()] < clothesSort[b:getBodyLocation()] + end) + end + return items +end + +-- This is mostly a combination function that reimplements 'ISInventoryPaneContextMenu.addFixerSubOption' +---- The tooltip is used in our radial override tooltip +---- returns a "stuff" table that is used to build a radial command +local function fixerStuff(item, fixing, fixer, player) + local unavailable = false + local tooltip = { + description = "", + texture = item:getTex(), + name = item:getName(), + isFix = true + } + local fixerItem = fixing:haveThisFixer(player, fixer, item) + + local usedItem = InventoryItemFactory.CreateItem(fixing:getModule():getName() .. "." .. fixer:getFixerName()) + local itemName + if usedItem then + tooltip.texture = usedItem:getTex() + itemName = getItemNameFromFullType(usedItem:getFullType()) + else + itemName = fixer:getFixerName() + end + tooltip.name = itemName + + local condPercentRepaired = FixingManager.getCondRepaired(item, player, fixing, fixer) + local color1 = ""; + if condPercentRepaired > 15 and condPercentRepaired <= 25 then + color1 = ""; + elseif condPercentRepaired > 25 then + color1 = ""; + end + + local chanceOfSucess = 100 - FixingManager.getChanceOfFail(item, player, fixing, fixer) + local color2 = ""; + if chanceOfSucess > 15 and chanceOfSucess <= 40 then + color2 = ""; + elseif chanceOfSucess > 40 then + color2 = ""; + end + + tooltip.description = " " .. color1 .. " " .. getText("Tooltip_potentialRepair") .. " " .. math.ceil(condPercentRepaired) .. "%" + tooltip.description = tooltip.description .. " " .. color2 .. " " .. getText("Tooltip_chanceSuccess") .. " " .. math.ceil(chanceOfSucess) .. "%" + tooltip.description = tooltip.description .. " " .. getText("Tooltip_craft_Needs") .. ": " + + if fixing:getGlobalItem() then + local globalItem = fixing:haveGlobalItem(player); + local uses = fixing:countUses(player, fixing:getGlobalItem(), nil) + if globalItem then + tooltip.description = tooltip.description .. " " .. globalItem:getName() .. " " .. uses .. "/" .. fixing:getGlobalItem():getNumberOfUse() .. " " + else + local globalItem = InventoryItemFactory.CreateItem(fixing:getModule():getName() .. "." .. fixing:getGlobalItem():getFixerName()) + local name = fixing:getGlobalItem():getFixerName(); + if globalItem then name = globalItem:getName(); end + tooltip.description = tooltip.description .. " " .. name .. " " .. uses .. "/" .. fixing:getGlobalItem():getNumberOfUse() .. " " + unavailable = true + end + end + + local uses = fixing:countUses(player, fixer, item) + if uses >= fixer:getNumberOfUse() then + color1 = " " + else + color1 = " " + unavailable = true + end + tooltip.description = tooltip.description .. color1 .. itemName .. " " .. uses .. "/" .. fixer:getNumberOfUse() + + if fixer:getFixerSkills() then + local skills = fixer:getFixerSkills() + for j=0,skills:size()-1 do + local skill = skills:get(j) + local perk = Perks.FromString(skill:getSkillName()) + local perkLvl = player:getPerkLevel(perk) + if perkLvl >= skill:getSkillLevel() then + color1 = " " + else + color1 = " " + unavailable = true + end + tooltip.description = tooltip.description .. " " .. color1 .. PerkFactory.getPerk(perk):getName() .. " " .. perkLvl .. "/" .. skill:getSkillLevel() + end + end + + if unavailable then + tooltip.description = tooltip.description .. " " .. "**FUCK YOU, ASSHOLE**" + end + + return { + fixing = fixing, + fixer = fixer, + item = item, + tooltip = tooltip, + label = getText("ContextMenu_Repair") .. getItemNameFromFullType(item:getFullType()), + texture = tooltip.texture, + unavailable = unavailable, + mode = 6 + } +end +-- spiff.functions = {} +-- spiff.functions.FixerStuff = fixerStuff + +function SpiffUIEquipmentRadial:itemOptions(item) + if not self.commands[self.page] then + self.commands[self.page] = {} + else + table.wipe(self.commands[self.page]) + end + + if not item then return end + + -- Get Hotbar + local hotbar = getPlayerHotbar(self.player:getPlayerNum()) + + -- Add "Inspect" + if item:getCategory() == "Clothing" and item:getCoveredParts():size() > 0 then + local stuff = { + item = item, + label = getText("IGUI_invpanel_Inspect"), + texture = item:getTexture(), + tooltip = item, + mode = 0 + } + table.insert(self.commands[self.page], SpiffUIEquipmentItemRadialCommand:new(self, stuff)) + end + + do -- Add "Unequip" + local stuff = { + item = item, + label = getText("ContextMenu_Unequip"), + texture = spiff.icons["unequip"], + tooltip = item, + inHotbar = hotbar:isInHotbar(item) and not self.player:isEquipped(item), -- Trigger a remove from hotbar if item is not equipped + mode = 1 + } + table.insert(self.commands[self.page], SpiffUIEquipmentItemRadialCommand:new(self, stuff)) + end + + local loot = getPlayerLoot(self.playerNum) + if loot.inventory:getType() ~= "floor" then + local stuff = { + item = item, + label = getText("UI_radial_SpiffUI_Transfer") .. loot.title, + texture = ContainerButtonIcons[loot.inventory:getType()], + inv = loot.inventory, + tooltip = item, + mode = 2 + } + table.insert(self.commands[self.page], SpiffUIEquipmentItemRadialCommand:new(self, stuff)) + end + + -- Add "Drop" + if spiff.config.equipShowDrop then + local stuff = { + item = item, + label = getText("ContextMenu_Drop"), + texture = spiff.icons["drop"], + tooltip = item, + mode = 3 + } + table.insert(self.commands[self.page], SpiffUIEquipmentItemRadialCommand:new(self, stuff)) + end + + + -- Add Clothing Items Extra + if item.getClothingItemExtraOption and item:getClothingItemExtraOption() and spiff.config.equipShowClothingActions then + for i=0,item:getClothingItemExtraOption():size()-1 do + local action = item:getClothingItemExtraOption():get(i) + local itemType = moduleDotType(item:getModule(), item:getClothingItemExtra():get(i)) + local stuff = { + item = item, + itype = itemType, + label = getText("ContextMenu_" .. action), + texture = InventoryItemFactory.CreateItem(itemType):getTexture(), + tooltip = item, + mode = 4 + } + table.insert(self.commands[self.page], SpiffUIEquipmentItemRadialCommand:new(self, stuff)) + end + end + + --Add Recipes + if spiff.config.equipShowRecipes then + local recs = RecipeManager.getUniqueRecipeItems(item, self.player, self.packs) + for i = 0, recs:size() - 1 do + local recipe = recs:get(i) + local stuff = { + item = item, + recipe = recipe, + label = recipe:getName(), + texture = InventoryItemFactory.CreateItem(recipe:getResult():getFullType()):getTexture(), + tooltip = { + recipe = recipe, + item = item, + isRecipe = true + }, + mode = 5 + } + + table.insert(self.commands[self.page], SpiffUIEquipmentItemRadialCommand:new(self, stuff)) + end + end + + -- Add Item Repairs + if item:isBroken() or item:getCondition() < item:getConditionMax() then + local fixingList = FixingManager.getFixes(item) + if not fixingList:isEmpty() then + for i=0,fixingList:size()-1 do + local fixing = fixingList:get(i) + for j=0,fixing:getFixers():size()-1 do + local fixer = fixing:getFixers():get(j) + local stuff = fixerStuff(item, fixing, fixer, self.player) + if stuff.unavailable then + if spiff.config.equipShowAllRepairs then + table.insert(self.commands[self.page], SpiffUIEquipmentItemRadialCommand:new(self, stuff)) + end + else + table.insert(self.commands[self.page], SpiffUIEquipmentItemRadialCommand:new(self, stuff)) + end + end + end + end + end + + -- Guns! + if item.isRanged and item:isRanged() then + local stuff = { + item = item, + label = "Firearm Radial", + texture = item:getTexture(), + tooltip = item, + mode = 7 + } + table.insert(self.commands[self.page], SpiffUIEquipmentItemRadialCommand:new(self, stuff)) + end + + self:show() +end + +function SpiffUIEquipmentRadial:accessories() + + if not self.commands[self.page] then + self.commands[self.page] = {} + else + table.wipe(self.commands[self.page]) + end + + for _,j in ipairs(self.items) do + if not clothesSort[j:getBodyLocation()] or clothesSort[j:getBodyLocation()] > 100 then + -- Add our items to page 2 + table.insert(self.commands[self.page], SpiffUIEquipmentRadialCommand:new(self, j, 0)) + end + end + + self:show() +end + +function SpiffUIEquipmentRadial:hotbar() + if not self.commands[self.page] then + self.commands[self.page] = {} + else + table.wipe(self.commands[self.page]) + end + + local hotbar = getPlayerHotbar(self.playerNum) + for i,item in pairs(hotbar.attachedItems) do + table.insert(self.commands[self.page], SpiffUIEquipmentRadialCommand:new(self, item, 0)) + end + + self:show() +end + +function SpiffUIEquipmentRadial:build() + + self.packs = ISInventoryPaneContextMenu.getContainers(self.player) + self.items = getItems(self.packs, self.player) + + self.page = 1 + self.maxPage = 1 + + local haveAccs = false + local accTex + local hasItems = false + if self.items then + for _,j in ipairs(self.items) do + if clothesSort[j:getBodyLocation()] and clothesSort[j:getBodyLocation()] < 100 then + -- Add our items to page 1 + if not self.commands[1] then + self.commands[1] = {} + end + table.insert(self.commands[1], SpiffUIEquipmentRadialCommand:new(self, j, 0)) + hasItems = true + else + haveAccs = true + if not accTex then + accTex = j:getTexture() + end + end + end + if haveAccs then + local stuff = { + label = getText("UI_radial_SpiffUI_Accessories"), + texture = accTex + } + table.insert(self.commands[1], SpiffUIEquipmentRadialCommand:new(self, stuff, 1)) + hasItems = true + end + end + + do + local hotbar = getPlayerHotbar(self.playerNum) + for _,item in pairs(hotbar.attachedItems) do + if item then + local stuff = { + label = getText("UI_radial_SpiffUI_Hotbar"), + texture = item:getTexture() + } + table.insert(self.commands[1], SpiffUIEquipmentRadialCommand:new(self, stuff, 2)) + hasItems = true + break + end + end + end + + if not hasItems then + self.player:Say(getText("UI_character_SpiffUI_noEquip")) + end +end + +function SpiffUIEquipmentRadial:new(player) + local o = spiff.radialmenu.new(self, player) + -- If we end up back at page 1, then we're at the main menu + o.pageReset = true + return o +end + +local function EquipDown(player) + SpiffUI.onKeyDown(player) + -- If showNow and we're doing an action, do it now + if not SpiffUI.action.ready then + if getPlayerInventory(0):getIsVisible() then + if SpiffUI["inventory"] then + ISInventoryPage.SpiffOnKey(player) + else + getPlayerInventory(0):setVisible(false) + getPlayerLoot(0):setVisible(false) + end + SpiffUI.action.wasVisible = true + end + end +end + +local function EquipHold(player) + if SpiffUI.holdTime() then + -- Create Menu + local menu = SpiffUIEquipmentRadial:new(player) + menu:display() + end +end + +local function EquipRelease(player) + if SpiffUI.releaseTime() then + if not SpiffUI.action.wasVisible then + if SpiffUI["inventory"] then + ISInventoryPage.SpiffOnKey(player) + else + local toggle = getPlayerInventory(0):getIsVisible() + getPlayerInventory(0):setVisible(not toggle) + getPlayerLoot(0):setVisible(not toggle) + end + end + SpiffUI.action.wasVisible = false + end +end + +local function actionInit() + local bind = { + name = 'SpiffUIEquipmentWheel', + key = Keyboard.KEY_TAB, + queue = false, + Down = EquipDown, + Hold = EquipHold, + Up = EquipRelease + } + SpiffUI:AddKeyBind(bind) +end + +actionInit() \ No newline at end of file diff --git a/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/Radials/SpiffUI_FirstAidCraft.lua b/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/Radials/SpiffUI_FirstAidCraft.lua new file mode 100644 index 0000000..c4ab982 --- /dev/null +++ b/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/Radials/SpiffUI_FirstAidCraft.lua @@ -0,0 +1,130 @@ +------------------------------------------ +-- SpiffUI First Aid Craft Actions +---- Radial Menu for First Aid Crafting +------------------------------------------ + +SpiffUI = SpiffUI or {} + +-- Register our Radials +local spiff = SpiffUI:Register("radials") + +local SpiffUIFirstAidCraftRadial = spiff.radialmenu:derive("SpiffUIFirstAidCraftRadial") +if not spiff.radials then spiff.radials = {} end +spiff.radials[4] = SpiffUIFirstAidCraftRadial +------------------------------------------ + +local SpiffUIFirstAidCraftRadialCommand = spiff.radialcommand:derive("SpiffUIFirstAidCraftRadialCommand") + +function SpiffUIFirstAidCraftRadialCommand:Action() + ISInventoryPaneContextMenu.OnCraft(self.item, self.recipe, self.player:getPlayerNum(), self.amount) +end + +function SpiffUIFirstAidCraftRadialCommand:new(menu, recipe) + local texture = InventoryItemFactory.CreateItem(recipe.recipe:getResult():getFullType()):getTexture() + + local tooltip = { + recipe = recipe.recipe, + item = recipe.item, + isRecipe = true + } + + local o = spiff.radialcommand.new(self, menu, recipe.recipe:getName(), texture, tooltip) + + o.recipe = recipe.recipe + o.item = recipe.item + + o.amount = false + + -- If we should and and we can make more than 1 + if spiff.config.firstAidCraftAmount == -1 and recipe.num > 1 then + -- Ask + o.shouldAsk = 2 + elseif spiff.config.firstAidCraftAmount == 1 then + -- Craft All + o.amount = true + end + + return o +end + +local function getRecipes(packs, player) + local items = {} + local recipes = {} + for p = 0, packs:size() - 1 do + local pack = packs:get(p) + local ps = pack:getAllEval(function(item) + return spiff.filters.firstAidCraft[item:getType()] or item:getStringItemType() == "Medical" + end) + if ps and ps:size() > 0 then + for i = 0, ps:size() - 1 do + local item = ps:get(i) + if item then + if not items[item:getType()] then + items[item:getType()] = item + end + end + end + end + end + + for _,item in pairs(items) do + local recs = RecipeManager.getUniqueRecipeItems(item, player, packs) + for i = 0, recs:size() - 1 do + local recipe = recs:get(i) + local key = recipe:getResult():getFullType() + recipes[key] = { + recipe = recipe, + num = RecipeManager.getNumberOfTimesRecipeCanBeDone(recipe, player, packs, item), + item = item + } + end + end + return recipes +end + +function SpiffUIFirstAidCraftRadial:build() + local recipes = {} + + local bags = ISInventoryPaneContextMenu.getContainers(self.player) + local recipes = getRecipes(bags, self.player) + + local hasCraft = false + -- Build Smokeables + for i,j in pairs(recipes) do + self:AddCommand(SpiffUIFirstAidCraftRadialCommand:new(self, j)) + hasCraft = true + end + + if not hasCraft then + self.player:Say(getText("UI_character_SpiffUI_noCraft")) + end +end + +function SpiffUIFirstAidCraftRadial:new(player) + return spiff.radialmenu.new(self, player) +end + +local function FirstAidCraftDown(player) + SpiffUI.onKeyDown(player) + -- if we're not ready, then we're doing an action. + ---- do it now + if not SpiffUI.action.ready then + -- Create Menu + local menu = SpiffUIFirstAidCraftRadial:new(player) + menu:display() + -- Ready for another action + SpiffUI.action.ready = true + end +end + +local function actionInit() + local bind = { + name = 'SpiffUIFirstAidCraftWheel', + key = 39, -- ; + queue = true, + Down = FirstAidCraftDown + } + SpiffUI:AddKeyBind(bind) +end + +actionInit() \ No newline at end of file diff --git a/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/Radials/SpiffUI_OneRadial.lua b/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/Radials/SpiffUI_OneRadial.lua new file mode 100644 index 0000000..0da6f73 --- /dev/null +++ b/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/Radials/SpiffUI_OneRadial.lua @@ -0,0 +1,121 @@ +------------------------------------------ +-- SpiffUI First Aid Craft Actions +---- Radial Menu for First Aid Crafting +------------------------------------------ + +SpiffUI = SpiffUI or {} + +-- Register our Radials +local spiff = SpiffUI:Register("radials") + +local SpiffUIOneRadial = spiff.radialmenu:derive("SpiffUIOneRadial") + +------------------------------------------ + +local SpiffUIOneRadialCommand = spiff.radialcommand:derive("SpiffUIOneRadialCommand") + +function SpiffUIOneRadialCommand:Action() + local radial = spiff.radials[self.mode] + if radial then + local menu = radial:new(self.player) + menu:display() + end + +end + +function SpiffUIOneRadialCommand:new(menu, name, texture, mode) + local o = spiff.radialcommand.new(self, menu, name, texture, nil) + o.mode = mode + return o +end + +function SpiffUIOneRadial:build() + -- Crafting + self:AddCommand(SpiffUIOneRadialCommand:new(self, "Crafting",getTexture("media/SpiffUI/crafting.png"), 0)) + -- Drink + self:AddCommand(SpiffUIOneRadialCommand:new(self, "Drink", InventoryItemFactory.CreateItem("Base.WaterBottleFull"):getTexture(), 1)) + -- Eat + self:AddCommand(SpiffUIOneRadialCommand:new(self, "Eat", InventoryItemFactory.CreateItem("Base.ChickenFried"):getTexture(), 2)) + -- Equipment + self:AddCommand(SpiffUIOneRadialCommand:new(self, "Equipment", getTexture("media/SpiffUI/inventory.png"), 3)) + -- First Aid Craft + self:AddCommand(SpiffUIOneRadialCommand:new(self, "First Aid Craft", InventoryItemFactory.CreateItem("Base.Bandage"):getTexture(), 4)) + -- Pills + self:AddCommand(SpiffUIOneRadialCommand:new(self, "Pills", InventoryItemFactory.CreateItem("Base.PillsAntiDep"):getTexture(), 5)) + -- Repair + self:AddCommand(SpiffUIOneRadialCommand:new(self, "Repair",InventoryItemFactory.CreateItem("Base.Hammer"):getTexture(), 6)) + -- Smoke Craft + if getActivatedMods():contains('jiggasGreenfireMod') then + self:AddCommand(SpiffUIOneRadialCommand:new(self, "Smoke Craft", InventoryItemFactory.CreateItem("Greenfire.SmokingPipe"):getTexture(), 7)) + elseif getActivatedMods():contains('Smoker') then + self:AddCommand(SpiffUIOneRadialCommand:new(self, "Smoke Craft", InventoryItemFactory.CreateItem("SM.SMSmokingBlend"):getTexture(), 7)) + elseif getActivatedMods():contains('MoreCigsMod') then + self:AddCommand(SpiffUIOneRadialCommand:new(self, "Smoke Craft", InventoryItemFactory.CreateItem("Cigs.CigsOpenPackReg"):getTexture(), 7)) + else + self:AddCommand(SpiffUIOneRadialCommand:new(self, "Smoke Craft", InventoryItemFactory.CreateItem("Base.Cigarettes"):getTexture(), 7)) + end + -- Smoke + self:AddCommand(SpiffUIOneRadialCommand:new(self, "Smoke",InventoryItemFactory.CreateItem("Base.Cigarettes"):getTexture(), 8)) + if spiff.radials[9] then + self:AddCommand(SpiffUIOneRadialCommand:new(self, "Clothing Action Radial Menu",InventoryItemFactory.CreateItem("Base.Hat_BaseballCapGreen"):getTexture(), 9)) + end +end + +function SpiffUIOneRadial:new(player) + return spiff.radialmenu.new(self, player) +end + +local function OneDown(player) + SpiffUI.onKeyDown(player) + -- if we're not ready, then we're doing an action. + ---- do it now + if not SpiffUI.action.ready then + -- Create Menu + local menu = SpiffUIOneRadial:new(player) + menu:display() + -- Ready for another action + SpiffUI.action.ready = true + end +end + +------------------------------------------ +--- For the DPad +local function showRadialMenu(player) + if UIManager.getSpeedControls() and (UIManager.getSpeedControls():getCurrentGameSpeed() == 0) then + return + end + + if not player or player:isDead() then + return + end + local queue = ISTimedActionQueue.queues[player] + if queue and #queue.queue > 0 then + return false + end + + local menu = SpiffUIOneRadial:new(player) + menu:display() +end + +---- Show the Radial Menu on the Up DPad when there's not a car around +local _ISDPadWheels_onDisplayUp = ISDPadWheels.onDisplayUp +function ISDPadWheels.onDisplayUp(joypadData) + local player = getSpecificPlayer(joypadData.player) + if not player:getVehicle() and not ISVehicleMenu.getVehicleToInteractWith(player) then + showRadialMenu(player) + else + _ISDPadWheels_onDisplayUp(joypadData) + end +end + +local function actionInit() + local bind = { + name = 'SpiffUIOneWheel', + key = Keyboard.KEY_CAPITAL, -- ; + queue = true, + Down = OneDown + } + SpiffUI:AddKeyBind(bind) +end + +actionInit() \ No newline at end of file diff --git a/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/Radials/SpiffUI_PillsRadial.lua b/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/Radials/SpiffUI_PillsRadial.lua new file mode 100644 index 0000000..5d0211c --- /dev/null +++ b/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/Radials/SpiffUI_PillsRadial.lua @@ -0,0 +1,212 @@ +------------------------------------------ +-- SpiffUI Pills Actions +---- Radial Menu for pills +------------------------------------------ + +SpiffUI = SpiffUI or {} + +-- Register our Radials +local spiff = SpiffUI:Register("radials") + +local SpiffUIPillsRadial = spiff.radialmenu:derive("SpiffUIPillsRadial") +if not spiff.radials then spiff.radials = {} end +spiff.radials[5] = SpiffUIPillsRadial +------------------------------------------ + +local SpiffUIPillsRadialCommand = spiff.radialcommand:derive("SpiffUIPillsRadialCommand") + +local function takePill(item, player) + ISInventoryPaneContextMenu.takePill(item, player:getPlayerNum()) + + -- Return from whence it came... + if item:getContainer() ~= player:getInventory() then + ISTimedActionQueue.add(ISInventoryTransferAction:new(player, item, player:getInventory(), item:getContainer())) + end +end + +function SpiffUIPillsRadialCommand:Action() + takePill(self.item, self.player) +end + +function SpiffUIPillsRadialCommand:new(menu, item) + local o = spiff.radialcommand.new(self, menu, item:getName(), item:getTexture(), item) + + o.item = item + return o +end + +------------------------------------------ + +local function getItems(packs, pills) + for p = 0, packs:size() - 1 do + local pack = packs:get(p) + local ps = pack:getAllEval(function(item) + return luautils.stringStarts(item:getType(), "Pills") or item:getType() == "Antibiotics" -- special case + end) + if ps and ps:size() > 0 then + for i = 0, ps:size() - 1 do + local pill = ps:get(i) + if pill then + -- If not found or has less pills + if not pills[pill:getType()] or pills[pill:getType()]:getUsedDelta() > pill:getUsedDelta() then + pills[pill:getType()] = pill + end + end + end + end + end + return pills +end + +function SpiffUIPillsRadial:build() + local pills = {} + + local packs = ISInventoryPaneContextMenu.getContainers(self.player) + pills = getItems(packs, pills) + + local hasPills = false + -- Build + for i,j in pairs(pills) do + self:AddCommand(SpiffUIPillsRadialCommand:new(self, j)) + hasPills = true + end + if not hasPills then + self.player:Say(getText("UI_character_SpiffUI_noPills")) + end +end + +function SpiffUIPillsRadial:new(player) + return spiff.radialmenu.new(self, player) +end + +------------------------------------------ + +local function getPillsQuick(player, ptype) + return player:getInventory():getFirstEvalRecurse(function(item) + return item:getType() == ptype + end) +end + +local function takePills(items, player) + -- First we'll take all our pills + for _,item in ipairs(items) do + ISInventoryPaneContextMenu.takePill(item, player:getPlayerNum()) + end + + -- Then we send them back + for _,item in ipairs(items) do + if item:getContainer() ~= player:getInventory() then + ISTimedActionQueue.add(ISInventoryTransferAction:new(player, item, player:getInventory(), item:getContainer())) + end + end +end + +local function quickPills(player) + local tried = "" + local pills = nil + if player:getMoodles():getMoodleLevel(MoodleType.Pain) >= 1 then + tried = getItemNameFromFullType("Base.Pills") + -- Take Painpills + local pill = getPillsQuick(player, "Pills") + if pill then + --print("Pain Pills") + if not pills then pills = {} end + table.insert(pills, pill) + end + end + if player:getMoodles():getMoodleLevel(MoodleType.Tired) >= 1 then + local name = getItemNameFromFullType("Base.PillsVitamins") + if tried ~= "" then + tried = tried .. ", " .. name + else + tried = name + end + -- Take Vitamins + local pill = getPillsQuick(player, "PillsVitamins") + if pill then + --print("Vitamins") + if not pills then pills = {} end + table.insert(pills, pill) + end + end + if player:getMoodles():getMoodleLevel(MoodleType.Panic) >= 1 then + local name = getItemNameFromFullType("Base.PillsBeta") + if tried ~= "" then + tried = tried .. ", " .. name + else + tried = name + end + -- Take Beta Blockers + local pill = getPillsQuick(player, "PillsBeta") + if pill then + --print("Beta Blockers") + if not pills then pills = {} end + table.insert(pills, pill) + end + end + if player:getMoodles():getMoodleLevel(MoodleType.Unhappy) >= 1 then + local name = getItemNameFromFullType("Base.PillsAntiDep") + if tried ~= "" then + tried = tried .. ", " .. name + else + tried = name + end + -- Take Antidepressents + local pill = getPillsQuick(player, "PillsAntiDep") + if pill then + --print("Antidepressents") + if not pills then pills = {} end + table.insert(pills, pill) + end + end + + if tried ~= "" then + if not pills then + player:Say(getText("UI_character_SpiffUI_noPillsQuick") .. tried) + else + takePills(pills, player) + end + else + player:Say(getText("UI_character_SpiffUI_noPillsNeed")) + end +end + +local function PillsDown(player) + SpiffUI.onKeyDown(player) + -- If showNow and we're doing an action, do it now + if spiff.config.pillsShowNow and not SpiffUI.action.ready then + -- Create Menu + local menu = SpiffUIPillsRadial:new(player) + menu:display() + -- Ready for another action + SpiffUI.action.ready = true + end +end + +local function PillsHold(player) + if SpiffUI.holdTime() then + -- Create Menu + local menu = SpiffUIPillsRadial:new(player) + menu:display() + end +end + +local function PillsRelease(player) + if SpiffUI.releaseTime() then + quickPills(player) + end +end + +local function actionInit() + local bind = { + name = 'SpiffUIPillWheel', + key = 40, -- ' + queue = true, + Down = PillsDown, + Hold = PillsHold, + Up = PillsRelease + } + SpiffUI:AddKeyBind(bind) +end + +actionInit() \ No newline at end of file diff --git a/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/Radials/SpiffUI_RepairRadial.lua b/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/Radials/SpiffUI_RepairRadial.lua new file mode 100644 index 0000000..fbdd67a --- /dev/null +++ b/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/Radials/SpiffUI_RepairRadial.lua @@ -0,0 +1,234 @@ +------------------------------------------ +-- SpiffUI Repair Actions +---- Radial Menu for Repair +------------------------------------------ + +SpiffUI = SpiffUI or {} + +-- Register our Radials +local spiff = SpiffUI:Register("radials") + +local SpiffUIRepairRadial = spiff.radialmenu:derive("SpiffUIRepairRadial") +if not spiff.radials then spiff.radials = {} end +spiff.radials[6] = SpiffUIRepairRadial +------------------------------------------ + +local SpiffUIRepairRadialCommand = spiff.radialcommand:derive("SpiffUIRepairRadialCommand") + +local function returnItems(items, player) + for i=0,items:size() - 1 do + local item = items:get(i) + if item:getContainer() ~= player:getInventory() then + ISTimedActionQueue.add(ISInventoryTransferAction:new(player, item, player:getInventory(), item:getContainer())) + end + end +end + +function SpiffUIRepairRadialCommand:Action() + local items = self.item.fixing:getRequiredItems(self.player, self.item.fixer, self.item.item) + ISInventoryPaneContextMenu.onFix(self.item.item, self.playerNum, self.item.fixing, self.item.fixer) + returnItems(items, self.player) +end + +function SpiffUIRepairRadialCommand:new(menu, stuff) + local o = spiff.radialcommand.new(self, menu, stuff.label, stuff.item:getTexture(), stuff.tooltip) + o.item = stuff + o.forceText = true + return o +end + +-- This is mostly a combination function that reimplements 'ISInventoryPaneContextMenu.addFixerSubOption' +---- The tooltip is used in our radial override tooltip +---- returns a "stuff" table that is used to build a radial command +local function fixerStuff(item, fixing, fixer, player) + local unavailable = false + local tooltip = { + description = "", + texture = item:getTex(), + name = item:getName(), + isFix = true + } + local fixerItem = fixing:haveThisFixer(player, fixer, item) + + local usedItem = InventoryItemFactory.CreateItem(fixing:getModule():getName() .. "." .. fixer:getFixerName()) + local itemName + if usedItem then + tooltip.texture = usedItem:getTex() + itemName = getItemNameFromFullType(usedItem:getFullType()) + else + itemName = fixer:getFixerName() + end + tooltip.name = itemName + + local condPercentRepaired = FixingManager.getCondRepaired(item, player, fixing, fixer) + local color1 = ""; + if condPercentRepaired > 15 and condPercentRepaired <= 25 then + color1 = ""; + elseif condPercentRepaired > 25 then + color1 = ""; + end + + local chanceOfSucess = 100 - FixingManager.getChanceOfFail(item, player, fixing, fixer) + local color2 = ""; + if chanceOfSucess > 15 and chanceOfSucess <= 40 then + color2 = ""; + elseif chanceOfSucess > 40 then + color2 = ""; + end + + tooltip.description = " " .. color1 .. " " .. getText("Tooltip_potentialRepair") .. " " .. math.ceil(condPercentRepaired) .. "%" + tooltip.description = tooltip.description .. " " .. color2 .. " " .. getText("Tooltip_chanceSuccess") .. " " .. math.ceil(chanceOfSucess) .. "%" + tooltip.description = tooltip.description .. " " .. getText("Tooltip_craft_Needs") .. ": " + + if fixing:getGlobalItem() then + local globalItem = fixing:haveGlobalItem(player); + local uses = fixing:countUses(player, fixing:getGlobalItem(), nil) + if globalItem then + tooltip.description = tooltip.description .. " " .. globalItem:getName() .. " " .. uses .. "/" .. fixing:getGlobalItem():getNumberOfUse() .. " " + else + local globalItem = InventoryItemFactory.CreateItem(fixing:getModule():getName() .. "." .. fixing:getGlobalItem():getFixerName()) + local name = fixing:getGlobalItem():getFixerName(); + if globalItem then name = globalItem:getName(); end + tooltip.description = tooltip.description .. " " .. name .. " " .. uses .. "/" .. fixing:getGlobalItem():getNumberOfUse() .. " " + unavailable = true + end + end + + local uses = fixing:countUses(player, fixer, item) + if uses >= fixer:getNumberOfUse() then + color1 = " " + else + color1 = " " + unavailable = true + end + tooltip.description = tooltip.description .. color1 .. itemName .. " " .. uses .. "/" .. fixer:getNumberOfUse() + + if fixer:getFixerSkills() then + local skills = fixer:getFixerSkills() + for j=0,skills:size()-1 do + local skill = skills:get(j) + local perk = Perks.FromString(skill:getSkillName()) + local perkLvl = player:getPerkLevel(perk) + if perkLvl >= skill:getSkillLevel() then + color1 = " " + else + color1 = " " + unavailable = true + end + tooltip.description = tooltip.description .. " " .. color1 .. PerkFactory.getPerk(perk):getName() .. " " .. perkLvl .. "/" .. skill:getSkillLevel() + end + end + + if unavailable then + tooltip.description = tooltip.description .. " " .. "**FUCK YOU, ASSHOLE**" + end + + return { + fixing = fixing, + fixer = fixer, + item = item, + tooltip = tooltip, + label = getText("ContextMenu_Repair") .. getItemNameFromFullType(item:getFullType()), + texture = tooltip.texture, + unavailable = unavailable, + mode = 5 + } +end + +local function getItems(packs, player) + local items = {} + for p = 0, packs:size() - 1 do + local pack = packs:get(p) + local ps = pack:getAllEval(function(item) + return item:isBroken() or item:getCondition() < item:getConditionMax() + end) + if ps and ps:size() > 0 then + for i = 0, ps:size() - 1 do + local item = ps:get(i) + if item then + items[i] = item + end + end + end + end + + if not spiff.config.repairShowEquipped then + for i,item in pairs(items) do + if player:isEquipped(item) then + items[i] = nil + end + end + end + + if not spiff.config.repairShowHotbar then + local hotbar = getPlayerHotbar(player:getPlayerNum()) + for i,item in pairs(items) do + if hotbar:isInHotbar(item) then + items[i] = nil + end + end + end + + local repairs = nil + local count = 0 + for _,item in pairs(items) do + local fixingList = FixingManager.getFixes(item) + if not fixingList:isEmpty() then + for i=0,fixingList:size()-1 do + local fixing = fixingList:get(i) + for j=0,fixing:getFixers():size()-1 do + local fixer = fixing:getFixers():get(j) + local stuff = fixerStuff(item, fixing, fixer, player) + if not stuff.unavailable then + if not repairs then repairs = {} end + table.insert(repairs, stuff) + end + end + end + end + end + return repairs +end + +function SpiffUIRepairRadial:build() + + local packs = ISInventoryPaneContextMenu.getContainers(self.player) + local items = getItems(packs, self.player) + + -- Build + if items then + for _,stuff in ipairs(items) do + self:AddCommand(SpiffUIRepairRadialCommand:new(self, stuff)) + end + else + self.player:Say(getText("UI_character_SpiffUI_noRepair")) + end +end + +function SpiffUIRepairRadial:new(player) + return spiff.radialmenu.new(self, player) +end + +local function RepairDown(player) + SpiffUI.onKeyDown(player) + -- If showNow and we're doing an action, do it now + if not SpiffUI.action.ready then + -- Create Menu + local menu = SpiffUIRepairRadial:new(player) + menu:display() + -- Ready for another action + SpiffUI.action.ready = true + end +end + +local function actionInit() + local bind = { + name = 'SpiffUIRepairWheel', + key = Keyboard.KEY_N, + queue = true, + Down = RepairDown + } + SpiffUI:AddKeyBind(bind) +end + +actionInit() \ No newline at end of file diff --git a/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/Radials/SpiffUI_SmokeCraftRadial.lua b/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/Radials/SpiffUI_SmokeCraftRadial.lua new file mode 100644 index 0000000..c858d63 --- /dev/null +++ b/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/Radials/SpiffUI_SmokeCraftRadial.lua @@ -0,0 +1,168 @@ +------------------------------------------ +-- SpiffUI Smoke Actions +---- Radial Menu for drinks +------------------------------------------ + +SpiffUI = SpiffUI or {} + +-- Register our Radials +local spiff = SpiffUI:Register("radials") + +local SpiffUISmokeCraftRadial = spiff.radialmenu:derive("SpiffUISmokeCraftRadial") +if not spiff.radials then spiff.radials = {} end +spiff.radials[7] = SpiffUISmokeCraftRadial +------------------------------------------ + +local SpiffUISmokeCraftRadialCommand = spiff.radialcommand:derive("SpiffUISmokeCraftRadialCommand") + +function SpiffUISmokeCraftRadialCommand:Action() + ISInventoryPaneContextMenu.OnCraft(self.item, self.recipe, self.player:getPlayerNum(), self.amount) +end + +function SpiffUISmokeCraftRadialCommand:new(menu, recipe) + local texture = InventoryItemFactory.CreateItem(recipe.recipe:getResult():getFullType()):getTexture() + + local tooltip = { + recipe = recipe.recipe, + item = recipe.item, + isRecipe = true + } + + local o = spiff.radialcommand.new(self, menu, recipe.recipe:getName(), texture, tooltip) + + o.recipe = recipe.recipe + o.item = recipe.item + + o.amount = false + + -- If we should and and we can make more than 1 + if spiff.config.smokeCraftAmount == -1 and recipe.num > 1 then + -- Ask + o.shouldAsk = 2 + elseif spiff.config.smokeCraftAmount == 1 then + -- Craft All + o.amount = true + end + + return o +end + +local function getRecipes(packs, player) + local items = {} + local recipes = {} + -- This will get cigs, or + for p = 0, packs:size() - 1 do + local pack = packs:get(p) + local ps = pack:getAllEval(function(item) + return (spiff.filters.smokecraft[item:getType()] ~= nil or item:getCustomMenuOption() == "Smoke") + end) + if ps and ps:size() > 0 then + for i = 0, ps:size() - 1 do + local item = ps:get(i) + if item then + if not items[item:getType()] then + items[item:getType()] = { + item = item, + cat = spiff.filters.smokecraft[item:getType()] or "misc" + } + end + end + end + end + end + + local count = 0 + for _,item in pairs(items) do + local recs = RecipeManager.getUniqueRecipeItems(item.item, player, packs) + for i = 0, recs:size() - 1 do + local recipe = recs:get(i) + if item.cat == "misc" and item.item:getStressChange() > -0.01 then + item.cat = "butts" + end + recipes[count] = { + recipe = recipe, + num = RecipeManager.getNumberOfTimesRecipeCanBeDone(recipe, player, packs, item.item), + item = item.item, + cat = item.cat + } + count = count + 1 + end + end + return recipes +end + + +function SpiffUISmokeCraftRadial:build() + local recipes = {} + + local bags = ISInventoryPaneContextMenu.getContainers(self.player) + local recipes = getRecipes(bags, self.player) + + -- Remove any breaking actions if applicable + if not spiff.config.smokeCraftShowDismantle then + for i,recipe in pairs(recipes) do + local first = luautils.split(recipe.recipe:getName(), " ")[1] + if spiff.rFilters.smokecraft.dismantle[first] then + recipes[i] = nil + end + end + end + + -- Remove any cigpack actions if applicable + if not spiff.config.smokeCraftShowCigPacks then + for i,recipe in pairs(recipes) do + local first = luautils.split(recipe.recipe:getName(), " ")[1] + if spiff.rFilters.smokecraft.cigpacks[first] then + recipes[i] = nil + end + end + end + + -- Always remove these ones + for i,recipe in pairs(recipes) do + local first = luautils.split(recipe.recipe:getName(), " ")[1] + if spiff.rFilters.smokecraft.always[first] then + recipes[i] = nil + end + end + + local hasCraft = false + -- Build Smokeables + for i,j in pairs(recipes) do + self:AddCommand(SpiffUISmokeCraftRadialCommand:new(self, j)) + hasCraft = true + end + + if not hasCraft then + self.player:Say(getText("UI_character_SpiffUI_noCraft")) + end +end + +function SpiffUISmokeCraftRadial:new(player) + return spiff.radialmenu.new(self, player) +end + +local function SmokeCraftDown(player) + SpiffUI.onKeyDown(player) + -- if we're not ready, then we're doing an action. + ---- do it now + if not SpiffUI.action.ready then + -- Create Menu + local menu = SpiffUISmokeCraftRadial:new(player) + menu:display() + -- Ready for another action + SpiffUI.action.ready = true + end +end + +local function actionInit() + local bind = { + name = 'SpiffUISmokeCraftWheel', + key = 43, -- \ + queue = true, + Down = SmokeCraftDown + } + SpiffUI:AddKeyBind(bind) +end + +actionInit() \ No newline at end of file diff --git a/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/Radials/SpiffUI_SmokeRadial.lua b/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/Radials/SpiffUI_SmokeRadial.lua new file mode 100644 index 0000000..b992390 --- /dev/null +++ b/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/Radials/SpiffUI_SmokeRadial.lua @@ -0,0 +1,263 @@ +------------------------------------------ +-- SpiffUI Smoke Radial +---- Radial Menu for smoking +------------------------------------------ + +SpiffUI = SpiffUI or {} + +-- Register our Radials +local spiff = SpiffUI:Register("radials") + +local SpiffUISmokeRadial = spiff.radialmenu:derive("SpiffUISmokeRadial") +if not spiff.radials then spiff.radials = {} end +spiff.radials[8] = SpiffUISmokeRadial +------------------------------------------ + +local SpiffUISmokeRadialCommand = spiff.radialcommand:derive("SpiffUISmokeRadialCommand") + +local function doSmokePack(pack, category, nextItem, player) + -- Smoking a pack requires AutoSmoke. + ---- AutoSmoke already has support for various mods out there, and is very popular + ---- All Credit to NoctisFalco for the original AutoSmoke code + if not AutoSmoke then return end + AutoSmoke.currentAction = AutoSmoke.activeMod.unpackAction(player, pack, pack:getContainer(), nextItem, + AutoSmoke.activeMod.actions[category].time, AutoSmoke.activeMod.actions[category].jobType, AutoSmoke.activeMod.actions[category].sound) + + ISInventoryPaneContextMenu.transferIfNeeded(player, pack) + ISTimedActionQueue.add(AutoSmoke.currentAction) +end + +function SpiffUISmokeRadialCommand:Action() + local lighterInv + -- let AutoSmoke handle the inventory for the lighter + ---- It seems to break it otherwise + if not AutoSmoke then + -- First we handle the lighter + lighterInv = self.lighter:getContainer() + ISInventoryPaneContextMenu.transferIfNeeded(self.player, self.lighter) + end + + -- If we have a "nextitem" its from a pack of something + if self.item.next then + doSmokePack(self.item.item, self.item.category, self.item.next, self.player) + else + ISInventoryPaneContextMenu.eatItem(self.item.item, 1, self.playerNum) + end + + -- Return lighter whence it came if needed! + if lighterInv and lighterInv ~= self.player:getInventory() then + ISTimedActionQueue.add(ISInventoryTransferAction:new(self.player, self.lighter, self.player:getInventory(), lighterInv)) + end +end + +function SpiffUISmokeRadialCommand:new(menu, item, lighter) + local o = spiff.radialcommand.new(self, menu, item.item:getName(), item.item:getTexture(), item.item) + + o.item = item + o.lighter = lighter + return o +end + +local function getNext(item) + for i,_ in pairs(spiff.filters.smoke) do + local out = spiff.filters.smoke[i][item] + if out then + return out + end + end + return nil +end + +local function getCat(item) + for i,_ in pairs(spiff.filters.smoke) do + local out = spiff.filters.smoke[i][item] + if out then + return i + end + end + return "misc" +end + +local function findRecursive(item) + local found = false + local out + local i = 0 + repeat + local iS = luautils.split(item, ".")[2] + if iS then + item = iS + end + local t = getNext(item) + if t and t ~= "" then + if not out then out = {} end + out[i] = t + i = i + 1 + item = t + else + found = true + end + until(found) + + return out +end + +local function checkFilters(item) + if not AutoSmoke then return false end + for i,_ in pairs(spiff.filters.smoke) do + if spiff.filters.smoke[i][item] then + return true + end + end + return false +end + +local function getItems(packs, lighter) + local items = {} + + -- This will get any smokeables + for p = 0, packs:size() - 1 do + local pack = packs:get(p) + local ps = pack:getAllEval(function(item) + -- Our Filter is only active if AutoSmoke is enabled + return (checkFilters(item:getType()) or item:getCustomMenuOption() == "Smoke") + end) + if ps and ps:size() > 0 then + for i = 0, ps:size() - 1 do + local item = ps:get(i) + local stuff = { + item = item, + category = getCat(item:getType()), + next = nil, + nexti = nil + } + local nexti = findRecursive(item:getType()) + if nexti then + stuff.nexti = nexti + stuff.next = nexti[0] + end + + local addItem = false + if item then + if spiff.rFilters.smoke.butts[item:getType()] then + if spiff.config.smokeShowButts then + addItem = true + end + elseif spiff.rFilters.smoke.gum[item:getType()] then + if spiff.config.smokeShowGum then + addItem = true + end + else + -- Everything else + addItem = true + end + if addItem and lighter then + items[item:getFullType()] = stuff + end + end + + end + end + end + + -- Only keep the most relevant. Cigs > Open Pack > Closed Pack > Carton | Gum > Gum Pack > Gum Carton + for i,j in pairs(items) do + if j.nexti then + for _,m in pairs(j.nexti) do + if items[m] then + items[i] = nil + break + end + end + end + end + + return items +end + +local function getLighter(pack) + return pack:getFirstEvalRecurse(function(item) + return (item:getType() == "Matches") or (item:getType() == "Lighter" and item:getUsedDelta() > 0) + end) +end + +function SpiffUISmokeRadial:build() + -- A lighter is required to be on you + local lighter = getLighter(self.player:getInventory()) + + local bags = ISInventoryPaneContextMenu.getContainers(self.player) + local items = getItems(bags, lighter) + + local haveItems = false + + for i,_ in pairs(items) do + haveItems = true + break + end + + -- We may still have gum! + if not haveItems then + self.player:Say(getText("UI_character_SpiffUI_noSmokes")) + return + end + if not haveItems and not lighter then + self.player:Say(getText("UI_character_SpiffUI_noLighter")) + return + end + + -- Build Smokeables + for _,j in pairs(items) do + self:AddCommand(SpiffUISmokeRadialCommand:new(self, j, lighter)) + end +end + +function SpiffUISmokeRadial:new(player) + return spiff.radialmenu.new(self, player) +end + +local function SmokeDown(player) + SpiffUI.onKeyDown(player) + -- If showNow and we're doing an action, do it now + if spiff.config.smokeShowNow and not SpiffUI.action.ready then + -- Create Menu + local menu = SpiffUISmokeRadial:new(player) + menu:display() + -- Ready for another action + SpiffUI.action.ready = true + end +end + +local function SmokeHold(player) + if SpiffUI.holdTime() then + -- Create Menu + local menu = SpiffUISmokeRadial:new(player) + menu:display() + end +end + +local function SmokeRelease(player) + if SpiffUI.releaseTime() then + -- We do the AutoSmoke Stuff if we don't do the radial + ---- From AutoSmoke + if AutoSmoke and AutoSmoke.player then + if AutoSmoke.Options.characterSpeaks then + AutoSmoke.pressedKey = true + end + AutoSmoke:checkInventory() + end + end +end + +local function actionInit() + local bind = { + name = 'SpiffUISmokeWheel', + key = Keyboard.KEY_BACK, + queue = true, + Down = SmokeDown, + Hold = SmokeHold, + Up = SmokeRelease + } + + SpiffUI:AddKeyBind(bind) +end + +actionInit() \ No newline at end of file diff --git a/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/SpiffUI-Radials.lua b/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/SpiffUI-Radials.lua new file mode 100644 index 0000000..6d71b4a --- /dev/null +++ b/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/SpiffUI-Radials.lua @@ -0,0 +1,599 @@ +------------------------------------------ +-- SpiffUI Radials Module +------------------------------------------ +SpiffUI = SpiffUI or {} + +-- Register our inventory +local spiff = SpiffUI:Register("radials") + +local rOptions = { + consume = { + [1] = 1, + [2] = 0.5, + [3] = 0.25, + [4] = 0, + [5] = -1 + }, + craft = { + [1] = 0, + [2] = 1, + [3] = -1 + } +} + +------------------------------------------ +-- Add functions +---- Used later +------------------------------------------ +spiff.functions = {} + +------------------------------------------ +-- Main Functions +------------------------------------------ + +local function SpiffUIOnGameStart() + spiff.filters = { + smoke = { + ["cigarettes"] = { + -- Smoker Homemade + ["SMHomemadeCigarette2"] = "", + ["SMHomemadeCigarette"] = "", + -- Smoker Cigs + ["SMCigarette"] = "", + ["SMCigaretteLight"] = "", + ["SMPCigaretteMenthol"] = "", + ["SMPCigaretteGold"] = "", + -- MCM Cigs + ["CigsCigaretteReg"] = "", + ["CigsCigaretteLite"] = "", + ["CigsCigaretteReg"] = "", + ["CigsCigaretteReg"] = "", + -- Greenfire Cigs + ["GFCigarette"] = "", + }, + ["butts"] = { + -- Smoker Butts + ["SMButt"] = "", + ["SMButt2"] = "", + -- MCM Butts + ["CigsButtReg"] = "", + ["CigsButtLite"] = "", + ["CigsButtMent"] = "", + ["CigsButtGold"] = "", + }, + ["openedPacks"] = { + -- Smoker Open Pack + ["SMPack"] = "SM.SMCigarette", + ["SMPackLight"] = "SM.SMCigaretteLight", + ["SMPackMenthol"] = "SM.SMPCigaretteMenthol", + ["SMPackGold"] = "SM.SMPCigaretteGold", + -- MCM Open Pack + ["CigsOpenPackReg"] = "Cigs.CigsCigaretteReg", + ["CigsOpenPackLite"] = "Cigs.CigsCigaretteLite", + ["CigsOpenPackMent"] = "Cigs.CigsCigaretteMent", + ["CigsOpenPackGold"] = "Cigs.CigsCigaretteGold", + }, + ["closedIncompletePacks"] = { + -- Smoker Random Packs (Base.Cigarettes only) + -- MCM Random packs (also Base.Cigarettes) + ["CigsSpawnPackLite"] = "Cigs.CigsOpenPackLite", + ["CigsSpawnPackMent"] = "Cigs.CigsOpenPackMent", + ["CigsSpawnPackGold"] = "Cigs.CigsOpenPackGold", + }, + ["closedPacks"] = { + --Smoker Full Pack + ["SMFullPack"] = "SM.SMPack", + ["SMFullPackLight"] = "SM.SMPackLight", + ["SMFullPackMenthol"] = "SM.SMPackMenthol", + ["SMFullPackGold"] = "SM.SMPackGold", + -- MCM Full Pack + ["CigsClosedPackReg"] = "Cigs.CigsOpenPackReg", + ["CigsClosedPackLite"] = "Cigs.CigsOpenPackLite", + ["CigsClosedPackMent"] = "Cigs.CigsOpenPackMent", + ["CigsClosedPackGold"] = "Cigs.CigsOpenPackGold", + --Greenfire Pack + ["GFCigarettes"] = "Greenfire.GFCigarette", + }, + ["openedCartons"] = { + --Greenfire Cartons + ["GFUsedCigaretteCarton"] = "Greenfire.GFCigarettes", + }, + ["cartons"] = { + --Smoker Carton + ["SMCartonCigarettes"] = "SM.SMFullPack", + ["SMCartonCigarettesLight"] = "SM.SMFullPackLight", + ["SMCartonCigarettesMenthol"] = "SM.SMFullPackMenthol", + ["SMCartonCigarettesGold"] = "SM.SMFullPackGold", + -- MCM Carton + ["CigsCartonReg"] = "Cigs.CigsClosedPackReg", + ["CigsCartonLite"] = "Cigs.CigsClosedPackLite", + ["CigsCartonMent"] = "Cigs.CigsClosedPackMent", + ["CigsCartonGold"] = "Cigs.CigsClosedPackGold", + --Greenfire Cartons + ["GFCigaretteCarton"] = "Greenfire.GFCigarettes", + }, + ["gum"] = { + -- Smoker Gum + ["SMGum"] = "", + }, + ["gumBlister"] = { + -- Smoker Gum pack + ["SMNicorette"] = "SM.SMGum", + }, + ["gumPack"] = { + -- Smoker Gum Carton + ["SMNicoretteBox"] = "SM.SMNicorette" + } + }, + smokecraft = { + ["Tobacco"] = "misc", + ["Cannabis"] = "misc", + ["CannabisShake"] = "misc", + ["Hashish"] = "misc", + ["CigarLeaf"] = "misc", + ["SMPinchTobacco"] = "misc", + ["SMSmallHandfulTobacco"] = "misc", + ["SMHandfulTobacco"] = "misc", + ["SMPileTobacco"] = "misc", + ["SMBigPileTobacco"] = "misc", + ["SMTobaccoPouches"] = "misc", + ["FreshUnCanna"] = "misc", + ["DryUnCanna"] = "misc", + ["FreshTCanna"] = "misc", + ["DryTCanna"] = "misc", + ["FreshCannabisFanLeaf"] = "misc", + ["DryCannabisFanLeaf"] = "misc", + ["FreshCannabisSugarLeaf"] = "misc", + ["DryCannabisSugarLeaf"] = "misc", + ["CannaJar"] = "misc", + ["CannaJar2"] = "misc", + ["CannaJar3"] = "misc", + ["CannaJar4"] = "misc", + ["UnCannaJar"] = "misc", + ["UnCannaJar2"] = "misc", + ["UnCannaJar3"] = "misc", + ["UnCannaJar4"] = "misc", + ["Cannabis"] = "misc", + ["OzCannabis"] = "misc", + ["KgCannabis"] = "misc", + ["CannabisShake"] = "misc", + ["FreshBTobacco"] = "misc", + ["DryBTobacco"] = "misc", + ["SMSmokingBlend"] = "misc", + }, + eat = { + ["Cannabis"] = true + }, + smokeables = { + ["Bong"] = "misc", + ["SmokingPipe"] = "misc", + ["RollingPapers"] = "misc", + ["GFGrinder"] = "misc", + ["BluntWrap"] = "misc", + ["SMFilter"] = "misc" + }, + firstAid = { + ["Bandage"] = true, + ["Bandaid"] = true, + ["RippedSheets"] = true, + ["Disinfectant"] = true, + ["Needle"] = true, + ["Thread"] = true, + ["SutureNeedle"] = true, + ["Tweezers"] = true, + ["SutureNeedleHolder"] = true, + ["Splint"] = true, + ["TreeBranch"] = true, + ["WoodenStick"] = true, + ["PlantainCataplasm"] = true, + ["WildGarlicCataplasm"] = true, + ["ComfreyCataplasm"] = true + }, + firstAidCraft = { + ["Bandage"] = true, + ["BandageDirty"] = true, + ["Bandaid"] = true, + ["RippedSheets"] = true, + ["RippedSheetsDirty"] = true, + ["Disinfectant"] = true, + ["Needle"] = true, + ["Thread"] = true, + ["SutureNeedle"] = true, + ["Tweezers"] = true, + ["SutureNeedleHolder"] = true, + ["Splint"] = true, + ["TreeBranch"] = true, + ["WoodenStick"] = true, + ["PlantainCataplasm"] = true, + ["WildGarlicCataplasm"] = true, + ["ComfreyCataplasm"] = true + } + } + + -- Lets add the base Cigs + if getActivatedMods():contains('Smoker') then + spiff.filters.smoke["closedIncompletePacks"]["Cigarettes"] = "SM.SMPack" + elseif getActivatedMods():contains('MoreCigsMod') then + spiff.filters.smoke["closedIncompletePacks"]["Cigarettes"] = "Cigs.CigsOpenPackReg" + else + spiff.filters.smoke["cigarettes"]["Cigarettes"] = "" + end + + -- Add Smokes to Smokeables + for i,_ in pairs(spiff.filters.smoke) do + for j,k in pairs(spiff.filters.smoke[i]) do + spiff.filters.smokeables[j] = k + end + end + + -- Add Smoke Craft to Smokeables + for i,j in pairs(spiff.filters.smokecraft) do + spiff.filters.smokeables[i] = j + end + + -- Add Smokes to Smoke Craft + for i,_ in pairs(spiff.filters.smoke) do + if not luautils.stringStarts(i, "gum") then + for j,_ in pairs(spiff.filters.smoke[i]) do + spiff.filters.smokecraft[j] = "cigs" + end + end + end + + spiff.rFilters = { + smoke = { + butts = { + -- Smoker Butts + ["SMButt"] = true, + ["SMButt2"] = true, + -- MCM Butts + ["CigsButtReg"] = true, + ["CigsButtLite"] = true, + ["CigsButtMent"] = true, + ["CigsButtGold"] = true + }, + gum = { + -- Smoker Gum + ["SMGum"] = true, + -- Smoker Gum pack + ["SMNicorette"] = true, + -- Smoker Gum Carton + ["SMNicoretteBox"] = true + } + }, + smokecraft = { + dismantle = { + ["Unload"] = true, + ["Dismantle"] = true, + ["Break"] = true, + ["Remove"] = true, + ["Unpack"] = true + }, + cigpacks = { + ["Put"] = true, + ["Take"] = true, + ["Open"] = true, + ["Close"] = true + }, + always = { + ["Convert"] = true + } + } + } +end + +local function SpiffUIBoot() + + spiff.config = { + showTooltips = true, + smokeShowButts = true, + smokeShowGum = true, + smokeCraftShowDismantle = true, + smokeCraftShowCigPacks = true, + smokeCraftAmount = -1, + craftShowEquipped = false, + craftShowSmokeables = false, + craftShowMedical = false, + craftAmount = -1, + craftSwitch = true, + craftFilterUnique = true, + equipShowDrop = true, + equipShowAllRepairs = false, + equipShowClothingActions = true, + equipShowRecipes = true, + repairShowEquipped = false, + repairShowHotbar = true, + firstAidCraftAmount = -1, + eatAmount = 0, + drinkAmount = 0, + eatQuickAmount = 1, + drinkQuickAmount = 1 + } + + if ModOptions and ModOptions.getInstance then + local function apply(data) + local options = data.settings.options + spiff.config.showTooltips = options.showTooltips + + spiff.config.smokeShowNow = options.smokeShowNow + spiff.config.smokeShowButts = options.smokeShowButts + spiff.config.smokeShowGum = options.smokeShowGum + + spiff.config.smokeCraftShowDismantle = options.smokeCraftShowDismantle + spiff.config.smokeCraftShowCigPacks = options.smokeCraftShowCigPacks + + spiff.config.craftSwitch = options.craftSwitch + spiff.config.craftShowEquipped = options.craftShowEquipped + spiff.config.craftShowSmokeables = options.craftShowSmokeables + spiff.config.craftShowMedical = options.craftShowMedical + spiff.config.craftFilterUnique = options.craftFilterUnique + + spiff.config.eatShowNow = options.eatShowNow + spiff.config.drinkShowNow = options.drinkShowNow + spiff.config.pillsShowNow = options.pillsShowNow + + spiff.config.equipShowDrop = options.equipShowDrop + spiff.config.equipShowAllRepairs = options.equipShowAllRepairs + spiff.config.equipShowClothingActions = options.equipShowClothingActions + spiff.config.equipShowRecipes = options.equipShowRecipes + + spiff.config.repairShowEquipped = options.repairShowEquipped + spiff.config.repairShowHotbar = options.repairShowHotbar + + spiff.config.smokeCraftAmount = rOptions.craft[options.smokeCraftAmount] + spiff.config.craftAmount = rOptions.craft[options.craftAmount] + spiff.config.eatAmount = rOptions.consume[options.eatAmount] + spiff.config.eatQuickAmount = rOptions.consume[options.eatQuickAmount] + spiff.config.drinkAmount = rOptions.consume[options.drinkAmount] + spiff.config.drinkQuickAmount = rOptions.consume[options.drinkQuickAmount] + + SpiffUI.equippedItem["Craft"] = not options.hideCraftButton + end + + local function applyGame(data) + apply(data) + local options = data.settings.options + SpiffUI:updateEquippedItem() + end + + local SETTINGS = { + options_data = { + showTooltips = { + name = "UI_ModOptions_SpiffUI_showTooltips", + default = true, + tooltip = getText("UI_ModOptions_SpiffUI_tooltip_showTooltips"), + OnApplyMainMenu = apply, + OnApplyInGame = apply, + }, + hideCraftButton = { + name = "UI_ModOptions_SpiffUI_hideCraftButton", + default = true, + OnApplyMainMenu = apply, + OnApplyInGame = applyGame, + }, + eatShowNow = { + name = "UI_ModOptions_SpiffUI_eatShowNow", + default = false, + tooltip = getText("UI_ModOptions_SpiffUI_tooltip_eatShowNow"), + OnApplyMainMenu = apply, + OnApplyInGame = apply, + }, + eatAmount = { + getText("UI_amount_SpiffUI_One"), getText("UI_amount_SpiffUI_Half"), + getText("UI_amount_SpiffUI_Quarter"), getText("UI_amount_SpiffUI_Ask"), + getText("UI_amount_SpiffUI_Full"), + + name = "UI_ModOptions_SpiffUI_eatAmount", + default = 4, + OnApplyMainMenu = apply, + OnApplyInGame = apply, + }, + eatQuickAmount = { + getText("UI_amount_SpiffUI_One"), getText("UI_amount_SpiffUI_Half"), + getText("UI_amount_SpiffUI_Quarter"), getText("UI_amount_SpiffUI_Full"), + + name = "UI_ModOptions_SpiffUI_eatQuickAmount", + default = 1, + OnApplyMainMenu = apply, + OnApplyInGame = apply, + }, + drinkShowNow = { + name = "UI_ModOptions_SpiffUI_drinkShowNow", + default = false, + tooltip = getText("UI_ModOptions_SpiffUI_tooltip_drinkShowNow"), + OnApplyMainMenu = apply, + OnApplyInGame = apply, + }, + drinkAmount = { + getText("UI_amount_SpiffUI_One"), getText("UI_amount_SpiffUI_Half"), + getText("UI_amount_SpiffUI_Quarter"), getText("UI_amount_SpiffUI_Ask"), + getText("UI_amount_SpiffUI_Full"), + + name = "UI_ModOptions_SpiffUI_drinkAmount", + default = 4, + OnApplyMainMenu = apply, + OnApplyInGame = apply, + }, + drinkQuickAmount = { + getText("UI_amount_SpiffUI_One"), getText("UI_amount_SpiffUI_Half"), + getText("UI_amount_SpiffUI_Quarter"), getText("UI_amount_SpiffUI_Full"), + + name = "UI_ModOptions_SpiffUI_drinkQuickAmount", + default = 1, + OnApplyMainMenu = apply, + OnApplyInGame = apply, + }, + pillsShowNow = { + name = "UI_ModOptions_SpiffUI_pillsShowNow", + default = false, + tooltip = getText("UI_ModOptions_SpiffUI_tooltip_pillsShowNow"), + OnApplyMainMenu = apply, + OnApplyInGame = apply, + }, + smokeShowNow = { + name = "UI_ModOptions_SpiffUI_smokeShowNow", + default = false, + tooltip = getText("UI_ModOptions_SpiffUI_tooltip_smokeShowNow"), + OnApplyMainMenu = apply, + OnApplyInGame = apply, + }, + smokeShowButts = { + name = "UI_ModOptions_SpiffUI_smokeShowButts", + default = true, + OnApplyMainMenu = apply, + OnApplyInGame = apply, + }, + smokeShowGum = { + name = "UI_ModOptions_SpiffUI_smokeShowGum", + default = true, + OnApplyMainMenu = apply, + OnApplyInGame = apply, + }, + smokeCraftShowDismantle = { + name = "UI_ModOptions_SpiffUI_smokeCraftShowDismantle", + default = true, + OnApplyMainMenu = apply, + OnApplyInGame = apply, + }, + smokeCraftShowCigPacks = { + name = "UI_ModOptions_SpiffUI_smokeCraftShowCigPacks", + default = false, + OnApplyMainMenu = apply, + OnApplyInGame = apply, + }, + smokeCraftAmount = { + getText("UI_amount_SpiffUI_One"), getText("UI_amount_SpiffUI_All"), + getText("UI_amount_SpiffUI_Ask"), + + name = "UI_ModOptions_SpiffUI_smokeCraftAmount", + default = 3, + OnApplyMainMenu = apply, + OnApplyInGame = apply, + }, + craftSwitch = { + name = "UI_ModOptions_SpiffUI_craftSwitch", + default = true, + tooltip = getText("UI_ModOptions_SpiffUI_tooltip_CraftingWheelSwitch"), + OnApplyMainMenu = apply, + OnApplyInGame = apply, + }, + craftShowEquipped = { + name = "UI_ModOptions_SpiffUI_craftShowEquipped", + default = false, + tooltip = getText("UI_ModOptions_SpiffUI_tooltip_craftShowEquipped"), + OnApplyMainMenu = apply, + OnApplyInGame = apply, + }, + craftShowSmokeables = { + name = "UI_ModOptions_SpiffUI_craftShowSmokeables", + default = false, + tooltip = getText("UI_ModOptions_SpiffUI_tooltip_craftShowSmokeables"), + OnApplyMainMenu = apply, + OnApplyInGame = apply, + }, + craftShowMedical = { + name = "UI_ModOptions_SpiffUI_craftShowMedical", + default = false, + tooltip = getText("UI_ModOptions_SpiffUI_tooltip_craftShowMedical"), + OnApplyMainMenu = apply, + OnApplyInGame = apply, + }, + craftFilterUnique = { + name = "UI_ModOptions_SpiffUI_craftFilterUnique", + default = true, + OnApplyMainMenu = apply, + OnApplyInGame = apply, + }, + craftAmount = { + getText("UI_amount_SpiffUI_One"), getText("UI_amount_SpiffUI_All"), + getText("UI_amount_SpiffUI_Ask"), + + name = "UI_ModOptions_SpiffUI_craftAmount", + default = 3, + OnApplyMainMenu = apply, + OnApplyInGame = apply, + }, + equipShowDrop = { + name = "UI_ModOptions_SpiffUI_equipShowDrop", + default = true, + OnApplyMainMenu = apply, + OnApplyInGame = apply, + }, + equipShowAllRepairs = { + name = "UI_ModOptions_SpiffUI_equipShowAllRepairs", + default = false, + tooltip = getText("UI_ModOptions_SpiffUI_tooltip_equipShowAllRepairs"), + OnApplyMainMenu = apply, + OnApplyInGame = apply, + }, + equipShowClothingActions = { + name = "UI_ModOptions_SpiffUI_equipShowClothingActions", + default = true, + OnApplyMainMenu = apply, + OnApplyInGame = apply, + }, + equipShowRecipes = { + name = "UI_ModOptions_SpiffUI_equipShowRecipes", + default = true, + OnApplyMainMenu = apply, + OnApplyInGame = apply, + }, + repairShowEquipped = { + name = "UI_ModOptions_SpiffUI_repairShowEquipped", + default = false, + tooltip = getText("UI_ModOptions_SpiffUI_tooltip_repairShowEquipped"), + OnApplyMainMenu = apply, + OnApplyInGame = apply, + }, + repairShowHotbar = { + name = "UI_ModOptions_SpiffUI_repairShowHotbar", + default = true, + OnApplyMainMenu = apply, + OnApplyInGame = apply, + }, + firstAidCraftAmount = { + getText("UI_amount_SpiffUI_One"), getText("UI_amount_SpiffUI_All"), + getText("UI_amount_SpiffUI_Ask"), + + name = "UI_ModOptions_SpiffUI_firstAidCraftAmount", + default = 3, + OnApplyMainMenu = apply, + OnApplyInGame = apply + } + }, + mod_id = "SpiffUI-Rads", + mod_shortname = "SpiffUI-Rads", + mod_fullname = getText("UI_Name_SpiffUI_Radials") + } + + local oInstance = ModOptions:getInstance(SETTINGS) + ModOptions:loadFile() + + Events.OnPreMapLoad.Add(function() + apply({settings = SETTINGS}) + end) + end + + spiff.icons = { + [1] = getTexture("media/SpiffUI/1.png"), + [2] = getTexture("media/SpiffUI/1-2.png"), + [3] = getTexture("media/SpiffUI/1-4.png"), + [4] = getTexture("media/SpiffUI/ALL.png"), + [5] = getTexture("media/SpiffUI/FULL.png"), + ["unequip"] = getTexture("media/ui/Icon_InventoryBasic.png"), + ["drop"] = getTexture("media/ui/Container_Floor.png") + } + + SpiffUI:AddKeyDisable("Toggle Inventory") + SpiffUI:AddKeyDisable("Crafting UI") + SpiffUI:AddKeyDisable("SpiffUI_Inv") + SpiffUI:AddKeyDisable("NF Smoke") + + SpiffUI:AddKeyDefault("Toggle Moveable Panel Mode", 0) + SpiffUI:AddKeyDefault("Display FPS", 0) + + print(getText("UI_Hello_SpiffUI_Radials")) +end + +spiff.Boot = SpiffUIBoot +spiff.Start = SpiffUIOnGameStart \ No newline at end of file diff --git a/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/TimedActions/SpiffUI_ISClothingExtraAction.lua b/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/TimedActions/SpiffUI_ISClothingExtraAction.lua new file mode 100644 index 0000000..c7f16ac --- /dev/null +++ b/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/TimedActions/SpiffUI_ISClothingExtraAction.lua @@ -0,0 +1,22 @@ +------------------------------------------ +-- SpiffUI Clothing Extra Action override +---- Adds time to the Clothing Extra Action +------------------------------------------ + +-- This is included with the Clothing Actions Radial Menu already +if getActivatedMods():contains('ClothingActionsRM') then return end + +-- I just want to change a few of the init things +local _ISClothingExtraAction_new = ISClothingExtraAction.new +function ISClothingExtraAction:new(...) + local o = _ISClothingExtraAction_new(self, ...) + o.stopOnAim = false + o.stopOnWalk = false + o.stopOnRun = true + o.maxTime = 25 + o.useProgressBar = false + if o.character:isTimedActionInstant() then + o.maxTime = 1 + end + return o +end diff --git a/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/TimedActions/SpiffUI_ISFixAction.lua b/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/TimedActions/SpiffUI_ISFixAction.lua new file mode 100644 index 0000000..3538b53 --- /dev/null +++ b/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/TimedActions/SpiffUI_ISFixAction.lua @@ -0,0 +1,11 @@ +------------------------------------------ +-- SpiffUI ISFixAction +---- Adds an animation to ISFixAction +------------------------------------------ + +local _ISFixAction_start = ISFixAction.start +function ISFixAction:start() + _ISFixAction_start(self) + + self:setActionAnim(CharacterActionAnims.Craft) +end \ No newline at end of file diff --git a/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/TimedActions/SpiffUI_ISWearClothing.lua b/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/TimedActions/SpiffUI_ISWearClothing.lua new file mode 100644 index 0000000..848b90e --- /dev/null +++ b/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/client/TimedActions/SpiffUI_ISWearClothing.lua @@ -0,0 +1,15 @@ +------------------------------------------ +-- SpiffUI ISWearClothing +---- Allows you to walk and put on clothes that makes sense +------------------------------------------ + +local _ISWearClothing_new = ISWearClothing.new +function ISWearClothing:new(...) + local o = _ISWearClothing_new(self, ...) + + o.stopOnAim = false + o.stopOnWalk = false + o.stopOnRun = true + + return o +end \ No newline at end of file diff --git a/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/shared/Translate/EN/UI_EN.txt b/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/shared/Translate/EN/UI_EN.txt new file mode 100644 index 0000000..5cd1458 --- /dev/null +++ b/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/shared/Translate/EN/UI_EN.txt @@ -0,0 +1,119 @@ +UI_EN = { + -- SpiffUI + UI_Hello_SpiffUI = "Hello SpiffUI!", + UI_Name_SpiffUI = "SpiffUI", + UI_optionscreen_binding_SpiffUI = "SpiffUI" + + UI_ModOptions_SpiffUI_applyNewKeybinds = "Set SpiffUI Recommended Keybinds", + UI_ModOptions_SpiffUI_Modal_applyNewKeybinds = " Set SpiffUI Keybinds Sets the following Keybinds: ", + UI_ModOptions_SpiffUI_Modal_aNKChild = " %1 to: [%2] ", + + UI_ModOptions_SpiffUI_runAllResets = "Run All SpiffUI Resets", + UI_ModOptions_SpiffUI_tooltip_runResets = "Only works In-Game!", + UI_ModOptions_SpiffUI_Modal_runResets = " SpiffUI Reset The following will be reset: ", + + -- SpiffUI -- Radials + UI_Hello_SpiffUI_Radials = "Hello SpiffUI - Radials", + + UI_Name_SpiffUI_Radials = "SpiffUI - Radials", + + UI_ModOptions_SpiffUI_showTooltips = "Show Tooltips", + UI_ModOptions_SpiffUI_hideCraftButton = "Hide Crafting Button", + + UI_ModOptions_SpiffUI_smokeShowButts = "Show Cigarette Butts (Smoke)", + UI_ModOptions_SpiffUI_smokeShowGum = "Show Gum (Smoke)", + UI_ModOptions_SpiffUI_smokeShowNow = "Show Radial on Press (Smoke)", + + UI_ModOptions_SpiffUI_pillsShowNow = "Show Radial on Press (Pills)", + + UI_ModOptions_SpiffUI_eatAmount = "Amount to Eat (Food)", + UI_ModOptions_SpiffUI_eatQuickAmount = "Amount to Quick Eat (Food)", + UI_ModOptions_SpiffUI_eatShowNow = "Show Radial on Press (Food)", + + UI_ModOptions_SpiffUI_drinkAmount = "Amount to Drink (Drink)", + UI_ModOptions_SpiffUI_drinkQuickAmount = "Amount to Quick Drink (Drink)", + UI_ModOptions_SpiffUI_drinkShowNow = "Show Radial on Press (Drink)", + + UI_ModOptions_SpiffUI_smokeCraftShowDismantle = "Show Dismantle Recipes (Smoke Craft)", + UI_ModOptions_SpiffUI_smokeCraftShowCigPacks = "Show Cigarette Packs (Smoke Craft)", + UI_ModOptions_SpiffUI_smokeCraftAmount = "Amount To Craft (Smoke Craft)", + + UI_ModOptions_SpiffUI_craftSwitch = "Show on Press (Crafting)", + UI_ModOptions_SpiffUI_craftShowEquipped = "Show Recipes on Equipped Items (Crafting)", + UI_ModOptions_SpiffUI_craftShowSmokeables = "Show Smokeable Recipes (Crafting)", + UI_ModOptions_SpiffUI_craftShowMedical = "Show Medical Recipes (Crafting)", + UI_ModOptions_SpiffUI_craftAmount = "Amount To Craft (Crafting)", + UI_ModOptions_SpiffUI_craftFilterUnique = "Filter Duplicate Recipes (Crafting)", + + UI_ModOptions_SpiffUI_equipShowDrop = "Show Drop Action (Equipment)", + UI_ModOptions_SpiffUI_equipShowAllRepairs = "Show Unavailable Repair Options (Equipment)", + UI_ModOptions_SpiffUI_equipShowClothingActions = "Show Extra Clothing Actions (Equipment)", + UI_ModOptions_SpiffUI_equipShowRecipes = "Show Recipes (Equipment)", + + UI_ModOptions_SpiffUI_repairShowEquipped = "Show Repairs on Equipped Items (Repair)", + UI_ModOptions_SpiffUI_repairShowHotbar = "Show Repairs for Items in Hotbar (Repair)", + + UI_ModOptions_SpiffUI_firstAidCraftAmount = "Amount to Craft (Medical Craft)", + + UI_ModOptions_SpiffUI_tooltip_showTooltips = "Show Tooltips in Radial Menus for Items, Recipes, and Repairs (Recommended)", + + UI_ModOptions_SpiffUI_tooltip_pillsShowNow = "Note: Disables Quick Pills Action", + + UI_ModOptions_SpiffUI_tooltip_drinkShowNow = "Note: Disables Quick Drink Water Action", + + UI_ModOptions_SpiffUI_tooltip_eatShowNow = "Note: Disables Quick Eat Food Action", + + UI_ModOptions_SpiffUI_tooltip_craftShowMedical = "Note: Some Recipes may still filter through. Consider using the First Aid Crafting Menu instead!", + UI_ModOptions_SpiffUI_tooltip_craftShowEquipped = "Note: Recipes on worn items can be done from the Equipment Menu. Items in your hand will still show recipes", + UI_ModOptions_SpiffUI_tooltip_craftShowSmokeables = "Consider using the Smoke Crafting Menu instead!" + + UI_ModOptions_SpiffUI_tooltip_smokeShowNow = "Note: Disables AutoSmoke Quick Smoke", + + UI_ModOptions_SpiffUI_tooltip_CraftingWheelSwitch = "Press Opens Radial Menu, Hold for Crafting Window", + + UI_ModOptions_SpiffUI_tooltip_equipShowAllRepairs = "Show Repair Options even if the required items are not in your inventory", + + UI_ModOptions_SpiffUI_tooltip_repairShowEquipped = "Repairs for Equipment can be done from the Equipment Menu", + + UI_amount_SpiffUI_Ask = "Ask", + UI_amount_SpiffUI_All = "All", + UI_amount_SpiffUI_Full = "Dieter", + UI_amount_SpiffUI_One = "1", + UI_amount_SpiffUI_Half = "1/2", + UI_amount_SpiffUI_Quarter = "1/4", + + UI_radial_SpiffUI_Accessories = "Accessories", + UI_radial_SpiffUI_Hotbar = "Hotbar", + UI_radial_SpiffUI_Transfer = "Transfer to ", + + UI_optionscreen_binding_SpiffUIPillWheel = "Pill Radial", + UI_optionscreen_binding_SpiffUIDrinkWheel = "Drink Radial", + UI_optionscreen_binding_SpiffUIEatWheel = "Eat Radial", + UI_optionscreen_binding_SpiffUISmokeWheel = "Smoke Radial", + UI_optionscreen_binding_SpiffUISmokeCraftWheel = "Smoke Craft Radial", + UI_optionscreen_binding_SpiffUICraftWheel = "Crafting UI/Radial", + UI_optionscreen_binding_SpiffUIEquipmentWheel = "Inventory Toggle/Radial", + UI_optionscreen_binding_SpiffUIRepairWheel = "Repair Radial", + UI_optionscreen_binding_SpiffUIFirstAidCraftWheel = "First Aid Craft", + UI_optionscreen_binding_SpiffUIOneWheel = "SpiffUI Radial", + + UI_character_SpiffUI_noLighter = "I need a lighter.", + UI_character_SpiffUI_noSmokes = "There's nothing to Smoke.", + + UI_character_SpiffUI_noCraft = "There's nothing to Craft.", + + UI_character_SpiffUI_noEquip = "I am Naked!", + + UI_character_SpiffUI_notHungry = "I'm not Hungry.", + UI_character_SpiffUI_noFood = "There's no Food to Eat.", + + UI_character_SpiffUI_notThirsty = "I'm not Thirsty.", + UI_character_SpiffUI_noDrinks = "There's nothing to Drink.", + + UI_character_SpiffUI_noRepair = "There's nothing to Repair.", + UI_character_SpiffUI_noRepairItems = "I can't Reapir that.", + + UI_character_SpiffUI_noPillsQuick = "I have no ", + UI_character_SpiffUI_noPills = "There's no pills", + UI_character_SpiffUI_noPillsNeed = "I'm not in any Mood." +} \ No newline at end of file diff --git a/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/shared/Translate/RU/UI_RU.txt b/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/shared/Translate/RU/UI_RU.txt new file mode 100644 index 0000000..2702cce --- /dev/null +++ b/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/media/lua/shared/Translate/RU/UI_RU.txt @@ -0,0 +1,122 @@ +UI_RU = { + -- Translation By: fourteensix + -- Перевод: fourteensix + + -- SpiffUI Radial + UI_Hello_SpiffUI = "Hello SpiffUI!", + UI_Name_SpiffUI = "SpiffUI", + UI_optionscreen_binding_SpiffUI = "SpiffUI" + + UI_ModOptions_SpiffUI_applyNewKeybinds = "Установите рекомендуемые сочетания клавиш SpiffUI", + UI_ModOptions_SpiffUI_Modal_applyNewKeybinds = " Установить привязки клавиш SpiffUI Устанавливает следующие сочетания клавиш: ", + UI_ModOptions_SpiffUI_Modal_aNKChild = " %1 для: [%2] ", + + UI_ModOptions_SpiffUI_runAllResets = "Запустить полный сброс SpiffUI", + UI_ModOptions_SpiffUI_tooltip_runResets = "Работает только в игре!", + UI_ModOptions_SpiffUI_Modal_runResets = " Сброс SpiffUI Будет сброшено следующее: ", + + -- SpiffUI -- Radials + UI_Hello_SpiffUI_Radials = "Hello SpiffUI - Radials", + + UI_Name_SpiffUI_Radials = "SpiffUI - Radials", + + UI_ModOptions_SpiffUI_showTooltips = "Показать подсказки", + UI_ModOptions_SpiffUI_hideCraftButton = "Скрыть кнопку крафта", + + UI_ModOptions_SpiffUI_smokeShowButts = "Показать окурки (мод Smoke)", + UI_ModOptions_SpiffUI_smokeShowGum = "Показать жвачку (мод Smoke)", + UI_ModOptions_SpiffUI_smokeShowNow = "Показать радиальное меню при нажатии (мод Smoke)", + + UI_ModOptions_SpiffUI_pillsShowNow = "Показать радиальное меню при нажатии (Таблетки)", + + UI_ModOptions_SpiffUI_eatAmount = "Количество еды (Еда)", + UI_ModOptions_SpiffUI_eatQuickAmount = "Количество еды для быстрого перекуса (Еда)", + UI_ModOptions_SpiffUI_eatShowNow = "Показать радиальное меню при нажатии (Еда)", + + UI_ModOptions_SpiffUI_drinkAmount = "Количество питья (Напитки)", + UI_ModOptions_SpiffUI_drinkQuickAmount = "Количество напитка для быстрого удаления жажды (Напитки)", + UI_ModOptions_SpiffUI_drinkShowNow = "Показать радиальное меню при нажатии (Напитки)", + + UI_ModOptions_SpiffUI_smokeCraftShowDismantle = "Показать рецепты разборки (крафт мода Smoke)", + UI_ModOptions_SpiffUI_smokeCraftShowCigPacks = "Показать пачки сигарет (крафт мода Smoke)", + UI_ModOptions_SpiffUI_smokeCraftAmount = "Количество для создания (крафт мода Smoke)", + + UI_ModOptions_SpiffUI_craftSwitch = "Показать радиальное меню при нажатии (Крафт)", + UI_ModOptions_SpiffUI_craftShowEquipped = "Показать рецепты на экипированных предметах (Крафт)", + UI_ModOptions_SpiffUI_craftShowSmokeables = "Показать рецепты для курения (Крафт)", + UI_ModOptions_SpiffUI_craftShowMedical = "Показать медицинские рецепты (Крафт)", + UI_ModOptions_SpiffUI_craftAmount = "Количество для крафта (Крафт)", + UI_ModOptions_SpiffUI_craftFilterUnique = "Фильтр повторяющихся рецептов (Крафт)", + + UI_ModOptions_SpiffUI_equipShowDrop = "Показать действие дропа (Экипировка)", + UI_ModOptions_SpiffUI_equipShowAllRepairs = "Показать недоступные параметры ремонта (Экипировка)", + UI_ModOptions_SpiffUI_equipShowClothingActions = "Показать действия с дополнительной одеждой (Экипировка)", + UI_ModOptions_SpiffUI_equipShowRecipes = "Показать рецепты (Экипировка)", + + UI_ModOptions_SpiffUI_repairShowEquipped = "Показать ремонт экипированных предметов (Ремонт)", + UI_ModOptions_SpiffUI_repairShowHotbar = "Показать ремонт предметов в хотбаре (Ремонт)", + + UI_ModOptions_SpiffUI_firstAidCraftAmount = "Количество для крафта (Крафт медикаментов)", + + UI_ModOptions_SpiffUI_tooltip_showTooltips = "Показывать всплывающие подсказки в радиальных меню для предметов, рецептов и ремонтов (Рекомендуется)", + + UI_ModOptions_SpiffUI_tooltip_pillsShowNow = "Примечание: отключает действие *Быстрые таблетки*", + + UI_ModOptions_SpiffUI_tooltip_drinkShowNow = "Примечание: отключает действие *Быстрое питьё воды*", + + UI_ModOptions_SpiffUI_tooltip_eatShowNow = "Примечание: отключает действие *Быстро съесть еду*", + + UI_ModOptions_SpiffUI_tooltip_craftShowMedical = "Примечание: некоторые рецепты могут по-прежнему фильтроваться. Вместо этого рассмотрите возможность использования меню крафта первой помощи!", + UI_ModOptions_SpiffUI_tooltip_craftShowEquipped = "Примечание: рецепты на изношенные предметы можно сделать из меню снаряжения. Предметы в вашей руке по-прежнему будут показывать рецепты", + UI_ModOptions_SpiffUI_tooltip_craftShowSmokeables = "Вместо этого рассмотрите возможность использования меню крафта мода Smoke!" + + UI_ModOptions_SpiffUI_tooltip_smokeShowNow = "Примечание: отключает мод AutoSmoke для быстрого курения", + + UI_ModOptions_SpiffUI_tooltip_CraftingWheelSwitch = "Нажмите, чтобы открыть радиальное меню, удерживайте, чтобы открыть окно крафта", + + UI_ModOptions_SpiffUI_tooltip_equipShowAllRepairs = "Показать параметры ремонта, даже если требуемых предметов нет в вашем инвентаре", + + UI_ModOptions_SpiffUI_tooltip_repairShowEquipped = "Ремонт снаряжения можно выполнить из меню снаряжения.", + + UI_amount_SpiffUI_Ask = "Спросить", + UI_amount_SpiffUI_All = "Всё", + UI_amount_SpiffUI_Full = "Диетолог", + UI_amount_SpiffUI_One = "1", + UI_amount_SpiffUI_Half = "1/2", + UI_amount_SpiffUI_Quarter = "1/4", + + UI_radial_SpiffUI_Accessories = "Аксессуары", + UI_radial_SpiffUI_Hotbar = "Хотбар", + UI_radial_SpiffUI_Transfer = "Переместить на ", + + UI_optionscreen_binding_SpiffUIPillWheel = "Таблетки в меню", + UI_optionscreen_binding_SpiffUIDrinkWheel = "Напитки в меню", + UI_optionscreen_binding_SpiffUIEatWheel = "Еда в меню", + UI_optionscreen_binding_SpiffUISmokeWheel = "Курение в меню", + UI_optionscreen_binding_SpiffUISmokeCraftWheel = "Крафт мода Smoke в меню", + UI_optionscreen_binding_SpiffUICraftWheel = "Интерфейс крафта/радиальное меню", + UI_optionscreen_binding_SpiffUIEquipmentWheel = "Переключатель инвентаря/Радиальное меню", + UI_optionscreen_binding_SpiffUIRepairWheel = "Ремонт в радиальном меню", + UI_optionscreen_binding_SpiffUIFirstAidCraftWheel = "Крафт для первой помощи", + UI_optionscreen_binding_SpiffUIOneWheel = "SpiffUI Радиальное меню", + + UI_character_SpiffUI_noLighter = "Мне нужна зажигалка.", + UI_character_SpiffUI_noSmokes = "Нечего курить.", + + UI_character_SpiffUI_noCraft = "Крафтить нечего.", + + UI_character_SpiffUI_noEquip = "Я Голый!", + + UI_character_SpiffUI_notHungry = "Я не голоден.", + UI_character_SpiffUI_noFood = "Нет еды, чтобы поесть.", + + UI_character_SpiffUI_notThirsty = "Я не хочу пить.", + UI_character_SpiffUI_noDrinks = "Пить нечего.", + + UI_character_SpiffUI_noRepair = "Ремонтировать нечего.", + UI_character_SpiffUI_noRepairItems = "Я не могу отремонтировать это.", + + UI_character_SpiffUI_noPillsQuick = "У меня нет ", + UI_character_SpiffUI_noPills = "Нет таблеток", + UI_character_SpiffUI_noPillsNeed = "Я не в настроении.", +} \ No newline at end of file diff --git a/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/mod.info b/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/mod.info new file mode 100644 index 0000000..ca6cfc8 --- /dev/null +++ b/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/mod.info @@ -0,0 +1,10 @@ +name=SpiffUI - Radials +id=SpiffUI-Rads +authors=dhert + +description=Adds a bunch of Radial Menus for various things + +pzversion=41 +tags=Interface;Framework;Misc + +poster=poster.png \ No newline at end of file diff --git a/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/poster.png b/SpiffUI-Radials/Contents/mods/SpiffUI-Radials/poster.png new file mode 100644 index 0000000000000000000000000000000000000000..4755e36ade007b06ebd6a76e372a58e5893d8eba GIT binary patch literal 192721 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%0D%ifUl)Z$h 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 literal 0 HcmV?d00001 diff --git a/SpiffUI-Radials/README.md b/SpiffUI-Radials/README.md new file mode 100644 index 0000000..64dcb76 --- /dev/null +++ b/SpiffUI-Radials/README.md @@ -0,0 +1,306 @@ +# SpiffUI Radials + +![poster](Contents/mods/SpiffUI-Radials/poster.png) + +**Supports B41+. Works in Multiplayer** + +## SpiffUI - Radials + +Adds 9 New Radials for easy interactions with the objects that are in your inventories and the world. If a Radial is unavailable, your character will Say something. Items return to their original location when used. + +Included Radials: +- Crafting Radial +- Medical Craft Radial +- Smoke Craft Radial +- Equipment Radial +- Drink Radial +- Food Radial +- Pill Radial +- Repair Radial +- Smoke Radial + +Possibly Next: +- Medical Radial - Would allow for quick access to any injuries. +- Inspect Radial - Port the Inspect Window to a Radial (I have this somewhat working) +- More Mod Compatibility + +Got an idea for a Radial or any features I missed? Let me know! + +### Included Base Game Fixes + +These are small tweaks to Base Game Actions that I overall help the immersion of these Radials and the game overall. + +- ISFixAction - (Repair) + - Added an Animation when doing a Repair Action +- ISWearAction - (Wear Clothes) + - Fixed the Rules for Equipping Clothes. + - You can now walk and equip any upper-body pieces of clothing (ie. shirts). + - Your character now stops walking for lower-body clothes (ie. shoes). + - This matches how the Unequip Actions works for these items +- ISClothingExtraActions - (Clothing Extra Actions) + - Fixed the Rules for Clothing Extra Actions similarly to the ISWearAction + - Added time (Half the Equip Time) to show an Animation + +### Controlers! + +Controllers are currently not supported. The Radials are currently not designed to give focus to the Radial either so, really, don't try it please; it won't work. + +There are simply too many radials to accomodate a controller at this time. I have something in the works regarding this, but for now no controllers. + +### Quick Actions + +Some Radials have a "Quick Action" that is performed by a quick press of the key; the Radial is shown with a press and hold. Each available quick action is explained further in the description. If you set the Radial to be "Show on Press" the Quick Action will be disabled. + +### Amount to Eat/Drink/Craft + +Some actions can be performed on part or all of the items when you use the context menu, and these Radials can too! A new Radial will appear asking to confirm how much if applicable. + +You can also specify an amount to always perform by default in the ModOptions. + +Quick Actions can only be set to an amount and will not ask. + +### Radial Pages + +The Radials will automatically paginate if enough items or recipes are available. "Next" and "Previous" buttons will become available when applicable. + +### Tooltips + +The Tooltips have been ported to show in these Radials for all Recipes, Items, and Repairs. When enabled, the item name does not appear in the middle of the Radial anymore. This was a design decision as often the name is too long. Besides, the name is in the Tooltip! The Tooltips can be disabled, but are recommended. + +**Known issue for the Recipe Tooltip:** I modified this from the default to prevent the lag from having too many items. One side-effect of this is that sometimes an ingredient will be duplicated or listed in the wrong category. This ONLY affects the Tooltip, the Recipe works as intended. + +### Recommended External Mods +Some Radials have external mod soft requirements listed below. Each Radial will work without any external mods, however, certain features and apparent usefulness are only available with other mods. + +- AutoSmoke by NoctisFalco: It is highly recommended that you use have this mod to unlock the full Smoke Radial Menu. I use AutoSmoke's Item Filters and Actions to include support for the various cigarette mods in both the Smoke and Smoke Craft Radials. Without this mod, you will still be able to smoke cigarettes but will be unable to interact with packs in the Smoke or Smoke Craft Radials. Either AutoSmoke or AutoSmoke-Stable can be used. + +- Having AutoSmoke gives support for both Smoker by Nebula and More Cigarettes Mod by Madman_Andre. ONE of these mods is recommended as well. + +- jigga's Green Fire by jiggawut: Honestly, the reason I made the Smoke Craft Radial. This mod is one of my personal favorites. Adds items that populates the Radial. + +- SpiffUI - Inventory: Modified behaviors to show and hide the Inventory Window, and part of SpiffUI! + +## SpiffUI Configuration + +If ModOptions is installed (Recommended) SpiffUI will appear as a category. This is intended to have common configuration across all of SpiffUI, as well as tools to help configure the game to SpiffUI recommendations. + +- Set SpiffUI Recommended Keybinds + - Default: (None) It's a Button! + - Sets keybinds for built-in keys to recommended defaults. A dialog will ask confirming this change, and will display the changes it will make. +- Run All SpiffUI Resets + - Default: (None) It's a Button! + - Runs all "Reset" functions for SpiffUI modules. A user is able to change where the UI is, its size, etc. This will set this to default. A dialog will ask confirming this change, and will display the changes it will make. + - **NOTE:** This will only be usable in-game. + +## SpiffUI - Radials Configuration + +- Show Tooltips + - Default: True + - Show Tooltips in Radial Menus for Items, Recipes, and Repairs (Recommended) +- Hide Crafting Button + - Default: True + - Hides the Crafting button in the left sidemenu + +## Radials + +### Crafting Radial + +Unlock the full power of Crafting with the Crafting Radial! Shows available recipes for items that can be performed for items on the player and in the world. + +**Default Key:** `B` + +By default, this changes the behavior so pressing the key opens the Radial while a long press will open the Crafting window. + +**Configuration:** +- Show on Press (Crafting) + - Default: True + - Press Opens Radial Menu, Hold for Crafting Window +- Show Recipes on Equipped Items (Crafting) + - Default: False + - Note: Recipes on worn items can be done from the Equipment Menu. Items in your hand will still show recipes +- Show Smokeable Recipes (Crafting) + - Default: False + - Consider using the Smoke Crafting Menu instead! +- Show Medical Recipes (Crafting) + - Default: False + - Note: Some Recipes may still filter through. For example, having a Plank and Ripped Sheets will still the recipe for a Splint due to the Plank. Consider using the First Aid Crafting Menu instead! +- Craft Amount (Crafting) + - Default: Ask + - How many to craft (Only shows if more than 1 is available) +- Filter Duplicate Recipes (Crafting) + - Default: True + - Filters Duplicate Crafting Recipes to help de-clutter the Radial + +### Medical Craft Radial + +Easy Access to those life-saving crafing recipes quick! + +**Default Key:** `;` + +Shows on press + +**Configuration:** +- Craft Amount (Medical Craft) + - Default: Ask + - How many to craft (Only shows if more than 1 is available) + +### Smoke Craft Radial + +Want to role-play as a hipster who rolls their own cigarettes? Or a stoner who is always keeping things packed? Or maybe you're just classy and only smoke from a pipe? Here's for you! + +This Radial may be a bit niche, but hey we're just having fun! + +**Default Key:** `\` + +Shows on press + +**Configuration:** +- Show Dismantle Recipes (Smoke Craft) + - Default: True + - Shows Recipes to Break/Unpack Items +- Show Cigarette Packs (Smoke Craft) + - Default: False + - Shows the Unpack actions on cigarettes +- Amount To Craft (Smoke Craft) + - Default: Ask + - How many to craft (Only shows if more than 1 is available) + + +### Equipment Radial + +A Radial that shows equipped items from Head-to-Toe! Accessories, such as Glasses, Jewelry, etc, and items in your Hotbar are organized in a submenu to help declutter the Radial. + +Selecting an item gives many of the same options as the Context Menu such as Unequiping, "Inspect" (shows the Insepct Window), any Recipes (configurable), Repairs, and item-specific interactions! + +**Default Key:** `Tab` + +Press and hold + +**Configuration:** + +- Show Drop Action (Equipment) + - Default: True + - Shows Option to Drop an item +- Show Unavailable Repair Options (Equipment) + - Default: False + - Shows all Repair Recipes even if you don't have the items/skills +- Show Extra Clothing Actions (Equipment) + - Default: True + - Shows "Extra Clothing Actions" on clothing Items (Putting up the Hood, Turning your hat, etc) +- Show Recipes (Equipment) + - Default: True + - Shows available Recipes for an item + +### Drink Radial + +Shows available drinks on or around your character. There's a Zombie Apocolypse, no one will blame you for chugging that warm 2-liter of Orange Soda 90+ days in. Also perfect for an Alcoholic on-the-go who loves choice! + +**Default Key:** `{` + +**Quick Action:** Drink! + +Drinks water or the first found drinkable in your inventory if you are Thirsty. If Water, drinks how much you need. Otherwise uses the "Amount to Quick Drink" setting. + +**WARNING** Poisons **WILL** appear in the Radial and can be chosen for the Quick Action if your character doesn't know its Poisonous!!!! + +**Configuration:** + +- Amount to Drink (Drink) + - Default: Ask + - How much to Drink +- Amount to Quick Drink (Drink) + - Default: All + - How much to Drink on Quick Action +- Show Radial on Press (Drink) + - Default: False + - Shows the Drink Radial on Press. Disables the Quick Drink Action + +### Food Radial + +Shows available food on or around your character. We all get Snacky. + +**Default Key:** `}` + +**Quick Action:** Eat a Snack! + +Eats the food item in your inventory that has the lowest Hunger Change. + +**Configuration:** + +- Amount to Eat (Food) + - Default: Ask + - How much to Eat +- Amount to Quick Eat (Food) + - Default: All + - How much to Eat on Quick Action +- Show Radial on Press (Food) + - Default: False + - Shows the Food Radial on Press. Disables the Quick Eat Action + +### Pill Radial + +Shows available pills on or around your character. + +**Default Key:** `'` + +**Quick Action:** Take Needed Pills + +Takes the pills to control Moodlets! Supports "Pain Pills", "Vitamins", "Beta Blockers", and "Antidepressents". Will attempt to take ALL needed pills. + +**Configuration:** +- Show Radial on Press (Pills) + - Default: False + - Shows the Pill Radial on Press. Disables the Quick Pills Action + +### Repair Radial + +Shows available Repairs for items on or around your character. + +**Default Key:** `N` + +Shows on press + +**Configuration:** + +- Show Repairs on Equipped Items (Repair) + - Default: False + - Can instead be done from the Equipment Radial! Note, the items in your Hands will still show +- Show Repairs for Items in Hotbar (Repair) + - Default: False + - Can instead be done from the Equipment Radial! Note, the items in your Hands will still show + +### Smoke Radial + +Shows available Smokeables on or around your character. A Lighter or Matches is required in order to display items. + +**Default Key:** `Backspace` + +**Quick Action:** AutoSmoke + +If AutoSmoke is not enabled, there is no Quick Action + +**Configuration:** + +- Show Cigarette Butts (Smoke) + - Default: False + - Show Cigarette Butts if added by a Mod +- Show Gum (Smoke) + - Default: True + - Show Nicotine Gum if added by a Mod +- Show Radial on Press (Smoke) + - Default: False + - Shows the Smoke Radial on Press. Disables the AutoSmoke Quick Action + +## Translations + +English + +Russian - fourteensix + +If you would like to help with translations, please submit a Pull Request. + + +``` +Workshop ID: 2802525922 +Mod ID: SpiffUI-Rads +``` \ No newline at end of file diff --git a/SpiffUI-Radials/preview.png b/SpiffUI-Radials/preview.png new file mode 100644 index 0000000000000000000000000000000000000000..56b541b43699f42a4b71db9ab7001fb806444aa3 GIT binary patch literal 28706 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 literal 0 HcmV?d00001 diff --git a/SpiffUI-Radials/workshop.txt b/SpiffUI-Radials/workshop.txt new file mode 100644 index 0000000..754e0b2 --- /dev/null +++ b/SpiffUI-Radials/workshop.txt @@ -0,0 +1,136 @@ +version=1 +id=2802525922 +title=SpiffUI - Radials +description=[h1]Supports B41+. Works in Multiplayer[/h1] +description=[h3]A new save is not required[/h3] +description= +description=SpiffUI (pronounced "Spiffy") Radials adds 10 new Radial Menus for easy interactions with the objects that are in your inventories and the world. If a Radial is unavailable, your character will Say something. Items return to their original location when used. +description= +description=[b]Included Radials:[/b] +description=[list] +description=[*]Crafting Radial +description=[*]Medical Craft Radial +description=[*]Smoke Craft Radial +description=[*]Equipment Radial +description=[*]Drink Radial +description=[*]Food Radial +description=[*]Pill Radial +description=[*]Repair Radial +description=[*]Smoke Radial +description=[*]SpiffUI Radial -- A quick way to access ALL of the Radials! +description=[/list] +description= +description=Please see the Discussion [url=https://steamcommunity.com/workshop/filedetails/discussion/2802525922/3273564019257617796]SpiffUI Radials and their Configurations[/url] for further information on each Radial, including each keybind. +description= +description=[b]Possibly Next:[/b] +description=[list] +description=[*]Medical Radial - Would allow for quick access to any injuries. +description=[*]Inspect Radial - Port the Inspect Window to a Radial (I have this somewhat working) +description=[*]More Mod Compatibility +description=[/list] +description= +description=Got an idea for a Radial or any features I missed? Let me know! +description= +description=[h2]Included Base Game Fixes[/h2] +description=These are small tweaks to Base Game Actions that help the immersion of these Radials and the game overall. +description= +description=[b]ISFixAction[/b] - (Repair) +description=[list] +description=[*]Added an Animation when doing a Repair Action +description=[/list] +description=[b]ISWearAction[/b] - (Wear Clothes) +description=[list] +description=[*]Fixed the Rules for Equipping Clothes. +description=[*]You can now walk and equip any upper-body pieces of clothing (ie. shirts). +description=[*]Your character now stops walking for lower-body clothes (ie. shoes). +description=[*]This matches how the Unequip Actions works for these items +description=[/list] +description=[b]ISClothingExtraActions[/b] - (Clothing Extra Actions) +description=[list] +description=[*]Fixed the Rules for Clothing Extra Actions similarly to the ISWearAction +description=[*]Added time (Half the Equip Time) to show an Animation +description=[/list] +description= +description=[h2]Controllers[/h2] +description=Press UP on the D-PAD to show the Main SpiffUI Radial! Accessing options in each submenu is done by pressing "Up" on the D-PAD as well. +description= +description=[b]NOTE:[/b]This will ONLY work if your character is not in or near a car. +description= +description=[h2]Other Features:[/h2] +description= +description=[h3]Quick Actions[/h3] +description=Some Radials have a "Quick Action" that is performed by a quick press of the key; the Radial is shown with a press and hold. Each available quick action is explained further in the description. If you set the Radial to "Show on Press" the Quick Action will be disabled. +description= +description=[h3]Amount to Eat/Drink/Craft[/h3] +description=Some actions can be performed on part or all of the items when you use the context menu, and these Radials can too! A new Radial will appear asking to confirm how much if applicable. +description= +description=You can also specify an amount to always perform by default in the ModOptions. +description= +description=Quick Actions can only be set to an amount and will not ask. +description= +description=[h3]Radial Pages[/h3] +description=The Radials will automatically paginate if enough items or recipes are available. "Next" and "Previous" buttons will become available when applicable. +description= +description=[h3]Tooltips[/h3] +description=The Tooltips have been ported to show in these Radials for all Recipes, Items, and Repairs. When enabled, the item name does not appear in the middle of the Radial anymore. This was a design decision as often the name is too long. Besides, the name is in the Tooltip! The Tooltips can be disabled, but are recommended. +description= +description=[b]Known issue for the Recipe Tooltip:[/b] I modified this from the default to prevent the lag from having too many items. One side-effect of this is that sometimes an ingredient will be duplicated or listed in the wrong category. This ONLY affects the Tooltip, the Recipe works as intended. +description= +description=[h2]Recommended External Mods[/h2] +description=Some Radials have external mod soft requirements listed below. Each Radial will work without any external mods, however, certain features and apparent usefulness are only available with other mods. +description=[list] +description=[*][b][url=https://steamcommunity.com/sharedfiles/filedetails/?id=2643751872]AutoSmoke[/url] by NoctisFalco[/b]: It is highly recommended that you use have this mod to unlock the full Smoke Radial Menu. I use AutoSmoke's Actions to include support for the various cigarette mods in Smoke Radial. Without this mod, you will still be able to smoke cigarettes but will be unable to interact with packs in the Smoke Radial. Either AutoSmoke or [url=https://steamcommunity.com/sharedfiles/filedetails/?id=2691602472]AutoSmoke-Stable[/url] can be used. +description=[*]Having AutoSmoke gives support for both [b][url=https://steamcommunity.com/sharedfiles/filedetails/?id=2026976958]Smoker[/url] by Nebula[/b] and [b][url=https://steamcommunity.com/sharedfiles/filedetails/?id=2396329386]More Cigarettes Mod[/url] by Madman_Andre[/b]. Using only ONE of these cigarette mods is recommended as well. +description=[*][b][url=https://steamcommunity.com/sharedfiles/filedetails/?id=1703604612]jigga's Green Fire[/url] by jiggawut[/b]: Honestly, the reason I made the Smoke Craft Radial. This mod is one of my personal favorites. Adds items that populates the Smoke Craft Radial. +description=[*][b][url=https://steamcommunity.com/sharedfiles/filedetails/?id=2799848602]SpiffUI - Inventory[/url][/b]: Modified behaviors to show and hide the Inventory Window, and part of SpiffUI! +description=[/list] +description= +description=[h2]SpiffUI Configuration[/h2] +description= +description=[url=https://steamcommunity.com/workshop/filedetails/?id=2169435993]ModOptions[/url] is required for futher configuration, but the mod will function without. +description=If ModOptions is installed (Recommended) SpiffUI will appear as a category. This is intended to have common configuration across all of SpiffUI, as well as tools to help configure the game to SpiffUI recommendations. +description= +description=[table] +description=[tr] +description=[th]Name[/th] +description=[th]Default[/th] +description=[th]Description[/th] +description=[/tr] +description=[tr] +description=[td]Set SpiffUI Recommended Keybinds[/td] +description=[td](None) It's a Button![/td] +description=[td]Sets keybinds for built-in keys to recommended defaults. A dialog will ask confirming this change, and will display the changes it will make.[/td] +description=[/tr] +description=[tr] +description=[td]Run All SpiffUI Resets[/td] +description=[td](None) It's a Button![/td] +description=[td]Runs all "Reset" functions for SpiffUI modules. A user is able to change where the UI is, its size, etc. This will set this to default. A dialog will ask confirming this change, and will display the changes it will make. PLEASE NOTE: This will only be usable in-game.[/td] +description=[/tr] +description=[/table] +description= +description=[h2]SpiffUI - Radials Configuration[/h2] +description= +description=[table] +description=[tr] +description=[th]Name[/th] +description=[th]Default[/th] +description=[th]Description[/th] +description=[/tr] +description=[tr] +description=[td]Show Tooltips[/td] +description=[td]True[/td] +description=[td]Show Tooltips in Radial Menus for Items, Recipes, and Repairs (Recommended)[/td] +description=[/tr] +description=[tr] +description=[td]Hide Crafting Button[/td] +description=[td]True[/td] +description=[td]Hides the Crafting button in the left sidemenu[/td] +description=[/tr] +description=[/table] +description= +description=Each Radial has its own Configuration as well. This is expanded upon in the Discussion [url=https://steamcommunity.com/workshop/filedetails/discussion/2802525922/3273564019257617796]SpiffUI Radials and their Configurations[/url]. +description= +description=[h2]Translations[/h2] +description=Item Names, Recipes, and others use the built-in translations; mods must include this. If you would like to contribute a translation, please submit a pull request on [url=https://github.com/hlfstr/pz-mods]GitHub![/url] I will happily give credit! +tags=Build 41;Food;Interface;Silly/Fun +visibility=public