Add technology utilities, button styles, and builder function

This commit is contained in:
Caleb Heuer
2023-11-09 00:09:43 -07:00
parent 642270e584
commit 92a3d410c8
8 changed files with 282 additions and 3 deletions

View File

@@ -1,7 +1,10 @@
---------------------------------------------------------------------------------------------------
Version: 0.13.1
Date: ????
Changes:
Features:
- Added `gui-templates` module for building various common and/or annoying GUI components, including technology slots.
- Added `technology` module with various runtime technology-related utilities.
- Added technology slot styles.
---------------------------------------------------------------------------------------------------
Version: 0.13.0
Date: 2023-10-14

View File

@@ -1,2 +1,3 @@
require("prototypes/sprite")
require("prototypes/style")
require("prototypes/technology-slot-style")

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

85
gui-templates.lua Normal file
View File

@@ -0,0 +1,85 @@
local flib_math = require("__flib__/math")
local flib_gui = require("__flib__/gui-lite")
local flib_table = require("__flib__/table")
local flib_technology = require("__flib__/technology")
local flib_gui_templates = {}
--- @param parent LuaGuiElement
--- @param technology LuaTechnology
--- @param level uint
--- @param research_state TechnologyResearchState
--- @param on_click function
--- @return LuaGuiElement
function flib_gui_templates.technology_slot(parent, technology, level, research_state, on_click)
local progress = flib_technology.get_research_progress(technology, level)
local research_state_str = flib_table.find(flib_technology.research_state, research_state)
local style = "flib_technology_slot_" .. research_state_str
if technology.upgrade or flib_technology.is_multilevel(technology) or technology.prototype.level > 1 then
style = style .. "_multilevel"
end
local base = parent.add({
type = "sprite-button",
name = technology.name,
style = style,
elem_tooltip = { type = "technology", name = technology.name },
tags = flib_gui.format_handlers({ [defines.events.on_gui_click] = on_click }),
})
base
.add({ type = "flow", style = "flib_technology_slot_sprite_flow", ignored_by_interaction = true })
.add({ type = "sprite", style = "flib_technology_slot_sprite", sprite = "technology/" .. technology.name })
if technology.upgrade or flib_technology.is_multilevel(technology) or technology.prototype.level > 1 then
base.add({
type = "label",
name = "level_label",
style = "flib_technology_slot_level_label_" .. research_state_str,
caption = level,
ignored_by_interaction = true,
})
end
if flib_technology.is_multilevel(technology) then
local max_level_str = technology.prototype.max_level == flib_math.max_uint and "[img=infinity]"
or tostring(technology.prototype.max_level)
base.add({
type = "label",
name = "level_range_label",
style = "flib_technology_slot_level_range_label_" .. research_state_str,
caption = technology.prototype.level .. " - " .. max_level_str,
ignored_by_interaction = true,
})
end
local ingredients_flow = base.add({
type = "flow",
style = "flib_technology_slot_ingredients_flow",
ignored_by_interaction = true,
})
local ingredients_len = 0
for i, ingredient in pairs(technology.research_unit_ingredients) do
ingredients_len = i
ingredients_flow.add({
type = "sprite",
style = "flib_technology_slot_ingredient",
sprite = ingredient.type .. "/" .. ingredient.name,
ignored_by_interaction = true,
})
end
ingredients_flow.style.horizontal_spacing = flib_math.clamp((68 - 16) / (ingredients_len - 1) - 16, -15, -5)
base.add({
type = "progressbar",
name = "progressbar",
style = "flib_technology_slot_progressbar",
value = progress,
visible = progress > 0,
ignored_by_interaction = true,
})
return base
end
return flib_gui_templates

View File

