diff --git a/LICENSE b/LICENSE index aeb0e16..0c08310 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2022 Monica Moniot +Copyright (c) 2022 Mami Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/cybersyn/control.lua b/cybersyn/control.lua index 9ef9749..ed1cfee 100644 --- a/cybersyn/control.lua +++ b/cybersyn/control.lua @@ -1,7 +1,8 @@ - +--By Mami require("scripts.constants") require("scripts.global") require("scripts.controller") require("scripts.layout") +require("scripts.gui") require("scripts.main") diff --git a/cybersyn/data.lua b/cybersyn/data.lua index 78fc92c..7b95676 100644 --- a/cybersyn/data.lua +++ b/cybersyn/data.lua @@ -6,20 +6,20 @@ require('prototypes.item') require('prototypes.tech') require('prototypes.entity') require('prototypes.signal') +require('prototypes.misc') data:extend({ - cybersyn_depot_item, - cybersyn_station_item, - cybersyn_depot_recipe, - cybersyn_station_recipe, + combinator_entity, + combinator_out_entity, + combinator_item, + combinator_recipe, cybersyn_tech, - cybersyn_depot_entity, - cybersyn_station_entity, - cybersyn_station_in, - cybersyn_station_out, - cybersyn_subgroup, - cybersyn_priority, - cybersyn_p_threshold, - cybersyn_r_threshold, - cybersyn_locked_slots, + subgroup_signal, + priority_signal, + p_threshold_signal, + r_threshold_signal, + locked_slots_signal, + missing_train_icon, + lost_train_icon, + nonempty_train_icon, }) diff --git a/cybersyn/graphics/icons/depot.png b/cybersyn/graphics/icons/combinator.png similarity index 100% rename from cybersyn/graphics/icons/depot.png rename to cybersyn/graphics/icons/combinator.png diff --git a/cybersyn/graphics/icons/locked_slots.png b/cybersyn/graphics/icons/locked-slots.png similarity index 100% rename from cybersyn/graphics/icons/locked_slots.png rename to cybersyn/graphics/icons/locked-slots.png diff --git a/cybersyn/graphics/icons/p_threshold.png b/cybersyn/graphics/icons/lost-train.png similarity index 100% rename from cybersyn/graphics/icons/p_threshold.png rename to cybersyn/graphics/icons/lost-train.png diff --git a/cybersyn/graphics/icons/r_threshold.png b/cybersyn/graphics/icons/missing-train.png similarity index 100% rename from cybersyn/graphics/icons/r_threshold.png rename to cybersyn/graphics/icons/missing-train.png diff --git a/cybersyn/graphics/icons/station.png b/cybersyn/graphics/icons/nonempty-train.png similarity index 100% rename from cybersyn/graphics/icons/station.png rename to cybersyn/graphics/icons/nonempty-train.png diff --git a/cybersyn/graphics/icons/provide-threshold.png b/cybersyn/graphics/icons/provide-threshold.png new file mode 100644 index 0000000..3f42332 Binary files /dev/null and b/cybersyn/graphics/icons/provide-threshold.png differ diff --git a/cybersyn/graphics/icons/request-threshold.png b/cybersyn/graphics/icons/request-threshold.png new file mode 100644 index 0000000..3f42332 Binary files /dev/null and b/cybersyn/graphics/icons/request-threshold.png differ diff --git a/cybersyn/graphics/invisible.png b/cybersyn/graphics/invisible.png new file mode 100644 index 0000000..b04843b Binary files /dev/null and b/cybersyn/graphics/invisible.png differ diff --git a/cybersyn/locale/en/base.cfg b/cybersyn/locale/en/base.cfg index 9c42495..e432a4d 100644 --- a/cybersyn/locale/en/base.cfg +++ b/cybersyn/locale/en/base.cfg @@ -1,32 +1,26 @@ [mod-setting-name] cybersyn-ticks-per-second=Dispatcher ticks per second -cybersyn-requester-threshold=Default requester threshold -cybersyn-provider-threshold=Default provider threshold +cybersyn-request-threshold=Default requester threshold +cybersyn-provide-threshold=Default provider threshold [mod-setting-description] cybersyn-ticks-per-second=How many times per second to check all stations for possible deliveries. This value will be rounded up to a divisor of 60. -cybersyn-requester-threshold=When a requester threshold signal is not recieved by a station it will default to this value. -cybersyn-provider-threshold=When a provider threshold signal is not recieved by a station it will default to this value. +cybersyn-request-threshold=When a requester threshold signal is not recieved by a station it will default to this value. +cybersyn-provide-threshold=When a provider threshold signal is not recieved by a station it will default to this value. [item-name] -cybersyn-depot=Cybersyn depot -cybersyn-station=Cybersyn station +cybersyn-combinator=Cybernetic combinator [item-description] -cybersyn-depot=Cybersyn depot -cybersyn-station=Cybersyn station +cybersyn-combinator=Cybernetic combinator [entity-name] -cybersyn-depot=Cybersyn depot -cybersyn-station=Cybersyn station -cybersyn-station-out=Cybersyn station output -cybersyn-station-in=Cybersyn station input +cybersyn-combinator=Cybernetic combinator +cybersyn-combinator-output=NA [entity-description] -cybersyn-depot=Cybersyn depot -cybersyn-station=Cybersyn station -cybersyn-station-out=Cybersyn station output -cybersyn-station-in=Cybersyn station input +cybersyn-combinator=Cybersyn depot +cybersyn-combinator-output=NA [technology-name] cybersyn-train-network=Cybernetic train network @@ -36,6 +30,19 @@ cybersyn-train-network=Cybernetic train network [virtual-signal-name] cybersyn-priority=Station priority -cybersyn-p_threshold=Provide threshold -cybersyn-r_threshold=Request threshold +cybersyn-provide-threshold=Provide threshold +cybersyn-request-threshold=Request threshold cybersyn-locked-slots=Locked slots per cargo wagon + +[cybersyn-messages] +missing-trains=No trains available to make a delivery from station __2__ to station __1__ +lost-train=A train has become lost +nonempty-train=A train has parked in a depot while still containing items; it cannot be dispatched until it is empty + +[cybersyn-gui] +operation=Choose combinator type +comb1=Primary controller +comb2=Secondary station control +depot=Depot +wagon-manifest=Wagon +combinator-title=Cybernetic combinator diff --git a/cybersyn/prototypes/entity.lua b/cybersyn/prototypes/entity.lua index fc9fb6a..e9d08e4 100644 --- a/cybersyn/prototypes/entity.lua +++ b/cybersyn/prototypes/entity.lua @@ -1,39 +1,47 @@ --By Mami -cybersyn_station_entity = flib.copy_prototype(data.raw["train-stop"]["train-stop"], BUFFER_STATION_NAME) -cybersyn_station_entity.icon = "__cybersyn__/graphics/icons/station.png" -cybersyn_station_entity.icon_size = 64 -cybersyn_station_entity.icon_mipmaps = 4 -cybersyn_station_entity.next_upgrade = nil -cybersyn_station_entity.color = {.5, .1, .9} +combinator_entity = flib.copy_prototype(data.raw["arithmetic-combinator"]["arithmetic-combinator"], COMBINATOR_NAME) +combinator_entity.icon = "__cybersyn__/graphics/icons/combinator.png" +combinator_entity.radius_visualisation_specification = { + sprite = { + filename = "__cybersyn__/graphics/icons/combinator.png", + tint = {r = 1, g = 1, b = .25, a = 1}, + height = 64, + width = 64, + }, + distance = 1, +} -cybersyn_depot_entity = flib.copy_prototype(data.raw["train-stop"]["train-stop"], DEPOT_STATION_NAME) -cybersyn_depot_entity.icon = "__cybersyn__/graphics/icons/depot.png" -cybersyn_depot_entity.icon_size = 64 -cybersyn_depot_entity.icon_mipmaps = 4 -cybersyn_depot_entity.next_upgrade = nil -cybersyn_depot_entity.color = {1, .9, .9} +combinator_out_entity = flib.copy_prototype(data.raw["constant-combinator"]["constant-combinator"], COMBINATOR_OUT_NAME) +combinator_out_entity.icon = nil +combinator_out_entity.icon_size = nil +combinator_out_entity.icon_mipmaps = nil +combinator_out_entity.next_upgrade = nil +combinator_out_entity.minable = nil +combinator_out_entity.selection_box = nil +combinator_out_entity.collision_box = nil +combinator_out_entity.collision_mask = {} +combinator_out_entity.item_slot_count = 500 +combinator_out_entity.circuit_wire_max_distance = 3 +combinator_out_entity.flags = {"not-blueprintable", "not-deconstructable", "placeable-off-grid"} -cybersyn_station_in = flib.copy_prototype(data.raw["lamp"]["small-lamp"], STATION_IN_NAME) -cybersyn_station_in.icon = "__cybersyn__/graphics/icons/station.png" -cybersyn_station_in.icon_size = 64 -cybersyn_station_in.icon_mipmaps = 4 -cybersyn_station_in.next_upgrade = nil -cybersyn_station_in.minable = nil -cybersyn_station_in.selection_box = {{-0.5, -0.5}, {0.5, 0.5}} -cybersyn_station_in.selection_priority = 60 -cybersyn_station_in.collision_box = {{-0.15, -0.15}, {0.15, 0.15}} -cybersyn_station_in.collision_mask = {"rail-layer"} -cybersyn_station_in.energy_usage_per_tick = "10W" -cybersyn_station_in.light = {intensity = 1, size = 6} -cybersyn_station_in.energy_source = {type="void"} - -cybersyn_station_out = flib.copy_prototype(data.raw["constant-combinator"]["constant-combinator"],STATION_OUT_NAME) -cybersyn_station_out.icon = "__cybersyn__/graphics/icons/station.png" -cybersyn_station_out.icon_size = 64 -cybersyn_station_out.icon_mipmaps = 4 -cybersyn_station_out.next_upgrade = nil -cybersyn_station_out.minable = nil -cybersyn_station_out.selection_box = {{-0.5, -0.5}, {0.5, 0.5}} -cybersyn_station_out.selection_priority = 60 -cybersyn_station_out.collision_box = {{-0.15, -0.15}, {0.15, 0.15}} -cybersyn_station_out.collision_mask = {"rail-layer"} +local origin = {0.0, 0.0} +local invisible_sprite = {filename = "__cybersyn__/graphics/invisible.png", width = 1, height = 1} +local wire_con1 = { + red = origin, + green = origin +} +local wire_con0 = {wire = wire_con1, shadow = wire_con1} +combinator_out_entity.sprites = invisible_sprite +combinator_out_entity.activity_led_sprites = invisible_sprite +combinator_out_entity.activity_led_light = { + intensity = 0, + size = 0, +} +combinator_out_entity.activity_led_light_offsets = {origin, origin, origin, origin} +combinator_out_entity.draw_circuit_wires = false +combinator_out_entity.circuit_wire_connection_points = { + wire_con0, + wire_con0, + wire_con0, + wire_con0 +} diff --git a/cybersyn/prototypes/item.lua b/cybersyn/prototypes/item.lua index cbe919e..428db83 100644 --- a/cybersyn/prototypes/item.lua +++ b/cybersyn/prototypes/item.lua @@ -1,12 +1,6 @@ --By Mami -cybersyn_station_item = flib.copy_prototype(data.raw["item"]["train-stop"], BUFFER_STATION_NAME) -cybersyn_station_item.icon = "__cybersyn__/graphics/icons/station.png" -cybersyn_station_item.icon_size = 64 -cybersyn_station_item.icon_mipmaps = 4 -cybersyn_station_item.order = cybersyn_station_item.order.."-c" - -cybersyn_depot_item = flib.copy_prototype(data.raw["item"]["train-stop"], DEPOT_STATION_NAME) -cybersyn_depot_item.icon = "__cybersyn__/graphics/icons/depot.png" -cybersyn_depot_item.icon_size = 64 -cybersyn_depot_item.icon_mipmaps = 4 -cybersyn_depot_item.order = cybersyn_depot_item.order.."-d" +combinator_item = flib.copy_prototype(data.raw["item"]["arithmetic-combinator"], COMBINATOR_NAME) +combinator_item.icon = "__cybersyn__/graphics/icons/combinator.png" +combinator_item.icon_size = 64 +combinator_item.icon_mipmaps = 4 +combinator_item.order = combinator_item.order.."-c" diff --git a/cybersyn/prototypes/misc.lua b/cybersyn/prototypes/misc.lua new file mode 100644 index 0000000..65309b9 --- /dev/null +++ b/cybersyn/prototypes/misc.lua @@ -0,0 +1,24 @@ + +missing_train_icon = flib.copy_prototype(data.raw["fluid"]["water"], MISSING_TRAIN_NAME) +missing_train_icon.icon = "__cybersyn__/graphics/icons/missing-train.png" +missing_train_icon.icon_size = 64 +missing_train_icon.icon_mipmaps = 0 +missing_train_icon.hidden = true +missing_train_icon.auto_barrel = false +missing_train_icon.subgroup = "cybersyn-signal" + +lost_train_icon = flib.copy_prototype(data.raw["fluid"]["water"], LOST_TRAIN_NAME) +lost_train_icon.icon = "__cybersyn__/graphics/icons/lost-train.png" +lost_train_icon.icon_size = 64 +lost_train_icon.icon_mipmaps = 0 +lost_train_icon.hidden = true +lost_train_icon.auto_barrel = false +lost_train_icon.subgroup = "cybersyn-signal" + +nonempty_train_icon = flib.copy_prototype(data.raw["fluid"]["water"], NONEMPTY_TRAIN_NAME) +nonempty_train_icon.icon = "__cybersyn__/graphics/icons/nonempty-train.png" +nonempty_train_icon.icon_size = 64 +nonempty_train_icon.icon_mipmaps = 0 +nonempty_train_icon.hidden = true +nonempty_train_icon.auto_barrel = false +nonempty_train_icon.subgroup = "cybersyn-signal" diff --git a/cybersyn/prototypes/signal.lua b/cybersyn/prototypes/signal.lua index cc5a5e8..6e80e5b 100644 --- a/cybersyn/prototypes/signal.lua +++ b/cybersyn/prototypes/signal.lua @@ -1,11 +1,11 @@ --By Mami -cybersyn_subgroup = { +subgroup_signal = { type = "item-subgroup", name = "cybersyn-signal", group = "signals", order = "cybersyn0[cybersyn-signal]" } -cybersyn_priority = { +priority_signal = { type = "virtual-signal", name = SIGNAL_PRIORITY, icon = "__cybersyn__/graphics/icons/priority.png", @@ -13,26 +13,26 @@ cybersyn_priority = { subgroup = "cybersyn-signal", order = "a-a" } -cybersyn_p_threshold = { +p_threshold_signal = { type = "virtual-signal", name = PROVIDE_THRESHOLD, - icon = "__cybersyn__/graphics/icons/p_threshold.png", + icon = "__cybersyn__/graphics/icons/provide-threshold.png", icon_size = 64, subgroup = "cybersyn-signal", order = "a-b" } -cybersyn_r_threshold = { +r_threshold_signal = { type = "virtual-signal", name = REQUEST_THRESHOLD, - icon = "__cybersyn__/graphics/icons/r_threshold.png", + icon = "__cybersyn__/graphics/icons/request-threshold.png", icon_size = 64, subgroup = "cybersyn-signal", order = "a-c" } -cybersyn_locked_slots = { +locked_slots_signal = { type = "virtual-signal", name = LOCKED_SLOTS, - icon = "__cybersyn__/graphics/icons/locked_slots.png", + icon = "__cybersyn__/graphics/icons/locked-slots.png", icon_size = 64, subgroup = "cybersyn-signal", order = "a-d" diff --git a/cybersyn/prototypes/tech.lua b/cybersyn/prototypes/tech.lua index fa7c661..e787109 100644 --- a/cybersyn/prototypes/tech.lua +++ b/cybersyn/prototypes/tech.lua @@ -1,17 +1,10 @@ --By Mami -cybersyn_station_recipe = flib.copy_prototype(data.raw["recipe"]["train-stop"], BUFFER_STATION_NAME) -cybersyn_station_recipe.ingredients = { - {"train-stop", 1}, +combinator_recipe = flib.copy_prototype(data.raw["recipe"]["train-stop"], COMBINATOR_NAME) +combinator_recipe.ingredients = { + {"copper-cable", 5}, {"advanced-circuit", 5}, } -cybersyn_station_recipe.enabled = false - -cybersyn_depot_recipe = flib.copy_prototype(data.raw["recipe"]["train-stop"], DEPOT_STATION_NAME) -cybersyn_depot_recipe.ingredients = { - {"train-stop", 1}, - {"electronic-circuit", 5}, -} -cybersyn_depot_recipe.enabled = false +combinator_recipe.enabled = false cybersyn_tech = { type = "technology", @@ -27,11 +20,7 @@ cybersyn_tech = { effects = { { type = "unlock-recipe", - recipe = BUFFER_STATION_NAME - }, - { - type = "unlock-recipe", - recipe = DEPOT_STATION_NAME + recipe = COMBINATOR_NAME }, }, unit = { @@ -39,7 +28,7 @@ cybersyn_tech = { {"automation-science-pack", 1}, {"logistic-science-pack", 1} }, - count = 300, + count = 400, time = 30 }, order = "c-g-c" diff --git a/cybersyn/scripts/alerts.lua b/cybersyn/scripts/alerts.lua new file mode 100644 index 0000000..81cca79 --- /dev/null +++ b/cybersyn/scripts/alerts.lua @@ -0,0 +1,48 @@ +--By Mami + +local send_missing_train_alert_for_stop_icon = {name = MISSING_TRAIN_NAME, type = "fluid"} +---@param r_stop LuaEntity +---@param p_stop LuaEntity +function send_missing_train_alert_for_stops(r_stop, p_stop) + for _, player in pairs(r_stop.force.players) do + player.add_custom_alert( + r_stop, + send_missing_train_alert_for_stop_icon, + {"cybersyn-messages.missing-trains", r_stop.backer_name, p_stop.backer_name}, + true + ) + end +end + +local send_lost_train_alert_icon = {name = LOST_TRAIN_NAME, type = "fluid"} +---@param train LuaTrain +function send_lost_train_alert(train) + local loco = train.front_stock or train.back_stock + if loco then + for _, player in pairs(loco.force.players) do + player.add_custom_alert( + loco, + send_lost_train_alert_icon, + {"cybersyn-messages.lost-train"}, + true + ) + end + end +end + + +local send_nonempty_train_in_depot_alert_icon = {name = NONEMPTY_TRAIN_NAME, type = "fluid"} +---@param train LuaTrain +function send_nonempty_train_in_depot_alert(train) + local loco = train.front_stock or train.back_stock + if loco then + for _, player in pairs(loco.force.players) do + player.add_custom_alert( + loco, + send_nonempty_train_in_depot_alert_icon, + {"cybersyn-messages.nonempty-train"}, + true + ) + end + end +end diff --git a/cybersyn/scripts/constants.lua b/cybersyn/scripts/constants.lua index ca80e9e..6b0e4a9 100644 --- a/cybersyn/scripts/constants.lua +++ b/cybersyn/scripts/constants.lua @@ -1,14 +1,21 @@ --By Mami +MISSING_TRAIN_NAME = "cybersyn-missing-train" +LOST_TRAIN_NAME = "cybersyn-lost-train" +NONEMPTY_TRAIN_NAME = "cybersyn-nonempty-train" + SIGNAL_PRIORITY = "cybersyn-priority" -REQUEST_THRESHOLD = "cybersyn-r_threshold" -PROVIDE_THRESHOLD = "cybersyn-p_threshold" +REQUEST_THRESHOLD = "cybersyn-request-threshold" +PROVIDE_THRESHOLD = "cybersyn-provide-threshold" LOCKED_SLOTS = "cybersyn-locked-slots" -STATION_IN_NAME = "cybersyn-station-in" -STATION_OUT_NAME = "cybersyn-station-out" -BUFFER_STATION_NAME = "cybersyn-station" -DEPOT_STATION_NAME = "cybersyn-depot" +COMBINATOR_NAME = "cybersyn-combinator" +COMBINATOR_OUT_NAME = "cybersyn-combinator-output" + +OPERATION_PRIMARY_IO = "*" +OPERATION_SECONDARY_IO = "/" +OPERATION_DEPOT = "+" +OPERATION_WAGON_MANIFEST = "-" DELTA = 1/2048 @@ -23,13 +30,12 @@ TRAIN_LAYOUT_NA = "N" TRAIN_LAYOUT_CARGO = "C" TRAIN_LAYOUT_FLUID = "F" --TRAIN_LAYOUT_ARTILLERY = "A" - STATION_LAYOUT_NA = "N" -STATION_LAYOUT_CARGO = "C" -STATION_LAYOUT_FLUID = "F" -STATION_LAYOUT_BOTH = "." +STATION_LAYOUT_ALL = "." +STATION_LAYOUT_NOT_FLUID = "[NC]" +STATION_LAYOUT_NOT_CARGO = "[NF]" LONGEST_INSERTER_REACH = 2 -TRAIN_CLASS_ALL = "all" -TRAIN_CLASS_AUTO = "auto" +TRAIN_CLASS_ALL = {name = "all", type = "virtual"} +TRAIN_CLASS_AUTO = {name = "auto", type = "virtual"} diff --git a/cybersyn/scripts/controller.lua b/cybersyn/scripts/controller.lua index 045f40f..592874c 100644 --- a/cybersyn/scripts/controller.lua +++ b/cybersyn/scripts/controller.lua @@ -4,6 +4,8 @@ local math = math local INF = math.huge local create_loading_order_condition = {type = "inactivity", compare_type = "and", ticks = 120} +---@param stop LuaEntity +---@param manifest Manifest function create_loading_order(stop, manifest) local condition = {} for _, item in ipairs(manifest) do @@ -25,24 +27,31 @@ function create_loading_order(stop, manifest) end local create_unloading_order_condition = {{type = "empty", compare_type = "and"}} +---@param stop LuaEntity function create_unloading_order(stop) return {station = stop.backer_name, wait_conditions = create_unloading_order_condition} end local create_inactivity_order_condition = {{type = "inactivity", compare_type = "and", ticks = 120}} +---@param depot_name string function create_inactivity_order(depot_name) return {station = depot_name, wait_conditions = create_inactivity_order_condition} end -local create_direct_to_station_order_condition = {{type = "time", compare_type = "and", ticks = 0}} +---@param stop LuaEntity local function create_direct_to_station_order(stop) return {rail = stop.connected_rail, rail_direction = stop.connected_rail_direction} end +---@param depot_name string function create_depot_schedule(depot_name) return {current = 1, records = {create_inactivity_order(depot_name)}} end +---@param depot_name string +---@param p_stop LuaEntity +---@param r_stop LuaEntity +---@param manifest Manifest function create_manifest_schedule(depot_name, p_stop, r_stop, manifest) return {current = 1, records = { create_inactivity_order(depot_name), @@ -53,27 +62,103 @@ function create_manifest_schedule(depot_name, p_stop, r_stop, manifest) }} end - - +---@param station Station local function get_signals(station) - local signals = station.entity_in.get_merged_signals() - return signals + if station.entity_comb1.valid then + local signals = station.entity_comb1.get_merged_signals(defines.circuit_connector_id.combinator_input) + return signals + else + return nil + end end +---@param map_data MapData +---@param comb LuaEntity +---@param signals ConstantCombinatorParameters[]? +function set_combinator_output(map_data, comb, signals) + if comb.valid then + local out = map_data.to_output[comb.unit_number] + if out.valid then + out.get_or_create_control_behavior().parameters = signals + else + --TODO: error logging? + end + else + --TODO: error logging? + end +end + +---@param map_data MapData +---@param station Station +local function set_comb2(map_data, station) + if station.entity_comb2 then + local deliveries = station.deliveries + local signals = {} + for item_name, count in pairs(deliveries) do + local i = #signals + 1 + local item_type = game.item_prototypes[item_name].type + signals[i] = {index = i, signal = {type = item_type, name = item_name}, count = count} + end + set_combinator_output(map_data, station.entity_comb2, signals) + end +end + +---@param map_data MapData +---@param station Station +---@param manifest Manifest +function remove_manifest(map_data, station, manifest, sign) + local deliveries = station.deliveries + for i, item in ipairs(manifest) do + deliveries[item.name] = deliveries[item.name] + sign*item.count + if deliveries[item.name] == 0 then + deliveries[item.name] = nil + end + end + set_comb2(map_data, station) + station.deliveries_total = station.deliveries_total - 1 +end + +---@param map_data MapData +---@param station Station +---@param signal SignalID +local function get_thresholds(map_data, station, signal) + local comb2 = station.entity_comb2 + if comb2 and comb2.valid then + local count = comb2.get_merged_signal(signal, defines.circuit_connector_id.combinator_input) + if count > 0 then + return station.r_threshold, count + elseif count < 0 then + return -count, station.p_threshold + end + end + return station.r_threshold, station.p_threshold +end + +---@param stop0 LuaEntity +---@param stop1 LuaEntity local function get_stop_dist(stop0, stop1) return get_distance(stop0.position, stop1.position) end + +---@param station Station +---@param layout_id uint local function station_accepts_layout(station, layout_id) return true end + + +---@param map_data MapData +---@param r_station_id uint +---@param p_station_id uint +---@param item_type string local function get_valid_train(map_data, r_station_id, p_station_id, item_type) --NOTE: this code is the critical section for run-time optimization local r_station = map_data.stations[r_station_id] local p_station = map_data.stations[p_station_id] - local p_to_r_dist = get_stop_dist(p_station.entity, r_station.entity) + local p_to_r_dist = get_stop_dist(p_station.entity_stop, r_station.entity_stop) if p_to_r_dist == INF then return nil, INF end @@ -96,7 +181,7 @@ local function get_valid_train(map_data, r_station_id, p_station_id, item_type) valid_train_exists = true --check if exists valid path --check if path is shortest so we prioritize locality - local d_to_p_dist = get_stop_dist(train.entity.station, p_station.entity) + local d_to_p_dist = get_stop_dist(train.entity.station, p_station.entity_stop) local dist = d_to_p_dist if dist < best_dist then @@ -113,6 +198,13 @@ local function get_valid_train(map_data, r_station_id, p_station_id, item_type) end end + +---@param map_data MapData +---@param r_station_id uint +---@param p_station_id uint +---@param train Train +---@param primary_item_name string +---@param economy Economy local function send_train_between(map_data, r_station_id, p_station_id, train, primary_item_name, economy) local r_station = map_data.stations[r_station_id] local p_station = map_data.stations[p_station_id] @@ -128,7 +220,8 @@ local function send_train_between(map_data, r_station_id, p_station_id, train, p local item_type = v.signal.type if item_name and item_type and item_type ~= "virtual" then local effective_item_count = item_count + (r_station.deliveries[item_name] or 0) - if -effective_item_count >= r_station.r_threshold then + local r_threshold, p_threshold = get_thresholds(map_data, r_station, v.signal) + if -effective_item_count >= r_threshold then requests[item_name] = -effective_item_count end end @@ -143,7 +236,8 @@ local function send_train_between(map_data, r_station_id, p_station_id, train, p local item_type = v.signal.type if item_name and item_type and item_type ~= "virtual" then local effective_item_count = item_count + (p_station.deliveries[item_name] or 0) - if effective_item_count >= p_station.p_threshold then + local r_threshold, p_threshold = get_thresholds(map_data, r_station, v.signal) + if effective_item_count >= p_threshold then local r = requests[item_name] if r then local item = {name = item_name, count = math.min(r, effective_item_count), type = item_type} @@ -229,10 +323,12 @@ local function send_train_between(map_data, r_station_id, p_station_id, train, p train.r_station_id = r_station_id train.manifest = manifest - train.entity.schedule = create_manifest_schedule(train.depot_name, p_station.entity, r_station.entity, manifest) + train.entity.schedule = create_manifest_schedule(train.depot_name, p_station.entity_stop, r_station.entity_stop, manifest) + set_comb2(map_data, p_station) + set_comb2(map_data, r_station) end - +---@param map_data MapData function tick(map_data, mod_settings) local total_ticks = map_data.total_ticks local stations = map_data.stations @@ -247,7 +343,7 @@ function tick(map_data, mod_settings) local all_items = economy.all_items for station_id, station in pairs(stations) do - if station.deliveries_total < station.entity.trains_limit then + if station.deliveries_total < station.entity_stop.trains_limit then station.r_threshold = mod_settings.r_threshold station.p_threshold = mod_settings.p_threshold station.priority = 0 @@ -279,30 +375,33 @@ function tick(map_data, mod_settings) local item_name = v.signal.name local item_count = v.count local effective_item_count = item_count + (station.deliveries[item_name] or 0) + local r_threshold, p_threshold = get_thresholds(map_data, station, v.signal) - if -effective_item_count >= station.r_threshold then - if r_stations_all[item_name] == nil then - r_stations_all[item_name] = {} - p_stations_all[item_name] = {} - all_items[#all_items + 1] = item_name - all_items[#all_items + 1] = v.signal.type + if item_name then + if -effective_item_count >= r_threshold then + if r_stations_all[item_name] == nil then + r_stations_all[item_name] = {} + p_stations_all[item_name] = {} + all_items[#all_items + 1] = item_name + all_items[#all_items + 1] = v.signal.type + end + table.insert(r_stations_all[item_name], station_id) + elseif effective_item_count >= p_threshold then + if r_stations_all[item_name] == nil then + r_stations_all[item_name] = {} + p_stations_all[item_name] = {} + all_items[#all_items + 1] = item_name + all_items[#all_items + 1] = v.signal.type + end + table.insert(p_stations_all[item_name], station_id) end - table.insert(r_stations_all[item_name], station_id) - elseif effective_item_count >= station.p_threshold then - if r_stations_all[item_name] == nil then - r_stations_all[item_name] = {} - p_stations_all[item_name] = {} - all_items[#all_items + 1] = item_name - all_items[#all_items + 1] = v.signal.type - end - table.insert(p_stations_all[item_name], station_id) end end end end end - local failed_because_missing_trains_total = 0 + local failed_because_missing_trains = {} --we do not dispatch more than one train per station per tick --psuedo-randomize what item (and what station) to check first so if trains available is low they choose orders psuedo-randomly local start_i = 2*(total_ticks%(#all_items/2)) + 1 @@ -336,13 +435,14 @@ function tick(map_data, mod_settings) highest_prior = prior elseif d < INF then could_have_been_serviced = true + best = j end end end - if best > 0 then + if best_train then send_train_between(map_data, r_station_id, p_stations[best], best_train, item_name, economy) elseif could_have_been_serviced then - failed_because_missing_trains_total = failed_because_missing_trains_total + 1 + send_missing_train_alert_for_stops(stations[r_station_id].entity_stop, p_stations[best].entity_stop) end until #r_stations == 0 else @@ -368,17 +468,17 @@ function tick(map_data, mod_settings) highest_prior = prior elseif d < INF then could_have_been_serviced = true + best = i end end end - if best > 0 then + if best_train then send_train_between(map_data, r_stations[best], p_station_id, best_train, item_name, economy) elseif could_have_been_serviced then - failed_because_missing_trains_total = failed_because_missing_trains_total + 1 + send_missing_train_alert_for_stops(stations[best].entity_stop, p_stations[p_station_id].entity_stop) end until #p_stations == 0 end end end - --TODO: add alert for missing trains end diff --git a/cybersyn/scripts/global.lua b/cybersyn/scripts/global.lua index d5d8dae..449030a 100644 --- a/cybersyn/scripts/global.lua +++ b/cybersyn/scripts/global.lua @@ -1,61 +1,65 @@ --By Mami +---@class MapData +---@field public total_ticks uint +---@field public layout_top_id uint +---@field public to_output {[uint]: LuaEntity} +---@field public to_stop {[uint]: LuaEntity} +---@field public stations {[uint]: Station} +---@field public depots {[uint]: LuaEntity} +---@field public trains {[uint]: Train} +---@field public trains_available {[uint]: boolean} +---@field public layouts {[uint]: string} +---@field public layout_train_count {[uint]: int} +---@field public train_classes {[string]: TrainClass} + +---@class Station +---@field public deliveries_total int +---@field public priority int +---@field public last_delivery_tick int +---@field public r_threshold int >= 0 +---@field public p_threshold int >= 0 +---@field public locked_slots int >= 0 +---@field public entity_stop LuaEntity +---@field public entity_comb1 LuaEntity +---@field public entity_comb2 LuaEntity? +---@field public wagon_combs {[int]: LuaEntity}?--NOTE: allowed to be invalid entities or combinators with the wrong operation, these must be checked and lazy deleted when found +---@field public deliveries {[string]: int} +---@field public train_class SignalID? +---@field public accepted_layouts TrainClass +---@field public layout_pattern string? + +---@class Train +---@field public entity LuaTrain +---@field public layout_id uint +---@field public item_slot_capacity int +---@field public fluid_capacity int +---@field public depot_name string +---@field public status int +---@field public p_station_id uint +---@field public r_station_id uint +---@field public manifest Manifest + +---@alias Manifest {}[] +---@alias TrainClass {[uint]: boolean} +---@alias cybersyn.global MapData + +---@class Economy +---@field public r_stations_all {[string]: uint[]} +---@field public p_stations_all {[string]: uint[]} +---@field public all_items string[] +---@field public total_ticks uint ---[[ -global: { - total_ticks: int - layout_top_id: int - stations: {[stop_id]: Station} - trains: {[train_id]: Train} - trains_available: {[train_id]: bool} - layouts: {[layout_id]: Layout} - layout_train_count: {[layout_id]: int} - train_classes: {[string]: TrainClass} -} -Station: { - deliveries_total: int - priority: int - last_delivery_tick: int - r_threshold: int >= 0 - p_threshold: int >= 0 - locked_slots: int >= 0 - entity: LuaEntity - entity_in: LuaEntity - entity_out: LuaEntity - deliveries: { - [item_name]: int - } - train_class: string - accepted_layouts: TrainClass - layout_pattern: string|nil -} -Train: { - entity: LuaEntity - layout_id: int - item_slot_capacity: int - fluid_capacity: int - depot_name: string - status: int - p_station_id: stop_id - r_station_id: stop_id - manifest: [{ - name: string - type: string - count: int - }] -} -TrainClass: { - [layout_id]: bool -} -Layout: string -]] --TODO: only init once mod_settings = {} mod_settings.tps = settings.global["cybersyn-ticks-per-second"].value -mod_settings.r_threshold = settings.global["cybersyn-requester-threshold"].value -mod_settings.p_threshold = settings.global["cybersyn-provider-threshold"].value +mod_settings.r_threshold = settings.global["cybersyn-request-threshold"].value +mod_settings.p_threshold = settings.global["cybersyn-provide-threshold"].value global.total_ticks = 0 +global.to_output = {} +global.to_stop = {} global.stations = {} +global.depots = {} global.trains = {} global.trains_available = {} global.layouts = {} diff --git a/cybersyn/scripts/gui.lua b/cybersyn/scripts/gui.lua new file mode 100644 index 0000000..9c3c493 --- /dev/null +++ b/cybersyn/scripts/gui.lua @@ -0,0 +1,98 @@ +--By Mami +local gui = require("__flib__.gui") + +local RED = "utility/status_not_working" +local GREEN = "utility/status_working" +local YELLOW = "utility/status_yellow" + +local STATUS_SPRITES = {} +STATUS_SPRITES[defines.entity_status.working] = GREEN +STATUS_SPRITES[defines.entity_status.normal] = GREEN +STATUS_SPRITES[defines.entity_status.no_power] = RED +STATUS_SPRITES[defines.entity_status.low_power] = YELLOW +STATUS_SPRITES[defines.entity_status.disabled_by_control_behavior] = RED +STATUS_SPRITES[defines.entity_status.disabled_by_script] = RED +STATUS_SPRITES[defines.entity_status.marked_for_deconstruction] = RED +local STATUS_SPRITES_DEFAULT = RED + +local STATUS_NAMES = {} +STATUS_NAMES[defines.entity_status.working] = "entity-status.working" +STATUS_NAMES[defines.entity_status.normal] = "entity-status.normal" +STATUS_NAMES[defines.entity_status.no_power] = "entity-status.no-power" +STATUS_NAMES[defines.entity_status.low_power] = "entity-status.low-power" +STATUS_NAMES[defines.entity_status.disabled_by_control_behavior] = "entity-status.disabled" +STATUS_NAMES[defines.entity_status.disabled_by_script] = "entity-status.disabled-by-script" +STATUS_NAMES[defines.entity_status.marked_for_deconstruction] = "entity-status.marked-for-deconstruction" +STATUS_NAMES_DEFAULT = "entity-status.disabled" + +---@param entity LuaEntity +function gui_opened(entity, player) + local rootgui = player.gui.screen + local window = gui.build(rootgui, { + {type="frame", direction="vertical", ref={"main_window"}, name=COMBINATOR_NAME, tags={unit_number=entity.unit_number}, actions={ + on_close = {"test"} + }, children={ + --title bar + {type="flow", ref={"titlebar"}, children={ + {type="label", style="frame_title", caption={"cybersyn-gui.combinator-title"}, elem_mods={ignored_by_interaction=true}}, + {type="empty-widget", style="flib_titlebar_drag_handle", elem_mods={ignored_by_interaction=true}}, + {type="sprite-button", style="frame_action_button", mouse_button_filter={"left"}, sprite="utility/close_white", hovered_sprite="utility/close_black", name=COMBINATOR_NAME, actions={ + on_click = {"test"} + }} + }}, + {type="frame", style="inside_shallow_frame_with_padding", style_mods={padding=8}, children={ + {type="flow", direction="vertical", style_mods={horizontal_align="left"}, children={ + --status + {type="flow", style = "status_flow", direction = "horizontal", style_mods={vertical_align="center", horizontally_stretchable=true}, children={ + {type="sprite", sprite=STATUS_SPRITES[entity.status] or STATUS_SPRITES_DEFAULT, style="status_image", ref={"status_icon"}, style_mods={stretch_image_to_widget_size=true}}, + {type="label", caption={STATUS_NAMES[entity.status] or STATUS_NAMES_DEFAULT}, ref={"status_label"}} + }}, + --preview + {type="frame", style="deep_frame_in_shallow_frame", style_mods={minimal_width=0, horizontally_stretchable=true, padding=0}, children={ + {type="entity-preview", style="wide_entity_button", ref={"preview"}}, + }}, + {type="label", caption={"cybersyn-gui.operation"}, style_mods={top_padding=8}}, + {type="drop-down", ref={"operation"}, actions={ + on_selection_state_changed = {"test"} + }, items={ + {"cybersyn-gui.comb1"}, + {"cybersyn-gui.comb2"}, + {"cybersyn-gui.depot"}, + {"cybersyn-gui.wagon-manifest"}, + }}, + }} + }} + }} + }) + + window.preview.entity = entity + window.titlebar.drag_target = window.main_window + window.main_window.force_auto_center() + + player.opened = window.main_window +end + +local function o(event) + local entity = event.entity + if not entity or not entity.valid then return end + local player = game.get_player(event.player_index) + if not player then return end + local rootgui = player.gui.screen + + if rootgui[COMBINATOR_NAME] then + --rootgui[COMBINATOR_NAME].destroy() + else + gui_opened(entity, player) + end +end + +function register_gui_actions() + gui.hook_events(function(event) + local msg = gui.read_action(event) + if msg then + -- read the action to determine what to do + local hi = 2 + end + end) + script.on_event(defines.events.on_gui_opened, o) +end diff --git a/cybersyn/scripts/layout.lua b/cybersyn/scripts/layout.lua index 30403d7..5dafdfa 100644 --- a/cybersyn/scripts/layout.lua +++ b/cybersyn/scripts/layout.lua @@ -1,6 +1,9 @@ --By Mami local area = require("__flib__.area") +---@param map_data MapData +---@param train Train +---@param train_id uint function remove_train(map_data, train, train_id) map_data.trains[train_id] = nil map_data.trains_available[train_id] = nil @@ -18,6 +21,8 @@ function remove_train(map_data, train, train_id) end end +---@param map_data MapData +---@param train Train function update_train_layout(map_data, train) local carriages = train.entity.carriages local layout = "" @@ -68,54 +73,72 @@ function update_train_layout(map_data, train) train.fluid_capacity = fluid_capacity end -local function reset_station_layout(map_data, station) - --station.entity - local station_rail = station.entity.connected_rail +---@param map_data MapData +---@param station Station +---@param forbidden_entity LuaEntity? +local function reset_station_layout(map_data, station, forbidden_entity) + --NOTE: station must be in auto mode + local station_rail = station.entity_stop.connected_rail + if station_rail == nil then + --cannot accept deliveries + station.layout_pattern = "X" + station.accepted_layouts = {} + return + end local rail_direction_from_station - if station.entity.connected_rail_direction == defines.rail_direction.front then + if station.entity_stop.connected_rail_direction == defines.rail_direction.front then rail_direction_from_station = defines.rail_direction.back else rail_direction_from_station = defines.rail_direction.front end - local station_direction = station.entity.direction - local surface = station.entity.surface + local station_direction = station.entity_stop.direction + local surface = station.entity_stop.surface local middle_x = station_rail.position.x local middle_y = station_rail.position.y - local reach = LONGEST_INSERTER_REACH + 1 - DELTA + local reach = LONGEST_INSERTER_REACH + 1 local search_area local area_delta local direction_filter + local is_ver + --local center_line if station_direction == defines.direction.north then - search_area = {left_top = {x = middle_x - reach, y = middle_y}, right_bottom = {x = middle_x + reach, y = middle_y - 6}} - area_delta = {x = 0, y = -7} - direction_filter = {defines.direction.east, defines.direction.west} - elseif station_direction == defines.direction.east then - search_area = {left_top = {y = middle_y - reach, x = middle_x}, right_bottom = {y = middle_y + reach, x = middle_x - 6}} - area_delta = {y = 0, x = -7} - direction_filter = {defines.direction.north, defines.direction.south} - elseif station_direction == defines.direction.south then - search_area = {left_top = {x = middle_x - reach, y = middle_y + 6}, right_bottom = {x = middle_x + reach, y = middle_y}} + search_area = {left_top = {x = middle_x - reach, y = middle_y}, right_bottom = {x = middle_x + reach, y = middle_y + 6}} area_delta = {x = 0, y = 7} direction_filter = {defines.direction.east, defines.direction.west} + is_ver = true + elseif station_direction == defines.direction.east then + search_area = {left_top = {y = middle_y - reach, x = middle_x}, right_bottom = {y = middle_y + reach, x = middle_x - 6}} + area_delta = {x = -7, y = 0} + direction_filter = {defines.direction.north, defines.direction.south} + is_ver = false + elseif station_direction == defines.direction.south then + search_area = {left_top = {x = middle_x - reach, y = middle_y - 6}, right_bottom = {x = middle_x + reach, y = middle_y}} + area_delta = {x = 0, y = -7} + direction_filter = {defines.direction.east, defines.direction.west} + is_ver = true elseif station_direction == defines.direction.west then search_area = {left_top = {y = middle_y - reach, x = middle_x + 6}, right_bottom = {y = middle_y + reach, x = middle_x}} - area_delta = {y = 0, x = 7} + area_delta = {x = 7, y = 0} direction_filter = {defines.direction.north, defines.direction.south} + is_ver = false else assert(false, "cybersyn: invalid station direction") end local length = 2 local pre_rail = station_rail local layout_pattern = "^" - local layout_min_size = 10000 - local type_filter = {"inserter", "pump"} + local type_filter = {"inserter", "pump", "arithmetic-combinator"} + local wagon_number = 0 + local pattern_length = 1 for i = 1, 100 do local rail, rail_direction, rail_connection_direction = pre_rail.get_connected_rail({rail_direction = rail_direction_from_station, rail_connection_direction = defines.rail_connection_direction.straight}) - if rail_connection_direction ~= defines.rail_connection_direction.straight or not rail.valid then + if not rail or rail_connection_direction ~= defines.rail_connection_direction.straight or not rail.valid then break end + pre_rail = rail length = length + 2 if length%7 <= 1 then + wagon_number = wagon_number + 1 local supports_cargo = false local supports_fluid = false local entities = surface.find_entities_filtered({ @@ -124,38 +147,73 @@ local function reset_station_layout(map_data, station) direction = direction_filter, }) for _, entity in pairs(entities) do - if entity.type == "inserter" then - --local pickup_pos = entity.prototype.inserter_pickup_position + entity.position - --local drop_pos = entity.prototype.inserter_drop_position + entity.position - --TODO: add further checks - supports_cargo = true - elseif entity.type == "pump" then - if entity.pump_rail_target then - supports_fluid = true + if entity.valid and entity ~= forbidden_entity then + if entity.type == "inserter" then + if not supports_cargo then + local pos = entity.pickup_position + local is_there + if is_ver then + is_there = middle_x - 1 <= pos.x and pos.x <= middle_x + 1 + else + is_there = middle_y - 1 <= pos.y and pos.y <= middle_y + 1 + end + if is_there then + supports_cargo = true + else + pos = entity.drop_position + if is_ver then + is_there = middle_x - 1 <= pos.x and pos.x <= middle_x + 1 + else + is_there = middle_y - 1 <= pos.y and pos.y <= middle_y + 1 + end + if is_there then + supports_cargo = true + end + end + end + elseif entity.type == "pump" then + if not supports_fluid and entity.pump_rail_target then + supports_fluid = true + end + elseif entity.name == COMBINATOR_NAME then + local control = entity.get_or_create_control_behavior().parameters + if control.operation == OPERATION_WAGON_MANIFEST then + local pos = entity.position + local is_there + if is_ver then + is_there = middle_x - 2.1 <= pos.x and pos.x <= middle_x + 2.1 + else + is_there = middle_y - 2.1 <= pos.y and pos.y <= middle_y + 2.1 + end + if is_there then + if not station.wagon_combs then + station.wagon_combs = {} + end + station.wagon_combs[wagon_number] = entity + end + end end end end if supports_cargo then if supports_fluid then - layout_pattern = layout_pattern..STATION_LAYOUT_BOTH + layout_pattern = layout_pattern..STATION_LAYOUT_ALL else - layout_pattern = layout_pattern..STATION_LAYOUT_CARGO + --TODO: needs to allow misc wagons as well + layout_pattern = layout_pattern..STATION_LAYOUT_NOT_FLUID end + pattern_length = #layout_pattern elseif supports_fluid then - layout_pattern = layout_pattern..STATION_LAYOUT_FLUID + layout_pattern = layout_pattern..STATION_LAYOUT_NOT_CARGO + pattern_length = #layout_pattern else layout_pattern = layout_pattern..STATION_LAYOUT_NA end - if layout_min_size <= 0 then - layout_pattern = layout_pattern.."?" - else - layout_min_size = layout_min_size - 1 - end search_area = area.move(search_area, area_delta) end end - layout_pattern = layout_pattern..STATION_LAYOUT_NA.."*$" + layout_pattern = string.sub(layout_pattern, 1, pattern_length)..STATION_LAYOUT_NA.."*$" station.layout_pattern = layout_pattern local accepted_layouts = station.accepted_layouts for id, layout in pairs(map_data.layouts) do @@ -167,52 +225,75 @@ local function reset_station_layout(map_data, station) end end -function set_station_train_class(map_data, station, train_class_name) - if train_class_name == TRAIN_CLASS_AUTO then - if station.train_class ~= TRAIN_CLASS_AUTO then +---@param map_data MapData +---@param station Station +---@param train_class SignalID +function set_station_train_class(map_data, station, train_class) + if train_class.name == TRAIN_CLASS_AUTO.name then + if station.train_class.name ~= TRAIN_CLASS_AUTO.name then station.train_class = TRAIN_CLASS_AUTO station.accepted_layouts = {} end - reset_station_layout(map_data, station) + reset_station_layout(map_data, station, nil) else - station.train_class = train_class_name - station.accepted_layouts = map_data.train_classes[train_class_name] + station.train_class = train_class + station.accepted_layouts = map_data.train_classes[train_class.name] assert(station.accepted_layouts ~= nil) station.layout_pattern = nil end end -function update_station_if_auto(map_data, station) - if station.train_class == TRAIN_CLASS_AUTO then - reset_station_layout(map_data, station) +---@param map_data MapData +---@param station Station +---@param forbidden_entity LuaEntity? +function update_station_if_auto(map_data, station, forbidden_entity) + if station.train_class.name == TRAIN_CLASS_AUTO.name then + reset_station_layout(map_data, station, forbidden_entity) end end -function update_station_from_rail(map_data, rail) - --TODO: search further? - local entity = rail.get_rail_segment_entity(nil, false) - if entity.name == BUFFER_STATION_NAME then - update_station_if_auto(map_data, map_data.stations[entity.unit_number]) +---@param map_data MapData +---@param rail LuaEntity +---@param forbidden_entity LuaEntity? +function update_station_from_rail(map_data, rail, forbidden_entity) + --TODO: search further or better? + local entity = rail.get_rail_segment_entity(defines.rail_direction.back, false) + if entity and entity.valid and entity.name == "train-stop" then + local station = map_data.stations[entity.unit_number] + if station then + update_station_if_auto(map_data, station, forbidden_entity) + end + else + entity = rail.get_rail_segment_entity(defines.rail_direction.front, false) + if entity and entity.valid and entity.name == "train-stop" then + local station = map_data.stations[entity.unit_number] + if station then + update_station_if_auto(map_data, station, forbidden_entity) + end + end end end -function update_station_from_pump(map_data, pump) +---@param map_data MapData +---@param pump LuaEntity +---@param forbidden_entity LuaEntity? +function update_station_from_pump(map_data, pump, forbidden_entity) if pump.pump_rail_target then - update_station_from_rail(map_data, pump.pump_rail_target) + update_station_from_rail(map_data, pump.pump_rail_target, forbidden_entity) end end -function update_station_from_inserter(map_data, inserter) +---@param map_data MapData +---@param inserter LuaEntity +---@param forbidden_entity LuaEntity? +function update_station_from_inserter(map_data, inserter, forbidden_entity) --TODO: check if correct local surface = inserter.surface - local pos = inserter.position - local pickup_pos = inserter.prototype.inserter_pickup_position - local drop_pos = inserter.prototype.inserter_drop_position - local rail = surface.find_entity("straight-rail", {pos.x + pickup_pos.x, pos.y + pickup_pos.y}) + local rail = surface.find_entity("straight-rail", inserter.pickup_position) if rail then - update_station_from_rail(map_data, rail) + update_station_from_rail(map_data, rail, forbidden_entity) end - rail = surface.find_entity("straight-rail", {pos.x + drop_pos.x, pos.y + drop_pos.y}) + rail = surface.find_entity("straight-rail", inserter.drop_position) if rail then - update_station_from_rail(map_data, rail) + update_station_from_rail(map_data, rail, forbidden_entity) end end diff --git a/cybersyn/scripts/main.lua b/cybersyn/scripts/main.lua index e428922..2d69b9b 100644 --- a/cybersyn/scripts/main.lua +++ b/cybersyn/scripts/main.lua @@ -1,38 +1,23 @@ --By Mami -local function set_station_output_empty(station) - --change circuit outputs - station.entity_out.get_control_behavior().parameters = nil -end - +---@param map_data MapData +---@param train Train local function on_failed_delivery(map_data, train) --NOTE: must change train status to STATUS_D or remove it from tracked trains after this call local is_p_delivery_made = train.status ~= STATUS_D_TO_P and train.status ~= STATUS_P if not is_p_delivery_made then local station = map_data.stations[train.p_station_id] - for i, item in ipairs(train.manifest) do - station.deliveries[item.name] = station.deliveries[item.name] + item.count - if station.deliveries[item.name] == 0 then - station.deliveries[item.name] = nil - end - end - station.deliveries_total = station.deliveries_total - 1 + remove_manifest(map_data, station, train.manifest, 1) if train.status == STATUS_P then - set_station_output_empty(station) + set_combinator_output(map_data, station.entity_comb1, nil) end end local is_r_delivery_made = train.status == STATUS_R_TO_D if not is_r_delivery_made then local station = map_data.stations[train.r_station_id] - for i, item in ipairs(train.manifest) do - station.deliveries[item.name] = station.deliveries[item.name] - item.count - if station.deliveries[item.name] == 0 then - station.deliveries[item.name] = nil - end - end - station.deliveries_total = station.deliveries_total - 1 + remove_manifest(map_data, station, train.manifest, -1) if train.status == STATUS_R then - set_station_output_empty(station) + set_combinator_output(map_data, station.entity_comb1, nil) end end train.r_station_id = 0 @@ -40,91 +25,16 @@ local function on_failed_delivery(map_data, train) train.manifest = nil end -local function on_station_built(map_data, stop) - local pos_x = stop.position.x - local pos_y = stop.position.y - - local in_pos - local out_pos - local search_area - if stop.direction == 0 then - in_pos = {pos_x, pos_y - 1} - out_pos = {pos_x - 1, pos_y - 1} - search_area = { - {pos_x + DELTA - 1, pos_y + DELTA - 1}, - {pos_x - DELTA + 1, pos_y - DELTA} - } - elseif stop.direction == 2 then - in_pos = {pos_x, pos_y} - out_pos = {pos_x, pos_y - 1} - search_area = { - {pos_x + DELTA, pos_y + DELTA - 1}, - {pos_x - DELTA + 1, pos_y - DELTA + 1} - } - elseif stop.direction == 4 then - in_pos = {pos_x - 1, pos_y} - out_pos = {pos_x, pos_y} - search_area = { - {pos_x + DELTA - 1, pos_y + DELTA}, - {pos_x - DELTA + 1, pos_y - DELTA + 1} - } - elseif stop.direction == 6 then - in_pos = {pos_x - 1, pos_y - 1} - out_pos = {pos_x - 1, pos_y} - search_area = { - {pos_x + DELTA - 1, pos_y + DELTA - 1}, - {pos_x - DELTA, pos_y - DELTA + 1} - } - else - assert(false, "cybersyn: invalid direction of train stop") - end - - local entity_in = nil - local entity_out = nil - local entities = stop.surface.find_entities(search_area) - for _, cur_entity in pairs(entities) do - if cur_entity.valid then - if cur_entity.name == "entity-ghost" then - if cur_entity.ghost_name == STATION_IN_NAME then - _, entity_in = cur_entity.silent_revive() - elseif cur_entity.ghost_name == STATION_OUT_NAME then - _, entity_out = cur_entity.silent_revive() - end - elseif cur_entity.name == STATION_IN_NAME then - entity_in = cur_entity - elseif cur_entity.name == STATION_OUT_NAME then - entity_out = cur_entity - end - end - end - - if entity_in == nil then - entity_in = stop.surface.create_entity({ - name = STATION_IN_NAME, - position = in_pos, - force = stop.force - }) - end - entity_in.operable = false - entity_in.minable = false - entity_in.destructible = false - - if entity_out == nil then - entity_out = stop.surface.create_entity({ - name = STATION_OUT_NAME, - position = out_pos, - direction = stop.direction, - force = stop.force - }) - end - entity_out.operable = false - entity_out.minable = false - entity_out.destructible = false - +---@param map_data MapData +---@param stop LuaEntity +---@param comb1 LuaEntity +---@param comb2 LuaEntity +local function on_station_built(map_data, stop, comb1, comb2) local station = { - entity = stop, - entity_in = entity_in, - entity_out = entity_out, + entity_stop = stop, + entity_comb1 = comb1, + entity_comb2 = comb2, + wagon_combs = nil, deliveries_total = 0, last_delivery_tick = 0, priority = 0, @@ -138,13 +48,14 @@ local function on_station_built(map_data, stop) } map_data.stations[stop.unit_number] = station - update_station_if_auto(map_data, station) + update_station_if_auto(map_data, station, nil) end -local function on_station_broken(map_data, stop) - --search for trains coming to the destroyed station - local station_id = stop.unit_number - local station = map_data.stations[station_id] +---@param map_data MapData +---@param station_id uint +---@param station Station +local function on_station_broken(map_data, station_id, station) if station.deliveries_total > 0 then + --search for trains coming to the destroyed station for train_id, train in pairs(map_data.trains) do local is_r = train.r_station_id == station_id local is_p = train.p_station_id == station_id @@ -156,18 +67,239 @@ local function on_station_broken(map_data, stop) on_failed_delivery(map_data, train) train.entity.schedule = nil remove_train(map_data, train, train_id) - --TODO: mark train as lost in the alerts system + send_lost_train_alert(train.entity) end end end end - - if station.entity_in.valid then station.entity_in.destroy() end - if station.entity_out.valid then station.entity_out.destroy() end - map_data.stations[station_id] = nil end +---@param map_data MapData +---@param stop LuaEntity +---@param comb_operation string +---@param comb_forbidden LuaEntity? +local function search_for_station_combinator(map_data, stop, comb_operation, comb_forbidden) + local pos_x = stop.position.x + local pos_y = stop.position.y + --TODO: fix search area + local search_area = { + {pos_x - 2, pos_y - 2}, + {pos_x + 2, pos_y + 2} + } + local entities = stop.surface.find_entities(search_area) + for _, entity in pairs(entities) do + if + entity.valid and entity.name == COMBINATOR_NAME and + entity ~= comb_forbidden and map_data.to_stop[entity.unit_number] == stop + then + local control = entity.get_or_create_control_behavior().parameters + if control.operation == comb_operation then + return entity + end + end + end +end + +---@param map_data MapData +---@param comb LuaEntity +local function on_combinator_built(map_data, comb) + local pos_x = comb.position.x + local pos_y = comb.position.y + + --TODO: fix search area + local search_area + if comb.direction == defines.direction.north or comb.direction == defines.direction.south then + search_area = { + {pos_x - 1.5, pos_y - 2}, + {pos_x + 1.5, pos_y + 2} + } + else + search_area = { + {pos_x - 2, pos_y - 1.5}, + {pos_x + 2, pos_y + 1.5} + } + end + local stop = nil + local rail = nil + local entities = comb.surface.find_entities(search_area) + for _, cur_entity in pairs(entities) do + if cur_entity.valid then + if cur_entity.name == "train-stop" then + --NOTE: if there are multiple stops we take the later one + stop = cur_entity + elseif cur_entity.name == "straight-rail" then + rail = cur_entity + end + end + end + + local out = comb.surface.create_entity({ + name = COMBINATOR_OUT_NAME, + position = comb.position, + force = comb.force + }) + assert(out, "cybersyn: could not spawn combinator controller") + comb.connect_neighbour({ + target_entity = out, + source_circuit_id = defines.circuit_connector_id.combinator_output, + wire = defines.wire_type.green, + }) + comb.connect_neighbour({ + target_entity = out, + source_circuit_id = defines.circuit_connector_id.combinator_output, + wire = defines.wire_type.red, + }) + + map_data.to_output[comb.unit_number] = out + map_data.to_stop[comb.unit_number] = stop + + local control = comb.get_or_create_control_behavior().parameters + if control.operation == OPERATION_WAGON_MANIFEST then + if rail then + update_station_from_rail(map_data, rail, nil) + end + elseif control.operation == OPERATION_DEPOT then + if stop then + local station = map_data.stations[stop.unit_number] + local depot_comb = map_data.depots[stop.unit_number] + if depot_comb or station then + --NOTE: repeated combinators are ignored + else + map_data.depots[stop.unit_number] = comb + end + end + elseif control.operation == OPERATION_SECONDARY_IO then + if stop then + local station = map_data.stations[stop.unit_number] + if station and not station.entity_comb2 then + station.entity_comb2 = comb + end + end + elseif stop then + control.operation = OPERATION_PRIMARY_IO + local station = map_data.stations[stop.unit_number] + local depot_comb = map_data.depots[stop.unit_number] + if station then + --NOTE: repeated combinators are ignored + else + if depot_comb then + --NOTE: this will disrupt deliveries in progress that where dispatched from this station in a minor way + map_data.depots[stop.unit_number] = nil + end + --no station or depot + --add station + + local comb2 = search_for_station_combinator(map_data, stop, OPERATION_SECONDARY_IO, comb) + + on_station_built(map_data, stop, comb, comb2) + end + end +end +---@param map_data MapData +---@param comb LuaEntity +local function on_combinator_broken(map_data, comb) + --NOTE: we do not check for wagon manifest combinators and update their stations, it is assumed they will be lazy deleted later + local out = map_data.to_output[comb.unit_number] + local stop = map_data.to_stop[comb.unit_number] + + if stop and stop.valid then + local station = map_data.stations[stop.unit_number] + if station then + if station.entity_comb1 == comb then + local comb1 = search_for_station_combinator(map_data, stop, OPERATION_PRIMARY_IO, comb) + if comb1 then + station.entity_comb1 = comb1 + else + on_station_broken(map_data, stop.unit_number, station) + map_data.depots[stop.unit_number] = search_for_station_combinator(map_data, stop, OPERATION_DEPOT, nil) + end + elseif station.entity_comb2 == comb then + station.entity_comb2 = search_for_station_combinator(map_data, stop, OPERATION_SECONDARY_IO, comb) + end + else + local depot_comb = map_data.depots[stop.unit_number] + if depot_comb == comb then + --NOTE: this will disrupt deliveries in progress that where dispatched from this station in a minor way + map_data.depots[stop.unit_number] = search_for_station_combinator(map_data, stop, OPERATION_DEPOT, comb) + end + end + end + + if out and out.valid then + out.destroy() + end + map_data.to_output[comb.unit_number] = nil + map_data.to_stop[comb.unit_number] = nil +end +---@param map_data MapData +---@param comb LuaEntity +local function on_combinator_updated(map_data, comb) + --NOTE: this is the lazy way to implement updates and puts strong restrictions on data validity on on_combinator_broken + on_combinator_broken(map_data, comb) + on_combinator_built(map_data, comb) +end + +---@param map_data MapData +---@param stop LuaEntity +local function on_stop_built(map_data, stop) + local pos_x = stop.position.x + local pos_y = stop.position.y + + --TODO: fix search area + local search_area = { + {pos_x - 2, pos_y - 2}, + {pos_x + 2, pos_y + 2} + } + local comb2 = nil + local comb1 = nil + local depot_comb = nil + local entities = stop.surface.find_entities(search_area) + for _, entity in pairs(entities) do + if entity.valid and entity.name == COMBINATOR_NAME and map_data.to_stop[entity.unit_number] == nil then + map_data.to_stop[entity.unit_number] = stop + local control = entity.get_or_create_control_behavior().parameters + if control.operation == OPERATION_PRIMARY_IO then + comb1 = entity + elseif control.operation == OPERATION_SECONDARY_IO then + comb2 = entity + elseif control.operation == OPERATION_DEPOT then + depot_comb = entity + end + end + end + if comb1 then + on_station_built(map_data, stop, comb1, comb2) + elseif depot_comb then + map_data.depots[stop.unit_number] = depot_comb + end +end +---@param map_data MapData +---@param stop LuaEntity +local function on_stop_broken(map_data, stop) + local pos_x = stop.position.x + local pos_y = stop.position.y + + --TODO: fix search area + local search_area = { + {pos_x - 2, pos_y - 2}, + {pos_x + 2, pos_y + 2} + } + local entities = stop.surface.find_entities(search_area) + for _, entity in pairs(entities) do + if map_data.to_stop[entity.unit_number] == stop then + map_data.to_stop[entity.unit_number] = nil + end + end + + local station = map_data.stations[stop.unit_number] + if station then + on_station_broken(map_data, stop.unit_number, station) + end + map_data.depots[stop.unit_number] = nil +end +---@param map_data MapData +---@param stop LuaEntity local function on_station_rename(map_data, stop) --search for trains coming to the renamed station local station_id = stop.unit_number @@ -183,7 +315,7 @@ local function on_station_rename(map_data, stop) --train is attempting delivery to a stop that was renamed local p_station = map_data.stations[train.p_station_id] local r_station = map_data.stations[train.r_station_id] - local schedule = create_manifest_schedule(train.depot_name, p_station.entity, r_station.entity, train.manifest) + local schedule = create_manifest_schedule(train.depot_name, p_station.entity_stop, r_station.entity_stop, train.manifest) schedule.current = train.entity.schedule.current train.entity.schedule = schedule end @@ -193,53 +325,51 @@ local function on_station_rename(map_data, stop) end -local function find_and_add_all_stations(map_data) +---@param map_data MapData +local function find_and_add_all_stations_from_nothing(map_data) for _, surface in pairs(game.surfaces) do - local stops = surface.find_entities_filtered({type="train-stop"}) - if stops then - for k, stop in pairs(stops) do - if stop.name == BUFFER_STATION_NAME then - local station = map_data.stations[stop.unit_number] - if not station then - on_station_built(map_data, stop) - end - end + local entities = surface.find_entities_filtered({name = COMBINATOR_NAME}) + for k, comb in pairs(entities) do + if comb.valid then + on_combinator_built(map_data, comb) end end end end - +---@param map_data MapData +---@param train_entity LuaTrain local function on_train_arrives_depot(map_data, train_entity) + local contents = train_entity.get_contents() local train = map_data.trains[train_entity.id] if train then - if train.manifest then - if train.status == STATUS_R_TO_D then - --succeeded delivery - train.p_station_id = 0 - train.r_station_id = 0 - train.manifest = nil - train.depot_name = train_entity.station.backer_name - train.status = STATUS_D - train.entity.schedule = create_depot_schedule(train.depot_name) - map_data.trains_available[train_entity.id] = true - else + if train.manifest and train.status == STATUS_R_TO_D then + --succeeded delivery + train.p_station_id = 0 + train.r_station_id = 0 + train.manifest = nil + train.depot_name = train_entity.station.backer_name + train.status = STATUS_D + map_data.trains_available[train_entity.id] = true + else + if train.manifest then on_failed_delivery(map_data, train) - local contents = train.entity.get_contents() - if next(contents) == nil then - train.depot_name = train_entity.station.backer_name - train.status = STATUS_D - train.entity.schedule = create_depot_schedule(train.depot_name) - map_data.trains_available[train_entity.id] = true - else--train still has cargo - train.entity.schedule = nil - remove_train(map_data, train, train_entity.id) - --TODO: mark train as lost in the alerts system - end + send_lost_train_alert(train.entity) end + train.depot_name = train_entity.station.backer_name + train.status = STATUS_D + map_data.trains_available[train_entity.id] = true end - else + if next(contents) ~= nil then + --train still has cargo + train_entity.schedule = nil + remove_train(map_data, train, train_entity.id) + send_nonempty_train_in_depot_alert(train_entity) + else + train_entity.schedule = create_depot_schedule(train.depot_name) + end + elseif next(contents) == nil then train = { depot_name = train_entity.station.backer_name, status = STATUS_D, @@ -251,15 +381,20 @@ local function on_train_arrives_depot(map_data, train_entity) r_station_id = 0, manifest = nil, } - update_train_layout(global, train) + update_train_layout(map_data, train) map_data.trains[train_entity.id] = train map_data.trains_available[train_entity.id] = true local schedule = create_depot_schedule(train.depot_name) train_entity.schedule = schedule + else + send_nonempty_train_in_depot_alert(train_entity) end end - -local function on_train_arrives_buffer(map_data, station_id, train) +---@param map_data MapData +---@param stop LuaEntity +---@param train Train +local function on_train_arrives_buffer(map_data, stop, train) + local station_id = stop.unit_number if train.manifest then if train.status == STATUS_D_TO_P then if train.p_station_id == station_id then @@ -270,7 +405,12 @@ local function on_train_arrives_buffer(map_data, station_id, train) for i, item in ipairs(train.manifest) do signals[i] = {index = i, signal = {type = item.type, name = item.name}, count = item.count} end - station.entity_out.get_control_behavior().parameters = signals + set_combinator_output(map_data, station.comb1, signals) + if station.wagon_combs then + for i, entity in ipairs(station.wagon_combs) do + + end + end end elseif train.status == STATUS_P_TO_R then if train.r_station_id == station_id then @@ -281,47 +421,40 @@ local function on_train_arrives_buffer(map_data, station_id, train) for i, item in ipairs(train.manifest) do signals[i] = {index = i, signal = {type = item.type, name = item.name}, count = -1} end - station.entity_out.get_control_behavior().parameters = signals + set_combinator_output(map_data, station.comb1, signals) end else on_failed_delivery(map_data, train) remove_train(map_data, train, train.entity.id) train.entity.schedule = nil + send_lost_train_alert(train.entity) end else --train is lost somehow, probably from player intervention remove_train(map_data, train, train.entity.id) end end - +---@param map_data MapData +---@param train Train local function on_train_leaves_station(map_data, train) if train.manifest then if train.status == STATUS_P then train.status = STATUS_P_TO_R local station = map_data.stations[train.p_station_id] - for i, item in ipairs(train.manifest) do - station.deliveries[item.name] = station.deliveries[item.name] + item.count - if station.deliveries[item.name] == 0 then - station.deliveries[item.name] = nil - end - end - station.deliveries_total = station.deliveries_total - 1 - set_station_output_empty(station) + remove_manifest(map_data, station, train.manifest, 1) + set_combinator_output(map_data, station.entity_comb1, nil) elseif train.status == STATUS_R then train.status = STATUS_R_TO_D local station = map_data.stations[train.r_station_id] - for i, item in ipairs(train.manifest) do - station.deliveries[item.name] = station.deliveries[item.name] - item.count - if station.deliveries[item.name] == 0 then - station.deliveries[item.name] = nil - end - end - station.deliveries_total = station.deliveries_total - 1 - set_station_output_empty(station) + remove_manifest(map_data, station, train.manifest, -1) + set_combinator_output(map_data, station.entity_comb1, nil) end end end + +---@param map_data MapData +---@param train Train local function on_train_broken(map_data, train) if train.manifest then on_failed_delivery(map_data, train) @@ -331,7 +464,9 @@ local function on_train_broken(map_data, train) end end end - +---@param map_data MapData +---@param pre_train_id uint +---@param train_entity LuaEntity local function on_train_modified(map_data, pre_train_id, train_entity) local train = map_data.trains[pre_train_id] if train then @@ -347,8 +482,6 @@ local function on_train_modified(map_data, pre_train_id, train_entity) end - - local function on_tick(event) tick(global, mod_settings) global.total_ticks = global.total_ticks + 1 @@ -358,8 +491,10 @@ local function on_built(event) local entity = event.entity or event.created_entity or event.destination if not entity or not entity.valid then return end - if entity.name == BUFFER_STATION_NAME then - on_station_built(global, entity) + if entity.name == "train-stop" then + on_stop_built(global, entity) + elseif entity.name == COMBINATOR_NAME then + on_combinator_built(global, entity) elseif entity.type == "inserter" then update_station_from_inserter(global, entity) elseif entity.type == "pump" then @@ -377,33 +512,21 @@ local function on_broken(event) if train then on_train_broken(global, train) end - elseif entity.name == BUFFER_STATION_NAME then - on_station_broken(global, entity) + elseif entity.name == "train-stop" then + on_stop_broken(global, entity) + elseif entity.name == COMBINATOR_NAME then + on_combinator_broken(global, entity) elseif entity.type == "inserter" then - --NOTE: check if this works or if it needs to be delayed - update_station_from_inserter(global, entity) + update_station_from_inserter(global, entity, entity) elseif entity.type == "pump" then - update_station_from_pump(global, entity) + update_station_from_pump(global, entity, entity) elseif entity.type == "straight-rail" then - update_station_from_rail(global, entity) + update_station_from_rail(global, entity, nil) end end - -local function on_train_changed(event) - local train_e = event.train - local train = global.trains[train_e.id] - if train_e.state == defines.train_state.wait_station and train_e.station ~= nil then - if train_e.station.name == DEPOT_STATION_NAME then - on_train_arrives_depot(global, train_e) - elseif train_e.station.name == BUFFER_STATION_NAME then - if train then - on_train_arrives_buffer(global, train_e.station.unit_number, train) - end - end - elseif event.old_state == defines.train_state.wait_station then - if train then - on_train_leaves_station(global, train) - end +local function on_rename(event) + if event.entity.name == "train-stop" then + on_station_rename(global, event.entity) end end @@ -416,33 +539,48 @@ local function on_train_built(event) on_train_modified(global, event.old_train_id_2, train_e) end end +local function on_train_changed(event) + local train_e = event.train + local train = global.trains[train_e.id] + if train_e.state == defines.train_state.wait_station then + local stop = train_e.station + if stop and stop.name == "train-stop" then + if global.stations[stop.unit_number] then + on_train_arrives_buffer(global, stop, train) + elseif global.depots[stop.unit_number] then + on_train_arrives_depot(global, train_e) + end + end + elseif event.old_state == defines.train_state.wait_station then + if train then + on_train_leaves_station(global, train) + end + end +end local function on_surface_removed(event) local surface = game.surfaces[event.surface_index] if surface then local train_stops = surface.find_entities_filtered({type = "train-stop"}) for _, entity in pairs(train_stops) do - if entity.name == BUFFER_STATION_NAME then - on_station_broken(global, entity) + if entity.name == "train-stop" then + on_stop_broken(global, entity) end end end end -local function on_rename(event) - if event.entity.name == BUFFER_STATION_NAME then - on_station_rename(global, event.entity) - end -end local filter_built = { {filter = "type", type = "train-stop"}, + {filter = "type", type = "arithmetic-combinator"}, {filter = "type", type = "inserter"}, {filter = "type", type = "pump"}, {filter = "type", type = "straight-rail"}, } local filter_broken = { {filter = "type", type = "train-stop"}, + {filter = "type", type = "arithmetic-combinator"}, {filter = "type", type = "inserter"}, {filter = "type", type = "pump"}, {filter = "type", type = "straight-rail"}, @@ -469,6 +607,8 @@ local function register_events() script.on_event(defines.events.on_train_changed_state, on_train_changed) script.on_event(defines.events.on_entity_renamed, on_rename) + + register_gui_actions() end script.on_load(function() @@ -477,12 +617,12 @@ end) script.on_init(function() --TODO: we are not checking changed cargo capacities - find_and_add_all_stations(global) + --find_and_add_all_stations(global) register_events() end) script.on_configuration_changed(function(data) --TODO: we are not checking changed cargo capacities - find_and_add_all_stations(global) + --find_and_add_all_stations(global) register_events() end) diff --git a/cybersyn/settings.lua b/cybersyn/settings.lua index 8de42a3..be2a1c9 100644 --- a/cybersyn/settings.lua +++ b/cybersyn/settings.lua @@ -1,4 +1,4 @@ ---By cybersyn +--By Mami data:extend({ { type = "int-setting", @@ -11,7 +11,7 @@ data:extend({ }, { type = "int-setting", - name = "cybersyn-requester-threshold", + name = "cybersyn-request-threshold", order = "ab", setting_type = "runtime-global", default_value = 1000000000, @@ -20,7 +20,7 @@ data:extend({ }, { type = "int-setting", - name = "cybersyn-provider-threshold", + name = "cybersyn-provide-threshold", order = "ac", setting_type = "runtime-global", default_value = 1000000000,