Initial Commit

This commit is contained in:
2026-08-12 13:36:14 -04:00
parent cdedb1cb5e
commit 19e4ac0cce
22 changed files with 30278 additions and 1 deletions
@@ -0,0 +1,211 @@
require "ISUI/ISCollapsableWindow"
require "ISUI/ISScrollingListBox"
require "ISUI/ISButton"
require "Vehicles/TimedActions/ISPathFindAction"
require "PaintMyKI5/PaintRequirements"
require "PaintMyKI5/PaintInventory"
require "PaintMyKI5/TimedActions/ISPaintMyKI5Vehicle"
ISPaintMyKI5UI = ISCollapsableWindow:derive("ISPaintMyKI5UI")
ISPaintMyKI5UI.instances = ISPaintMyKI5UI.instances or {}
local FONT_SMALL = UIFont.Small
local FONT_MEDIUM = UIFont.Medium
local SMALL_HEIGHT = getTextManager():getFontHeight(FONT_SMALL)
local MEDIUM_HEIGHT = getTextManager():getFontHeight(FONT_MEDIUM)
local function textureLabel(textureData)
local name = string.match(textureData.texture or "", "([^/]+)$") or ""
return getText("IGUI_PaintMyKI5_Skin", textureData.skinIndex + 1) .. " - " .. name
end
local function getPaletteColor(itemType)
for _, paint in ipairs(PaintMyKI5.VehiclePaintData.paintCans or {}) do
if paint.item == itemType and paint.rgb then
return paint.rgb[1], paint.rgb[2], paint.rgb[3]
end
end
return 0.5, 0.5, 0.5
end
function ISPaintMyKI5UI.drawSkinItem(list, y, item, alt)
if item.itemindex == list.selected then
list:drawRect(0, y, list:getWidth(), item.height, 0.25, 0.3, 0.7, 1.0)
elseif alt then
list:drawRect(0, y, list:getWidth(), item.height, 0.08, 1, 1, 1)
end
list:drawText(item.text, 8, y + 3, 1, 1, 1, 1, FONT_SMALL)
return y + item.height
end
function ISPaintMyKI5UI:createChildren()
ISCollapsableWindow.createChildren(self)
local top = self:titleBarHeight() + 10
self.skinList = ISScrollingListBox:new(10, top, 275, self.height - top - 52)
self.skinList:initialise()
self.skinList:instantiate()
self.skinList.itemheight = SMALL_HEIGHT + 8
self.skinList.doDrawItem = ISPaintMyKI5UI.drawSkinItem
self.skinList.drawBorder = true
self:addChild(self.skinList)
for _, textureData in ipairs(self.vehicleData.textures or {}) do
self.skinList:addItem(textureLabel(textureData), textureData)
end
local currentIndex = self.vehicle:getSkinIndex()
for index, row in ipairs(self.skinList.items) do
if row.item.skinIndex == currentIndex then self.skinList.selected = index end
end
if self.skinList.selected <= 0 and #self.skinList.items > 0 then self.skinList.selected = 1 end
self.paintButton = ISButton:new(
self.width - 210, self.height - 38, 95, 28,
getText("IGUI_PaintMyKI5_Paint"), self, ISPaintMyKI5UI.onPaint
)
self.paintButton:initialise()
self.paintButton:instantiate()
self:addChild(self.paintButton)
self.cancelButton = ISButton:new(
self.width - 105, self.height - 38, 95, 28,
getText("UI_btn_close"), self, ISPaintMyKI5UI.close
)
self.cancelButton:initialise()
self.cancelButton:instantiate()
self:addChild(self.cancelButton)
end
function ISPaintMyKI5UI:getSelectedTexture()
local row = self.skinList and self.skinList.items[self.skinList.selected] or nil
return row and row.item or nil
end
function ISPaintMyKI5UI:prerender()
ISCollapsableWindow.prerender(self)
local textureData = self:getSelectedTexture()
local enabled = false
if textureData then
local area = PaintMyKI5.PaintRequirements.findInteractionArea(
self.vehicle, self.character
)
local requirements = PaintMyKI5.PaintRequirements.getRequirements(
self.vehicle, textureData.skinIndex
)
enabled = requirements ~= nil
and PaintMyKI5.PaintRequirements.isValidTarget(
self.character, self.vehicle, textureData.skinIndex, area
)
and PaintMyKI5.PaintInventory.checkRequirements(self.character, requirements)
end
self.paintButton:setEnable(enabled)
end
function ISPaintMyKI5UI:render()
ISCollapsableWindow.render(self)
local textureData = self:getSelectedTexture()
if not textureData then return end
local rightX = 300
local contentWidth = self.width - rightX - 10
local previewY = self:titleBarHeight() + 10
local requirements = PaintMyKI5.PaintRequirements.getRequirements(
self.vehicle, textureData.skinIndex
) or {}
local requirementHeight = #requirements * (SMALL_HEIGHT + 5)
local availablePreviewHeight = self.height - previewY - requirementHeight - 110
local previewHeight = math.max(120, math.min(245, availablePreviewHeight))
self:drawRectBorder(rightX, previewY, contentWidth, previewHeight, 0.7, 0.6, 0.6, 0.6)
local preview = getTexture("media/textures/" .. textureData.texture .. ".png")
or getTexture(textureData.texture)
if preview then
self:drawTextureScaledAspect(preview, rightX + 5, previewY + 5, contentWidth - 10, previewHeight - 10, 1, 1, 1, 1)
else
self:drawTextCentre(
getText("IGUI_PaintMyKI5_PreviewMissing"),
rightX + contentWidth / 2, previewY + previewHeight / 2,
0.8, 0.8, 0.8, 1, FONT_SMALL
)
end
local y = previewY + previewHeight + 12
self:drawText(getText("IGUI_PaintMyKI5_Requirements"), rightX, y, 1, 1, 1, 1, FONT_MEDIUM)
y = y + MEDIUM_HEIGHT + 6
for _, requirement in ipairs(requirements) do
local available = PaintMyKI5.PaintInventory.countUses(self.character, requirement.item)
local enough = available + 0.0001 >= requirement.uses
local red, green, blue = getPaletteColor(requirement.item)
self:drawRect(rightX, y + 2, 14, 14, 1, red, green, blue)
self:drawRectBorder(rightX, y + 2, 14, 14, 1, 0.9, 0.9, 0.9)
local itemName = getItemNameFromFullType(requirement.item)
available = math.floor(available * 100 + 0.5) / 100
local text = getText(
"IGUI_PaintMyKI5_RequirementLine",
itemName, requirement.percent, requirement.uses, available
)
if enough then
self:drawText(text, rightX + 22, y, 0.7, 1, 0.7, 1, FONT_SMALL)
else
self:drawText(text, rightX + 22, y, 1, 0.4, 0.4, 1, FONT_SMALL)
end
y = y + SMALL_HEIGHT + 5
end
self:drawText(
getText("IGUI_PaintMyKI5_OneBucket", PaintMyKI5.PaintRequirements.getBucketUses()),
rightX, y + 4, 1, 1, 1, 1, FONT_SMALL
)
end
function ISPaintMyKI5UI:onPaint()
local textureData = self:getSelectedTexture()
if not textureData then return end
local requirements = PaintMyKI5.PaintRequirements.getRequirements(
self.vehicle, textureData.skinIndex
)
if not requirements then return end
local enough = PaintMyKI5.PaintInventory.checkRequirements(self.character, requirements)
if not enough then return end
local area = PaintMyKI5.PaintRequirements.findInteractionArea(self.vehicle, self.character)
if not area then return end
if not PaintMyKI5.PaintRequirements.isValidTarget(
self.character, self.vehicle, textureData.skinIndex, area
) then return end
ISTimedActionQueue.add(ISPathFindAction:pathToVehicleArea(self.character, self.vehicle, area))
ISTimedActionQueue.add(ISPaintMyKI5Vehicle:new(
self.character, self.vehicle, textureData.skinIndex, area
))
self:close()
end
function ISPaintMyKI5UI:close()
ISPaintMyKI5UI.instances[self.playerNum] = nil
self:setVisible(false)
self:removeFromUIManager()
end
function ISPaintMyKI5UI.open(playerNum, vehicle)
local existing = ISPaintMyKI5UI.instances[playerNum]
if existing then existing:close() end
local character = getSpecificPlayer(playerNum)
local window = ISPaintMyKI5UI:new(character, vehicle, playerNum)
window:initialise()
window:addToUIManager()
ISPaintMyKI5UI.instances[playerNum] = window
end
function ISPaintMyKI5UI:new(character, vehicle, playerNum)
local width = math.min(800, getCore():getScreenWidth() - 40)
local height = math.min(600, getCore():getScreenHeight() - 40)
local x = (getCore():getScreenWidth() - width) / 2
local y = (getCore():getScreenHeight() - height) / 2
local window = ISCollapsableWindow:new(x, y, width, height)
setmetatable(window, self)
self.__index = self
window.title = getText("IGUI_PaintMyKI5_Title")
window.resizable = false
window.character = character
window.vehicle = vehicle
window.vehicleData = PaintMyKI5.PaintRequirements.getVehicleData(vehicle)
window.playerNum = playerNum
return window
end
@@ -0,0 +1,45 @@
require "Vehicles/ISUI/ISVehicleMenu"
require "PaintMyKI5/PaintRequirements"
require "PaintMyKI5/ISPaintMyKI5UI"
PaintMyKI5 = PaintMyKI5 or {}
PaintMyKI5.PaintVehicleContextMenu = PaintMyKI5.PaintVehicleContextMenu or {}
local PaintVehicleContextMenu = PaintMyKI5.PaintVehicleContextMenu
local function getTargetVehicle(playerObj)
if JoypadState.players[playerObj:getPlayerNum() + 1] then
return ISVehicleMenu.getVehicleToInteractWith(playerObj)
end
return IsoObjectPicker.Instance:PickVehicle(getMouseXScaled(), getMouseYScaled())
end
function PaintVehicleContextMenu.open(playerObj, vehicle)
ISPaintMyKI5UI.open(playerObj:getPlayerNum(), vehicle)
end
function PaintVehicleContextMenu.onFillWorldObjectContextMenu(player, context, worldobjects, test)
if test and ISWorldObjectContextMenu.Test then return true end
local playerObj = getSpecificPlayer(player)
if not playerObj or playerObj:getVehicle() then return false end
local vehicle = getTargetVehicle(playerObj)
local script = vehicle and vehicle:getScript() or nil
local vehicleId = script and script:getFullName() or nil
local vehicles = PaintMyKI5.VehiclePaintData and PaintMyKI5.VehiclePaintData.vehicles
local shortId = vehicleId and string.match(vehicleId, "[^.]+$") or nil
if not shortId or string.match(string.lower(shortId), "^trailer") then return false end
if not vehicles or not vehicles[vehicleId] then return false end
if math.abs(vehicle:getCurrentSpeedKmHour()) > 0.8 then return false end
if test then return ISWorldObjectContextMenu.setTest() end
local option = context:addOption(
getText("ContextMenu_PaintMyKI5"),
playerObj,
PaintVehicleContextMenu.open,
vehicle
)
option.iconTexture = getTexture("media/textures/PaintBrush.png")
return true
end
Events.OnFillWorldObjectContextMenu.Add(PaintVehicleContextMenu.onFillWorldObjectContextMenu)