@@ -1,13 +1,13 @@
{
"name": "flib",
"version": "0.13.1",
"version": "0.14.0",
"title": "Factorio Library",
"author": "raiguard, Optera, justarandomgeek, Nexela",
"contact": "https://github.com/factoriolib/flib",
"homepage": "https://github.com/factoriolib/flib",
"description": "A set of high-quality, commonly-used utilities for creating Factorio mods.",
"factorio_version": "1.1",
"dependencies": [ "base >= 1.1.80" ],
"dependencies": [ "base >= 1.1.96" ],
"package": {
"git_publish_branch": "master",
"ignore": [ "crowdin.yml", "imgui.ini", "stylua.toml", "tests" ],

View File

@@ -0,0 +1,136 @@
local styles = data.raw["gui-style"]["default"]
--- @param name string
--- @param y number
--- @param level_color Color
--- @param level_range_color Color
local function build_technology_slot(name, y, level_color, level_range_color)
styles["flib_technology_slot_" .. name] = {
type = "button_style",
default_graphical_set = {
base = {
filename = "__flib__/graphics/technology-slots.png",
position = { 0, y },
size = { 144, 200 },
},
shadow = default_shadow,
},
hovered_graphical_set = {
base = {
filename = "__flib__/graphics/technology-slots.png",
position = { 144, y },
size = { 144, 200 },
},
shadow = default_shadow,
},
clicked_graphical_set = {
base = {
filename = "__flib__/graphics/technology-slots.png",
position = { 144, y },
size = { 144, 200 },
},
shadow = default_shadow,
},
padding = 0,
size = { 72, 100 },
left_click_sound = { filename = "__core__/sound/gui-square-button-large.ogg", volume = 1 },
}
styles["flib_technology_slot_" .. name .. "_multilevel"] = {
type = "button_style",
default_graphical_set = {
base = {
filename = "__flib__/graphics/technology-slots.png",
position = { 576, y },
size = { 144, 200 },
},
shadow = default_shadow,
},
hovered_graphical_set = {
base = {
filename = "__flib__/graphics/technology-slots.png",
position = { 720, y },
size = { 144, 200 },
},
shadow = default_shadow,
},
clicked_graphical_set = {
base = {
filename = "__flib__/graphics/technology-slots.png",
position = { 720, y },
size = { 144, 200 },
},
shadow = default_shadow,
},
padding = 0,
size = { 72, 100 },
left_click_sound = { filename = "__core__/sound/gui-square-button-large.ogg", volume = 1 },
}
styles["flib_technology_slot_level_label_" .. name] = {
type = "label_style",
font = "technology-slot-level-font",
font_color = level_color,
top_padding = 66,
width = 26,
horizontal_align = "center",
}
styles["flib_technology_slot_level_range_label_" .. name] = {
type = "label_style",
font = "technology-slot-level-font",
font_color = level_range_color,
top_padding = 66,
right_padding = 4,
width = 72,
horizontal_align = "right",
}
end
build_technology_slot("available", 0, { 77, 71, 48 }, { 255, 241, 183 })
build_technology_slot("conditionally_available", 200, { 95, 68, 32 }, { 255, 234, 206 })
build_technology_slot("not_available", 400, { 116, 34, 32 }, { 255, 214, 213 })
build_technology_slot("researched", 600, { 0, 84, 5 }, { 165, 255, 171 })
build_technology_slot("disabled", 800, { 132, 132, 132 }, { 132, 132, 132 })
styles.flib_technology_slot_sprite_flow = {
type = "horizontal_flow_style",
width = 72,
height = 68,
vertical_align = "center",
horizontal_align = "center",
}
styles.flib_technology_slot_sprite = {
type = "image_style",
size = 64,
stretch_image_to_widget_size = true,
}
styles.flib_technology_slot_ingredients_flow = {
type = "horizontal_flow_style",
top_padding = 82,
left_padding = 2,
}
styles.flib_technology_slot_ingredient = {
type = "image_style",
size = 16,
stretch_image_to_widget_size = true,
}
styles.flib_technology_slot_progressbar = {
type = "progressbar_style",
bar = { position = { 305, 39 }, corner_size = 4 },
bar_shadow = {
base = { position = { 296, 39 }, corner_size = 4 },
shadow = {
left = { position = { 456, 152 }, size = { 16, 1 } },
center = { position = { 472, 152 }, size = { 1, 1 } },
right = { position = { 473, 152 }, size = { 16, 1 } },
},
},
bar_width = 4,
color = { g = 1 },
width = 72,
}

54
technology.lua Normal file
View File

@@ -0,0 +1,54 @@
--- @class flib_technology
local flib_technology = {}
--- Gets the active or saved research progress for the given technology.
--- @param technology LuaTechnology
--- @param level uint
--- @return double
function flib_technology.get_research_progress(technology, level)
local force = technology.force
local current_research = force.current_research
if current_research and current_research.name == technology.name then
if technology.level == level or not flib_technology.is_multilevel(technology) then
return force.research_progress
else
return 0
end
else
return force.get_saved_technology_progress(technology) or 0
end
end
--- Gets the research unit count for the given technology.
--- @param technology LuaTechnology
--- @param level uint?
--- @return uint
function flib_technology.get_research_unit_count(technology, level)
local formula = technology.research_unit_count_formula
if formula then
local level = level or technology.level
return math.floor(game.evaluate_expression(formula, { l = level, L = level }))
end
return math.floor(technology.research_unit_count)
end
--- Returns whether the technology has multiple levels.
--- @param technology LuaTechnology|LuaTechnologyPrototype
--- @return boolean
function flib_technology.is_multilevel(technology)
if technology.object_name == "LuaTechnology" then
technology = technology.prototype
end
return technology.level ~= technology.max_level
end
--- @enum TechnologyResearchState
flib_technology.research_state = {
available = 1,
conditionally_available = 2,
not_available = 3,
researched = 4,
disabled = 5,
}
return flib_technology