diff --git a/cybersyn/data.lua b/cybersyn/data.lua index 3cc2b38..7b95676 100644 --- a/cybersyn/data.lua +++ b/cybersyn/data.lua @@ -6,6 +6,7 @@ require('prototypes.item') require('prototypes.tech') require('prototypes.entity') require('prototypes.signal') +require('prototypes.misc') data:extend({ combinator_entity, @@ -18,4 +19,7 @@ data:extend({ p_threshold_signal, r_threshold_signal, locked_slots_signal, + missing_train_icon, + lost_train_icon, + nonempty_train_icon, }) diff --git a/cybersyn/locale/en/base.cfg b/cybersyn/locale/en/base.cfg index 27d1aff..503d985 100644 --- a/cybersyn/locale/en/base.cfg +++ b/cybersyn/locale/en/base.cfg @@ -33,3 +33,8 @@ cybersyn-priority=Station priority cybersyn-provide-threshold=Provide threshold cybersyn-request-threshold=Request threshold cybersyn-locked-slots=Locked slots per cargo wagon + +[cybersyn-messages] +missing-trains=No trains available to make a delivery from station __2__ to station __1__ +lost-train=A train has become lost +nonempty-train=A train has parked in a depot while still containing items; it cannot be dispatched until it is empty diff --git a/cybersyn/prototypes/misc.lua b/cybersyn/prototypes/misc.lua new file mode 100644 index 0000000..65309b9 --- /dev/null +++ b/cybersyn/prototypes/misc.lua @@ -0,0 +1,24 @@ + +missing_train_icon = flib.copy_prototype(data.raw["fluid"]["water"], MISSING_TRAIN_NAME) +missing_train_icon.icon = "__cybersyn__/graphics/icons/missing-train.png" +missing_train_icon.icon_size = 64 +missing_train_icon.icon_mipmaps = 0 +missing_train_icon.hidden = true +missing_train_icon.auto_barrel = false +missing_train_icon.subgroup = "cybersyn-signal" + +lost_train_icon = flib.copy_prototype(data.raw["fluid"]["water"], LOST_TRAIN_NAME) +lost_train_icon.icon = "__cybersyn__/graphics/icons/lost-train.png" +lost_train_icon.icon_size = 64 +lost_train_icon.icon_mipmaps = 0 +lost_train_icon.hidden = true +lost_train_icon.auto_barrel = false +lost_train_icon.subgroup = "cybersyn-signal" + +nonempty_train_icon = flib.copy_prototype(data.raw["fluid"]["water"], NONEMPTY_TRAIN_NAME) +nonempty_train_icon.icon = "__cybersyn__/graphics/icons/nonempty-train.png" +nonempty_train_icon.icon_size = 64 +nonempty_train_icon.icon_mipmaps = 0 +nonempty_train_icon.hidden = true +nonempty_train_icon.auto_barrel = false +nonempty_train_icon.subgroup = "cybersyn-signal" diff --git a/cybersyn/scripts/alerts.lua b/cybersyn/scripts/alerts.lua new file mode 100644 index 0000000..2f90450 --- /dev/null +++ b/cybersyn/scripts/alerts.lua @@ -0,0 +1,38 @@ +--By Mami + +local send_missing_train_alert_for_stop_icon = {name = MISSING_TRAIN_NAME, type = "fluid"} +function send_missing_train_alert_for_stops(r_stop, p_stop) + for _, player in pairs(r_stop.force.players) do + player.add_custom_alert( + r_stop, + send_missing_train_alert_for_stop_icon, + {"cybersyn-messages.missing-trains", r_stop.backer_name, p_stop.backer_name}, + true + ) + end +end + +local send_lost_train_alert_icon = {name = LOST_TRAIN_NAME, type = "fluid"} +function send_lost_train_alert(train) + for _, player in pairs(train.force.players) do + player.add_custom_alert( + train, + send_lost_train_alert_icon, + {"cybersyn-messages.lost-train"}, + true + ) + end +end + + +local send_nonempty_train_in_depot_alert_icon = {name = NONEMPTY_TRAIN_NAME, type = "fluid"} +function send_nonempty_train_in_depot_alert(train) + for _, player in pairs(train.force.players) do + player.add_custom_alert( + train, + send_nonempty_train_in_depot_alert_icon, + {"cybersyn-messages.nonempty-train"}, + true + ) + end +end diff --git a/cybersyn/scripts/constants.lua b/cybersyn/scripts/constants.lua index 86cd4e2..df8b31b 100644 --- a/cybersyn/scripts/constants.lua +++ b/cybersyn/scripts/constants.lua @@ -1,5 +1,9 @@ --By Mami +MISSING_TRAIN_NAME = "cybersyn-missing-train" +LOST_TRAIN_NAME = "cybersyn-lost-train" +NONEMPTY_TRAIN_NAME = "cybersyn-nonempty-train" + SIGNAL_PRIORITY = "cybersyn-priority" REQUEST_THRESHOLD = "cybersyn-request-threshold" PROVIDE_THRESHOLD = "cybersyn-provide-threshold" diff --git a/cybersyn/scripts/controller.lua b/cybersyn/scripts/controller.lua index cc8fbe9..acf4dc3 100644 --- a/cybersyn/scripts/controller.lua +++ b/cybersyn/scripts/controller.lua @@ -129,7 +129,7 @@ local function get_valid_train(map_data, r_station_id, p_station_id, item_type) local r_station = map_data.stations[r_station_id] local p_station = map_data.stations[p_station_id] - local p_to_r_dist = get_stop_dist(p_station.entity, r_station.entity) + local p_to_r_dist = get_stop_dist(p_station.entity_stop, r_station.entity_stop) if p_to_r_dist == INF then return nil, INF end @@ -147,12 +147,12 @@ local function get_valid_train(map_data, r_station_id, p_station_id, item_type) ((is_fluid and train.fluid_capacity > 0) or (not is_fluid and train.item_slot_capacity > 0)) and station_accepts_layout(r_station, train.layout_id) and station_accepts_layout(p_station, train.layout_id) - and train.entity.station + and train.entity_stop.station then valid_train_exists = true --check if exists valid path --check if path is shortest so we prioritize locality - local d_to_p_dist = get_stop_dist(train.entity.station, p_station.entity) + local d_to_p_dist = get_stop_dist(train.entity.station, p_station.entity_stop) local dist = d_to_p_dist if dist < best_dist then @@ -288,7 +288,7 @@ local function send_train_between(map_data, r_station_id, p_station_id, train, p train.r_station_id = r_station_id train.manifest = manifest - train.entity.schedule = create_manifest_schedule(train.depot_name, p_station.entity, r_station.entity, manifest) + train.entity.schedule = create_manifest_schedule(train.depot_name, p_station.entity_stop, r_station.entity_stop, manifest) set_comb2(map_data, p_station) set_comb2(map_data, r_station) end @@ -308,7 +308,7 @@ function tick(map_data, mod_settings) local all_items = economy.all_items for station_id, station in pairs(stations) do - if station.deliveries_total < station.entity.trains_limit then + if station.deliveries_total < station.entity_stop.trains_limit then station.r_threshold = mod_settings.r_threshold station.p_threshold = mod_settings.p_threshold station.priority = 0 @@ -364,7 +364,7 @@ function tick(map_data, mod_settings) end end - local failed_because_missing_trains_total = 0 + local failed_because_missing_trains = {} --we do not dispatch more than one train per station per tick --psuedo-randomize what item (and what station) to check first so if trains available is low they choose orders psuedo-randomly local start_i = 2*(total_ticks%(#all_items/2)) + 1 @@ -398,13 +398,14 @@ function tick(map_data, mod_settings) highest_prior = prior elseif d < INF then could_have_been_serviced = true + best = j end end end - if best > 0 then + if best_train then send_train_between(map_data, r_station_id, p_stations[best], best_train, item_name, economy) elseif could_have_been_serviced then - failed_because_missing_trains_total = failed_because_missing_trains_total + 1 + send_missing_train_alert_for_stops(stations[r_station_id].entity_stop, p_stations[best].entity_stop) end until #r_stations == 0 else @@ -430,17 +431,17 @@ function tick(map_data, mod_settings) highest_prior = prior elseif d < INF then could_have_been_serviced = true + best = i end end end - if best > 0 then + if best_train then send_train_between(map_data, r_stations[best], p_station_id, best_train, item_name, economy) elseif could_have_been_serviced then - failed_because_missing_trains_total = failed_because_missing_trains_total + 1 + send_missing_train_alert_for_stops(stations[best].entity_stop, p_stations[p_station_id].entity_stop) end until #p_stations == 0 end end end - --TODO: add alert for missing trains end diff --git a/cybersyn/scripts/main.lua b/cybersyn/scripts/main.lua index a1b1315..5dbc2c8 100644 --- a/cybersyn/scripts/main.lua +++ b/cybersyn/scripts/main.lua @@ -58,7 +58,7 @@ local function on_station_broken(map_data, station_id, station) on_failed_delivery(map_data, train) train.entity.schedule = nil remove_train(map_data, train, train_id) - --TODO: mark train as lost in the alerts system + send_lost_train_alert(train.entity) end end end @@ -298,7 +298,7 @@ local function on_station_rename(map_data, stop) --train is attempting delivery to a stop that was renamed local p_station = map_data.stations[train.p_station_id] local r_station = map_data.stations[train.r_station_id] - local schedule = create_manifest_schedule(train.depot_name, p_station.entity, r_station.entity, train.manifest) + local schedule = create_manifest_schedule(train.depot_name, p_station.entity_stop, r_station.entity_stop, train.manifest) schedule.current = train.entity.schedule.current train.entity.schedule = schedule end @@ -321,34 +321,35 @@ end local function on_train_arrives_depot(map_data, train_entity) + local contents = train_entity.get_contents() local train = map_data.trains[train_entity.id] if train then - if train.manifest then - if train.status == STATUS_R_TO_D then - --succeeded delivery - train.p_station_id = 0 - train.r_station_id = 0 - train.manifest = nil - train.depot_name = train_entity.station.backer_name - train.status = STATUS_D - train.entity.schedule = create_depot_schedule(train.depot_name) - map_data.trains_available[train_entity.id] = true - else + if train.manifest and train.status == STATUS_R_TO_D then + --succeeded delivery + train.p_station_id = 0 + train.r_station_id = 0 + train.manifest = nil + train.depot_name = train_entity.station.backer_name + train.status = STATUS_D + map_data.trains_available[train_entity.id] = true + else + if train.manifest then on_failed_delivery(map_data, train) - local contents = train.entity.get_contents() - if next(contents) == nil then - train.depot_name = train_entity.station.backer_name - train.status = STATUS_D - train.entity.schedule = create_depot_schedule(train.depot_name) - map_data.trains_available[train_entity.id] = true - else--train still has cargo - train.entity.schedule = nil - remove_train(map_data, train, train_entity.id) - --TODO: mark train as lost in the alerts system - end + send_lost_train_alert(train.entity) end + train.depot_name = train_entity.station.backer_name + train.status = STATUS_D + map_data.trains_available[train_entity.id] = true end - else + if next(contents) ~= nil then + --train still has cargo + train_entity.schedule = nil + remove_train(map_data, train, train_entity.id) + send_nonempty_train_in_depot_alert(train_entity) + else + train_entity.schedule = create_depot_schedule(train.depot_name) + end + elseif next(contents) == nil then train = { depot_name = train_entity.station.backer_name, status = STATUS_D, @@ -365,6 +366,8 @@ local function on_train_arrives_depot(map_data, train_entity) map_data.trains_available[train_entity.id] = true local schedule = create_depot_schedule(train.depot_name) train_entity.schedule = schedule + else + send_nonempty_train_in_depot_alert(train_entity) end end local function on_train_arrives_buffer(map_data, stop, train) @@ -396,6 +399,7 @@ local function on_train_arrives_buffer(map_data, stop, train) on_failed_delivery(map_data, train) remove_train(map_data, train, train.entity.id) train.entity.schedule = nil + send_lost_train_alert(train.entity) end else --train is lost somehow, probably from player intervention