mirror of
https://github.com/PHIDIAS0303/ExpCluster.git
synced 2026-11-12 23:54:53 +09:00
Review points from Cooldude: - Feature.register(name[, config]) is required again and returns a feature object. Each feature has its config, its fields, and its overrides, so one registry holds all the data. Only the overrides are stored. On load each feature points at its own stored table again. - The methods are feature:guard(lib), feature:update_config(enabled, values), and feature:is_enabled(). Feature.get(name) looks up a feature, and commands flag the feature object. - update_config raises on_config_updated once per changed value, with the feature name, path, old value, and new value. The gui refresh only reacts to the "enabled" path. - apply only sets values. on_apply is gone. Lookup sets built from lists use Feature.to_set, which is cached by the list itself. A replaced list gets a new set, so the sets are also correct after a load. Protection exposes getters for its protected names and types. Web: settings use small inputs, the same size as the config pages. Fields are shaped like clusterio config field definitions. A field with an inputComponent renders the component registered with the web interface, so the role setting now uses core's role input, and other plugin inputs can be used later. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
114 lines
4.0 KiB
Lua
114 lines
4.0 KiB
Lua
--[[-- Control - Station Auto Name
|
|
Automatically name stations when they are placed based on closest resource and direction from spawn
|
|
]]
|
|
|
|
local Feature = require("modules/exp_scenario/features")
|
|
|
|
local feature = Feature.register("station_auto_name", {
|
|
--- @setting station_name the name given to new stations, placeholders:
|
|
-- __icon__ __item_name__ __backer_name__ __direction__ __x__ __y__
|
|
station_name = "[L] __icon__",
|
|
})
|
|
local config = feature.config
|
|
|
|
local get_direction do
|
|
local directions = {
|
|
["W"] = -0.875,
|
|
["NW"] = -0.625,
|
|
["N"] = -0.375,
|
|
["NE"] = -0.125,
|
|
["E"] = 0.125,
|
|
["SE"] = 0.375,
|
|
["S"] = 0.625,
|
|
["SW"] = 0.875,
|
|
}
|
|
|
|
--- Get the direction of a position from the centre of the surface
|
|
--- @param position MapPosition
|
|
--- @return string
|
|
function get_direction(position)
|
|
local angle = math.atan2(position.y, position.x) / math.pi
|
|
for direction, required_angle in pairs(directions) do
|
|
if angle < required_angle then
|
|
return direction
|
|
end
|
|
end
|
|
|
|
return "W"
|
|
end
|
|
end
|
|
|
|
-- Custom strings are used to detect backer names from ghosts
|
|
local custom_string = " *"
|
|
local custom_string_len = #custom_string
|
|
|
|
--- Change the name of a station when it is placed
|
|
--- @param event EventData.on_built_entity | EventData.on_robot_built_entity
|
|
local function rename_station(event)
|
|
local entity = event.entity
|
|
local name = entity.name
|
|
if name == "entity-ghost" and entity.ghost_name == "train-stop" then
|
|
local backer_name = entity.backer_name
|
|
if backer_name ~= "" then
|
|
entity.backer_name = backer_name .. custom_string
|
|
end
|
|
|
|
elseif name == "train-stop" then
|
|
-- Restore the backer name
|
|
local backer_name = entity.backer_name or ""
|
|
if backer_name:sub(-custom_string_len) == custom_string then
|
|
entity.backer_name = backer_name:sub(1, -custom_string_len - 1)
|
|
return
|
|
end
|
|
|
|
-- Find the closest resource
|
|
local icon = ""
|
|
local item_name = ""
|
|
local bounding_box = entity.bounding_box
|
|
local resources = entity.surface.find_entities_filtered{ position = entity.position, radius = 250, type = "resource" }
|
|
if #resources > 0 then
|
|
local closest_recourse --- @type LuaEntity?
|
|
local closest_distance = 250 * 250 -- search radius + 1
|
|
local px, py = bounding_box.left_top.x, bounding_box.left_top.y
|
|
|
|
-- Check which recourse is closest
|
|
for _, resource in ipairs(resources) do
|
|
local resource_box = resource.bounding_box
|
|
local dx = px - resource_box.left_top.x
|
|
local dy = py - resource_box.left_top.y
|
|
local distance = (dx * dx) + (dy * dy)
|
|
if distance < closest_distance then
|
|
closest_distance = distance
|
|
closest_recourse = resource
|
|
end
|
|
end
|
|
|
|
-- Set the item name and icon
|
|
if closest_recourse then
|
|
item_name = closest_recourse.name:gsub("^%l", string.upper):gsub("-", " ") -- remove dashes and making first letter capital
|
|
local products = assert(closest_recourse.prototype.mineable_properties.products)
|
|
local product = assert(products[1])
|
|
icon = string.format("[img=%s.%s]", product.type, product.name)
|
|
end
|
|
end
|
|
|
|
-- Rename the station
|
|
entity.backer_name = config.station_name
|
|
:gsub("__icon__", icon)
|
|
:gsub("__item_name__", item_name)
|
|
:gsub("__backer_name__", entity.backer_name)
|
|
:gsub("__direction__", get_direction(entity.position))
|
|
:gsub("__x__", math.floor(entity.position.x))
|
|
:gsub("__y__", math.floor(entity.position.y))
|
|
end
|
|
end
|
|
|
|
local e = defines.events
|
|
|
|
return feature:guard{
|
|
events = {
|
|
[e.on_built_entity] = rename_station,
|
|
[e.on_robot_built_entity] = rename_station,
|
|
},
|
|
}
|