Skip to content

Commit

Permalink
Add icons to the visualization of agricultural tower
Browse files Browse the repository at this point in the history
Wube should simply allow for customizing the visualization range of each
color separately, but until then, this is a hack that works.

When hovering an agricultural tower, check the 3x3 boxes and give them
an icon based on their color. This is done per player, so each player
gets some local storage to keep their render objects so we can delete
them later.

Since this is done at runtime, these can be runtime settings.

This has limitations though: since the API does not expose a way for
getting the cursor location, there is no way to apply these icons when
an agricultural tower is in the cursor. Similarly, there is no way to do
so when an agricultural tower is in the blueprint that is in the cursor.

Additionally, I made the logic of what "color" to apply the same that
the agricultural tower uses. This means it will show things as "green"
even when the tower is unable to plant there because different types of
soil are mixed (meaning no plant is eligible). Hopefully Wube fixes this
at the same time they fix the API limiations.
  • Loading branch information
Rycieos committed Dec 19, 2024
1 parent be46300 commit 9009011
Show file tree
Hide file tree
Showing 10 changed files with 286 additions and 6 deletions.
8 changes: 8 additions & 0 deletions control.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,11 @@ end

script.on_init(rechart)
script.on_configuration_changed(rechart)

require("scripts.utils")

for mod, mod_stages in pairs(Mods) do
if script.active_mods[mod] and mod_stages.control then
require("data." .. mod .. ".control")
end
end
166 changes: 166 additions & 0 deletions data/space-age/control.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
local math2d = require("__core__.lualib.math2d")

require("scripts.config")
require("scripts.utils")

-- Draw helper for agricultural tower.

-- Hardcoded as the API does not expose what tiles upgrade to what tiles at runtime.
local plant_tiles = {
["dirt-1"] = "green",
["dirt-2"] = "green",
["dirt-3"] = "green",
["dirt-4"] = "green",
["dirt-5"] = "green",
["dirt-6"] = "green",
["dirt-7"] = "green",
["dry-dirt"] = "green",
["grass-1"] = "green",
["grass-2"] = "green",
["grass-3"] = "green",
["grass-4"] = "green",
["red-desert-0"] = "green",
["red-desert-1"] = "green",
["red-desert-2"] = "green",
["red-desert-3"] = "green",

["natural-yumako-soil"] = "green",
["artificial-yumako-soil"] = "green",
["overgrowth-yumako-soil"] = "green",

["natural-jellynut-soil"] = "green",
["artificial-jellynut-soil"] = "green",
["overgrowth-jellynut-soil"] = "green",

["lowland-brown-blubber"] = "yellow",
["lowland-olive-blubber"] = "yellow",
["lowland-olive-blubber-2"] = "yellow",
["lowland-olive-blubber-3"] = "yellow",
["lowland-pale-green"] = "yellow",
["wetland-green-slime"] = "yellow",
["wetland-light-green-slime"] = "yellow",
["wetland-yumako"] = "yellow",

["lowland-cream-red"] = "yellow",
["lowland-red-infection"] = "yellow",
["lowland-red-vein"] = "yellow",
["lowland-red-vein-2"] = "yellow",
["lowland-red-vein-3"] = "yellow",
["lowland-red-vein-4"] = "yellow",
["lowland-red-vein-dead"] = "yellow",
["wetland-jellynut"] = "yellow",
["wetland-pink-tentacle"] = "yellow",
["wetland-red-tentacle"] = "yellow",
}

local plant_green_tile_names = {}
local plant_yellow_tile_names = {}
for tile_name, color in pairs(plant_tiles) do
if color == "green" then
table.insert(plant_green_tile_names, tile_name)
else
table.insert(plant_yellow_tile_names, tile_name)
end
end

local function is_player_selecting_agricultural_tower(player)
if player.selected then
if player.selected.name == "agricultural-tower" then
return true
end
if player.selected.type == "entity-ghost" and player.selected.ghost_name == "agricultural-tower" then
return true
end
end
return false
end

script.on_event(defines.events.on_selected_entity_changed, function(event)
if not storage.agri_objects then
storage.agri_objects = {}
end
if storage.agri_objects[event.player_index] then
for _, item in pairs(storage.agri_objects[event.player_index]) do
item.destroy()
end
storage.agri_objects[event.player_index] = nil
end

local player = game.get_player(event.player_index)
if is_player_selecting_agricultural_tower(player) then
local player_config_green = player_config(player, "agricultural-tower-visual-green")
local player_config_red = player_config(player, "agricultural-tower-visual-red")
local player_config_yellow = player_config(player, "agricultural-tower-visual-yellow")
if not player_config_green and not player_config_red and not player_config_yellow then
return
end
local player_config_alt = player_config(player, "agricultural-tower-visual-alt")

local sprites = {}
local position = player.selected.position
-- 3 sized squares and 3 radius is set in the prototype, but is unreadable at runtime.
for x = -9, 9, 3 do
for y = -9, 9, 3 do
-- Skip the 3x3 grid the tower is on.
if x == 0 and y == 0 then
goto continue
end

local grid_position = math2d.position.add(position, { x, y })
local bounding_box = math2d.bounding_box.create_from_centre(grid_position, 2)
local green_grid_count = player.selected.surface.count_tiles_filtered({
area = bounding_box,
name = plant_green_tile_names,
})
if green_grid_count == 9 then
if player_config_green then
table.insert(
sprites,
rendering.draw_sprite({
sprite = ModPath .. "green-check",
surface = player.selected.surface,
target = grid_position,
only_in_alt_mode = player_config_alt,
})
)
end
goto continue
end

local yellow_grid_count = player.selected.surface.count_tiles_filtered({
area = bounding_box,
name = plant_yellow_tile_names,
})
if green_grid_count + yellow_grid_count == 9 then
if player_config_yellow then
table.insert(
sprites,
rendering.draw_sprite({
sprite = ModPath .. "warning",
surface = player.selected.surface,
target = grid_position,
only_in_alt_mode = player_config_alt,
})
)
end
else
if player_config_red then
table.insert(
sprites,
rendering.draw_sprite({
sprite = ModPath .. "no-entry",
surface = player.selected.surface,
target = grid_position,
only_in_alt_mode = player_config_alt,
})
)
end
end

::continue::
end
end

storage.agri_objects[event.player_index] = sprites
end
end)
29 changes: 29 additions & 0 deletions data/space-age/data.lua
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,32 @@ if color and not color_equals(color, SpaceAgeDefaultColors["yumako-fruit"]) then
end
end
end

