mirror of
https://github.com/Xevion/project-cybersyn.git
synced 2025-12-15 16:12:41 -06:00
1.2.8 (#28)
Version: 1.2.8
Date: 2022-1-5
Features:
- Improved placeholder cybernetic combinator art
- Added a wagon control setting to bar unfiltered slots in adjacent cargo wagons
- Added a setting and keybind for toggling on or off the central planner
Changes:
- Sped up the rate at which copy-paste by blueprint will be noticed
Bugfixes:
- Fixed a bug with combinators sometimes failing to connect with train stops
- Fixed wagon control combinators outputting wagon contents after inserters have already taken out items
- Fixed a rare crash on world migration
Scripting:
- Added missing return values to some interface functions
- Migrated to non-deprecated flib modules
This commit is contained in:
@@ -47,66 +47,66 @@ function create_delivery(map_data, r_station_id, p_station_id, train_id, manifes
|
||||
--NOTE: we assume that the train is not being teleported at this time
|
||||
--NOTE: set_manifest_schedule is allowed to cancel the delivery at the last second if applying the schedule to the train makes it lost
|
||||
if set_manifest_schedule(map_data, train.entity, depot.entity_stop, not train.use_any_depot, p_station.entity_stop, p_station.enable_inactive, r_station.entity_stop, mod_settings.allow_cargo_in_depot and r_station.enable_inactive--[[@as boolean]], manifest, is_at_depot) then
|
||||
local old_status = train.status
|
||||
train.status = STATUS_TO_P
|
||||
train.p_station_id = p_station_id
|
||||
train.r_station_id = r_station_id
|
||||
train.manifest = manifest
|
||||
train.last_manifest_tick = map_data.total_ticks
|
||||
local old_status = train.status
|
||||
train.status = STATUS_TO_P
|
||||
train.p_station_id = p_station_id
|
||||
train.r_station_id = r_station_id
|
||||
train.manifest = manifest
|
||||
train.last_manifest_tick = map_data.total_ticks
|
||||
|
||||
r_station.last_delivery_tick = map_data.total_ticks
|
||||
p_station.last_delivery_tick = map_data.total_ticks
|
||||
r_station.last_delivery_tick = map_data.total_ticks
|
||||
p_station.last_delivery_tick = map_data.total_ticks
|
||||
|
||||
r_station.deliveries_total = r_station.deliveries_total + 1
|
||||
p_station.deliveries_total = p_station.deliveries_total + 1
|
||||
r_station.deliveries_total = r_station.deliveries_total + 1
|
||||
p_station.deliveries_total = p_station.deliveries_total + 1
|
||||
|
||||
local r_is_each = r_station.network_name == NETWORK_EACH
|
||||
local p_is_each = p_station.network_name == NETWORK_EACH
|
||||
for item_i, item in ipairs(manifest) do
|
||||
assert(item.count > 0, "main.lua error, transfer amount was not positive")
|
||||
local r_is_each = r_station.network_name == NETWORK_EACH
|
||||
local p_is_each = p_station.network_name == NETWORK_EACH
|
||||
for item_i, item in ipairs(manifest) do
|
||||
assert(item.count > 0, "main.lua error, transfer amount was not positive")
|
||||
|
||||
r_station.deliveries[item.name] = (r_station.deliveries[item.name] or 0) + item.count
|
||||
p_station.deliveries[item.name] = (p_station.deliveries[item.name] or 0) - item.count
|
||||
r_station.deliveries[item.name] = (r_station.deliveries[item.name] or 0) + item.count
|
||||
p_station.deliveries[item.name] = (p_station.deliveries[item.name] or 0) - item.count
|
||||
|
||||
if item_i > 1 or r_is_each or p_is_each then
|
||||
local f, a
|
||||
if r_is_each then
|
||||
f, a = pairs(r_station.network_flag--[[@as {[string]: int}]])
|
||||
if p_is_each then
|
||||
for network_name, _ in f, a do
|
||||
local item_network_name = network_name..":"..item.name
|
||||
economy.all_r_stations[item_network_name] = nil
|
||||
economy.all_p_stations[item_network_name] = nil
|
||||
end
|
||||
f, a = pairs(p_station.network_flag--[[@as {[string]: int}]])
|
||||
if item_i > 1 or r_is_each or p_is_each then
|
||||
local f, a
|
||||
if r_is_each then
|
||||
f, a = pairs(r_station.network_flag--[[@as {[string]: int}]])
|
||||
if p_is_each then
|
||||
for network_name, _ in f, a do
|
||||
local item_network_name = network_name..":"..item.name
|
||||
economy.all_r_stations[item_network_name] = nil
|
||||
economy.all_p_stations[item_network_name] = nil
|
||||
end
|
||||
elseif p_is_each then
|
||||
f, a = pairs(p_station.network_flag--[[@as {[string]: int}]])
|
||||
else
|
||||
f, a = once, r_station.network_name
|
||||
end
|
||||
--prevent deliveries from being processed for these items until their stations are re-polled
|
||||
--if we don't wait until they are repolled a duplicate delivery might be generated for stations that share inventories
|
||||
for network_name, _ in f, a do
|
||||
local item_network_name = network_name..":"..item.name
|
||||
economy.all_r_stations[item_network_name] = nil
|
||||
economy.all_p_stations[item_network_name] = nil
|
||||
end
|
||||
elseif p_is_each then
|
||||
f, a = pairs(p_station.network_flag--[[@as {[string]: int}]])
|
||||
else
|
||||
f, a = once, r_station.network_name
|
||||
end
|
||||
--prevent deliveries from being processed for these items until their stations are re-polled
|
||||
--if we don't wait until they are repolled a duplicate delivery might be generated for stations that share inventories
|
||||
for network_name, _ in f, a do
|
||||
local item_network_name = network_name..":"..item.name
|
||||
economy.all_r_stations[item_network_name] = nil
|
||||
economy.all_p_stations[item_network_name] = nil
|
||||
end
|
||||
end
|
||||
|
||||
set_comb2(map_data, p_station)
|
||||
set_comb2(map_data, r_station)
|
||||
|
||||
p_station.display_state = 1
|
||||
update_display(map_data, p_station)
|
||||
r_station.display_state = 1
|
||||
update_display(map_data, r_station)
|
||||
|
||||
interface_raise_train_status_changed(train_id, old_status, STATUS_TO_P)
|
||||
else
|
||||
interface_raise_train_dispatch_failed(train_id)
|
||||
end
|
||||
|
||||
set_comb2(map_data, p_station)
|
||||
set_comb2(map_data, r_station)
|
||||
|
||||
p_station.display_state = 1
|
||||
update_display(map_data, p_station)
|
||||
r_station.display_state = 1
|
||||
update_display(map_data, r_station)
|
||||
|
||||
interface_raise_train_status_changed(train_id, old_status, STATUS_TO_P)
|
||||
else
|
||||
interface_raise_train_dispatch_failed(train_id)
|
||||
end
|
||||
end
|
||||
---@param map_data MapData
|
||||
---@param r_station_id uint
|
||||
@@ -654,9 +654,39 @@ local function tick_poll_station(map_data, mod_settings)
|
||||
end
|
||||
---@param map_data MapData
|
||||
---@param mod_settings CybersynModSettings
|
||||
function tick_init(map_data, mod_settings)
|
||||
function tick_poll_entities(map_data, mod_settings)
|
||||
local tick_data = map_data.tick_data
|
||||
|
||||
--NOTE: the following have undefined behaviour if the item on tick_data is deleted
|
||||
if map_data.total_ticks%5 == 0 then
|
||||
local train_id, train = next(map_data.trains, tick_data.last_train)
|
||||
tick_data.last_train = train_id
|
||||
if train then
|
||||
if train.manifest and not train.se_is_being_teleported and train.last_manifest_tick + mod_settings.stuck_train_time*mod_settings.tps < map_data.total_ticks then
|
||||
if mod_settings.stuck_train_alert_enabled then
|
||||
send_alert_stuck_train(map_data, train.entity)
|
||||
end
|
||||
interface_raise_train_stuck(train_id)
|
||||
end
|
||||
end
|
||||
|
||||
local refueler_id, _ = next(map_data.each_refuelers, tick_data.last_refueler)
|
||||
tick_data.last_refueler = refueler_id
|
||||
if refueler_id then
|
||||
set_refueler_from_comb(map_data, mod_settings, refueler_id)
|
||||
end
|
||||
else
|
||||
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, true)
|
||||
end
|
||||
end
|
||||
end
|
||||
---@param map_data MapData
|
||||
---@param mod_settings CybersynModSettings
|
||||
function tick_init(map_data, mod_settings)
|
||||
|
||||
map_data.economy.all_p_stations = {}
|
||||
map_data.economy.all_r_stations = {}
|
||||
map_data.economy.all_names = {}
|
||||
@@ -667,6 +697,7 @@ function tick_init(map_data, mod_settings)
|
||||
if station.last_delivery_tick + mod_settings.warmup_time*mod_settings.tps < map_data.total_ticks then
|
||||
map_data.active_station_ids[#map_data.active_station_ids + 1] = id
|
||||
map_data.warmup_station_ids[i] = nil
|
||||
combinator_update(map_data, station.entity_comb1)
|
||||
end
|
||||
else
|
||||
map_data.warmup_station_ids[i] = nil
|
||||
@@ -686,30 +717,6 @@ function tick_init(map_data, mod_settings)
|
||||
map_data.queue_station_update = nil
|
||||
end
|
||||
|
||||
--NOTE: the following has undefined behavior if last_train is deleted, this should be ok since the following doesn't care how inconsistent our access pattern is
|
||||
local train_id, train = next(map_data.trains, tick_data.last_train)
|
||||
tick_data.last_train = train_id
|
||||
|
||||
if train and train.manifest and not train.se_is_being_teleported and train.last_manifest_tick + mod_settings.stuck_train_time*mod_settings.tps < map_data.total_ticks then
|
||||
if mod_settings.stuck_train_alert_enabled then
|
||||
send_alert_stuck_train(map_data, train.entity)
|
||||
end
|
||||
interface_raise_train_stuck(train_id)
|
||||
end
|
||||
|
||||
--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
|
||||
local refueler_id, _ = next(map_data.each_refuelers, tick_data.last_refueler)
|
||||
tick_data.last_refueler = refueler_id
|
||||
|
||||
if comb and comb.valid then
|
||||
combinator_update(map_data, comb, true)
|
||||
end
|
||||
if refueler_id then
|
||||
set_refueler_from_comb(map_data, mod_settings, refueler_id)
|
||||
end
|
||||
|
||||
map_data.tick_state = STATE_POLL_STATIONS
|
||||
interface_raise_tick_init()
|
||||
end
|
||||
@@ -718,21 +725,30 @@ end
|
||||
function tick(map_data, mod_settings)
|
||||
map_data.total_ticks = map_data.total_ticks + 1
|
||||
|
||||
|
||||
if map_data.active_alerts then
|
||||
if map_data.total_ticks%(8*mod_settings.tps) < 1 then
|
||||
process_active_alerts(map_data)
|
||||
end
|
||||
end
|
||||
|
||||
if map_data.tick_state == STATE_INIT then
|
||||
tick_init(map_data, mod_settings)
|
||||
elseif map_data.tick_state == STATE_POLL_STATIONS then
|
||||
for i = 1, mod_settings.update_rate do
|
||||
if tick_poll_station(map_data, mod_settings) then break end
|
||||
tick_poll_entities(map_data, mod_settings)
|
||||
|
||||
if mod_settings.enable_planner then
|
||||
if map_data.tick_state == STATE_INIT then
|
||||
tick_init(map_data, mod_settings)
|
||||
end
|
||||
elseif map_data.tick_state == STATE_DISPATCH then
|
||||
for i = 1, mod_settings.update_rate do
|
||||
tick_dispatch(map_data, mod_settings)
|
||||
|
||||
if map_data.tick_state == STATE_POLL_STATIONS then
|
||||
for i = 1, mod_settings.update_rate do
|
||||
if tick_poll_station(map_data, mod_settings) then break end
|
||||
end
|
||||
elseif map_data.tick_state == STATE_DISPATCH then
|
||||
for i = 1, mod_settings.update_rate do
|
||||
tick_dispatch(map_data, mod_settings)
|
||||
end
|
||||
end
|
||||
else
|
||||
map_data.tick_state = STATE_INIT
|
||||
end
|
||||
end
|
||||
|
||||
@@ -27,6 +27,7 @@ SETTING_IS_STACK = 3
|
||||
SETTING_ENABLE_INACTIVE = 4
|
||||
SETTING_USE_ANY_DEPOT = 5
|
||||
SETTING_DISABLE_DEPOT_BYPASS = 6
|
||||
SETTING_ENABLE_SLOT_BARRING = 7
|
||||
|
||||
NETWORK_SIGNAL_DEFAULT = {name="signal-A", type="virtual"}
|
||||
NETWORK_EACH = "signal-each"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
--By Mami
|
||||
local get_distance = require("__flib__.misc").get_distance
|
||||
local get_distance = require("__flib__.position").distance
|
||||
local table_insert = table.insert
|
||||
local bit_extract = bit32.extract
|
||||
local bit_replace = bit32.replace
|
||||
@@ -21,7 +21,7 @@ end
|
||||
function get_stop_dist(entity0, entity1)
|
||||
local surface0 = entity0.surface.index
|
||||
local surface1 = entity1.surface.index
|
||||
return (surface0 == surface1 and get_distance(entity0.position, entity1.position) or DIFFERENT_SURFACE_DISTANCE)--[[@as number]]
|
||||
return (surface0 == surface1 and get_distance(entity0.position, entity1.position) or DIFFERENT_SURFACE_DISTANCE)
|
||||
end
|
||||
|
||||
|
||||
@@ -566,7 +566,7 @@ function get_comb_gui_settings(comb)
|
||||
elseif op == MODE_WAGON then
|
||||
selected_index = 5
|
||||
end
|
||||
return selected_index, params.first_signal, switch_state, bits
|
||||
return selected_index--[[@as uint]], params.first_signal, switch_state, bits
|
||||
end
|
||||
---@param comb LuaEntity
|
||||
---@param is_pr_state 0|1|2
|
||||
|
||||
@@ -104,6 +104,7 @@
|
||||
--NOTE: any setting labeled as an "interface setting" can only be changed through the remote-interface, these settings are not save and have to be set at initialization
|
||||
--As a modder using the remote-interface, you may override any of these settings, including user settings. They will have to be overriden at initialization and whenever a user tries to change one.
|
||||
---@class CybersynModSettings
|
||||
---@field public enable_planner boolean
|
||||
---@field public tps double
|
||||
---@field public update_rate int
|
||||
---@field public r_threshold int
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
--By Mami
|
||||
local flib_gui = require("__flib__.gui")
|
||||
local flib_event = require("__flib__.event")
|
||||
local flib_gui = require("__flib__.gui-lite")
|
||||
|
||||
local RED = "utility/status_not_working"
|
||||
local GREEN = "utility/status_working"
|
||||
@@ -41,6 +40,7 @@ end
|
||||
local function set_visibility(main_window, selected_index)
|
||||
local is_station = selected_index == 1
|
||||
local is_depot = selected_index == 2
|
||||
local is_wagon = selected_index == 5
|
||||
local uses_network = is_station or is_depot or selected_index == 3
|
||||
local uses_allow_list = is_station or selected_index == 3
|
||||
|
||||
@@ -56,107 +56,107 @@ local function set_visibility(main_window, selected_index)
|
||||
first_settings.allow_list.visible = uses_allow_list
|
||||
first_settings.is_stack.visible = is_station
|
||||
bottom_flow.enable_inactive.visible = is_station
|
||||
top_flow.enable_slot_barring.visible = is_wagon
|
||||
depot_settings.visible = is_depot
|
||||
end
|
||||
|
||||
---@param comb LuaEntity
|
||||
---@param player LuaPlayer
|
||||
function gui_opened(comb, player)
|
||||
combinator_update(global, comb, true)
|
||||
|
||||
---@param e EventData.on_gui_click
|
||||
local function handle_close(e)
|
||||
local element = e.element
|
||||
if not element then return end
|
||||
local comb = global.to_comb[element.tags.id]
|
||||
if not comb or not comb.valid then return end
|
||||
local player = game.get_player(e.player_index)
|
||||
if not player then return end
|
||||
local rootgui = player.gui.screen
|
||||
local selected_index, signal, switch_state, bits = get_comb_gui_settings(comb)
|
||||
|
||||
local window = flib_gui.build(rootgui, {
|
||||
{type="frame", direction="vertical", ref={"main_window"}, name=COMBINATOR_NAME, 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 = {"close", comb.unit_number}
|
||||
}}
|
||||
}},
|
||||
{type="frame", name="frame", style="inside_shallow_frame_with_padding", style_mods={padding=12, bottom_padding=9}, children={
|
||||
{type="flow", name="vflow", direction="vertical", style_mods={horizontal_align="left"}, children={
|
||||
--status
|
||||
{type="flow", style="status_flow", direction="horizontal", style_mods={vertical_align="center", horizontally_stretchable=true, bottom_padding=4}, children={
|
||||
{type="sprite", sprite=STATUS_SPRITES[comb.status] or STATUS_SPRITES_DEFAULT, style="status_image", style_mods={stretch_image_to_widget_size=true}},
|
||||
{type="label", caption={STATUS_NAMES[comb.status] or STATUS_NAMES_DEFAULT}}
|
||||
}},
|
||||
--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"}},
|
||||
}},
|
||||
--drop down
|
||||
{type="label", style="heading_3_label", caption={"cybersyn-gui.operation"}, style_mods={top_padding=8}},
|
||||
{type="flow", name="top", direction="horizontal", style_mods={vertical_align="center"}, children={
|
||||
{type="drop-down", style_mods={top_padding=3, right_margin=8}, ref={"operation"}, actions={
|
||||
on_selection_state_changed={"drop-down", comb.unit_number}
|
||||
}, selected_index=selected_index, items={
|
||||
{"cybersyn-gui.comb1"},
|
||||
{"cybersyn-gui.depot"},
|
||||
{"cybersyn-gui.refueler"},
|
||||
{"cybersyn-gui.comb2"},
|
||||
{"cybersyn-gui.wagon-manifest"},
|
||||
}},
|
||||
{type="switch", name="is_pr_switch", ref={"is_pr_switch"}, allow_none_state=true, switch_state=switch_state, left_label_caption={"cybersyn-gui.switch-provide"}, right_label_caption={"cybersyn-gui.switch-request"}, left_label_tooltip={"cybersyn-gui.switch-provide-tooltip"}, right_label_tooltip={"cybersyn-gui.switch-request-tooltip"}, actions={
|
||||
on_switch_state_changed={"is_pr_switch", comb.unit_number}
|
||||
}}
|
||||
}},
|
||||
---choose-elem-button
|
||||
{type="line", style_mods={top_padding=10}},
|
||||
{type="label", name="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="top"}, children={
|
||||
{type="choose-elem-button", name="network", style="slot_button_in_shallow_frame", elem_type="signal", tooltip={"cybersyn-gui.network-tooltip"}, signal=signal, style_mods={bottom_margin=1, right_margin=6, top_margin=2}, actions={
|
||||
on_elem_changed={"choose-elem-button", comb.unit_number}
|
||||
}},
|
||||
{type="flow", name="depot", direction="vertical", style_mods={horizontal_align="left"}, children={
|
||||
{type="flow", name="use_any_depot", direction="horizontal", style_mods={vertical_align="center"}, children={
|
||||
{type="checkbox", name="use_same_depot", state=setting_flip(bits, SETTING_USE_ANY_DEPOT), tooltip={"cybersyn-gui.use-same-depot-tooltip"}, actions={
|
||||
on_checked_state_changed={"setting-flip", comb.unit_number, SETTING_USE_ANY_DEPOT}
|
||||
}},
|
||||
{type="label", name="use_same_depot_label", style_mods={left_padding=3}, caption={"cybersyn-gui.use-same-depot-description"}},
|
||||
}},
|
||||
{type="flow", name="depot_bypass", direction="horizontal", style_mods={vertical_align="center"}, children={
|
||||
{type="checkbox", name="depot_bypass", state=setting_flip(bits, SETTING_DISABLE_DEPOT_BYPASS), tooltip={"cybersyn-gui.depot-bypass-tooltip"}, actions={
|
||||
on_checked_state_changed={"setting-flip", comb.unit_number, SETTING_DISABLE_DEPOT_BYPASS}
|
||||
}},
|
||||
{type="label", name="depot_bypass_label", style_mods={left_padding=3}, caption={"cybersyn-gui.depot-bypass-description"}},
|
||||
}},
|
||||
}},
|
||||
{type="flow", name="first", direction="vertical", style_mods={horizontal_align="left", right_margin=8}, children={
|
||||
{type="flow", name="allow_list", direction="horizontal", style_mods={vertical_align="center"}, children={
|
||||
{type="checkbox", name="allow_list", state=setting_flip(bits, SETTING_DISABLE_ALLOW_LIST), tooltip={"cybersyn-gui.allow-list-tooltip"}, actions={
|
||||
on_checked_state_changed={"setting-flip", comb.unit_number, SETTING_DISABLE_ALLOW_LIST}
|
||||
}},
|
||||
{type="label", name="allow_list_label", style_mods={left_padding=3}, caption={"cybersyn-gui.allow-list-description"}},
|
||||
}},
|
||||
{type="flow", name="is_stack", direction="horizontal", style_mods={vertical_align="center"}, children={
|
||||
{type="checkbox", name="is_stack", state=setting(bits, SETTING_IS_STACK), tooltip={"cybersyn-gui.is-stack-tooltip"}, actions={
|
||||
on_checked_state_changed={"setting", comb.unit_number, SETTING_IS_STACK}
|
||||
}},
|
||||
{type="label", name="is_stack_label", style_mods={left_padding=3}, caption={"cybersyn-gui.is-stack-description"}},
|
||||
}},
|
||||
}},
|
||||
{type="flow", name="enable_inactive", direction="horizontal", style_mods={vertical_align="center"}, children={
|
||||
{type="checkbox", name="enable_inactive", state=setting(bits, SETTING_ENABLE_INACTIVE), tooltip={"cybersyn-gui.enable-inactive-tooltip"}, actions={
|
||||
on_checked_state_changed={"setting", comb.unit_number, SETTING_ENABLE_INACTIVE}
|
||||
}},
|
||||
{type="label", name="enable_inactive_label", style_mods={left_padding=3}, caption={"cybersyn-gui.enable-inactive-description"}},
|
||||
}},
|
||||
}}
|
||||
}}
|
||||
}}
|
||||
}}
|
||||
})
|
||||
if rootgui[COMBINATOR_NAME] then
|
||||
rootgui[COMBINATOR_NAME].destroy()
|
||||
player.play_sound({path = COMBINATOR_CLOSE_SOUND})
|
||||
end
|
||||
end
|
||||
---@param e EventData.on_gui_selection_state_changed
|
||||
local function handle_drop_down(e)
|
||||
local element = e.element
|
||||
if not element then return end
|
||||
local comb = global.to_comb[element.tags.id]
|
||||
if not comb or not comb.valid then return end
|
||||
|
||||
window.preview.entity = comb
|
||||
window.titlebar.drag_target = window.main_window
|
||||
window.main_window.force_auto_center()
|
||||
set_visibility(element.parent.parent.parent.parent, element.selected_index)
|
||||
|
||||
set_visibility(window.main_window, selected_index)
|
||||
player.opened = window.main_window
|
||||
if element.selected_index == 1 then
|
||||
set_comb_operation(comb, MODE_PRIMARY_IO)
|
||||
elseif element.selected_index == 2 then
|
||||
set_comb_operation(comb, MODE_DEPOT)
|
||||
--prevent the use of the each signal with depots
|
||||
local network = element.parent.parent.bottom.network--[[@as LuaGuiElement]]
|
||||
local signal = network.elem_value--[[@as SignalID]]
|
||||
if signal.name == NETWORK_EACH then
|
||||
network.elem_value = nil
|
||||
set_comb_network_name(comb, nil)
|
||||
end
|
||||
elseif element.selected_index == 3 then
|
||||
set_comb_operation(comb, MODE_REFUELER)
|
||||
elseif element.selected_index == 4 then
|
||||
set_comb_operation(comb, MODE_SECONDARY_IO)
|
||||
elseif element.selected_index == 5 then
|
||||
set_comb_operation(comb, MODE_WAGON)
|
||||
else
|
||||
return
|
||||
end
|
||||
|
||||
combinator_update(global, comb)
|
||||
end
|
||||
---@param e EventData.on_gui_switch_state_changed
|
||||
local function handle_pr_switch(e)
|
||||
local element = e.element
|
||||
if not element then return end
|
||||
local comb = global.to_comb[element.tags.id]
|
||||
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
|
||||
set_comb_is_pr_state(comb, is_pr_state)
|
||||
|
||||
combinator_update(global, comb)
|
||||
end
|
||||
---@param e EventData.on_gui_elem_changed
|
||||
local function handle_network(e)
|
||||
local element = e.element
|
||||
if not element then return end
|
||||
local comb = global.to_comb[element.tags.id]
|
||||
if not comb or not comb.valid then return end
|
||||
|
||||
local signal = element.elem_value--[[@as SignalID]]
|
||||
if signal and (signal.name == "signal-everything" or signal.name == "signal-anything" or signal.name == "signal-each") then
|
||||
signal.name = NETWORK_EACH
|
||||
element.elem_value = signal
|
||||
end
|
||||
set_comb_network_name(comb, signal)
|
||||
|
||||
combinator_update(global, comb)
|
||||
end
|
||||
---@param e EventData.on_gui_checked_state_changed
|
||||
local function handle_setting(e)
|
||||
local element = e.element
|
||||
if not element then return end
|
||||
local comb = global.to_comb[element.tags.id]
|
||||
if not comb or not comb.valid then return end
|
||||
|
||||
set_comb_setting(comb, element.tags.bit--[[@as int]], element.state)
|
||||
|
||||
combinator_update(global, comb)
|
||||
end
|
||||
---@param e EventData.on_gui_checked_state_changed
|
||||
local function handle_setting_flip(e)
|
||||
local element = e.element
|
||||
if not element then return end
|
||||
local comb = global.to_comb[element.tags.id]
|
||||
if not comb or not comb.valid then return end
|
||||
|
||||
set_comb_setting(comb, element.tags.bit--[[@as int]], not element.state)
|
||||
|
||||
combinator_update(global, comb)
|
||||
end
|
||||
|
||||
local function on_gui_opened(event)
|
||||
@@ -180,94 +180,103 @@ local function on_gui_closed(event)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function register_gui_actions()
|
||||
flib_gui.hook_events(function(event)
|
||||
local msg = flib_gui.read_action(event)
|
||||
if msg then
|
||||
local player = game.get_player(event.player_index)
|
||||
if not player then return end
|
||||
local rootgui = player.gui.screen
|
||||
-- read the action to determine what to do
|
||||
if msg[1] == "close" then
|
||||
if rootgui[COMBINATOR_NAME] then
|
||||
rootgui[COMBINATOR_NAME].destroy()
|
||||
player.play_sound({path = COMBINATOR_CLOSE_SOUND})
|
||||
end
|
||||
elseif msg[1] == "drop-down" then
|
||||
local element = event.element
|
||||
if not element then return end
|
||||
local comb = global.to_comb[msg[2]]
|
||||
if not comb or not comb.valid then return end
|
||||
|
||||
set_visibility(rootgui[COMBINATOR_NAME], element.selected_index)
|
||||
|
||||
if element.selected_index == 1 then
|
||||
set_comb_operation(comb, MODE_PRIMARY_IO)
|
||||
elseif element.selected_index == 2 then
|
||||
set_comb_operation(comb, MODE_DEPOT)
|
||||
--prevent the use of the each signal with depots
|
||||
local network = element.parent.parent.bottom.network
|
||||
local signal = network.elem_value
|
||||
if signal.name == NETWORK_EACH then
|
||||
network.elem_value = nil
|
||||
set_comb_network_name(comb, nil)
|
||||
end
|
||||
elseif element.selected_index == 3 then
|
||||
set_comb_operation(comb, MODE_REFUELER)
|
||||
elseif element.selected_index == 4 then
|
||||
set_comb_operation(comb, MODE_SECONDARY_IO)
|
||||
elseif element.selected_index == 5 then
|
||||
set_comb_operation(comb, MODE_WAGON)
|
||||
else
|
||||
return
|
||||
end
|
||||
|
||||
combinator_update(global, comb)
|
||||
elseif msg[1] == "choose-elem-button" then
|
||||
local element = event.element
|
||||
if not element then return end
|
||||
local comb = global.to_comb[msg[2]]
|
||||
if not comb or not comb.valid then return end
|
||||
|
||||
local signal = element.elem_value
|
||||
if signal and (signal.name == "signal-everything" or signal.name == "signal-anything" or signal.name == "signal-each") then
|
||||
signal.name = NETWORK_EACH
|
||||
element.elem_value = signal
|
||||
end
|
||||
set_comb_network_name(comb, signal)
|
||||
|
||||
combinator_update(global, comb)
|
||||
elseif msg[1] == "setting" then
|
||||
local element = event.element
|
||||
if not element then return end
|
||||
local comb = global.to_comb[msg[2]]
|
||||
if not comb or not comb.valid then return end
|
||||
|
||||
set_comb_setting(comb, msg[3], element.state)
|
||||
|
||||
combinator_update(global, comb)
|
||||
elseif msg[1] == "setting-flip" then
|
||||
local element = event.element
|
||||
if not element then return end
|
||||
local comb = global.to_comb[msg[2]]
|
||||
if not comb or not comb.valid then return end
|
||||
|
||||
set_comb_setting(comb, msg[3], not element.state)
|
||||
|
||||
combinator_update(global, comb)
|
||||
elseif msg[1] == "is_pr_switch" then
|
||||
local element = event.element
|
||||
if not element then return end
|
||||
local comb = global.to_comb[msg[2]]
|
||||
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
|
||||
set_comb_is_pr_state(comb, is_pr_state)
|
||||
|
||||
combinator_update(global, comb)
|
||||
end
|
||||
end
|
||||
end)
|
||||
flib_event.register(defines.events.on_gui_opened, on_gui_opened)
|
||||
flib_event.register(defines.events.on_gui_closed, on_gui_closed)
|
||||
flib_gui.add_handlers({
|
||||
["close"] = handle_close,
|
||||
["drop_down"] = handle_drop_down,
|
||||
["pr_switch"] = handle_pr_switch,
|
||||
["network"] = handle_network,
|
||||
["setting"] = handle_setting,
|
||||
["setting_flip"] = handle_setting_flip,
|
||||
})
|
||||
script.on_event(defines.events.on_gui_opened, on_gui_opened)
|
||||
script.on_event(defines.events.on_gui_closed, on_gui_closed)
|
||||
flib_gui.handle_events()
|
||||
end
|
||||
|
||||
---@param comb LuaEntity
|
||||
---@param player LuaPlayer
|
||||
function gui_opened(comb, player)
|
||||
combinator_update(global, comb, true)
|
||||
|
||||
local rootgui = player.gui.screen
|
||||
local selected_index, signal, switch_state, bits = get_comb_gui_settings(comb)
|
||||
|
||||
local _, main_window = flib_gui.add(rootgui, {
|
||||
{type="frame", direction="vertical", name=COMBINATOR_NAME, children={
|
||||
--title bar
|
||||
{type="flow", name="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, handler=handle_close, tags={id=comb.unit_number}}
|
||||
}},
|
||||
{type="frame", name="frame", style="inside_shallow_frame_with_padding", style_mods={padding=12, bottom_padding=9}, children={
|
||||
{type="flow", name="vflow", direction="vertical", style_mods={horizontal_align="left"}, children={
|
||||
--status
|
||||
{type="flow", style="status_flow", direction="horizontal", style_mods={vertical_align="center", horizontally_stretchable=true, bottom_padding=4}, children={
|
||||
{type="sprite", sprite=STATUS_SPRITES[comb.status] or STATUS_SPRITES_DEFAULT, style="status_image", style_mods={stretch_image_to_widget_size=true}},
|
||||
{type="label", caption={STATUS_NAMES[comb.status] or STATUS_NAMES_DEFAULT}}
|
||||
}},
|
||||
--preview
|
||||
{type="frame", name="preview_frame", style="deep_frame_in_shallow_frame", style_mods={minimal_width=0, horizontally_stretchable=true, padding=0}, children={
|
||||
{type="entity-preview", name="preview", style="wide_entity_button"},
|
||||
}},
|
||||
--drop down
|
||||
{type="label", style="heading_3_label", caption={"cybersyn-gui.operation"}, style_mods={top_padding=8}},
|
||||
{type="flow", name="top", direction="horizontal", style_mods={vertical_align="center"}, children={
|
||||
{type="drop-down", style_mods={top_padding=3, right_margin=8}, handler=handle_drop_down, tags={id=comb.unit_number}, selected_index=selected_index, items={
|
||||
{"cybersyn-gui.comb1"},
|
||||
{"cybersyn-gui.depot"},
|
||||
{"cybersyn-gui.refueler"},
|
||||
{"cybersyn-gui.comb2"},
|
||||
{"cybersyn-gui.wagon-manifest"},
|
||||
}},
|
||||
{type="switch", name="is_pr_switch", allow_none_state=true, switch_state=switch_state, left_label_caption={"cybersyn-gui.switch-provide"}, right_label_caption={"cybersyn-gui.switch-request"}, left_label_tooltip={"cybersyn-gui.switch-provide-tooltip"}, right_label_tooltip={"cybersyn-gui.switch-request-tooltip"}, handler=handle_pr_switch, tags={id=comb.unit_number}},
|
||||
{type="flow", name="enable_slot_barring", direction="horizontal", style_mods={vertical_align="center", left_padding=6}, children={
|
||||
{type="checkbox", name="enable_slot_barring", state=setting(bits, SETTING_ENABLE_SLOT_BARRING), handler=handle_setting, tags={id=comb.unit_number, bit=SETTING_ENABLE_SLOT_BARRING}, tooltip={"cybersyn-gui.enable-slot-barring-tooltip"}},
|
||||
{type="label", name="enable_slot_barring_label", style_mods={left_padding=3}, caption={"cybersyn-gui.enable-slot-barring-description"}},
|
||||
}},
|
||||
}},
|
||||
---choose-elem-button
|
||||
{type="line", style_mods={top_padding=10}},
|
||||
{type="label", name="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="top"}, children={
|
||||
{type="choose-elem-button", name="network", style="slot_button_in_shallow_frame", elem_type="signal", tooltip={"cybersyn-gui.network-tooltip"}, signal=signal, style_mods={bottom_margin=1, right_margin=6, top_margin=2}, handler=handle_network, tags={id=comb.unit_number}},
|
||||
{type="flow", name="depot", direction="vertical", style_mods={horizontal_align="left"}, children={
|
||||
{type="flow", name="use_any_depot", direction="horizontal", style_mods={vertical_align="center"}, children={
|
||||
{type="checkbox", name="use_same_depot", state=setting_flip(bits, SETTING_USE_ANY_DEPOT), handler=handle_setting_flip, tags={id=comb.unit_number, bit=SETTING_USE_ANY_DEPOT}, tooltip={"cybersyn-gui.use-same-depot-tooltip"}},
|
||||
{type="label", name="use_same_depot_label", style_mods={left_padding=3}, caption={"cybersyn-gui.use-same-depot-description"}},
|
||||
}},
|
||||
{type="flow", name="depot_bypass", direction="horizontal", style_mods={vertical_align="center"}, children={
|
||||
{type="checkbox", name="depot_bypass", state=setting_flip(bits, SETTING_DISABLE_DEPOT_BYPASS), handler=handle_setting_flip, tags={id=comb.unit_number, bit=SETTING_DISABLE_DEPOT_BYPASS}, tooltip={"cybersyn-gui.depot-bypass-tooltip"}},
|
||||
{type="label", name="depot_bypass_label", style_mods={left_padding=3}, caption={"cybersyn-gui.depot-bypass-description"}},
|
||||
}},
|
||||
}},
|
||||
{type="flow", name="first", direction="vertical", style_mods={horizontal_align="left", right_margin=8}, children={
|
||||
{type="flow", name="allow_list", direction="horizontal", style_mods={vertical_align="center"}, children={
|
||||
{type="checkbox", name="allow_list", state=setting_flip(bits, SETTING_DISABLE_ALLOW_LIST), handler=handle_setting_flip, tags={id=comb.unit_number, bit=SETTING_DISABLE_ALLOW_LIST}, tooltip={"cybersyn-gui.allow-list-tooltip"}},
|
||||
{type="label", name="allow_list_label", style_mods={left_padding=3}, caption={"cybersyn-gui.allow-list-description"}},
|
||||
}},
|
||||
{type="flow", name="is_stack", direction="horizontal", style_mods={vertical_align="center"}, children={
|
||||
{type="checkbox", name="is_stack", state=setting(bits, SETTING_IS_STACK), handler=handle_setting, tags={id=comb.unit_number, bit=SETTING_IS_STACK}, tooltip={"cybersyn-gui.is-stack-tooltip"}},
|
||||
{type="label", name="is_stack_label", style_mods={left_padding=3}, caption={"cybersyn-gui.is-stack-description"}},
|
||||
}},
|
||||
}},
|
||||
{type="flow", name="enable_inactive", direction="horizontal", style_mods={vertical_align="center"}, children={
|
||||
{type="checkbox", name="enable_inactive", state=setting(bits, SETTING_ENABLE_INACTIVE), handler=handle_setting, tags={id=comb.unit_number, bit=SETTING_ENABLE_INACTIVE}, tooltip={"cybersyn-gui.enable-inactive-tooltip"}},
|
||||
{type="label", name="enable_inactive_label", style_mods={left_padding=3}, caption={"cybersyn-gui.enable-inactive-description"}},
|
||||
}},
|
||||
}}
|
||||
}}
|
||||
}}
|
||||
}}
|
||||
})
|
||||
|
||||
main_window.frame.vflow.preview_frame.preview.entity = comb
|
||||
main_window.titlebar.drag_target = main_window
|
||||
main_window.force_auto_center()
|
||||
|
||||
set_visibility(main_window, selected_index)
|
||||
player.opened = main_window
|
||||
end
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
--By Mami
|
||||
local area = require("__flib__.area")
|
||||
local area = require("__flib__.bounding-box")
|
||||
local abs = math.abs
|
||||
local floor = math.floor
|
||||
local ceil = math.ceil
|
||||
local min = math.min
|
||||
local max = math.max
|
||||
local bit_extract = bit32.extract
|
||||
|
||||
|
||||
---@param layout_pattern (0|1|2|3)[]
|
||||
@@ -204,14 +205,15 @@ function set_p_wagon_combs(map_data, station, train)
|
||||
break
|
||||
end
|
||||
end
|
||||
if carriage.type == "cargo-wagon" and item_i <= #manifest then
|
||||
if carriage.type == "cargo-wagon" then
|
||||
local inv = carriage.get_inventory(defines.inventory.cargo_wagon)
|
||||
if inv then
|
||||
---@type ConstantCombinatorParameters
|
||||
local signals = {}
|
||||
|
||||
local inv_filter_i = 1
|
||||
local item_slots_capacity = max(ceil((#inv - locked_slots)*percent_slots_to_use_per_wagon), 1)
|
||||
while item_slots_capacity > 0 do
|
||||
while item_slots_capacity > 0 and item_i <= #manifest do
|
||||
local do_inc
|
||||
if item.type == "item" then
|
||||
local stack_size = get_stack_size(map_data, item.name)
|
||||
@@ -222,11 +224,13 @@ function set_p_wagon_combs(map_data, station, train)
|
||||
signals[i] = {index = i, signal = {type = item.type, name = item.name}, count = sign*count_to_fill}
|
||||
item_count = item_count - count_to_fill
|
||||
item_slots_capacity = item_slots_capacity - slots_to_fill
|
||||
for j = 1, slots_to_fill do
|
||||
inv.set_filter(inv_filter_i, item.name)
|
||||
inv_filter_i = inv_filter_i + 1
|
||||
if comb then
|
||||
for j = 1, slots_to_fill do
|
||||
inv.set_filter(inv_filter_i, item.name)
|
||||
inv_filter_i = inv_filter_i + 1
|
||||
end
|
||||
train.has_filtered_wagon = true
|
||||
end
|
||||
train.has_filtered_wagon = true
|
||||
do_inc = item_count == 0
|
||||
else
|
||||
do_inc = true
|
||||
@@ -243,14 +247,18 @@ function set_p_wagon_combs(map_data, station, train)
|
||||
end
|
||||
|
||||
if comb then
|
||||
if bit_extract(get_comb_params(comb).second_constant, SETTING_ENABLE_SLOT_BARRING) > 0 then
|
||||
inv.set_bar(inv_filter_i--[[@as uint]])
|
||||
train.has_filtered_wagon = true
|
||||
end
|
||||
set_combinator_output(map_data, comb, signals)
|
||||
end
|
||||
end
|
||||
elseif carriage.type == "fluid-wagon" and fluid_i <= #manifest then
|
||||
elseif carriage.type == "fluid-wagon" then
|
||||
local fluid_capacity = carriage.prototype.fluid_capacity
|
||||
local signals = {}
|
||||
|
||||
while fluid_capacity > 0 do
|
||||
while fluid_capacity > 0 and fluid_i <= #manifest do
|
||||
local do_inc
|
||||
if fluid.type == "fluid" then
|
||||
local count_to_fill = min(fluid_count, fluid_capacity)
|
||||
|
||||
@@ -189,12 +189,9 @@ local function search_for_station_combinator(map_data, stop, comb_operation, com
|
||||
{pos_x - 2, pos_y - 2},
|
||||
{pos_x + 2, pos_y + 2}
|
||||
}
|
||||
local entities = stop.surface.find_entities(search_area)
|
||||
local entities = stop.surface.find_entities_filtered({area = search_area, name = COMBINATOR_NAME})
|
||||
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
|
||||
if entity.valid and entity ~= comb_forbidden and map_data.to_stop[entity.unit_number] == stop then
|
||||
local param = get_comb_params(entity)
|
||||
if param.operation == comb_operation then
|
||||
return entity
|
||||
@@ -223,7 +220,7 @@ local function on_combinator_built(map_data, comb)
|
||||
end
|
||||
local stop = nil
|
||||
local rail = nil
|
||||
local entities = comb.surface.find_entities(search_area)
|
||||
local entities = comb.surface.find_entities_filtered({area = search_area, name = {"train-stop", "straight-rail"}})
|
||||
for _, cur_entity in pairs(entities) do
|
||||
if cur_entity.valid then
|
||||
if cur_entity.name == "train-stop" then
|
||||
@@ -325,7 +322,7 @@ function on_combinator_broken(map_data, comb)
|
||||
if station then
|
||||
if station.entity_comb1 == comb then
|
||||
on_station_broken(map_data, id, station)
|
||||
on_stop_built(map_data, stop, comb)
|
||||
on_stop_built_or_updated(map_data, stop, comb)
|
||||
elseif station.entity_comb2 == comb then
|
||||
station.entity_comb2 = search_for_station_combinator(map_data, stop, MODE_SECONDARY_IO, comb)
|
||||
end
|
||||
@@ -334,13 +331,13 @@ function on_combinator_broken(map_data, comb)
|
||||
if depot then
|
||||
if depot.entity_comb == comb then
|
||||
on_depot_broken(map_data, id, depot)
|
||||
on_stop_built(map_data, stop, comb)
|
||||
on_stop_built_or_updated(map_data, stop, comb)
|
||||
end
|
||||
else
|
||||
local refueler = map_data.refuelers[id]
|
||||
if refueler and refueler.entity_comb == comb then
|
||||
on_refueler_broken(map_data, id, refueler)
|
||||
on_stop_built(map_data, stop, comb)
|
||||
on_stop_built_or_updated(map_data, stop, comb)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -468,7 +465,8 @@ end
|
||||
---@param map_data MapData
|
||||
---@param stop LuaEntity
|
||||
---@param comb_forbidden LuaEntity?
|
||||
function on_stop_built(map_data, stop, comb_forbidden)
|
||||
function on_stop_built_or_updated(map_data, stop, comb_forbidden)
|
||||
--NOTE: this stop must not be a part of any station before entering this function
|
||||
local pos_x = stop.position.x
|
||||
local pos_y = stop.position.y
|
||||
|
||||
@@ -480,20 +478,24 @@ function on_stop_built(map_data, stop, comb_forbidden)
|
||||
local comb1 = nil
|
||||
local depot_comb = nil
|
||||
local refueler_comb = nil
|
||||
local entities = stop.surface.find_entities(search_area)
|
||||
local entities = stop.surface.find_entities_filtered({area = search_area, name = COMBINATOR_NAME})
|
||||
for _, entity in pairs(entities) do
|
||||
if entity.valid and entity ~= comb_forbidden and entity.name == COMBINATOR_NAME and map_data.to_stop[entity.unit_number] == nil then
|
||||
map_data.to_stop[entity.unit_number] = stop
|
||||
local param = get_comb_params(entity)
|
||||
local op = param.operation
|
||||
if op == MODE_PRIMARY_IO then
|
||||
comb1 = entity
|
||||
elseif op == MODE_SECONDARY_IO then
|
||||
comb2 = entity
|
||||
elseif op == MODE_DEPOT then
|
||||
depot_comb = entity
|
||||
elseif op == MODE_REFUELER then
|
||||
refueler_comb = entity
|
||||
if entity.valid and entity ~= comb_forbidden then
|
||||
local id = entity.unit_number--[[@as uint]]
|
||||
local adj_stop = map_data.to_stop[id]
|
||||
if adj_stop == nil or adj_stop == stop then
|
||||
map_data.to_stop[id] = stop
|
||||
local param = get_comb_params(entity)
|
||||
local op = param.operation
|
||||
if op == MODE_PRIMARY_IO then
|
||||
comb1 = entity
|
||||
elseif op == MODE_SECONDARY_IO then
|
||||
comb2 = entity
|
||||
elseif op == MODE_DEPOT then
|
||||
depot_comb = entity
|
||||
elseif op == MODE_REFUELER then
|
||||
refueler_comb = entity
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -515,7 +517,7 @@ local function on_stop_broken(map_data, stop)
|
||||
{pos_x - 2, pos_y - 2},
|
||||
{pos_x + 2, pos_y + 2}
|
||||
}
|
||||
local entities = stop.surface.find_entities(search_area)
|
||||
local entities = stop.surface.find_entities_filtered({area = search_area, name = COMBINATOR_NAME})
|
||||
for _, entity in pairs(entities) do
|
||||
if entity.valid and map_data.to_stop[entity.unit_number] == stop then
|
||||
map_data.to_stop[entity.unit_number] = nil
|
||||
@@ -592,7 +594,7 @@ local function on_built(event)
|
||||
if not entity or not entity.valid then return end
|
||||
|
||||
if entity.name == "train-stop" then
|
||||
on_stop_built(global, entity)
|
||||
on_stop_built_or_updated(global, entity)
|
||||
elseif entity.name == COMBINATOR_NAME then
|
||||
on_combinator_built(global, entity)
|
||||
elseif entity.type == "inserter" then
|
||||
@@ -778,6 +780,7 @@ end
|
||||
|
||||
|
||||
local function grab_all_settings()
|
||||
mod_settings.enable_planner = settings.global["cybersyn-enable-planner"].value --[[@as boolean]]
|
||||
mod_settings.tps = settings.global["cybersyn-ticks-per-second"].value --[[@as double]]
|
||||
mod_settings.update_rate = settings.global["cybersyn-update-rate"].value --[[@as int]]
|
||||
mod_settings.r_threshold = settings.global["cybersyn-request-threshold"].value--[[@as int]]
|
||||
@@ -845,6 +848,15 @@ local function main()
|
||||
|
||||
script.on_event(defines.events.on_entity_settings_pasted, on_paste)
|
||||
|
||||
script.on_event(defines.events.on_train_created, on_train_built)
|
||||
script.on_event(defines.events.on_train_changed_state, on_train_changed)
|
||||
|
||||
script.on_event(defines.events.on_entity_renamed, on_rename)
|
||||
|
||||
script.on_event(defines.events.on_runtime_mod_setting_changed, on_settings_changed)
|
||||
|
||||
register_gui_actions()
|
||||
|
||||
if mod_settings.tps > DELTA then
|
||||
local nth_tick = ceil(60/mod_settings.tps)--[[@as uint]];
|
||||
script.on_nth_tick(nth_tick, function()
|
||||
@@ -854,14 +866,11 @@ local function main()
|
||||
script.on_nth_tick(nil)
|
||||
end
|
||||
|
||||
script.on_event(defines.events.on_train_created, on_train_built)
|
||||
script.on_event(defines.events.on_train_changed_state, on_train_changed)
|
||||
|
||||
script.on_event(defines.events.on_entity_renamed, on_rename)
|
||||
|
||||
script.on_event(defines.events.on_runtime_mod_setting_changed, on_settings_changed)
|
||||
|
||||
register_gui_actions()
|
||||
script.on_event("cybersyn-toggle-planner", function(event)
|
||||
local setting = settings.global["cybersyn-enable-planner"]
|
||||
setting.value = not setting.value
|
||||
settings.global["cybersyn-enable-planner"] = setting
|
||||
end)
|
||||
|
||||
script.on_init(function()
|
||||
local setting = settings.global["cybersyn-invert-sign"]
|
||||
|
||||
@@ -185,13 +185,15 @@ local migrations_table = {
|
||||
for train_id, train in pairs(map_data.trains) do
|
||||
train.depot_id = train.parked_at_depot_id
|
||||
if not train.depot_id then
|
||||
local e = get_any_train_entity(train.entity)
|
||||
local stops = e.force.get_train_stops({name = train.depot_name, surface = e.surface})
|
||||
for stop in rnext_consume, stops do
|
||||
local new_depot_id = stop.unit_number
|
||||
if map_data.depots[new_depot_id] then
|
||||
train.depot_id = new_depot_id--[[@as uint]]
|
||||
break
|
||||
if train.entity.valid then
|
||||
local e = get_any_train_entity(train.entity)
|
||||
local stops = e.force.get_train_stops({name = train.depot_name, surface = e.surface})
|
||||
for stop in rnext_consume, stops do
|
||||
local new_depot_id = stop.unit_number
|
||||
if map_data.depots[new_depot_id] then
|
||||
train.depot_id = new_depot_id--[[@as uint]]
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -200,7 +202,9 @@ local migrations_table = {
|
||||
end
|
||||
if not train.depot_id then
|
||||
train.entity.manual_mode = true
|
||||
send_alert_depot_of_train_broken(map_data, train.entity)
|
||||
if train.entity.valid then
|
||||
send_alert_depot_of_train_broken(map_data, train.entity)
|
||||
end
|
||||
local layout_id = train.layout_id
|
||||
local count = global.layout_train_count[layout_id]
|
||||
if count <= 1 then
|
||||
|
||||
@@ -115,6 +115,7 @@ end
|
||||
--[[helper functions]]
|
||||
------------------------------------------------------------------
|
||||
--NOTE: the policy of cybersyn is to give modders access to as much of the raw data of the mod as possible. Factorio only allows me to return copies of the original data rather than the actual thing, which sucks. The unsafe api has some tools to help you bypass this limitation.
|
||||
--Some of these functions are so simplistic I'd recommend not even using them and just copy-pasting their internal code.
|
||||
|
||||
function interface.get_mod_settings()
|
||||
return mod_settings
|
||||
@@ -246,12 +247,13 @@ end
|
||||
--[[unsafe API]]
|
||||
------------------------------------------------------------------
|
||||
--NOTE: The following functions can cause serious longterm damage to someone's world if they are given bad parameters. Please refer to global.lua for type information. Use caution.
|
||||
--If there is any useful function missing from this API I'd be happy to add it. Join the Cybersyn discord to request it be added.
|
||||
|
||||
---@param value any
|
||||
---@param ... string|int
|
||||
function interface.write_global(value, ...)
|
||||
--this can write anything into cybersyn's map_data, please be very careful with anything you write, it can cause permanent damage
|
||||
--so interface.read_global(nil, "trains", 31415, "manifest") will cause global.trains[31415].manifest = nil (or return false if train 31415 does not exist)
|
||||
--so interface.write_global(nil, "trains", 31415, "manifest") will cause global.trains[31415].manifest = nil (or return false if train 31415 does not exist)
|
||||
local params = {...}
|
||||
local size = #params
|
||||
local key = params[size]
|
||||
@@ -271,7 +273,7 @@ end
|
||||
function interface.remove_manifest_from_station_deliveries(station_id, manifest, sign)
|
||||
local station = global.stations[station_id]
|
||||
assert(station)
|
||||
remove_manifest(global, station, manifest, sign)
|
||||
return remove_manifest(global, station, manifest, sign)
|
||||
end
|
||||
---@param r_station_id uint
|
||||
---@param p_station_id uint
|
||||
@@ -279,7 +281,7 @@ end
|
||||
function interface.create_manifest(r_station_id, p_station_id, train_id)
|
||||
local train = global.trains[train_id]
|
||||
assert(global.stations[r_station_id] and global.stations[p_station_id] and train and train.is_available)
|
||||
create_manifest(global, r_station_id, p_station_id, train_id)
|
||||
return create_manifest(global, r_station_id, p_station_id, train_id)
|
||||
end
|
||||
---@param r_station_id uint
|
||||
---@param p_station_id uint
|
||||
@@ -288,19 +290,19 @@ end
|
||||
function interface.create_delivery(r_station_id, p_station_id, train_id, manifest)
|
||||
local train = global.trains[train_id]
|
||||
assert(global.stations[r_station_id] and global.stations[p_station_id] and train and train.is_available and manifest)
|
||||
create_delivery(global, r_station_id, p_station_id, train_id, manifest)
|
||||
return create_delivery(global, r_station_id, p_station_id, train_id, manifest)
|
||||
end
|
||||
---@param train_id uint
|
||||
function interface.fail_delivery(train_id)
|
||||
local train = global.trains[train_id]
|
||||
assert(train)
|
||||
on_failed_delivery(global, train_id, train)
|
||||
return on_failed_delivery(global, train_id, train)
|
||||
end
|
||||
---@param train_id uint
|
||||
function interface.remove_train(train_id)
|
||||
local train = global.trains[train_id]
|
||||
assert(train)
|
||||
remove_train(global, train_id, train)
|
||||
return remove_train(global, train_id, train)
|
||||
end
|
||||
|
||||
---@param train_id uint
|
||||
@@ -320,14 +322,14 @@ function interface.add_available_train_to_depot(train_id, depot_id)
|
||||
local train = global.trains[train_id]
|
||||
local depot = global.depots[depot_id]
|
||||
assert(train and depot)
|
||||
add_available_train_to_depot(global, mod_settings, train_id, train, depot_id, depot)
|
||||
return add_available_train_to_depot(global, mod_settings, train_id, train, depot_id, depot)
|
||||
end
|
||||
---@param train_id uint
|
||||
function interface.remove_available_train(train_id)
|
||||
--this function removes a train from the available trains list so it cannot be rescheduled and dispatched. if the train was not already available nothing will happen
|
||||
local train = global.trains[train_id]
|
||||
assert(train)
|
||||
remove_available_train(global, train_id, train)
|
||||
return remove_available_train(global, train_id, train)
|
||||
end
|
||||
|
||||
------------------------------------------------------------------
|
||||
|
||||
@@ -52,11 +52,12 @@ function on_failed_delivery(map_data, train_id, train)
|
||||
train.has_filtered_wagon = nil
|
||||
for carriage_i, carriage in ipairs(train.entity.cargo_wagons) do
|
||||
local inv = carriage.get_inventory(defines.inventory.cargo_wagon)
|
||||
if inv and inv.is_filtered() then
|
||||
if inv then
|
||||
---@type uint
|
||||
for i = 1, #inv do
|
||||
for i = 1, inv.get_bar() - 1 do
|
||||
inv.set_filter(i, nil)
|
||||
end
|
||||
inv.set_bar()
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -211,38 +212,19 @@ end
|
||||
---@param train_id uint
|
||||
---@param train Train
|
||||
local function on_train_arrives_station(map_data, station_id, train_id, train)
|
||||
if train.manifest then
|
||||
---@type uint
|
||||
if train.status == STATUS_TO_P then
|
||||
if train.p_station_id == station_id then
|
||||
train.status = STATUS_P
|
||||
local station = map_data.stations[station_id]
|
||||
set_comb1(map_data, station, train.manifest, mod_settings.invert_sign and 1 or -1)
|
||||
set_p_wagon_combs(map_data, station, train)
|
||||
interface_raise_train_status_changed(train_id, STATUS_TO_P, STATUS_P)
|
||||
end
|
||||
elseif train.status == STATUS_TO_R then
|
||||
if train.r_station_id == station_id then
|
||||
train.status = STATUS_R
|
||||
local station = map_data.stations[station_id]
|
||||
set_comb1(map_data, station, train.manifest, mod_settings.invert_sign and -1 or 1)
|
||||
set_r_wagon_combs(map_data, station, train)
|
||||
interface_raise_train_status_changed(train_id, STATUS_TO_R, STATUS_R)
|
||||
end
|
||||
elseif train.status == STATUS_P and train.p_station_id == station_id then
|
||||
--this is player intervention that is considered valid
|
||||
elseif (train.status == STATUS_R or train.status == STATUS_TO_D or train.status == STATUS_TO_D_BYPASS) and train.r_station_id == station_id then
|
||||
--this is player intervention that is considered valid
|
||||
elseif mod_settings.react_to_train_at_incorrect_station then
|
||||
on_failed_delivery(map_data, train_id, train)
|
||||
remove_train(map_data, train_id, train)
|
||||
lock_train(train.entity)
|
||||
send_alert_train_at_incorrect_station(map_data, train.entity)
|
||||
end
|
||||
elseif mod_settings.react_to_train_at_incorrect_station then
|
||||
--train is lost somehow, probably from player intervention
|
||||
remove_train(map_data, train_id, train)
|
||||
send_alert_train_at_incorrect_station(map_data, train.entity)
|
||||
---@type uint
|
||||
if train.status == STATUS_TO_P then
|
||||
train.status = STATUS_P
|
||||
local station = map_data.stations[station_id]
|
||||
set_comb1(map_data, station, train.manifest, mod_settings.invert_sign and 1 or -1)
|
||||
set_p_wagon_combs(map_data, station, train)
|
||||
interface_raise_train_status_changed(train_id, STATUS_TO_P, STATUS_P)
|
||||
elseif train.status == STATUS_TO_R then
|
||||
train.status = STATUS_R
|
||||
local station = map_data.stations[station_id]
|
||||
set_comb1(map_data, station, train.manifest, mod_settings.invert_sign and -1 or 1)
|
||||
set_r_wagon_combs(map_data, station, train)
|
||||
interface_raise_train_status_changed(train_id, STATUS_TO_R, STATUS_R)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -274,11 +256,12 @@ local function on_train_leaves_stop(map_data, mod_settings, train_id, train)
|
||||
train.has_filtered_wagon = nil
|
||||
for carriage_i, carriage in ipairs(train.entity.cargo_wagons) do
|
||||
local inv = carriage.get_inventory(defines.inventory.cargo_wagon)
|
||||
if inv and inv.is_filtered() then
|
||||
if inv then
|
||||
---@type uint
|
||||
for i = 1, #inv do
|
||||
for i = 1, inv.get_bar() - 1 do
|
||||
inv.set_filter(i, nil)
|
||||
end
|
||||
inv.set_bar()
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -426,19 +409,21 @@ function on_train_built(event)
|
||||
end
|
||||
end
|
||||
function on_train_changed(event)
|
||||
---@type MapData
|
||||
local map_data = global
|
||||
local train_e = event.train--[[@as LuaTrain]]
|
||||
if not train_e.valid then return end
|
||||
local train_id = train_e.id
|
||||
|
||||
if global.active_alerts then
|
||||
if map_data.active_alerts then
|
||||
--remove the alert if the train is interacted with at all
|
||||
local data = global.active_alerts[train_id]
|
||||
local data = map_data.active_alerts[train_id]
|
||||
if data then
|
||||
--we need to wait for the train to come to a stop from being locked
|
||||
if data[3] + 10*mod_settings.tps < global.total_ticks then
|
||||
global.active_alerts[train_id] = nil
|
||||
if next(global.active_alerts) == nil then
|
||||
global.active_alerts = nil
|
||||
if data[3] + 10*mod_settings.tps < map_data.total_ticks then
|
||||
map_data.active_alerts[train_id] = nil
|
||||
if next(map_data.active_alerts) == nil then
|
||||
map_data.active_alerts = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -448,24 +433,48 @@ function on_train_changed(event)
|
||||
local stop = train_e.station
|
||||
if stop and stop.valid and stop.name == "train-stop" then
|
||||
local id = stop.unit_number--[[@as uint]]
|
||||
if global.stations[id] then
|
||||
local train = global.trains[train_id]
|
||||
if train then
|
||||
on_train_arrives_station(global, id, train_id, train)
|
||||
end
|
||||
elseif global.depots[id] then
|
||||
on_train_arrives_depot(global, id, train_e)
|
||||
elseif global.refuelers[id] then
|
||||
local train = global.trains[train_id]
|
||||
if train then
|
||||
on_train_arrives_refueler(global, id, train_id, train)
|
||||
if map_data.depots[id] then
|
||||
on_train_arrives_depot(map_data, id, train_e)
|
||||
end
|
||||
else
|
||||
local train = map_data.trains[train_id]
|
||||
if train then
|
||||
local schedule = train_e.schedule
|
||||
if schedule then
|
||||
local rail = schedule.records[schedule.current].rail
|
||||
if rail then
|
||||
local id, station, is_station
|
||||
if train.status == STATUS_TO_P then
|
||||
id = train.p_station_id
|
||||
station = map_data.stations[id]
|
||||
is_station = true
|
||||
elseif train.status == STATUS_TO_R then
|
||||
id = train.r_station_id
|
||||
station = map_data.stations[id]
|
||||
is_station = true
|
||||
elseif train.status == STATUS_TO_F then
|
||||
id = train.refueler_id
|
||||
station = map_data.refuelers[id]
|
||||
is_station = false
|
||||
end
|
||||
if id and station.entity_stop.connected_rail == rail then
|
||||
if is_station then
|
||||
on_train_arrives_station(map_data, id, train_id, train)
|
||||
else
|
||||
on_train_arrives_refueler(map_data, id, train_id, train)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
elseif event.old_state == defines.train_state.wait_station then
|
||||
local train = global.trains[train_id]
|
||||
if train then
|
||||
on_train_leaves_stop(global, mod_settings, train_id, train)
|
||||
local path = train_e.path
|
||||
if path and path.total_distance > 4 then
|
||||
local train = map_data.trains[train_id]
|
||||
if train then
|
||||
on_train_leaves_stop(map_data, mod_settings, train_id, train)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user