mirror of
https://github.com/Xevion/project-cybersyn.git
synced 2025-12-09 14:08:15 -06:00
renamed mod
This commit is contained in:
5
cybersyn/changelog.txt
Normal file
5
cybersyn/changelog.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
---------------------------------------------------------------------------------------------------
|
||||
Version: 0.1.0
|
||||
Date: 2021-09-28
|
||||
Features:
|
||||
- Initial proof-of-concept
|
||||
6
cybersyn/control.lua
Normal file
6
cybersyn/control.lua
Normal file
@@ -0,0 +1,6 @@
|
||||
|
||||
|
||||
require("scripts.constants")
|
||||
require("scripts.global")
|
||||
require("scripts.controller")
|
||||
require("scripts.main")
|
||||
19
cybersyn/data.lua
Normal file
19
cybersyn/data.lua
Normal file
@@ -0,0 +1,19 @@
|
||||
--By Mami
|
||||
flib = require('__flib__.data-util')
|
||||
|
||||
require('scripts.constants')
|
||||
require('prototypes.item')
|
||||
require('prototypes.tech')
|
||||
require('prototypes.entity')
|
||||
|
||||
data:extend({
|
||||
cybersyn_depot_item,
|
||||
cybersyn_station_item,
|
||||
cybersyn_depot_recipe,
|
||||
cybersyn_station_recipe,
|
||||
cybersyn_tech,
|
||||
cybersyn_depot_entity,
|
||||
cybersyn_station_entity,
|
||||
cybersyn_station_in,
|
||||
cybersyn_station_out,
|
||||
})
|
||||
BIN
cybersyn/graphics/icons/depot.png
Normal file
BIN
cybersyn/graphics/icons/depot.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.5 KiB |
BIN
cybersyn/graphics/icons/station.png
Normal file
BIN
cybersyn/graphics/icons/station.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.5 KiB |
BIN
cybersyn/graphics/icons/tech.png
Normal file
BIN
cybersyn/graphics/icons/tech.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.5 KiB |
BIN
cybersyn/graphics/place.png
Normal file
BIN
cybersyn/graphics/place.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.5 KiB |
11
cybersyn/info.json
Normal file
11
cybersyn/info.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "cybersyn",
|
||||
"version": "0.0.1",
|
||||
"title": "Project Cybersyn",
|
||||
"author": "Mami",
|
||||
"factorio_version": "1.1",
|
||||
"dependencies": [
|
||||
"base",
|
||||
"flib >= 0.6.0"
|
||||
]
|
||||
}
|
||||
9
cybersyn/locale/en/base.cfg
Normal file
9
cybersyn/locale/en/base.cfg
Normal file
@@ -0,0 +1,9 @@
|
||||
[mod-setting-name]
|
||||
cybersyn-ticks-per-second=Dispatcher ticks per second
|
||||
cybersyn-requester-threshold=Default requester threshold
|
||||
cybersyn-provider-threshold=Default provider threshold
|
||||
|
||||
[mod-setting-description]
|
||||
cybersyn-ticks-per-second=How many times per second to check all stations for possible deliveries. This value will be rounded up to a divisor of 60.
|
||||
cybersyn-requester-threshold=When a requester threshold signal is not recieved by a station it will default to this value.
|
||||
cybersyn-provider-threshold=When a provider threshold signal is not recieved by a station it will default to this value.
|
||||
37
cybersyn/prototypes/entity.lua
Normal file
37
cybersyn/prototypes/entity.lua
Normal file
@@ -0,0 +1,37 @@
|
||||
--By Mami
|
||||
cybersyn_station_entity = flib.copy_prototype(data.raw["train-stop"]["train-stop"], BUFFER_STATION_NAME)
|
||||
cybersyn_station_entity.icon = "__cybersyn__/graphics/icon/station.png"
|
||||
cybersyn_station_entity.icon_size = 64
|
||||
cybersyn_station_entity.icon_mipmaps = 4
|
||||
cybersyn_station_entity.next_upgrade = nil
|
||||
|
||||
cybersyn_depot_entity = flib.copy_prototype(data.raw["train-stop"]["train-stop"], DEPOT_STATION_NAME)
|
||||
cybersyn_depot_entity.icon = "__cybersyn__/graphics/icon/depot.png"
|
||||
cybersyn_depot_entity.icon_size = 64
|
||||
cybersyn_depot_entity.icon_mipmaps = 4
|
||||
cybersyn_depot_entity.next_upgrade = nil
|
||||
|
||||
cybersyn_station_in = flib.copy_prototype(data.raw["lamp"]["small-lamp"], STATION_IN_NAME)
|
||||
cybersyn_station_in.icon = "__cybersyn__/graphics/icon/station.png"
|
||||
cybersyn_station_in.icon_size = 64
|
||||
cybersyn_station_in.icon_mipmaps = 4
|
||||
cybersyn_station_in.next_upgrade = nil
|
||||
cybersyn_station_in.minable = nil
|
||||
cybersyn_station_in.selection_box = {{-0.5, -0.5}, {0.5, 0.5}}
|
||||
cybersyn_station_in.selection_priority = cybersyn_station_in.selection_priority + 10
|
||||
cybersyn_station_in.collision_box = {{-0.15, -0.15}, {0.15, 0.15}}
|
||||
cybersyn_station_in.collision_mask = {"rail-layer"}
|
||||
cybersyn_station_in.energy_usage_per_tick = "10W"
|
||||
cybersyn_station_in.light = {intensity = 1, size = 6}
|
||||
cybersyn_station_in.energy_source = {type="void"}
|
||||
|
||||
cybersyn_station_out = flib.copy_prototype(data.raw["constant-combinator"]["constant-combinator"],STATION_OUT_NAME)
|
||||
cybersyn_station_out.icon = "__cybersyn__/graphics/icon/station.png"
|
||||
cybersyn_station_out.icon_size = 64
|
||||
cybersyn_station_out.icon_mipmaps = 4
|
||||
cybersyn_station_out.next_upgrade = nil
|
||||
cybersyn_station_out.minable = nil
|
||||
cybersyn_station_out.selection_box = {{-0.5, -0.5}, {0.5, 0.5}}
|
||||
cybersyn_station_out.selection_priority = cybersyn_station_out.selection_priority + 10
|
||||
cybersyn_station_out.collision_box = {{-0.15, -0.15}, {0.15, 0.15}}
|
||||
cybersyn_station_out.collision_mask = {"rail-layer"}
|
||||
12
cybersyn/prototypes/item.lua
Normal file
12
cybersyn/prototypes/item.lua
Normal file
@@ -0,0 +1,12 @@
|
||||
--By Mami
|
||||
cybersyn_station_item = flib.copy_prototype(data.raw["item"]["train-stop"], BUFFER_STATION_NAME)
|
||||
cybersyn_station_item.icon = "__cybersyn__/graphics/icons/station.png"
|
||||
cybersyn_station_item.icon_size = 64
|
||||
cybersyn_station_item.icon_mipmaps = 4
|
||||
cybersyn_station_item.order = cybersyn_station_item.order.."-c"
|
||||
|
||||
cybersyn_depot_item = flib.copy_prototype(data.raw["item"]["train-stop"], DEPOT_STATION_NAME)
|
||||
cybersyn_depot_item.icon = "__cybersyn__/graphics/icons/depot.png"
|
||||
cybersyn_depot_item.icon_size = 64
|
||||
cybersyn_depot_item.icon_mipmaps = 4
|
||||
cybersyn_depot_item.order = cybersyn_depot_item.order.."-d"
|
||||
46
cybersyn/prototypes/tech.lua
Normal file
46
cybersyn/prototypes/tech.lua
Normal file
@@ -0,0 +1,46 @@
|
||||
--By Mami
|
||||
cybersyn_station_recipe = flib.copy_prototype(data.raw["recipe"]["train-stop"], BUFFER_STATION_NAME)
|
||||
cybersyn_station_recipe.ingredients = {
|
||||
{"train-stop", 1},
|
||||
{"advanced-circuit", 5},
|
||||
}
|
||||
cybersyn_station_recipe.enabled = false
|
||||
|
||||
cybersyn_depot_recipe = flib.copy_prototype(data.raw["recipe"]["train-stop"], BUFFER_STATION_NAME)
|
||||
cybersyn_depot_recipe.ingredients = {
|
||||
{"train-stop", 1},
|
||||
{"electronic-circuit", 5},
|
||||
}
|
||||
cybersyn_depot_recipe.enabled = false
|
||||
|
||||
cybersyn_tech = {
|
||||
type = "technology",
|
||||
name = "cybernetic-train-network",
|
||||
icon = "__cybersyn__/graphics/icon/tech.png",
|
||||
icon_size = 64,
|
||||
icon_mipmaps = 4,
|
||||
prerequisites = {
|
||||
"automated-rail-transportation",
|
||||
"circuit-network",
|
||||
"advanced-electronics"
|
||||
},
|
||||
effects = {
|
||||
{
|
||||
type = "unlock-recipe",
|
||||
recipe = BUFFER_STATION_NAME
|
||||
},
|
||||
{
|
||||
type = "unlock-recipe",
|
||||
recipe = DEPOT_STATION_NAME
|
||||
},
|
||||
},
|
||||
unit = {
|
||||
ingredients = {
|
||||
{"automation-science-pack", 1},
|
||||
{"logistic-science-pack", 1}
|
||||
},
|
||||
count = 300,
|
||||
time = 30
|
||||
},
|
||||
order = "c-g-c"
|
||||
}
|
||||
19
cybersyn/scripts/constants.lua
Normal file
19
cybersyn/scripts/constants.lua
Normal file
@@ -0,0 +1,19 @@
|
||||
--By Mami
|
||||
|
||||
SIGNAL_PRIORITY = "cybersyn-priority"
|
||||
REQUEST_THRESHOLD = "cybersyn-request-threshold"
|
||||
PROVIDE_THRESHOLD = "cybersyn-provide-threshold"
|
||||
|
||||
STATION_IN_NAME = "cybersyn-station-in"
|
||||
STATION_OUT_NAME = "cybersyn-station-out"
|
||||
BUFFER_STATION_NAME = "cybersyn-station"
|
||||
DEPOT_STATION_NAME = "cybersyn-depot"
|
||||
|
||||
DELTA = 1/2048
|
||||
|
||||
STATUS_D = 0
|
||||
STATUS_D_TO_P = 1
|
||||
STATUS_P = 2
|
||||
STATUS_P_TO_R = 3
|
||||
STATUS_R = 4
|
||||
STATUS_R_TO_D = 5
|
||||
381
cybersyn/scripts/controller.lua
Normal file
381
cybersyn/scripts/controller.lua
Normal file
@@ -0,0 +1,381 @@
|
||||
--By Mami
|
||||
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 nil
|
||||
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 = {}
|
||||
for _, item in ipairs(manifest) do
|
||||
local cond_type
|
||||
if item.type == "fluid" then
|
||||
cond_type = "fluid_count"
|
||||
else
|
||||
cond_type = "item_count"
|
||||
end
|
||||
|
||||
condition[1] = {
|
||||
type = cond_type,
|
||||
compare_type = "and",
|
||||
condition = {comparator = "≥", first_signal = {type = item.type, name = item.name}, constant = item.count}
|
||||
}
|
||||
condition[2] = create_loading_order_condition
|
||||
end
|
||||
return {station = stop.backer_name, wait_conditions = condition}
|
||||
end
|
||||
|
||||
local create_unloading_order_condition = {type = "empty", compare_type = "and"}
|
||||
function create_unloading_order(stop)
|
||||
return {station = stop.backer_name, wait_conditions = create_unloading_order_condition}
|
||||
end
|
||||
|
||||
local create_inactivity_order_condition = create_loading_order_condition
|
||||
function create_inactivity_order(depot_name)
|
||||
return {station = depot_name, wait_conditions = create_inactivity_order_condition}
|
||||
end
|
||||
|
||||
local create_direct_to_station_order_condition = {{type = "time", compare_type = "and", ticks = 0}}
|
||||
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}
|
||||
end
|
||||
|
||||
|
||||
|
||||
local function get_signals(station)
|
||||
local signals = station.entity_in.get_merged_signals()
|
||||
return signals
|
||||
end
|
||||
|
||||
local function get_stop_dist(stop0, stop1)
|
||||
return get_distance(stop0.position, stop1.position)
|
||||
end
|
||||
|
||||
local function station_accepts_layout(station, layout_id)
|
||||
return true
|
||||
end
|
||||
|
||||
local function get_valid_train(map_data, r_station_id, p_station_id, item_type)
|
||||
--NOTE: this code is the critical section for run-time optimization
|
||||
local r_station = map_data.stations[r_station_id]
|
||||
local p_station = map_data.stations[p_station_id]
|
||||
|
||||
local p_to_r_dist = get_stop_dist(p_station.entity, r_station.entity)
|
||||
if p_to_r_dist == INF then
|
||||
return nil, INF
|
||||
end
|
||||
|
||||
local best_train = nil
|
||||
local best_dist = INF
|
||||
local valid_train_exists = false
|
||||
|
||||
local is_fluid = item_type == "fluid"
|
||||
for train_id, _ in pairs(map_data.trains_available) do
|
||||
local train = map_data.trains[train_id]
|
||||
--check cargo capabilities
|
||||
--check layout validity for both stations
|
||||
if
|
||||
((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
|
||||
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 dist = d_to_p_dist
|
||||
if dist < best_dist then
|
||||
best_dist = dist
|
||||
best_train = train
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if valid_train_exists then
|
||||
return best_train, best_dist + p_to_r_dist
|
||||
else
|
||||
return nil, p_to_r_dist
|
||||
end
|
||||
end
|
||||
|
||||
local function send_train_between(map_data, r_station_id, p_station_id, train, primary_item_name, economy)
|
||||
local r_station = map_data.stations[r_station_id]
|
||||
local p_station = map_data.stations[p_station_id]
|
||||
|
||||
local requests = {}
|
||||
local manifest = {}
|
||||
|
||||
local r_signals = get_signals(r_station)
|
||||
for k, v in pairs(r_signals) do
|
||||
local item_name = v.signal.name
|
||||
local item_count = v.count
|
||||
local item_type = v.signal.type
|
||||
if item_name and item_type and item_type ~= "virtual" then
|
||||
local effective_item_count = item_count + r_station.deliveries[item_name]
|
||||
if -effective_item_count >= r_station.r_threshold then
|
||||
requests[item_name] = -effective_item_count
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local p_signals = get_signals(r_station)
|
||||
for k, v in pairs(p_signals) do
|
||||
local item_name = v.signal.name
|
||||
local item_count = v.count
|
||||
local item_type = v.signal.type
|
||||
if item_name and item_type and item_type ~= "virtual" then
|
||||
local effective_item_count = item_count + p_station.deliveries[item_name]
|
||||
if effective_item_count >= p_station.p_threshold then
|
||||
local r = requests[item_name]
|
||||
if r then
|
||||
local item = {name = item_name, count = math.min(r, effective_item_count), type = item_type}
|
||||
if item_name == primary_item_name then
|
||||
manifest[#manifest + 1] = manifest[1]
|
||||
manifest[1] = item
|
||||
else
|
||||
manifest[#manifest + 1] = item
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local total_slots_left = train.item_slot_capacity
|
||||
local total_liquid_left = train.fluid_capacity
|
||||
|
||||
local i = 1
|
||||
while i <= #manifest do
|
||||
local item = manifest[i]
|
||||
local keep_item = false
|
||||
if item.type == "fluid" then
|
||||
if total_liquid_left > 0 then
|
||||
if item.count > total_liquid_left then
|
||||
item.count = total_liquid_left
|
||||
end
|
||||
total_liquid_left = 0--no liquid merging
|
||||
keep_item = true
|
||||
end
|
||||
elseif total_slots_left > 0 then
|
||||
local stack_size = game.item_prototypes[item.name].stack_size
|
||||
local slots = math.ceil(item.count/stack_size)
|
||||
if slots > total_slots_left then
|
||||
item.count = total_slots_left*stack_size
|
||||
end
|
||||
total_slots_left = total_slots_left - slots
|
||||
keep_item = true
|
||||
end
|
||||
if keep_item then
|
||||
i = i + 1
|
||||
else--swap remove
|
||||
manifest[i] = manifest[#manifest]
|
||||
manifest[#manifest] = nil
|
||||
end
|
||||
end
|
||||
|
||||
r_station.last_delivery_tick = economy.ticks_total
|
||||
p_station.last_delivery_tick = economy.ticks_total
|
||||
|
||||
r_station.deliveries_total = r_station.deliveries_total + 1
|
||||
p_station.deliveries_total = p_station.deliveries_total + 1
|
||||
|
||||
for _, 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
|
||||
|
||||
local r_stations = economy.r_stations_all[item.name]
|
||||
local p_stations = economy.p_stations_all[item.name]
|
||||
for i, id in ipairs(r_stations) do
|
||||
if id == r_station_id then
|
||||
table.remove(r_stations, i)
|
||||
break
|
||||
end
|
||||
end
|
||||
for i, id in ipairs(p_stations) do
|
||||
if id == p_station_id then
|
||||
table.remove(p_stations, i)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
map_data.trains_available[train.entity.id] = nil
|
||||
train.status = STATUS_D_TO_P
|
||||
train.p_station_id = p_station_id
|
||||
train.r_station_id = r_station_id
|
||||
train.manifest = manifest
|
||||
|
||||
do
|
||||
local records = {
|
||||
create_inactivity_order(train.depot_name),
|
||||
create_direct_to_station_order(p_station.entity),
|
||||
create_loading_order(p_station.entity, manifest),
|
||||
create_direct_to_station_order(r_station.entity),
|
||||
create_unloading_order(r_station.entity),
|
||||
}
|
||||
local schedule = {current = 1, records = records}
|
||||
|
||||
train.entity.schedule = schedule
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function tick(map_data, mod_settings)
|
||||
local ticks_total = map_data.ticks_total
|
||||
local stations = map_data.stations
|
||||
local economy = {
|
||||
r_stations_all = {},
|
||||
p_stations_all = {},
|
||||
all_items = {},
|
||||
ticks_total = ticks_total,
|
||||
}
|
||||
local r_stations_all = economy.r_stations_all
|
||||
local p_stations_all = economy.p_stations_all
|
||||
local all_items = economy.all_items
|
||||
|
||||
for station_id, station in pairs(stations) do
|
||||
if station.deliveries_total < station.train_limit then
|
||||
station.r_threshold = mod_settings.r_threshold
|
||||
station.p_threshold = mod_settings.p_threshold
|
||||
station.priority = 0
|
||||
local signals = get_signals(station)
|
||||
for k, v in pairs(signals) do
|
||||
local item_name = v.signal.name
|
||||
local item_count = v.count
|
||||
local item_type = v.signal.type
|
||||
if item_name and item_type then
|
||||
if item_type == "virtual" then
|
||||
if item_name == SIGNAL_PRIORITY then
|
||||
station.priority = item_count
|
||||
elseif item_name == REQUEST_THRESHOLD then
|
||||
station.r_threshold = math.abs(item_count)
|
||||
elseif item_name == PROVIDE_THRESHOLD then
|
||||
station.p_threshold = math.abs(item_count)
|
||||
end
|
||||
signals[k] = nil
|
||||
end
|
||||
else
|
||||
signals[k] = nil
|
||||
end
|
||||
end
|
||||
for k, v in pairs(signals) do
|
||||
local item_name = v.signal.name
|
||||
local item_count = v.count
|
||||
local effective_item_count = item_count + station.deliveries[item_name]
|
||||
|
||||
if -effective_item_count >= station.r_threshold then
|
||||
if r_stations_all[item_name] == nil then
|
||||
r_stations_all[item_name] = {}
|
||||
p_stations_all[item_name] = {}
|
||||
all_items[#all_items + 1] = item_name
|
||||
end
|
||||
table.insert(r_stations_all[item_name], station_id)
|
||||
elseif effective_item_count >= station.p_threshold then
|
||||
if r_stations_all[item_name] == nil then
|
||||
r_stations_all[item_name] = {}
|
||||
p_stations_all[item_name] = {}
|
||||
all_items[#all_items + 1] = item_name
|
||||
end
|
||||
table.insert(p_stations_all[item_name], station_id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
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, ticks_total) do
|
||||
local r_stations = r_stations_all[item_name]
|
||||
local p_stations = p_stations_all[item_name]
|
||||
|
||||
--NOTE: this is an approximation algorithm for solving the assignment problem (bipartite graph weighted matching), the true solution would be to implement the simplex algorithm (and run it twice to compare the locality solution to the round-robin solution) but I strongly believe most factorio players would prefer run-time efficiency over perfect train routing logic
|
||||
if #r_stations > 0 and #p_stations > 0 then
|
||||
if #r_stations <= #p_stations then
|
||||
--probably backpressure, prioritize locality
|
||||
repeat
|
||||
local i = ticks_total%#r_stations + 1
|
||||
local r_station_id = table.remove(r_stations, i)
|
||||
|
||||
local best = 0
|
||||
local best_train = nil
|
||||
local best_dist = INF
|
||||
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 prior = stations[p_station_id].priority
|
||||
if prior > highest_prior or (prior == highest_prior and d < best_dist) then
|
||||
if train then
|
||||
best = j
|
||||
best_dist = d
|
||||
best_train = train
|
||||
highest_prior = prior
|
||||
elseif d < INF then
|
||||
could_have_been_serviced = true
|
||||
end
|
||||
end
|
||||
end
|
||||
if best > 0 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
|
||||
end
|
||||
until #r_stations == 0
|
||||
else
|
||||
--prioritize round robin
|
||||
repeat
|
||||
local j = ticks_total%#p_stations + 1
|
||||
local p_station_id = table.remove(p_stations, j)
|
||||
|
||||
local best = 0
|
||||
local best_train = nil
|
||||
local lowest_tick = INF
|
||||
local highest_prior = -INF
|
||||
local could_have_been_serviced = false
|
||||
for i, r_station_id in ipairs(r_stations) do
|
||||
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)
|
||||
if train then
|
||||
best = i
|
||||
best_train = train
|
||||
lowest_tick = r_station.last_delivery_tick
|
||||
highest_prior = prior
|
||||
elseif d < INF then
|
||||
could_have_been_serviced = true
|
||||
end
|
||||
end
|
||||
end
|
||||
if best > 0 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
|
||||
end
|
||||
until #p_stations == 0
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
60
cybersyn/scripts/global.lua
Normal file
60
cybersyn/scripts/global.lua
Normal file
@@ -0,0 +1,60 @@
|
||||
--By Mami
|
||||
|
||||
--[[
|
||||
global: {
|
||||
total_ticks: int
|
||||
layout_top_id: int
|
||||
stations: {[stop_id]: Station}
|
||||
trains: {[train_id]: Train}
|
||||
trains_available: {[train_id]: bool}
|
||||
layouts: {[layout_id]: Layout}
|
||||
layout_train_count: {[layout_id]: int}
|
||||
}
|
||||
Station: {
|
||||
deliveries_total: int
|
||||
train_limit: int
|
||||
priority: int
|
||||
last_delivery_tick: int
|
||||
r_threshold: int >= 0
|
||||
p_threshold: int >= 0
|
||||
entity: LuaEntity
|
||||
deliveries: {
|
||||
[item_name]: int
|
||||
}
|
||||
--train_layout: [char]
|
||||
accepted_layouts: {
|
||||
[layout_id]: bool
|
||||
}
|
||||
}
|
||||
Train: {
|
||||
entity: LuaEntity
|
||||
entity_in: LuaEntity
|
||||
entity_out: LuaEntity
|
||||
layout_id: int
|
||||
item_slot_capacity: int
|
||||
fluid_capacity: int
|
||||
depot_name: string
|
||||
status: int
|
||||
p_station_id: stop_id
|
||||
r_station_id: stop_id
|
||||
manifest: [{
|
||||
name: string
|
||||
type: string
|
||||
count: int
|
||||
}]
|
||||
}
|
||||
Layout: string
|
||||
]]
|
||||
--TODO: only init once
|
||||
mod_settings = {}
|
||||
mod_settings.tps = settings.global["cybersyn-ticks-per-second"]
|
||||
mod_settings.r_threshold = settings.global["cybersyn-requester-threshold"]
|
||||
mod_settings.p_threshold = settings.global["cybersyn-provider-threshold"]
|
||||
|
||||
global.total_ticks = 0
|
||||
global.stations = {}
|
||||
global.trains = {}
|
||||
global.trains_available = {}
|
||||
global.layouts = {}
|
||||
global.layout_train_count = {}
|
||||
global.layout_top_id = 1
|
||||
563
cybersyn/scripts/main.lua
Normal file
563
cybersyn/scripts/main.lua
Normal file
@@ -0,0 +1,563 @@
|
||||
--By Mami
|
||||
|
||||
|
||||
|
||||
local function on_failed_delivery(map_data, train)
|
||||
--NOTE: must change train status to STATUS_D or remove it from tracked trains after this call
|
||||
local is_p_delivery_made = train.status ~= STATUS_D_TO_P and train.status ~= STATUS_P
|
||||
if not is_p_delivery_made then
|
||||
local station = map_data.stations[train.p_station_id]
|
||||
for i, item in ipairs(train.manifest) do
|
||||
station.deliveries[item.name] = station.deliveries[item.name] + item.count
|
||||
if station.deliveries[item.name] == 0 then
|
||||
station.deliveries[item.name] = nil
|
||||
end
|
||||
end
|
||||
station.deliveries_total = station.deliveries_total - 1
|
||||
if train.status == STATUS_P then
|
||||
--change circuit outputs
|
||||
station.entity_out.get_control_behavior().parameters = nil
|
||||
end
|
||||
end
|
||||
local is_r_delivery_made = train.status == STATUS_R_TO_D
|
||||
if not is_r_delivery_made then
|
||||
local station = map_data.stations[train.r_station_id]
|
||||
for i, item in ipairs(train.manifest) do
|
||||
station.deliveries[item.name] = station.deliveries[item.name] - item.count
|
||||
if station.deliveries[item.name] == 0 then
|
||||
station.deliveries[item.name] = nil
|
||||
end
|
||||
end
|
||||
station.deliveries_total = station.deliveries_total - 1
|
||||
if train.status == STATUS_R then
|
||||
--change circuit outputs
|
||||
station.entity_out.get_control_behavior().parameters = nil
|
||||
end
|
||||
end
|
||||
train.r_station_id = 0
|
||||
train.p_station_id = 0
|
||||
train.manifest = nil
|
||||
end
|
||||
|
||||
local function remove_train(map_data, train, train_id)
|
||||
map_data.trains[train_id] = nil
|
||||
map_data.trains_available[train_id] = nil
|
||||
local layout_id = train.layout_id
|
||||
local count = map_data.layout_train_count[layout_id]
|
||||
if count <= 1 then
|
||||
map_data.layout_train_count[layout_id] = nil
|
||||
map_data.layouts[layout_id] = nil
|
||||
for station_id, station in pairs(map_data.stations) do
|
||||
station.accepted_layouts[layout_id] = nil
|
||||
end
|
||||
else
|
||||
map_data.layout_train_count[layout_id] = count - 1
|
||||
end
|
||||
end
|
||||
|
||||
local function on_station_built(map_data, stop)
|
||||
local pos_x = stop.position.x
|
||||
local pos_y = stop.position.y
|
||||
|
||||
local in_pos
|
||||
local out_pos
|
||||
local direction
|
||||
local search_area
|
||||
if stop.direction == 0 then
|
||||
direction = 0
|
||||
in_pos = {pos_x, pos_y - 1}
|
||||
out_pos = {pos_x - 1, pos_y - 1}
|
||||
search_area = {
|
||||
{pos_x + DELTA - 1, pos_y + DELTA - 1},
|
||||
{pos_x - DELTA + 1, pos_y - DELTA}
|
||||
}
|
||||
elseif stop.direction == 2 then
|
||||
direction = 2
|
||||
in_pos = {pos_x, pos_y}
|
||||
out_pos = {pos_x, pos_y - 1}
|
||||
search_area = {
|
||||
{pos_x + DELTA, pos_y + DELTA - 1},
|
||||
{pos_x - DELTA + 1, pos_y - DELTA + 1}
|
||||
}
|
||||
elseif stop.direction == 4 then
|
||||
direction = 4
|
||||
in_pos = {pos_x - 1, pos_y}
|
||||
out_pos = {pos_x, pos_y}
|
||||
search_area = {
|
||||
{pos_x + DELTA - 1, pos_y + DELTA},
|
||||
{pos_x - DELTA + 1, pos_y - DELTA + 1}
|
||||
}
|
||||
elseif stop.direction == 6 then
|
||||
direction = 6
|
||||
in_pos = {pos_x - 1, pos_y - 1}
|
||||
out_pos = {pos_x - 1, pos_y}
|
||||
search_area = {
|
||||
{pos_x + DELTA - 1, pos_y + DELTA - 1},
|
||||
{pos_x - DELTA, pos_y - DELTA + 1}
|
||||
}
|
||||
else
|
||||
assert(false, "cybersyn: invalid direction of train stop")
|
||||
end
|
||||
|
||||
local entity_in = nil
|
||||
local entity_out = nil
|
||||
local entities = stop.surface.find_entities(search_area)
|
||||
for _, cur_entity in pairs (entities) do
|
||||
if cur_entity.valid then
|
||||
if cur_entity.name == "entity-ghost" then
|
||||
if cur_entity.ghost_name == STATION_IN_NAME then
|
||||
_, entity_in = cur_entity.revive()
|
||||
elseif cur_entity.ghost_name == STATION_OUT_NAME then
|
||||
_, entity_out = cur_entity.revive()
|
||||
end
|
||||
elseif cur_entity.name == STATION_IN_NAME then
|
||||
entity_in = cur_entity
|
||||
elseif cur_entity.name == STATION_OUT_NAME then
|
||||
entity_out = cur_entity
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if entity_in == nil then -- create new
|
||||
entity_in = stop.surface.create_entity({
|
||||
name = STATION_IN_NAME,
|
||||
position = in_pos,
|
||||
force = stop.force
|
||||
})
|
||||
end
|
||||
entity_in.operable = false
|
||||
entity_in.minable = false
|
||||
entity_in.destructible = false
|
||||
|
||||
if entity_out == nil then -- create new
|
||||
entity_out = stop.surface.create_entity({
|
||||
name = STATION_OUT_NAME,
|
||||
position = out_pos,
|
||||
direction = direction,
|
||||
force = stop.force
|
||||
})
|
||||
end
|
||||
entity_out.operable = false
|
||||
entity_out.minable = false
|
||||
entity_out.destructible = false
|
||||
|
||||
local station = {
|
||||
entity = stop,
|
||||
entity_in = entity_in,
|
||||
entity_out = entity_out,
|
||||
deliveries_total = 0,
|
||||
train_limit = 100,
|
||||
priority = 0,
|
||||
last_delivery_tick = 0,
|
||||
r_threshold = 0,
|
||||
p_threshold = 0,
|
||||
accepted_layouts = {}
|
||||
}
|
||||
|
||||
map_data.stations[stop.unit_number] = station
|
||||
end
|
||||
local function on_station_broken(map_data, stop)
|
||||
--search for trains coming to the destroyed station
|
||||
local station_id = stop.unit_number
|
||||
local station = map_data.stations[station_id]
|
||||
for train_id, train in pairs(map_data.trains) do
|
||||
if station.deliveries_total <= 0 then
|
||||
break
|
||||
end
|
||||
local is_p = train.r_station_id == station_id
|
||||
local is_r = train.p_station_id == station_id
|
||||
if is_p or is_r then
|
||||
local is_p_delivery_made = train.status ~= STATUS_D_TO_P and train.status ~= STATUS_P
|
||||
local is_r_delivery_made = train.status == STATUS_R_TO_D
|
||||
if (is_r and not is_r_delivery_made) or (is_p and not is_p_delivery_made) then
|
||||
--train is attempting delivery to a stop that was destroyed, stop it
|
||||
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
|
||||
end
|
||||
end
|
||||
end
|
||||
map_data.stations[station_id] = nil
|
||||
end
|
||||
|
||||
local function on_station_rename(map_data, stop)
|
||||
--search for trains coming to the renamed station
|
||||
local station_id = stop.unit_number
|
||||
local station = map_data.stations[station_id]
|
||||
for train_id, train in pairs(map_data.trains) do
|
||||
if station.deliveries_total <= 0 then
|
||||
break
|
||||
end
|
||||
local is_p = train.r_station_id == station_id
|
||||
local is_r = train.p_station_id == station_id
|
||||
if is_p or is_r then
|
||||
local is_p_delivery_made = train.status ~= STATUS_D_TO_P and train.status ~= STATUS_P
|
||||
local is_r_delivery_made = train.status == STATUS_R_TO_D
|
||||
if (is_r and not is_r_delivery_made) or (is_p and not is_p_delivery_made) then
|
||||
--train is attempting delivery to a stop that was renamed
|
||||
--TODO: test to make sure this code actually works
|
||||
local record = train.entity.schedule.records
|
||||
if is_p then
|
||||
record[3] = create_loading_order(station.entity, train.manifest)
|
||||
else
|
||||
record[5] = create_unloading_order(station.entity)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function find_and_add_all_stations(map_data)
|
||||
for _, surface in pairs(game.surfaces) do
|
||||
local stops = surface.find_entities_filtered({type="train-stop"})
|
||||
if stops then
|
||||
for k, stop in pairs(stops) do
|
||||
if stop.name == BUFFER_STATION_NAME then
|
||||
local station = map_data.stations[stop.unit_number]
|
||||
if not station then
|
||||
on_station_built(map_data, stop)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function update_train_layout(map_data, train)
|
||||
local carriages = train.entity.carriages
|
||||
local layout = ""
|
||||
local i = 1
|
||||
local item_slot_capacity = 0
|
||||
local fluid_capacity = 0
|
||||
for _, carriage in pairs(carriages) do
|
||||
if carriage.type == "cargo-wagon" then
|
||||
layout = layout.."C"
|
||||
item_slot_capacity = item_slot_capacity + carriage.prototype.inventory_size
|
||||
elseif carriage.type == "fluid-wagon" then
|
||||
layout = layout.."F"
|
||||
fluid_capacity = fluid_capacity + carriage.prototype.capacity
|
||||
else
|
||||
layout = layout.."?"
|
||||
end
|
||||
i = i + 1
|
||||
end
|
||||
local layout_id = 0
|
||||
for id, cur_layout in pairs(map_data.layouts) do
|
||||
if layout == cur_layout then
|
||||
layout_id = id
|
||||
break
|
||||
end
|
||||
end
|
||||
if layout_id == 0 then
|
||||
--define new layout
|
||||
layout_id = map_data.layout_top_id
|
||||
map_data.layout_top_id = map_data.layout_top_id + 1
|
||||
|
||||
map_data.layouts[layout_id] = layout
|
||||
map_data.layout_train_count[layout_id] = 1
|
||||
--for station_id, station in pairs(map_data.stations) do
|
||||
-- if #layout >= #station.train_layout then
|
||||
-- local is_approved = true
|
||||
-- for i, v in ipairs(station.train_layout) do
|
||||
-- local c = string.sub(layout, i, i)
|
||||
-- if v == "C" then
|
||||
-- if c ~= "C" and c ~= "?" then
|
||||
-- is_approved = false
|
||||
-- break
|
||||
-- end
|
||||
-- elseif v == "F" then
|
||||
-- if c ~= "F" then
|
||||
-- is_approved = false
|
||||
-- break
|
||||
-- end
|
||||
-- end
|
||||
-- end
|
||||
-- for i = #station.train_layout, #layout do
|
||||
-- local c = string.sub(layout, i, i)
|
||||
-- if c ~= "?" then
|
||||
-- is_approved = false
|
||||
-- break
|
||||
-- end
|
||||
-- end
|
||||
-- if is_approved then
|
||||
-- station.accepted_layouts[layout_id] = true
|
||||
-- end
|
||||
-- end
|
||||
--end
|
||||
else
|
||||
map_data.layout_train_count[layout_id] = map_data.layout_train_count[layout_id] + 1
|
||||
end
|
||||
train.layout_id = layout_id
|
||||
train.item_slot_capacity = item_slot_capacity
|
||||
train.fluid_capacity = fluid_capacity
|
||||
end
|
||||
|
||||
|
||||
local function on_train_arrives_depot(map_data, train_entity)
|
||||
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 = {current = 1, records = {create_inactivity_order(train.depot_name)}}
|
||||
map_data.trains_available[train_entity.id] = true
|
||||
else
|
||||
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
|
||||
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
|
||||
end
|
||||
end
|
||||
else
|
||||
train = {
|
||||
depot_name = train_entity.station.backer_name,
|
||||
status = STATUS_D,
|
||||
entity = train_entity,
|
||||
layout_id = 0,
|
||||
item_slot_capacity = 0,
|
||||
fluid_capacity = 0,
|
||||
p_station = 0,
|
||||
r_station = 0,
|
||||
manifest = nil,
|
||||
}
|
||||
update_train_layout(train)
|
||||
map_data.trains[train_entity.id] = train
|
||||
map_data.trains_available[train_entity.id] = true
|
||||
end
|
||||
end
|
||||
|
||||
local function on_train_arrives_buffer(map_data, station_id, train)
|
||||
if train.manifest then
|
||||
if train.status == STATUS_D_TO_P then
|
||||
if train.p_station_id == station_id then
|
||||
train.status = STATUS_P
|
||||
--change circuit outputs
|
||||
local station = map_data.stations[station_id]
|
||||
local signals = {}
|
||||
for i, item in ipairs(train.manifest) do
|
||||
signals[i] = {index = i, signal = {type = item.type, name = item.name}, count = item.count}
|
||||
end
|
||||
station.entity_out.get_control_behavior().parameters = signals
|
||||
end
|
||||
elseif train.status == STATUS_P_TO_R then
|
||||
if train.r_station_id == station_id then
|
||||
train.status = STATUS_R
|
||||
--change circuit outputs
|
||||
local station = map_data.stations[station_id]
|
||||
local signals = {}
|
||||
for i, item in ipairs(train.manifest) do
|
||||
signals[i] = {index = i, signal = {type = item.type, name = item.name}, count = -1}
|
||||
end
|
||||
station.entity_out.get_control_behavior().parameters = signals
|
||||
end
|
||||
else
|
||||
on_failed_delivery(map_data, train)
|
||||
remove_train(map_data, train, train.entity.id)
|
||||
end
|
||||
else
|
||||
--train is lost somehow, probably from player intervention
|
||||
remove_train(map_data, train, train.entity.id)
|
||||
end
|
||||
end
|
||||
|
||||
local function on_train_leaves_station(map_data, train)
|
||||
if train.manifest then
|
||||
if train.status == STATUS_P then
|
||||
train.status = STATUS_P_TO_R
|
||||
local station = map_data.stations[train.p_station_id]
|
||||
for i, item in ipairs(train.manifest) do
|
||||
station.deliveries[item.name] = station.deliveries[item.name] + item.count
|
||||
if station.deliveries[item.name] == 0 then
|
||||
station.deliveries[item.name] = nil
|
||||
end
|
||||
end
|
||||
station.deliveries_total = station.deliveries_total - 1
|
||||
--change circuit outputs
|
||||
station.entity_out.get_control_behavior().parameters = nil
|
||||
elseif train.status == STATUS_R then
|
||||
train.status = STATUS_R_TO_D
|
||||
local station = map_data.stations[train.r_station_id]
|
||||
for i, item in ipairs(train.manifest) do
|
||||
station.deliveries[item.name] = station.deliveries[item.name] - item.count
|
||||
if station.deliveries[item.name] == 0 then
|
||||
station.deliveries[item.name] = nil
|
||||
end
|
||||
end
|
||||
station.deliveries_total = station.deliveries_total - 1
|
||||
--change circuit outputs
|
||||
station.entity_out.get_control_behavior().parameters = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
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)
|
||||
end
|
||||
end
|
||||
|
||||
local function on_train_modified(map_data, pre_train_id, train_entity)
|
||||
local train = map_data.trains[pre_train_id]
|
||||
if train then
|
||||
|
||||
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
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
local function on_tick(event)
|
||||
tick(global, mod_settings)
|
||||
global.total_ticks = global.total_ticks + 1
|
||||
end
|
||||
|
||||
local function on_built(event)
|
||||
local entity = event.entity or event.created_entity or event.destination
|
||||
if not entity or not entity.valid then return end
|
||||
if entity.name == BUFFER_STATION_NAME then
|
||||
on_station_built(global, entity)
|
||||
elseif entity.type == "inserter" then
|
||||
elseif entity.type == "pump" then
|
||||
if entity.pump_rail_target then
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
local function on_broken(event)
|
||||
local entity = event.entity
|
||||
if not entity or not entity.valid then return end
|
||||
|
||||
if entity.train then
|
||||
local train = global.trains[entity.id]
|
||||
if train then
|
||||
on_train_broken(global, entity.train)
|
||||
end
|
||||
elseif entity.name == BUFFER_STATION_NAME then
|
||||
on_station_broken(entity.unit_number)
|
||||
elseif entity.type == "inserter" then
|
||||
elseif entity.type == "pump" then
|
||||
end
|
||||
end
|
||||
|
||||
local function on_train_changed(event)
|
||||
local train_e = event.train
|
||||
local train = global.trains[train_e.id]
|
||||
if train_e.state == defines.train_state.wait_station and train_e.station ~= nil then
|
||||
if train_e.station.name == DEPOT_STATION_NAME then
|
||||
on_train_arrives_depot(global, train_e)
|
||||
elseif train_e.station.name == BUFFER_STATION_NAME then
|
||||
if train then
|
||||
on_train_arrives_buffer(global, train_e.station.unit_number, train)
|
||||
end
|
||||
end
|
||||
elseif event.old_state == defines.train_state.wait_station then
|
||||
if train then
|
||||
on_train_leaves_station(global, train)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function on_train_built(event)
|
||||
local train_e = event.train
|
||||
if event.old_train_id_1 then
|
||||
on_train_modified(global, event.old_train_id_1, train_e)
|
||||
end
|
||||
if event.old_train_id_2 then
|
||||
on_train_modified(global, event.old_train_id_2, train_e)
|
||||
end
|
||||
end
|
||||
|
||||
local function on_surface_removed(event)
|
||||
local surface = game.surfaces[event.surface_index]
|
||||
if surface then
|
||||
local train_stops = surface.find_entities_filtered({type = "train-stop"})
|
||||
for _, entity in pairs(train_stops) do
|
||||
if entity.name == BUFFER_STATION_NAME then
|
||||
on_station_broken(entity.unit_number)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function on_rename(event)
|
||||
if event.entity.name == BUFFER_STATION_NAME then
|
||||
on_station_rename(global, event.entity)
|
||||
end
|
||||
end
|
||||
|
||||
local filter_built = {
|
||||
{filter = "type", type = "train-stop"},
|
||||
{filter = "type", type = "inserter"},
|
||||
{filter = "type", type = "pump"},
|
||||
}
|
||||
local filter_broken = {
|
||||
{filter = "type", type = "train-stop"},
|
||||
{filter = "type", type = "inserter"},
|
||||
{filter = "type", type = "pump"},
|
||||
{filter = "rolling-stock"},
|
||||
}
|
||||
local function register_events()
|
||||
--NOTE: I have no idea if this correctly registers all events once in all situations
|
||||
script.on_event(defines.events.on_built_entity, on_built, filter_built)
|
||||
script.on_event(defines.events.on_robot_built_entity, on_built, filter_built)
|
||||
script.on_event({defines.events.script_raised_built, defines.events.script_raised_revive, defines.events.on_entity_cloned}, on_built)
|
||||
|
||||
script.on_event(defines.events.on_pre_player_mined_item, on_broken, filter_broken)
|
||||
script.on_event(defines.events.on_robot_pre_mined, on_broken, filter_broken)
|
||||
script.on_event(defines.events.on_entity_died, on_broken, filter_broken)
|
||||
script.on_event(defines.events.script_raised_destroy, on_broken)
|
||||
|
||||
script.on_event({defines.events.on_pre_surface_deleted, defines.events.on_pre_surface_cleared}, on_surface_removed)
|
||||
|
||||
local nth_tick = math.ceil(60/mod_settings.tps);
|
||||
script.on_nth_tick(nil)
|
||||
script.on_nth_tick(nth_tick, on_tick)
|
||||
|
||||
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)
|
||||
end
|
||||
|
||||
script.on_load(function()
|
||||
register_events()
|
||||
end)
|
||||
|
||||
script.on_init(function()
|
||||
--TODO: we are not checking changed cargo capacities
|
||||
find_and_add_all_stations(global)
|
||||
register_events()
|
||||
end)
|
||||
|
||||
script.on_configuration_changed(function(data)
|
||||
--TODO: we are not checking changed cargo capacities
|
||||
find_and_add_all_stations(global)
|
||||
register_events()
|
||||
end)
|
||||
30
cybersyn/settings.lua
Normal file
30
cybersyn/settings.lua
Normal file
@@ -0,0 +1,30 @@
|
||||
--By cybersyn
|
||||
data:extend({
|
||||
{
|
||||
type = "int-setting",
|
||||
name = "cybersyn-ticks-per-second",
|
||||
order = "aa",
|
||||
setting_type = "runtime-global",
|
||||
default_value = 10,
|
||||
minimum_value = 1,
|
||||
maximum_value = 60,
|
||||
},
|
||||
{
|
||||
type = "int-setting",
|
||||
name = "cybersyn-requester-threshold",
|
||||
order = "ab",
|
||||
setting_type = "runtime-global",
|
||||
default_value = 1000000000,
|
||||
minimum_value = 1,
|
||||
maximum_value = 2147483647,
|
||||
},
|
||||
{
|
||||
type = "int-setting",
|
||||
name = "cybersyn-provider-threshold",
|
||||
order = "ac",
|
||||
setting_type = "runtime-global",
|
||||
default_value = 1000000000,
|
||||
minimum_value = 1,
|
||||
maximum_value = 2147483647,
|
||||
},
|
||||
})
|
||||
Reference in New Issue
Block a user