-- Draw helper for agricultural tower.
-- As it is a runtime setting per user, we need to load it always.
data:extend({
{
type = "sprite",
name = ModPath .. "green-check",
filename = ModPath .. "/graphics/icons/mip/green-check.png",
size = 32,
scale = 0.5,
mipmap_count = 2,
},
{
type = "sprite",
name = ModPath .. "warning",
filename = ModPath .. "/graphics/icons/mip/warning.png",
size = 32,
scale = 0.5,
mipmap_count = 2,
},
{
type = "sprite",
name = ModPath .. "no-entry",
filename = ModPath .. "/graphics/icons/mip/no-entry.png",
size = 32,
scale = 0.5,
mipmap_count = 2,
},
})
68 changes: 68 additions & 0 deletions data/space-age/settings.lua
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,71 @@ add_color_setting("yumako-fruit", "plant", SpaceAgeDefaultColors["yumako-fruit"]
"",
{ "entity-name.yumako-tree" },
})

data:extend({
{
name = config_name("agricultural-tower-visual-green"),
type = "bool-setting",
setting_type = "runtime-per-user",
default_value = false,
order = order_prefix .. "b[agricultural]b",
localised_name = {
"",
{ "entity-name.agricultural-tower" },
" ",
{ "color.green" },
" ",
{ "gui-interface-settings.visualization" },
},
localised_description = { "colorblind_ultimate-description.agricultural-tower-visual" },
},
{
name = config_name("agricultural-tower-visual-red"),
type = "bool-setting",
setting_type = "runtime-per-user",
default_value = false,
order = order_prefix .. "b[agricultural]b",
localised_name = {
"",
{ "entity-name.agricultural-tower" },
" ",
{ "color.red" },
" ",
{ "gui-interface-settings.visualization" },
},
localised_description = { "colorblind_ultimate-description.agricultural-tower-visual" },
},
{
name = config_name("agricultural-tower-visual-yellow"),
type = "bool-setting",
setting_type = "runtime-per-user",
default_value = false,
order = order_prefix .. "b[agricultural]b",
localised_name = {
"",
{ "entity-name.agricultural-tower" },
" ",
{ "color.yellow" },
" ",
{ "gui-interface-settings.visualization" },
},
localised_description = { "colorblind_ultimate-description.agricultural-tower-visual" },
},
{
name = config_name("agricultural-tower-visual-alt"),
type = "bool-setting",
setting_type = "runtime-per-user",
default_value = false,
order = order_prefix .. "b[agricultural]c",
localised_name = {
"",
{ "entity-name.agricultural-tower" },
" ",
{ "gui-interface-settings.visualization" },
" ",
{ "gui-interface-settings.alt-mode" },
" ",
{ "deconstruction-tile-mode.only" },
},
},
})
Binary file added graphics/icons/mip/green-check.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added graphics/icons/mip/warning.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions locale/en/locale.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,4 @@ icon-overlay=icon overlay
icon-replacement=icon replacement
sprite-overlay=sprite overlay
sprite-replacement=sprite replacement
agricultural-tower-visual=Icon in the square grid when hovering a [entity=agricultural-tower] to help distinguish color.
Binary file modified scenarios/Test palette/blueprint.zip
Binary file not shown.
5 changes: 5 additions & 0 deletions scripts/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,9 @@ function config(name)
return setting and setting.value
end

function player_config(player, name)
local setting = player.mod_settings[config_name(name)]
return setting and setting.value
end

IconScale = config("scale")
15 changes: 9 additions & 6 deletions scripts/utils.lua
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ Mods = {
["space-age"] = {
data = true,
settings = true,
control = true,
order = "bc",
},
["Ultracube"] = {
Expand Down Expand Up @@ -79,13 +80,15 @@ function keys(table)
return keys
end

function data:get(_type, name)
local types = self.raw[_type]
if not types or not types[name] then
log("Warning: prototype [" .. _type .. "][" .. name .. "] not found")
return false
if data then
function data:get(_type, name)
local types = self.raw[_type]
if not types or not types[name] then
log("Warning: prototype [" .. _type .. "][" .. name .. "] not found")
return false
end
return types[name]
end
return types[name]
end

-- Get the item object that corresponds to the entity object.
Expand Down

0 comments on commit 9009011

Please sign in to comment.