readded copy-paste

This commit is contained in:
Monica Moniot
2022-11-25 22:57:12 -05:00
parent be3f2f1d07
commit c4d8d3d21b
11 changed files with 346 additions and 284 deletions

View File

@@ -52,3 +52,10 @@ Version: 0.5.0
Date: 2022-11-25
Features:
- Added SE space elevator compat
---------------------------------------------------------------------------------------------------
Version: 0.5.1
Date: 2022-11-25
Features:
- Re-added combinator copy-paste
- Fixed bugs within train blacklist logic
- Fixed a crash

View File

@@ -1,6 +1,6 @@
{
"name": "cybersyn",
"version": "0.5.0",
"version": "0.5.1",
"title": "Project Cybersyn",
"author": "Mami",
"factorio_version": "1.1",

View File

@@ -12,7 +12,7 @@ combinator_entity.radius_visualisation_specification = {
distance = 1.5,
}
combinator_entity.active_energy_usage = "10KW"
combinator_entity.allow_copy_paste = false
--combinator_entity.allow_copy_paste = false

View File

@@ -26,7 +26,7 @@ function remove_manifest(map_data, station, manifest, sign)
set_comb2(map_data, station)
station.deliveries_total = station.deliveries_total - 1
if station.deliveries_total == 0 and station.entity_comb1.valid then
map_data.to_comb_params[station.entity_comb1.unit_number] = set_combinator_operation(station.entity_comb1, OPERATION_PRIMARY_IO)
set_comb_operation_with_check(map_data, station.entity_comb1, OPERATION_PRIMARY_IO)
end
end
@@ -214,10 +214,10 @@ local function send_train_between(map_data, r_station_id, p_station_id, depot, p
set_comb2(map_data, p_station)
set_comb2(map_data, r_station)
if p_station.entity_comb1.valid then
map_data.to_comb_params[p_station.entity_comb1.unit_number] = set_combinator_operation(p_station.entity_comb1, OPERATION_PRIMARY_IO_ACTIVE)
set_comb_operation_with_check(map_data, p_station.entity_comb1, OPERATION_PRIMARY_IO_ACTIVE)
end
if r_station.entity_comb1.valid then
map_data.to_comb_params[r_station.entity_comb1.unit_number] = set_combinator_operation(r_station.entity_comb1, OPERATION_PRIMARY_IO_ACTIVE)
set_comb_operation_with_check(map_data, r_station.entity_comb1, OPERATION_PRIMARY_IO_ACTIVE)
end
end
@@ -229,11 +229,22 @@ local function tick_poll_train(map_data, mod_settings)
local train_id, train = next(map_data.trains, tick_data.last_train)
tick_data.last_train = train_id
if train and train.manifest and train.last_manifest_tick + mod_settings.stuck_train_time*mod_settings.tps < map_data.total_ticks then
if train and train.manifest and train.entity and train.last_manifest_tick + mod_settings.stuck_train_time*mod_settings.tps < map_data.total_ticks then
send_stuck_train_alert(train.entity, train.depot_name)
end
end
---@param map_data MapData
local function tick_poll_comb(map_data)
local tick_data = map_data.tick_data
--NOTE: the following has undefined behavior if last_comb is deleted
local comb_id, comb = next(map_data.to_comb, tick_data.last_comb)
tick_data.last_comb = comb_id
if comb and comb.valid then
combinator_update(map_data, comb)
end
end
---@param map_data MapData
---@param mod_settings CybersynModSettings
local function tick_poll_station(map_data, mod_settings)
local tick_data = map_data.tick_data
@@ -254,7 +265,7 @@ local function tick_poll_station(map_data, mod_settings)
station = map_data.stations[station_id]
if station then
if station.display_update then
map_data.to_comb_params[station.entity_comb1.unit_number] = update_combinator_display(station.entity_comb1, station.display_failed_request)
update_combinator_display(map_data, station.entity_comb1, station.display_failed_request)
station.display_update = station.display_failed_request
station.display_failed_request = nil
end
@@ -373,6 +384,7 @@ local function tick_dispatch(map_data, mod_settings)
local name_i = size <= 2 and 2 or 2*random(size/2)
local item_network_name = all_names[name_i - 1]
local signal = all_names[name_i]
--swap remove
all_names[name_i - 1] = all_names[size - 1]
all_names[name_i] = all_names[size]
@@ -384,7 +396,7 @@ local function tick_dispatch(map_data, mod_settings)
if p_stations then
tick_data.r_stations = r_stations
tick_data.p_stations = p_stations
tick_data.item_name = signal.name
tick_data.item_name = signal.name--[[@as string]]
tick_data.item_type = signal.type
table_sort(r_stations, function(a_id, b_id)
local a = stations[a_id]
@@ -417,6 +429,7 @@ local function tick_dispatch(map_data, mod_settings)
if r_station and r_station.deliveries_total < r_station.entity_stop.trains_limit then
local item_name = tick_data.item_name
local item_type = tick_data.item_type
--NOTE: the station at r_station_id could have been deleted and reregistered since last poll, this check here prevents it from being processed for a delivery in that case
local r_threshold = r_station.p_count_or_r_threshold_per_item[item_name]
if r_threshold then
@@ -483,6 +496,7 @@ function tick(map_data, mod_settings)
end
end
tick_poll_train(map_data, mod_settings)
tick_poll_comb(map_data)
end
if map_data.tick_state == STATE_POLL_STATIONS then

View File

@@ -14,10 +14,31 @@ end
---@param stop0 LuaEntity
---@param stop1 LuaEntity
function get_stop_dist(stop0, stop1)
return get_distance(stop0.position, stop1.position)
local surface0 = stop0.surface.index
local surface1 = stop1.surface.index
return (surface0 == surface1 and get_distance(stop0.position, stop1.position) or DIFFERENT_SURFACE_DISTANCE)
end
---@param surface LuaSurface
local function se_get_space_elevator_name(surface)
--TODO: check how expensive the following is and potentially cache it's results
local entity = surface.find_entities_filtered({
name = SE_ELEVATOR_STOP_PROTO_NAME,
type = "train-stop",
limit = 1,
})[1]
if entity and entity.valid then
return string.sub(entity.backer_name, 1, string.len(entity.backer_name) - SE_ELEVATOR_SUFFIX_LENGTH)
end
end
------------------------------------------------------------------------------
--[[train schedules]]--
------------------------------------------------------------------------------
local create_loading_order_condition = {type = "inactivity", compare_type = "and", ticks = 120}
---@param stop LuaEntity
---@param manifest Manifest
@@ -69,22 +90,7 @@ end
function lock_train(train)
train.manual_mode = true
end
--[[
---@param train LuaTrain
---@param depot_stop LuaEntity
---@param p_stop LuaEntity
---@param r_stop LuaEntity
---@param manifest Manifest
function set_manifest_schedule(train, depot_stop, p_stop, r_stop, manifest)
train.schedule = {current = 1, records = {
create_inactivity_order(depot_stop.backer_name),
create_direct_to_station_order(p_stop),
create_loading_order(p_stop, manifest),
create_direct_to_station_order(r_stop),
create_unloading_order(r_stop),
}}
end
]]
---@param train LuaTrain
---@param stop LuaEntity
---@param old_name string
@@ -99,64 +105,230 @@ function rename_manifest_schedule(train, stop, old_name)
end
train.schedule = schedule
end
---@param train LuaTrain
---@param depot_stop LuaEntity
---@param p_stop LuaEntity
---@param r_stop LuaEntity
---@param manifest Manifest
function set_manifest_schedule(train, depot_stop, p_stop, r_stop, manifest)
--NOTE: train must be on same surface as depot_stop
local d_surface = depot_stop.surface
local p_surface = p_stop.surface
local r_surface = r_stop.surface
local d_surface_i = d_surface.index
local p_surface_i = p_surface.index
local r_surface_i = r_surface.index
if d_surface_i == p_surface_i and p_surface_i == r_surface_i then
train.schedule = {current = 1, records = {
create_inactivity_order(depot_stop.backer_name),
create_direct_to_station_order(p_stop),
create_loading_order(p_stop, manifest),
create_direct_to_station_order(r_stop),
create_unloading_order(r_stop),
}}
return
elseif IS_SE_PRESENT and (d_surface_i == p_surface_i or p_surface_i == r_surface_i or r_surface_i == d_surface_i) then
local d_zone = remote.call("space-exploration", "get_zone_from_surface_index", {surface_index = d_surface_i})
local other_zone = remote.call("space-exploration", "get_zone_from_surface_index", {surface_index = (d_surface_i == p_surface_i) and r_surface_i or p_surface_i})
local is_train_in_orbit = other_zone.orbit_index == d_zone.index
if is_train_in_orbit or d_zone.orbit_index == other_zone.index then
local elevator_name = se_get_space_elevator_name(d_surface)
if elevator_name then
local records = {create_inactivity_order(depot_stop.backer_name)}
if d_surface_i == p_surface_i then
records[#records + 1] = create_direct_to_station_order(p_stop)
else
records[#records + 1] = {station = elevator_name..(is_train_in_orbit and SE_ELEVATOR_ORBIT_SUFFIX or SE_ELEVATOR_PLANET_SUFFIX)}
is_train_in_orbit = not is_train_in_orbit
end
records[#records + 1] = create_loading_order(p_stop, manifest)
if p_surface_i ~= r_surface_i then
records[#records + 1] = {station = elevator_name..(is_train_in_orbit and SE_ELEVATOR_ORBIT_SUFFIX or SE_ELEVATOR_PLANET_SUFFIX)}
is_train_in_orbit = not is_train_in_orbit
end
records[#records + 1] = create_unloading_order(r_stop)
if r_surface_i ~= d_surface_i then
records[#records + 1] = {station = elevator_name..(is_train_in_orbit and SE_ELEVATOR_ORBIT_SUFFIX or SE_ELEVATOR_PLANET_SUFFIX)}
is_train_in_orbit = not is_train_in_orbit
end
train.schedule = {current = 1, records = records}
return
end
end
end
--NOTE: create a schedule that cannot be fulfilled, the train will be stuck but it will give the player information what went wrong
train.schedule = {current = 1, records = {
create_inactivity_order(depot_stop.backer_name),
create_loading_order(p_stop, manifest),
create_unloading_order(r_stop),
}}
lock_train(train)
send_lost_train_alert(train, depot_stop.backer_name)
end
------------------------------------------------------------------------------
--[[combinators]]--
------------------------------------------------------------------------------
---@param comb LuaEntity
function get_comb_control(comb)
--NOTE: using this as opposed to get_comb_params gives you R/W access
return comb.get_or_create_control_behavior()--[[@as LuaArithmeticCombinatorControlBehavior]]
end
---@param comb LuaEntity
function get_comb_params(comb)
return comb.get_or_create_control_behavior().parameters--[[@as ArithmeticCombinatorParameters]]
end
---@param param ArithmeticCombinatorParameters
function get_comb_secondary_state(param)
local bits = param.second_constant or 0
return bits%2 == 1, floor(bits/2)%3
---@param comb LuaEntity
function get_comb_gui_settings(comb)
local params = get_comb_params(comb)
local op = params.operation
local selected_index = 0
local switch_state = "none"
local bits = params.second_constant or 0
local allows_all_trains = bits%2 == 1
local is_pr_state = floor(bits/2)%3
if is_pr_state == 0 then
switch_state = "none"
elseif is_pr_state == 1 then
switch_state = "left"
elseif is_pr_state == 2 then
switch_state = "right"
end
if op == OPERATION_PRIMARY_IO or op == OPERATION_PRIMARY_IO_ACTIVE or op == OPERATION_PRIMARY_IO_FAILED_REQUEST then
selected_index = 1
elseif op == OPERATION_SECONDARY_IO then
selected_index = 2
elseif op == OPERATION_DEPOT then
selected_index = 3
elseif op == OPERATION_WAGON_MANIFEST then
selected_index = 4
end
return selected_index, params.first_signal, not allows_all_trains, switch_state
end
---@param comb LuaEntity
function get_comb_network_name(comb)
local params = get_comb_params(comb)
local signal = params.first_signal
return signal and signal.name or nil
end
---@param station Station
function set_station_from_comb_state(station)
--NOTE: this does nothing to update currently active deliveries
local param = get_comb_params(station.entity_comb1)
local bits = param.second_constant or 0
local params = get_comb_params(station.entity_comb1)
local bits = params.second_constant or 0
local is_pr_state = floor(bits/2)%3
local signal = param.first_signal
local signal = params.first_signal
station.network_name = signal and signal.name or nil
station.allows_all_trains = bits%2 == 1
station.is_p = is_pr_state == 0 or is_pr_state == 1
station.is_r = is_pr_state == 0 or is_pr_state == 2
end
---@param map_data MapData
---@param unit_number uint
---@param params ArithmeticCombinatorParameters
function has_comb_params_changed(map_data, unit_number, params)
local old_params = map_data.to_comb_params[unit_number]
if params.operation ~= old_params.operation then
if (old_params.operation == OPERATION_PRIMARY_IO) and (params.operation == OPERATION_PRIMARY_IO_ACTIVE or params.operation == OPERATION_PRIMARY_IO_FAILED_REQUEST) then
else
return true
end
end
local new_signal = params.first_signal
local old_signal = old_params.first_signal
local new_network = new_signal and new_signal.name or nil
local old_network = old_signal and old_signal.name or nil
if new_network ~= old_network then
return true
end
if params.second_constant ~= old_params.second_constant then
return true
end
return false
end
---@param map_data MapData
---@param comb LuaEntity
---@param op string
function set_comb_operation_with_check(map_data, comb, op)
---@type uint
local unit_number = comb.unit_number
local control = get_comb_control(comb)
local params = control.parameters
if not has_comb_params_changed(map_data, unit_number, params) then
params.operation = op
control.parameters = params
if (op == OPERATION_PRIMARY_IO_ACTIVE or op == OPERATION_PRIMARY_IO_FAILED_REQUEST) then
params.operation = OPERATION_PRIMARY_IO
end
map_data.to_comb_params[unit_number] = params
end
end
---@param map_data MapData
---@param comb LuaEntity
---@param is_failed boolean
function update_combinator_display(map_data, comb, is_failed)
---@type uint
local unit_number = comb.unit_number
local control = get_comb_control(comb)
local params = control.parameters
if not has_comb_params_changed(map_data, unit_number, params) then
if is_failed then
if params.operation == OPERATION_PRIMARY_IO then
params.operation = OPERATION_PRIMARY_IO_FAILED_REQUEST
control.parameters = params
params.operation = OPERATION_PRIMARY_IO
map_data.to_comb_params[unit_number] = params
end
elseif params.operation == OPERATION_PRIMARY_IO_FAILED_REQUEST then
params.operation = OPERATION_PRIMARY_IO
control.parameters = params
map_data.to_comb_params[unit_number] = params
end
end
end
---@param comb LuaEntity
---@param allows_all_trains boolean
function set_comb_allows_all_trains(comb, allows_all_trains)
local control = comb.get_or_create_control_behavior()--[[@as LuaArithmeticCombinatorControlBehavior]]
local control = get_comb_control(comb)
local param = control.parameters
local bits = param.second_constant or 0
param.second_constant = (bits - bits%2) + (allows_all_trains and 1 or 0)
control.parameters = param
return param
end
---@param comb LuaEntity
---@param is_pr_state 0|1|2
function set_comb_is_pr_state(comb, is_pr_state)
local control = comb.get_or_create_control_behavior()--[[@as LuaArithmeticCombinatorControlBehavior]]
local control = get_comb_control(comb)
local param = control.parameters
local bits = param.second_constant or 0
param.second_constant = (bits%2) + (2*is_pr_state)
control.parameters = param
return param
end
---@param comb LuaEntity
function get_comb_network_name(comb)
local control = comb.get_or_create_control_behavior()--[[@as LuaArithmeticCombinatorControlBehavior]]
local signal = control.parameters.first_signal
return signal and signal.name
end
---@param comb LuaEntity
---@param signal SignalID?
function set_comb_network_name(comb, signal)
local control = comb.get_or_create_control_behavior()--[[@as LuaArithmeticCombinatorControlBehavior]]
local control = get_comb_control(comb)
local param = control.parameters
param.first_signal = signal
control.parameters = param
return param
end
---@param comb LuaEntity
---@param op string
function set_comb_operation(comb, op)
local control = get_comb_control(comb)
local params = control.parameters
params.operation = op
control.parameters = params
end
@@ -169,32 +341,6 @@ function set_combinator_output(map_data, comb, signals)
out.get_or_create_control_behavior().parameters = signals
end
end
---@param comb LuaEntity
---@param op string
function set_combinator_operation(comb, op)
local control = comb.get_or_create_control_behavior()--[[@as LuaArithmeticCombinatorControlBehavior]]
local param = control.parameters
param.operation = op
control.parameters = param
return param
end
---@param comb LuaEntity
---@param is_failed boolean
function update_combinator_display(comb, is_failed)
local control = comb.get_or_create_control_behavior()--[[@as LuaArithmeticCombinatorControlBehavior]]
local param = control.parameters
if is_failed then
if param.operation == OPERATION_PRIMARY_IO then
param.operation = OPERATION_PRIMARY_IO_FAILED_REQUEST
control.parameters = param
end
elseif param.operation == OPERATION_PRIMARY_IO_FAILED_REQUEST then
param.operation = OPERATION_PRIMARY_IO
control.parameters = param
end
return param
end
---@param station Station
function get_signals(station)
@@ -236,6 +382,12 @@ function get_threshold(map_data, station, signal)
return station.r_threshold
end
------------------------------------------------------------------------------
--[[alerts]]--
------------------------------------------------------------------------------
local send_missing_train_alert_for_stop_icon = {name = MISSING_TRAIN_NAME, type = "fluid"}
---@param r_stop LuaEntity
---@param p_stop LuaEntity
@@ -312,89 +464,3 @@ function send_stuck_train_alert(train, depot_name)
end
end
end
--function se_create_placeholder_order()
--end
---@param surface LuaSurface
local function se_get_space_elevator_name(surface)
--TODO: check how expensive the following is and potentially cache it's results
local entity = surface.find_entities_filtered({
name = SE_ELEVATOR_STOP_PROTO_NAME,
type = "train-stop",
limit = 1,
})[1]
if entity and entity.valid then
return string.sub(entity.backer_name, 1, string.len(entity.backer_name) - SE_ELEVATOR_SUFFIX_LENGTH)
end
end
---@param train LuaTrain
---@param depot_stop LuaEntity
---@param p_stop LuaEntity
---@param r_stop LuaEntity
---@param manifest Manifest
function set_manifest_schedule(train, depot_stop, p_stop, r_stop, manifest)
--NOTE: train must be on same surface as depot_stop
local d_surface = depot_stop.surface
local p_surface = p_stop.surface
local r_surface = r_stop.surface
local d_surface_i = d_surface.index
local p_surface_i = p_surface.index
local r_surface_i = r_surface.index
if d_surface_i == p_surface_i and p_surface_i == r_surface_i then
train.schedule = {current = 1, records = {
create_inactivity_order(depot_stop.backer_name),
create_direct_to_station_order(p_stop),
create_loading_order(p_stop, manifest),
create_direct_to_station_order(r_stop),
create_unloading_order(r_stop),
}}
return
elseif IS_SE_PRESENT and (d_surface_i == p_surface_i or p_surface_i == r_surface_i or r_surface_i == d_surface_i) then
local d_zone = remote.call("space-exploration", "get_zone_from_surface_index", {surface_index = d_surface_i})
local other_zone = remote.call("space-exploration", "get_zone_from_surface_index", {surface_index = (d_surface_i == p_surface_i) and r_surface_i or p_surface_i})
local is_train_in_orbit = other_zone.orbit_index == d_zone.index
if is_train_in_orbit or d_zone.orbit_index == other_zone.index then
local elevator_name = se_get_space_elevator_name(d_surface)
if elevator_name then
local records = {create_inactivity_order(depot_stop.backer_name)}
if d_surface_i == p_surface_i then
records[#records + 1] = create_direct_to_station_order(p_stop)
else
records[#records + 1] = {station = elevator_name..(is_train_in_orbit and SE_ELEVATOR_ORBIT_SUFFIX or SE_ELEVATOR_PLANET_SUFFIX)}
is_train_in_orbit = not is_train_in_orbit
end
records[#records + 1] = create_loading_order(p_stop, manifest)
if p_surface_i ~= r_surface_i then
records[#records + 1] = {station = elevator_name..(is_train_in_orbit and SE_ELEVATOR_ORBIT_SUFFIX or SE_ELEVATOR_PLANET_SUFFIX)}
is_train_in_orbit = not is_train_in_orbit
end
records[#records + 1] = create_unloading_order(r_stop)
if r_surface_i ~= d_surface_i then
records[#records + 1] = {station = elevator_name..(is_train_in_orbit and SE_ELEVATOR_ORBIT_SUFFIX or SE_ELEVATOR_PLANET_SUFFIX)}
is_train_in_orbit = not is_train_in_orbit
end
train.schedule = {current = 1, records = records}
return
end
end
end
--NOTE: create a schedule that cannot be fulfilled, the train will be stuck but it will give the player information what went wrong
train.schedule = {current = 1, records = {
create_inactivity_order(depot_stop.backer_name),
create_loading_order(p_stop, manifest),
create_unloading_order(r_stop),
}}
lock_train(train)
send_lost_train_alert(train, depot_stop.backer_name)
end
---@param stop0 LuaEntity
---@param stop1 LuaEntity
function se_get_stop_dist(stop0, stop1)
local surface0 = stop0.surface.index
local surface1 = stop1.surface.index
return (surface0 == surface1 and get_distance(stop0.position, stop1.position) or DIFFERENT_SURFACE_DISTANCE)
end

View File

@@ -2,7 +2,6 @@
---@class MapData
---@field public total_ticks uint
---@field public layout_top_id uint
---@field public is_player_cursor_blueprint {[uint]: true|nil}
---@field public to_comb {[uint]: LuaEntity}
---@field public to_comb_params {[uint]: ArithmeticCombinatorParameters}
---@field public to_output {[uint]: LuaEntity}
@@ -36,7 +35,7 @@
---@field public deliveries {[string]: int}
---@field public network_name string?
---@field public network_flag int --transient
---@field public accepted_layouts TrainClass
---@field public accepted_layouts {[uint]: true?}
---@field public layout_pattern {[uint]: int}
---@field public tick_signals {[uint]: Signal}? --transient
---@field public p_count_or_r_threshold_per_item {[string]: int} --transient
@@ -61,21 +60,20 @@
---@field public has_filtered_wagon boolean
---@field public depot_id uint?
---@field public depot_name string
---@field public network_name string
---@field public network_name string?
---@field public network_flag int
---@field public priority int
---@field public se_awaiting_removal any?
---@field public se_awaiting_rename any?
---@alias Manifest {}[]
---@alias TrainClass {[uint]: true}
---@alias cybersyn.global MapData
---@class Economy
---could contain invalid stations
---@field public all_r_stations {[string]: uint[]} --{[network_name:item_name]: count}
---@field public all_p_stations {[string]: uint[]} --{[network_name:item_name]: count}
---@field public all_names {[string]: uint[]} --{[network_name:item_name]: count}
---@field public all_r_stations {[string]: uint[]} --{[network_name:item_name]: station_id}
---@field public all_p_stations {[string]: uint[]} --{[network_name:item_name]: station_id}
---@field public all_names (string|SignalID)[]
---@class CybersynModSettings
---@field public tps int
@@ -111,7 +109,6 @@ function init_global()
global.layouts = {}
global.layout_train_count = {}
global.layout_top_id = 1
global.is_player_cursor_blueprint = {}
if IS_SE_PRESENT then
global.se_tele_old_id = {}

View File

@@ -30,29 +30,7 @@ STATUS_NAMES_DEFAULT = "entity-status.disabled"
---@param player LuaPlayer
function gui_opened(comb, player)
local rootgui = player.gui.screen
local param = get_comb_params(comb)
local op = param.operation
local selected_index = 0
local switch_state = "none"
local allows_all_trains, is_pr_state = get_comb_secondary_state(param)
if is_pr_state == 0 then
switch_state = "none"
elseif is_pr_state == 1 then
switch_state = "left"
elseif is_pr_state == 2 then
switch_state = "right"
end
if op == OPERATION_PRIMARY_IO or op == OPERATION_PRIMARY_IO_ACTIVE or op == OPERATION_PRIMARY_IO_FAILED_REQUEST then
selected_index = 1
elseif op == OPERATION_SECONDARY_IO then
selected_index = 2
elseif op == OPERATION_DEPOT then
selected_index = 3
elseif op == OPERATION_WAGON_MANIFEST then
selected_index = 4
end
local selected_index, signal, check, switch_state = get_comb_gui_settings(comb)
local window = flib_gui.build(rootgui, {
{type="frame", direction="vertical", ref={"main_window"}, name=COMBINATOR_NAME, children={
@@ -94,10 +72,10 @@ function gui_opened(comb, player)
{type="line", style_mods={top_padding=10}},
{type="label", name="network_label", ref={"network_label"}, style="heading_3_label", caption={"cybersyn-gui.network"}, style_mods={top_padding=8}},
{type="flow", name="bottom", direction="horizontal", style_mods={vertical_align="center"}, children={
{type="choose-elem-button", name="network", style="slot_button_in_shallow_frame", ref={"network"}, elem_type="signal", tooltip={"cybersyn-gui.network-tooltip"}, signal=param.first_signal, style_mods={bottom_margin=1, right_margin=6}, actions={
{type="choose-elem-button", name="network", style="slot_button_in_shallow_frame", ref={"network"}, elem_type="signal", tooltip={"cybersyn-gui.network-tooltip"}, signal=signal, style_mods={bottom_margin=1, right_margin=6}, actions={
on_elem_changed={"choose-elem-button", comb.unit_number}
}},
{type="checkbox", name="radio_button", ref={"radio_button"}, state=not allows_all_trains, tooltip={"cybersyn-gui.auto-tooltip"}, actions={
{type="checkbox", name="radio_button", ref={"radio_button"}, state=check, tooltip={"cybersyn-gui.auto-tooltip"}, actions={
on_checked_state_changed={"radio_button", comb.unit_number}
}},
{type="label", name="radio_label", style_mods={left_padding=3}, ref={"radio_label"}, caption={"cybersyn-gui.auto-description"}},
@@ -164,28 +142,28 @@ function register_gui_actions()
local bottom_flow = all_flow.bottom
local param
if element.selected_index == 1 then
param = set_combinator_operation(comb, OPERATION_PRIMARY_IO)
set_comb_operation(comb, OPERATION_PRIMARY_IO)
top_flow["switch"].visible = true
all_flow["network_label"].visible = true
bottom_flow["network"].visible = true
bottom_flow["radio_button"].visible = true
bottom_flow["radio_label"].visible = true
elseif element.selected_index == 2 then
param = set_combinator_operation(comb, OPERATION_SECONDARY_IO)
set_comb_operation(comb, OPERATION_SECONDARY_IO)
top_flow["switch"].visible = false
all_flow["network_label"].visible = false
bottom_flow["network"].visible = false
bottom_flow["radio_button"].visible = false
bottom_flow["radio_label"].visible = false
elseif element.selected_index == 3 then
param = set_combinator_operation(comb, OPERATION_DEPOT)
set_comb_operation(comb, OPERATION_DEPOT)
top_flow["switch"].visible = false
all_flow["network_label"].visible = true
bottom_flow["network"].visible = true
bottom_flow["radio_button"].visible = false
bottom_flow["radio_label"].visible = false
elseif element.selected_index == 4 then
param = set_combinator_operation(comb, OPERATION_WAGON_MANIFEST)
set_comb_operation(comb, OPERATION_WAGON_MANIFEST)
top_flow["switch"].visible = false
all_flow["network_label"].visible = false
bottom_flow["network"].visible = false
@@ -195,7 +173,7 @@ function register_gui_actions()
return
end
on_combinator_updated(global, comb, param)
combinator_update(global, comb)
elseif msg[1] == "choose-elem-button" then
local element = event.element
if not element then return end
@@ -207,9 +185,9 @@ function register_gui_actions()
signal = nil
element.elem_value = nil
end
local param = set_comb_network_name(comb, signal)
set_comb_network_name(comb, signal)
on_combinator_updated(global, comb, param)
combinator_update(global, comb)
elseif msg[1] == "radio_button" then
local element = event.element
if not element then return end
@@ -217,9 +195,9 @@ function register_gui_actions()
if not comb or not comb.valid then return end
local allows_all_trains = not element.state
local param = set_comb_allows_all_trains(comb, allows_all_trains)
set_comb_allows_all_trains(comb, allows_all_trains)
on_combinator_updated(global, comb, param)
combinator_update(global, comb)
elseif msg[1] == "switch" then
local element = event.element
if not element then return end
@@ -227,9 +205,9 @@ function register_gui_actions()
if not comb or not comb.valid then return end
local is_pr_state = (element.switch_state == "none" and 0) or (element.switch_state == "left" and 1) or 2
local param = set_comb_is_pr_state(comb, is_pr_state)
set_comb_is_pr_state(comb, is_pr_state)
on_combinator_updated(global, comb, param)
combinator_update(global, comb)
end
end
end)

View File

@@ -5,7 +5,19 @@ local floor = math.floor
local ceil = math.ceil
local string_find = string.find
local string_sub = string.sub
local table_compare = table.compare
local function table_compare(t0, t1)
if #t0 ~= #t1 then
return false
end
for i = 0, #t0 do
if t0[i] ~= t1[i] then
return false
end
end
return true
end
local function iterr(a, i)
i = i + 1
@@ -447,10 +459,10 @@ function reset_station_layout(map_data, station, forbidden_entity)
if supports_fluid then
layout_pattern[wagon_number] = 3
else
layout_pattern[wagon_number] = 2
layout_pattern[wagon_number] = 1
end
elseif supports_fluid then
layout_pattern[wagon_number] = 1
layout_pattern[wagon_number] = 2
else
--layout_pattern[wagon_number] = nil
end

View File

@@ -152,10 +152,8 @@ local function on_station_built(map_data, stop, comb1, comb2)
priority = 0,
r_threshold = 0,
locked_slots = 0,
--network_name = param.first_signal and param.first_signal.name or nil,
network_flag = 0,
deliveries = {},
--allows_all_trains = param.second_constant == 1,
accepted_layouts = {},
layout_pattern = nil,
p_count_or_r_threshold_per_item = {},
@@ -270,25 +268,25 @@ local function on_combinator_built(map_data, comb)
wire = defines.wire_type.red,
})
local control = comb.get_or_create_control_behavior()--[[@as LuaArithmeticCombinatorControlBehavior]]
local param = control.parameters
local op = param.operation
local control = get_comb_control(comb)
local params = control.parameters
local op = params.operation
if op == OPERATION_DEFAULT then
op = OPERATION_PRIMARY_IO
param.operation = op
param.first_signal = NETWORK_SIGNAL_DEFAULT
control.parameters = param
elseif op == OPERATION_PRIMARY_IO_ACTIVE or op == OPERATION_PRIMARY_IO_FAILED_REQUEST then
params.operation = op
params.first_signal = NETWORK_SIGNAL_DEFAULT
control.parameters = params
elseif op ~= OPERATION_PRIMARY_IO and op ~= OPERATION_SECONDARY_IO and op ~= OPERATION_DEPOT and op ~= OPERATION_WAGON_MANIFEST then
op = OPERATION_PRIMARY_IO
param.operation = op
control.parameters = param
params.operation = op
control.parameters = params
end
map_data.to_comb[comb.unit_number] = comb
map_data.to_comb_params[comb.unit_number] = params
map_data.to_output[comb.unit_number] = out
map_data.to_stop[comb.unit_number] = stop
map_data.to_comb_params[comb.unit_number] = param
if op == OPERATION_WAGON_MANIFEST then
if rail then
@@ -360,7 +358,7 @@ function on_combinator_network_updated(map_data, comb, network_name)
end
---@param map_data MapData
---@param comb LuaEntity
local function on_combinator_broken(map_data, comb)
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
---@type uint
local comb_id = comb.unit_number
@@ -411,13 +409,17 @@ end
---@param map_data MapData
---@param comb LuaEntity
---@param new_params ArithmeticCombinatorParameters
function on_combinator_updated(map_data, comb, new_params)
local old_params = map_data.to_comb_params[comb.unit_number]
if new_params.operation ~= old_params.operation then
if (new_params.operation == OPERATION_PRIMARY_IO_ACTIVE or new_params.operation == OPERATION_PRIMARY_IO_FAILED_REQUEST or new_params.operation == OPERATION_PRIMARY_IO) and (old_params.operation == OPERATION_PRIMARY_IO_ACTIVE or old_params.operation == OPERATION_PRIMARY_IO_FAILED_REQUEST or old_params.operation == OPERATION_PRIMARY_IO) then
set_combinator_operation(comb, old_params.operation)
new_params.operation = old_params.operation
function combinator_update(map_data, comb)
---@type uint
local unit_number = comb.unit_number
local control = get_comb_control(comb)
local params = control.parameters
local old_params = map_data.to_comb_params[unit_number]
if params.operation ~= old_params.operation then
if (old_params.operation == OPERATION_PRIMARY_IO) and (params.operation == OPERATION_PRIMARY_IO_ACTIVE or params.operation == OPERATION_PRIMARY_IO_FAILED_REQUEST) then
--make sure only OPERATION_PRIMARY_IO gets stored on map_data.to_comb_params
params.operation = OPERATION_PRIMARY_IO
else
--NOTE: This is rather dangerous, we may need to actually implement operation changing
on_combinator_broken(map_data, comb)
@@ -425,19 +427,20 @@ function on_combinator_updated(map_data, comb, new_params)
return
end
end
local new_signal = new_params.first_signal
local new_signal = params.first_signal
local old_signal = old_params.first_signal
local new_network = new_signal and new_signal.name or nil
local old_network = old_signal and old_signal.name or nil
if new_network ~= old_network then
on_combinator_network_updated(map_data, comb, new_network)
map_data.to_comb_params[unit_number] = params
end
if new_params.second_constant ~= old_params.second_constant then
if params.second_constant ~= old_params.second_constant then
local stop = global.to_stop[comb.unit_number]
if stop then
local station = global.stations[stop.unit_number]
if station then
local bits = new_params.second_constant
local bits = params.second_constant
local is_pr_state = floor(bits/2)%3
station.is_p = is_pr_state == 0 or is_pr_state == 1
station.is_r = is_pr_state == 0 or is_pr_state == 2
@@ -448,8 +451,8 @@ function on_combinator_updated(map_data, comb, new_params)
end
end
end
map_data.to_comb_params[unit_number] = params
end
map_data.to_comb_params[comb.unit_number] = new_params
end
---@param map_data MapData
@@ -594,7 +597,7 @@ local function on_train_arrives_depot(map_data, depot_id, train_entity)
set_depot_schedule(train_entity, train.depot_name)
else
--train still has cargo
lock_train(train.entity)
lock_train(train_entity)
remove_train(map_data, train, train_id)
send_nonempty_train_in_depot_alert(train_entity)
end
@@ -616,7 +619,7 @@ local function on_train_arrives_depot(map_data, depot_id, train_entity)
set_depot_schedule(train_entity, train.depot_name)
else
lock_train(train.entity)
lock_train(train_entity)
send_nonempty_train_in_depot_alert(train_entity)
end
end
@@ -825,35 +828,10 @@ local function on_paste(event)
if not entity or not entity.valid then return end
if entity.name == COMBINATOR_NAME then
on_combinator_updated(global, entity, get_comb_params(entity))
combinator_update(global, entity)
end
end
local function on_cursor_stack_changed(event)
local i = event.player_index
local player = game.get_player(i)
if not player then return end
local cursor = player.cursor_stack
if global.is_player_cursor_blueprint[i] then
--TODO: check if we can limit this search somehow?
for id, comb in pairs(global.to_comb) do
on_combinator_updated(global, comb, get_comb_params(comb))
end
end
local contains_comb = nil
if cursor and cursor.valid_for_read and cursor.type == "blueprint" then
local cost_to_build = cursor.cost_to_build
for k, v in pairs(cost_to_build) do
if k == COMBINATOR_NAME then
contains_comb = true
break
end
end
end
global.is_player_cursor_blueprint[i] = contains_comb
end
local function on_settings_changed(event)
mod_settings.tps = settings.global["cybersyn-ticks-per-second"].value --[[@as int]]
@@ -907,8 +885,7 @@ local function main()
flib_event.register({defines.events.on_pre_surface_deleted, defines.events.on_pre_surface_cleared}, on_surface_removed)
--flib_event.register(defines.events.on_entity_settings_pasted, on_paste)
--flib_event.register(defines.events.on_player_cursor_stack_changed, on_cursor_stack_changed)
flib_event.register(defines.events.on_entity_settings_pasted, on_paste)
local nth_tick = math.ceil(60/mod_settings.tps);
flib_event.on_nth_tick(nth_tick, function()
@@ -939,7 +916,6 @@ local function main()
---@type MapData
local map_data = global
local old_id = event.old_train_id_1
local old_surface_index = event.old_surface_index
--NOTE: this is not guaranteed to be unique, it should be fine since the window of time for another train to mistakenly steal this train's event data is miniscule
--NOTE: please SE dev if you read this fix the issue where se_on_train_teleport_finished_event is returning the wrong old train id
local train_unique_identifier = event.train.front_stock.backer_name

View File

@@ -2,20 +2,6 @@ local flib_migration = require("__flib__.migration")
local migrations_table = {
["0.2.0"] = function()
---@type MapData
local map_data = global
map_data.tick_state = STATE_INIT
map_data.all_station_ids = {}
for id, station in pairs(map_data.stations) do
station.p_count_or_r_threshold_per_item = {}
station.p_threshold = nil
station.is_all = nil
set_station_from_comb_state(station)
set_combinator_operation(station.entity_comb1, OPERATION_PRIMARY_IO)
map_data.all_station_ids[#map_data.all_station_ids + 1] = id
end
end,
["0.2.1"] = function()
---@type MapData
local map_data = global
@@ -106,6 +92,28 @@ local migrations_table = {
end
map_data.layouts[id] = new_layout
end
end,
["0.5.1"] = function()
---@type MapData
local map_data = global
map_data.tick_state = STATE_INIT
map_data.is_player_cursor_blueprint = nil
for id, layout in pairs(map_data.layouts) do
local new_layout = {}
local max_i = 0
for i, v in pairs(layout) do
new_layout[i] = v
if i > max_i then
max_i = i
end
end
for i = 1, max_i do
if new_layout[i] == nil then
new_layout[i] = 0
end
end
map_data.layouts[id] = new_layout
end
for id, station in pairs(map_data.stations) do
reset_station_layout(map_data, station)
end