diff --git a/.vscode/launch.json b/.vscode/launch.json index 8adba00..dd52827 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -14,6 +14,7 @@ "debugadapter": true, "flib": true, "cybersyn": true, + "creative-mod": true, }, "disableExtraMods": true }, @@ -27,6 +28,7 @@ "debugadapter": true, "flib": true, "cybersyn": true, + "creative-mod": true, }, "disableExtraMods": true }, @@ -39,6 +41,7 @@ "debugadapter": true, "flib": true, "cybersyn": true, + "creative-mod": true, }, "disableExtraMods": true } diff --git a/cybersyn/data.lua b/cybersyn/data.lua index fd6ea3c..78fc92c 100644 --- a/cybersyn/data.lua +++ b/cybersyn/data.lua @@ -21,4 +21,5 @@ data:extend({ cybersyn_priority, cybersyn_p_threshold, cybersyn_r_threshold, + cybersyn_locked_slots, }) diff --git a/cybersyn/graphics/icons/locked_slots.png b/cybersyn/graphics/icons/locked_slots.png new file mode 100644 index 0000000..3f42332 Binary files /dev/null and b/cybersyn/graphics/icons/locked_slots.png differ diff --git a/cybersyn/locale/en/base.cfg b/cybersyn/locale/en/base.cfg index 474ea37..9c42495 100644 --- a/cybersyn/locale/en/base.cfg +++ b/cybersyn/locale/en/base.cfg @@ -38,3 +38,4 @@ cybersyn-train-network=Cybernetic train network cybersyn-priority=Station priority cybersyn-p_threshold=Provide threshold cybersyn-r_threshold=Request threshold +cybersyn-locked-slots=Locked slots per cargo wagon diff --git a/cybersyn/prototypes/signal.lua b/cybersyn/prototypes/signal.lua index 72770ba..cc5a5e8 100644 --- a/cybersyn/prototypes/signal.lua +++ b/cybersyn/prototypes/signal.lua @@ -27,5 +27,13 @@ cybersyn_r_threshold = { icon = "__cybersyn__/graphics/icons/r_threshold.png", icon_size = 64, subgroup = "cybersyn-signal", - order = "a-b" + order = "a-c" +} +cybersyn_locked_slots = { + type = "virtual-signal", + name = LOCKED_SLOTS, + icon = "__cybersyn__/graphics/icons/locked_slots.png", + icon_size = 64, + subgroup = "cybersyn-signal", + order = "a-d" } diff --git a/cybersyn/scripts/constants.lua b/cybersyn/scripts/constants.lua index 9987f2a..ac5a8a1 100644 --- a/cybersyn/scripts/constants.lua +++ b/cybersyn/scripts/constants.lua @@ -3,6 +3,7 @@ SIGNAL_PRIORITY = "cybersyn-priority" REQUEST_THRESHOLD = "cybersyn-r_threshold" PROVIDE_THRESHOLD = "cybersyn-p_threshold" +LOCKED_SLOTS = "cybersyn-locked-slots" STATION_IN_NAME = "cybersyn-station-in" STATION_OUT_NAME = "cybersyn-station-out" diff --git a/cybersyn/scripts/controller.lua b/cybersyn/scripts/controller.lua index 548806f..045f40f 100644 --- a/cybersyn/scripts/controller.lua +++ b/cybersyn/scripts/controller.lua @@ -3,25 +3,6 @@ local get_distance = require("__flib__.misc").get_distance local math = math local INF = math.huge -local function icpairs(a, start_i) - if #a == 0 then - return function() end - end - start_i = start_i%#a + 1 - local i = start_i - 1 - local flag = true - return function() - i = i%#a + 1 - if i ~= start_i or flag then - flag = false - local v = a[i] - if v then - return i, v - end - end - end -end - local create_loading_order_condition = {type = "inactivity", compare_type = "and", ticks = 120} function create_loading_order(stop, manifest) local condition = {} @@ -55,7 +36,7 @@ end local create_direct_to_station_order_condition = {{type = "time", compare_type = "and", ticks = 0}} local function create_direct_to_station_order(stop) - return {wait_conditions = create_direct_to_station_order_condition, rail = stop.connected_rail, rail_direction = stop.connected_rail_direction} + return {rail = stop.connected_rail, rail_direction = stop.connected_rail_direction} end function create_depot_schedule(depot_name) @@ -178,7 +159,11 @@ local function send_train_between(map_data, r_station_id, p_station_id, train, p end end + local locked_slots = math.max(p_station.locked_slots, r_station.locked_slots) local total_slots_left = train.item_slot_capacity + if locked_slots > 0 then + total_slots_left = math.max(total_slots_left - #train.entity.cargo_wagons*locked_slots, math.min(total_slots_left, #train.entity.cargo_wagons)) + end local total_liquid_left = train.fluid_capacity local i = 1 @@ -266,6 +251,7 @@ function tick(map_data, mod_settings) station.r_threshold = mod_settings.r_threshold station.p_threshold = mod_settings.p_threshold station.priority = 0 + station.locked_slots = 0 local signals = get_signals(station) if signals then for k, v in pairs(signals) do @@ -280,6 +266,8 @@ function tick(map_data, mod_settings) station.r_threshold = math.abs(item_count) elseif item_name == PROVIDE_THRESHOLD then station.p_threshold = math.abs(item_count) + elseif item_name == LOCKED_SLOTS then + station.locked_slots = math.max(item_count, 0) end signals[k] = nil end @@ -297,6 +285,7 @@ function tick(map_data, mod_settings) r_stations_all[item_name] = {} p_stations_all[item_name] = {} all_items[#all_items + 1] = item_name + all_items[#all_items + 1] = v.signal.type end table.insert(r_stations_all[item_name], station_id) elseif effective_item_count >= station.p_threshold then @@ -304,6 +293,7 @@ function tick(map_data, mod_settings) r_stations_all[item_name] = {} p_stations_all[item_name] = {} all_items[#all_items + 1] = item_name + all_items[#all_items + 1] = v.signal.type end table.insert(p_stations_all[item_name], station_id) end @@ -315,7 +305,10 @@ function tick(map_data, mod_settings) local failed_because_missing_trains_total = 0 --we do not dispatch more than one train per station per tick --psuedo-randomize what item (and what station) to check first so if trains available is low they choose orders psuedo-randomly - for _, item_name in icpairs(all_items, total_ticks) do + local start_i = 2*(total_ticks%(#all_items/2)) + 1 + for item_i = 0, #all_items - 1, 2 do + local item_name = all_items[(start_i + item_i - 1)%#all_items + 1] + local item_type = all_items[(start_i + item_i)%#all_items + 1] local r_stations = r_stations_all[item_name] local p_stations = p_stations_all[item_name] @@ -333,7 +326,7 @@ function tick(map_data, mod_settings) local highest_prior = -INF local could_have_been_serviced = false for j, p_station_id in ipairs(p_stations) do - local train, d = get_valid_train(map_data, r_station_id, p_station_id) + local train, d = get_valid_train(map_data, r_station_id, p_station_id, item_type) local prior = stations[p_station_id].priority if prior > highest_prior or (prior == highest_prior and d < best_dist) then if train then @@ -367,7 +360,7 @@ function tick(map_data, mod_settings) local r_station = stations[r_station_id] local prior = r_station.priority if prior > highest_prior or (prior == highest_prior and r_station.last_delivery_tick < lowest_tick) then - local train, d = get_valid_train(map_data, r_station_id, p_station_id) + local train, d = get_valid_train(map_data, r_station_id, p_station_id, item_type) if train then best = i best_train = train @@ -387,4 +380,5 @@ function tick(map_data, mod_settings) end end end + --TODO: add alert for missing trains end diff --git a/cybersyn/scripts/global.lua b/cybersyn/scripts/global.lua index acebe8a..96a717e 100644 --- a/cybersyn/scripts/global.lua +++ b/cybersyn/scripts/global.lua @@ -16,6 +16,7 @@ Station: { last_delivery_tick: int r_threshold: int >= 0 p_threshold: int >= 0 + locked_slots: int >= 0 entity: LuaEntity entity_in: LuaEntity entity_out: LuaEntity diff --git a/cybersyn/scripts/main.lua b/cybersyn/scripts/main.lua index 39365ed..bdc9526 100644 --- a/cybersyn/scripts/main.lua +++ b/cybersyn/scripts/main.lua @@ -147,10 +147,11 @@ local function on_station_built(map_data, stop) entity_in = entity_in, entity_out = entity_out, deliveries_total = 0, - priority = 0, last_delivery_tick = 0, + priority = 0, r_threshold = 0, p_threshold = 0, + locked_slots = 0, deliveries = {}, accepted_layouts = {} } @@ -238,7 +239,7 @@ local function update_train_layout(map_data, train) item_slot_capacity = item_slot_capacity + #inv elseif carriage.type == "fluid-wagon" then layout = layout.."F" - fluid_capacity = fluid_capacity + carriage.prototype.capacity + fluid_capacity = fluid_capacity + carriage.prototype.fluid_capacity else layout = layout.."?" end @@ -315,6 +316,7 @@ local function on_train_arrives_depot(map_data, train_entity) if next(contents) == nil then train.depot_name = train_entity.station.backer_name train.status = STATUS_D + train.entity.schedule = create_depot_schedule(train.depot_name) map_data.trains_available[train_entity.id] = true else--train still has cargo train.entity.schedule = nil @@ -370,6 +372,7 @@ local function on_train_arrives_buffer(map_data, station_id, train) else on_failed_delivery(map_data, train) remove_train(map_data, train, train.entity.id) + train.entity.schedule = nil end else --train is lost somehow, probably from player intervention @@ -409,6 +412,9 @@ local function on_train_broken(map_data, train) if train.manifest then on_failed_delivery(map_data, train) remove_train(map_data, train, train.entity.id) + if train.entity.valid then + train.entity.schedule = nil + end end end @@ -418,15 +424,10 @@ local function on_train_modified(map_data, pre_train_id, train_entity) if train.manifest then on_failed_delivery(map_data, train) - remove_train(map_data, train, pre_train_id) - else--train is in depot - remove_train(map_data, train, pre_train_id) - train.entity = train_entity - update_train_layout(map_data, train) - --TODO: update train stats - - map_data.trains[train_entity.id] = train - map_data.trains_available[train_entity.id] = true + end + remove_train(map_data, train, pre_train_id) + if train.entity.valid then + train.entity.schedule = nil end end end