Add 'prescient trains'
This commit is contained in:
commit
8320be0f5c
2
lua/prescient-trains/.gitignore
vendored
Normal file
2
lua/prescient-trains/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
stdlib
|
||||||
|
prototypes/debug.txt
|
33
lua/prescient-trains/.neoconf.json
Normal file
33
lua/prescient-trains/.neoconf.json
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
{
|
||||||
|
"lspconfig": {
|
||||||
|
"sumneko_lua": {
|
||||||
|
"Lua.workspace.library": [
|
||||||
|
"/home/adrielus/Projects/Foreign/vscode-factoriomod-debug/sumneko-3rd/factorio/library",
|
||||||
|
"/home/adrielus/.steam/steam/steamapps/common/Factorio/data"
|
||||||
|
],
|
||||||
|
"Lua.runtime.plugin": "/home/adrielus/Projects/Foreign/vscode-factoriomod-debug/sumneko-3rd/factorio/plugin.lua",
|
||||||
|
"Lua.workspace.checkThirdParty": false,
|
||||||
|
"Lua.runtime.version": "Lua 5.2",
|
||||||
|
"Lua.runtime.special": {
|
||||||
|
"__object_name": "type"
|
||||||
|
},
|
||||||
|
"Lua.runtime.builtin": {
|
||||||
|
"io": "disable",
|
||||||
|
"os": "disable",
|
||||||
|
"coroutine": "disable",
|
||||||
|
"package": "disable",
|
||||||
|
"math": "disable",
|
||||||
|
"debug": "disable"
|
||||||
|
},
|
||||||
|
"Lua.diagnostics.globals": [
|
||||||
|
"__DebugAdapter",
|
||||||
|
"__Profiler"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"neodev": {
|
||||||
|
"library": {
|
||||||
|
"enabled": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
lua/prescient-trains/common/constants.lua
Normal file
11
lua/prescient-trains/common/constants.lua
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
local M = {}
|
||||||
|
|
||||||
|
M.item_name = "dispatcher-train-stop"
|
||||||
|
M.input_item_name = M.item_name .. "-input"
|
||||||
|
|
||||||
|
-- Distance from rails for each stop type.
|
||||||
|
-- Useful if, in the future, I decide to
|
||||||
|
-- add support for cargo ships
|
||||||
|
M.stop_offsets = { [M.item_name] = 0 }
|
||||||
|
|
||||||
|
return M
|
1
lua/prescient-trains/control.lua
Normal file
1
lua/prescient-trains/control.lua
Normal file
|
@ -0,0 +1 @@
|
||||||
|
require("scripts.train_stop_events").setup()
|
4
lua/prescient-trains/data.lua
Normal file
4
lua/prescient-trains/data.lua
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
require("prototypes.technologies")
|
||||||
|
require("prototypes.recipes")
|
||||||
|
require("prototypes.items")
|
||||||
|
require("prototypes.entities")
|
9
lua/prescient-trains/info.json
Normal file
9
lua/prescient-trains/info.json
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
"name": "tinker-with-schedules",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"title": "Tinker with schedules",
|
||||||
|
"author": "Adriel",
|
||||||
|
"factorio_version": "1.1",
|
||||||
|
"dependencies": ["base >= 1.1", "stdlib >= 1.4"],
|
||||||
|
"description": "Let's you use combinators to add temporary stops to train schedules"
|
||||||
|
}
|
25
lua/prescient-trains/locale/en/en.cfg
Normal file
25
lua/prescient-trains/locale/en/en.cfg
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
[mod-setting-name]
|
||||||
|
|
||||||
|
[mod-setting-description]
|
||||||
|
|
||||||
|
[entity-name]
|
||||||
|
dispatcher-train-stop=Dispatcher
|
||||||
|
dispatcher-train-stop-input=Dispatcher input
|
||||||
|
|
||||||
|
[entity-description]
|
||||||
|
dispatcher-train-stop=Allows you to add temporary stops to train schedules using signals
|
||||||
|
dispatcher-train-stop-input=Listens for signals coming from the exterior
|
||||||
|
|
||||||
|
[item-name]
|
||||||
|
dispatcher-train-stop=Dispatcher
|
||||||
|
dispatcher-train-stop-input=Dispatcher input
|
||||||
|
|
||||||
|
[item-description]
|
||||||
|
dispatcher-train-stop=Allows you to add temporary stops to train schedules using signals
|
||||||
|
dispatcher-train-stop-input=Uh, why is this here
|
||||||
|
|
||||||
|
[technology-name]
|
||||||
|
tinker-with-schedules=Tinker with schedules
|
||||||
|
|
||||||
|
[technology-description]
|
||||||
|
tinker-with-schedules=Allows you to add temporary stops to train schedules using signals
|
44
lua/prescient-trains/prototypes/entities.lua
Normal file
44
lua/prescient-trains/prototypes/entities.lua
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
local C = require("common.constants")
|
||||||
|
|
||||||
|
local function copy(from, name)
|
||||||
|
local copied = table.deepcopy(from)
|
||||||
|
copied.name = name
|
||||||
|
copied.minable.result = name
|
||||||
|
|
||||||
|
return copied
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Train stop
|
||||||
|
-- {{{
|
||||||
|
local dispatcher_train_stop = copy(data.raw["train-stop"]["train-stop"],
|
||||||
|
C.item_name)
|
||||||
|
|
||||||
|
dispatcher_train_stop.color = {r = 0.46, g = 0.01, b = 0.98, a = 1}
|
||||||
|
dispatcher_train_stop.next_upgrade = nil
|
||||||
|
dispatcher_train_stop.selection_box = {{-0.9, -0.6}, {0.9, 0.9}}
|
||||||
|
-- }}}
|
||||||
|
|
||||||
|
-- Input
|
||||||
|
-- {{{
|
||||||
|
local dispatcher_train_stop_in = copy(data.raw["lamp"]["small-lamp"],
|
||||||
|
C.input_item_name)
|
||||||
|
|
||||||
|
dispatcher_train_stop_in.minable = nil
|
||||||
|
dispatcher_train_stop_in.next_upgrade = nil
|
||||||
|
|
||||||
|
dispatcher_train_stop_in.selection_box = {{-0.5, -0.5}, {0.5, 0.5}}
|
||||||
|
dispatcher_train_stop_in.selection_priority =
|
||||||
|
(dispatcher_train_stop_in.selection_priority or 50) + 10
|
||||||
|
|
||||||
|
dispatcher_train_stop_in.collision_box = {{-0.15, -0.15}, {0.15, 0.15}}
|
||||||
|
dispatcher_train_stop_in.collision_mask = {"rail-layer"} -- collide only with rail entities
|
||||||
|
|
||||||
|
dispatcher_train_stop_in.light = {intensity = 1, size = 6}
|
||||||
|
dispatcher_train_stop_in.energy_source = {type = "void"}
|
||||||
|
dispatcher_train_stop_in.energy_usage_per_tick = "10W"
|
||||||
|
dispatcher_train_stop_in.selectable_in_game = true
|
||||||
|
|
||||||
|
dispatcher_train_stop_in.flags = {"placeable-off-grid", "player-creation"}
|
||||||
|
-- }}}
|
||||||
|
|
||||||
|
data:extend({dispatcher_train_stop, dispatcher_train_stop_in})
|
24
lua/prescient-trains/prototypes/items.lua
Normal file
24
lua/prescient-trains/prototypes/items.lua
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
local C = require("common.constants")
|
||||||
|
|
||||||
|
local item_dispatcher_train_stop =
|
||||||
|
table.deepcopy(data.raw["item"]["train-stop"])
|
||||||
|
|
||||||
|
item_dispatcher_train_stop.name = C.item_name
|
||||||
|
item_dispatcher_train_stop.order = item_dispatcher_train_stop.order .. "-c"
|
||||||
|
item_dispatcher_train_stop.icon_size = 64
|
||||||
|
item_dispatcher_train_stop.place_result = C.item_name
|
||||||
|
item_dispatcher_train_stop.icons = {
|
||||||
|
{
|
||||||
|
icon = "__base__/graphics/icons/train-stop.png",
|
||||||
|
tint = {r = 0.46, g = 0.01, b = 0.98, a = 0.1}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
local item_dispatcher_train_stop_in = table.deepcopy(
|
||||||
|
data.raw["item"]["small-lamp"])
|
||||||
|
|
||||||
|
item_dispatcher_train_stop_in.name = C.input_item_name
|
||||||
|
item_dispatcher_train_stop_in.place_result = C.input_item_name
|
||||||
|
item_dispatcher_train_stop_in.flags = {"hidden"}
|
||||||
|
|
||||||
|
data:extend({item_dispatcher_train_stop, item_dispatcher_train_stop_in})
|
14
lua/prescient-trains/prototypes/recipes.lua
Normal file
14
lua/prescient-trains/prototypes/recipes.lua
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
local C = require("common.constants")
|
||||||
|
|
||||||
|
data:extend({
|
||||||
|
{
|
||||||
|
type = "recipe",
|
||||||
|
name = C.item_name,
|
||||||
|
energy_required = 5,
|
||||||
|
enabled = false,
|
||||||
|
ingredients = {
|
||||||
|
{"train-stop", 1}, {"electronic-circuit", 20}, {"copper-cable", 20}
|
||||||
|
},
|
||||||
|
result = C.item_name
|
||||||
|
}
|
||||||
|
})
|
20
lua/prescient-trains/prototypes/technologies.lua
Normal file
20
lua/prescient-trains/prototypes/technologies.lua
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
local C = require("common.constants")
|
||||||
|
|
||||||
|
data:extend({
|
||||||
|
{
|
||||||
|
type = "technology",
|
||||||
|
name = "tinker-with-schedules",
|
||||||
|
icon_size = 256,
|
||||||
|
icon = "__base__/graphics/technology/automated-rail-transportation.png",
|
||||||
|
effects = { { type = "unlock-recipe", recipe = C.item_name } },
|
||||||
|
prerequisites = { "automated-rail-transportation", "circuit-network" },
|
||||||
|
unit = {
|
||||||
|
count = 100,
|
||||||
|
ingredients = {
|
||||||
|
{ "automation-science-pack", 1 }, { "logistic-science-pack", 1 }
|
||||||
|
},
|
||||||
|
time = 15
|
||||||
|
},
|
||||||
|
order = "c-g-aa"
|
||||||
|
}
|
||||||
|
})
|
73
lua/prescient-trains/scripts/helpers.lua
Normal file
73
lua/prescient-trains/scripts/helpers.lua
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
local M = {}
|
||||||
|
|
||||||
|
-- See [this original implementation](https://github.com/coltonj96/UsefulCombinators/blob/master/UsefulCombinators_0.4.4/control.lua#L2062)
|
||||||
|
---Get the total count of some signal in some control behavior.
|
||||||
|
---@param control LuaControlBehavior
|
||||||
|
---@param signal SignalID
|
||||||
|
function M.get_signal_count(control, signal)
|
||||||
|
if not signal then
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
|
||||||
|
local red = control.get_circuit_network(defines.wire_type.red)
|
||||||
|
local green = control.get_circuit_network(defines.wire_type.green)
|
||||||
|
|
||||||
|
local total = 0
|
||||||
|
|
||||||
|
if red then
|
||||||
|
total = total + (red.get_signal(signal) or 0)
|
||||||
|
end
|
||||||
|
|
||||||
|
if green then
|
||||||
|
total = total + (green.get_signal(signal) or 0)
|
||||||
|
end
|
||||||
|
|
||||||
|
return total
|
||||||
|
end
|
||||||
|
|
||||||
|
---Returns the index if going past #array or under 1 would loop back the other side.
|
||||||
|
---Assumes the array is nonempty
|
||||||
|
---@generic T
|
||||||
|
---@param array T[]
|
||||||
|
---@param index integer
|
||||||
|
---@returns integer
|
||||||
|
---@nodiscard
|
||||||
|
function M.mod_index(array, index)
|
||||||
|
return (index - 1) % #array + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
---Uses the above function to normalize the index between the start and end of the array.
|
||||||
|
---Assumes the array is nonempty
|
||||||
|
---@generic T
|
||||||
|
---@param array T[]
|
||||||
|
---@param index integer
|
||||||
|
---@return T
|
||||||
|
---@nodiscard
|
||||||
|
function M.get_cycled(array, index)
|
||||||
|
return array[M.mod_index(array, index)]
|
||||||
|
end
|
||||||
|
|
||||||
|
---Annotated version of table.inset
|
||||||
|
---@generic T
|
||||||
|
---@param list T[]
|
||||||
|
---@param at integer
|
||||||
|
---@param value T
|
||||||
|
function M.list_insert(list, at, value)
|
||||||
|
table.insert(list, at, value)
|
||||||
|
end
|
||||||
|
|
||||||
|
---Shallow copies some table
|
||||||
|
---@generic T :table
|
||||||
|
---@param object T
|
||||||
|
---@return T
|
||||||
|
function M.copy(object)
|
||||||
|
local result = {}
|
||||||
|
|
||||||
|
for k, v in pairs(object) do
|
||||||
|
result[k] = v
|
||||||
|
end
|
||||||
|
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
|
return M
|
6
lua/prescient-trains/scripts/settings.lua
Normal file
6
lua/prescient-trains/scripts/settings.lua
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
local M = {}
|
||||||
|
|
||||||
|
M.message_level = tonumber(settings.global["tws-interface-console-level"].value)
|
||||||
|
M.debug_log = settings.global["tws-interface-debug-logfile"].value
|
||||||
|
|
||||||
|
return M
|
313
lua/prescient-trains/scripts/train_stop_events.lua
Normal file
313
lua/prescient-trains/scripts/train_stop_events.lua
Normal file
|
@ -0,0 +1,313 @@
|
||||||
|
local Entity = require("__stdlib__/stdlib/entity/entity")
|
||||||
|
local Direction = require("__stdlib__/stdlib/area/direction")
|
||||||
|
local Position = require("__stdlib__/stdlib/area/position")
|
||||||
|
local Area = require("__stdlib__/stdlib/area/area")
|
||||||
|
|
||||||
|
local H = require("scripts.helpers")
|
||||||
|
local C = require("common.constants")
|
||||||
|
|
||||||
|
-- local settings = require("scripts.settings")
|
||||||
|
|
||||||
|
local M = {}
|
||||||
|
|
||||||
|
---@class DispatcherTrainStopData
|
||||||
|
---@field entity LuaEntity
|
||||||
|
---@field input LuaEntity
|
||||||
|
|
||||||
|
---Gets the data attached to a dispatcher
|
||||||
|
---@param entity LuaEntity
|
||||||
|
---@return DispatcherTrainStopData|nil
|
||||||
|
---@nodiscard
|
||||||
|
local function get_dispatcher_data(entity)
|
||||||
|
if not global.tws_dispatchers then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
return global.tws_dispatchers[entity.unit_number]
|
||||||
|
end
|
||||||
|
|
||||||
|
---Attaches some data to a dispatcher
|
||||||
|
---@param entity LuaEntity
|
||||||
|
---@param value DispatcherTrainStopData|nil
|
||||||
|
local function set_dispatcher_data(entity, value)
|
||||||
|
if not global.tws_dispatchers then
|
||||||
|
global.tws_dispatchers = {}
|
||||||
|
end
|
||||||
|
|
||||||
|
global.tws_dispatchers[entity.unit_number] = value
|
||||||
|
end
|
||||||
|
|
||||||
|
-- {{{ CreateStop
|
||||||
|
---Runs when a stop gets created
|
||||||
|
---@param entity LuaEntity
|
||||||
|
local function CreateStop(entity)
|
||||||
|
if get_dispatcher_data(entity) then
|
||||||
|
-- TODO: better logs
|
||||||
|
game.print("Duplicate unit number, wtf")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local stop_offset = C.stop_offsets[entity.name]
|
||||||
|
local offset_adjustment = (not stop_offset) and stop_offset
|
||||||
|
or Direction.to_vector(Direction.next(entity.direction), stop_offset)
|
||||||
|
-- local offset_adjustment = 0
|
||||||
|
---@type MapPosition
|
||||||
|
local input_position = Position(entity.position)
|
||||||
|
+ offset_adjustment
|
||||||
|
-- Moves the center we rotate around to the
|
||||||
|
-- center of the top-left block,
|
||||||
|
-- Position(0.5, 0.5) +
|
||||||
|
-- then rotates counterclockwise once,
|
||||||
|
-- and go 0.5 more in that direction
|
||||||
|
-- Direction.to_vector(
|
||||||
|
-- Direction.next(entity.direction, true), 0.5)
|
||||||
|
+ Direction.to_vector(entity.direction, 0.5)
|
||||||
|
|
||||||
|
local search_area = Area.shrink(Area.new({ input_position }), 0.001)
|
||||||
|
|
||||||
|
local input
|
||||||
|
|
||||||
|
-- {{{ Handle blueprint ghosts and existing IO entities preserving circuit connections
|
||||||
|
local ghosts = entity.surface.find_entities(search_area)
|
||||||
|
for _, ghost in pairs(ghosts) do
|
||||||
|
if ghost.valid then
|
||||||
|
if ghost.name == "entity-ghost" then
|
||||||
|
if ghost.ghost_name == C.input_item_name then
|
||||||
|
_, input = ghost.revive()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- something has built I/O already (e.g.) Creative Mode Instant Blueprint
|
||||||
|
elseif ghost.name == C.input_item_name then
|
||||||
|
input = ghost
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- }}}
|
||||||
|
|
||||||
|
if input == nil then -- create new
|
||||||
|
input = entity.surface.create_entity({
|
||||||
|
name = C.input_item_name,
|
||||||
|
position = input_position,
|
||||||
|
force = entity.force,
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
if input == nil then
|
||||||
|
-- TODO: logging
|
||||||
|
game.print("Something went wrong")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
input.operable = false -- disable gui
|
||||||
|
input.minable = false
|
||||||
|
input.destructible = false -- don't bother checking if alive
|
||||||
|
|
||||||
|
---@type DispatcherTrainStopData
|
||||||
|
local stop_data = { entity = entity, input = input }
|
||||||
|
|
||||||
|
set_dispatcher_data(entity, stop_data)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- }}}
|
||||||
|
-- {{{ OnEntityCreated
|
||||||
|
local function OnEntityCreated(event)
|
||||||
|
local entity = event.created_entity or event.entity or event.destination
|
||||||
|
|
||||||
|
if not entity or not entity.valid then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if entity.name == C.item_name then
|
||||||
|
CreateStop(entity)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- }}}
|
||||||
|
-- {{{ RemoveStop
|
||||||
|
---Runs once a train stop has been removed.
|
||||||
|
---@param entity LuaEntity
|
||||||
|
---@param create_ghosts boolean
|
||||||
|
function RemoveStop(entity, create_ghosts)
|
||||||
|
local stop = get_dispatcher_data(entity)
|
||||||
|
|
||||||
|
-- {{{ Destroy io entities
|
||||||
|
if stop then
|
||||||
|
---@type LuaEntity
|
||||||
|
local input = stop.input
|
||||||
|
|
||||||
|
if input and input.valid then
|
||||||
|
if create_ghosts then
|
||||||
|
input.destructable = true
|
||||||
|
input.die()
|
||||||
|
else
|
||||||
|
input.destroy()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- }}}
|
||||||
|
|
||||||
|
-- Delete entity data
|
||||||
|
set_dispatcher_data(entity, nil)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- }}}
|
||||||
|
-- {{{ OnEntityRemoved
|
||||||
|
---Runs when any kind of entity has been removed.
|
||||||
|
---@param event EventData.on_entity_died|EventData.script_raised_destroy|EventData.on_robot_pre_mined|EventData.on_pre_player_mined_item
|
||||||
|
---@param create_ghosts any
|
||||||
|
function OnEntityRemoved(event, create_ghosts)
|
||||||
|
local entity = event.entity
|
||||||
|
|
||||||
|
if not entity or not entity.valid then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if entity.name == C.item_name then
|
||||||
|
RemoveStop(entity, create_ghosts)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- }}}
|
||||||
|
-- {{{ Remove entity data when surfaces get removed.
|
||||||
|
---@param event EventData.on_pre_surface_deleted|EventData.on_pre_surface_cleared
|
||||||
|
function OnSurfaceRemoved(event)
|
||||||
|
-- stop references
|
||||||
|
local surfaceID = event.surface_index
|
||||||
|
local surface = game.surfaces[surfaceID]
|
||||||
|
|
||||||
|
if surface then
|
||||||
|
local train_stops = surface.find_entities_filtered({ type = "train-stop" })
|
||||||
|
|
||||||
|
for _, entity in pairs(train_stops) do
|
||||||
|
if entity.name == C.item_name then
|
||||||
|
RemoveStop(entity, false)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- }}}
|
||||||
|
-- {{{ UpdateSchedule
|
||||||
|
---Runs every tick to update train schedules
|
||||||
|
---@param stop DispatcherTrainStopData
|
||||||
|
function UpdateSchedule(stop)
|
||||||
|
local control = stop.input.get_or_create_control_behavior()
|
||||||
|
|
||||||
|
if not control or not control.valid then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local signals = {
|
||||||
|
action_create = { type = "virtual", name = "signal-C" },
|
||||||
|
action_jump = { type = "virtual", name = "signal-J" },
|
||||||
|
target_after = { type = "virtual", name = "signal-A" },
|
||||||
|
target_before = { type = "virtual", name = "signal-B" },
|
||||||
|
template_past = { type = "virtual", name = "signal-P" },
|
||||||
|
template_future = { type = "virtual", name = "signal-F" },
|
||||||
|
option_infinite = { type = "virtual", name = "signal-O" },
|
||||||
|
option_extend = { type = "virtual", name = "signal-E" },
|
||||||
|
}
|
||||||
|
|
||||||
|
local create = H.get_signal_count(control, signals.action_create)
|
||||||
|
local jump = H.get_signal_count(control, signals.action_jump)
|
||||||
|
|
||||||
|
local train = stop.entity.get_stopped_train()
|
||||||
|
|
||||||
|
if not train or not train.valid then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local schedule = train.schedule
|
||||||
|
|
||||||
|
if not schedule then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
schedule = H.copy(schedule)
|
||||||
|
|
||||||
|
if create > 0 then
|
||||||
|
local target_after = H.get_signal_count(control, signals.target_after)
|
||||||
|
local target_before = H.get_signal_count(control, signals.target_before)
|
||||||
|
local target_index = schedule.current + target_after - target_before
|
||||||
|
|
||||||
|
local template_future = H.get_signal_count(control, signals.template_future)
|
||||||
|
local template_past = H.get_signal_count(control, signals.template_past)
|
||||||
|
local template_index = schedule.current + template_future - template_past
|
||||||
|
|
||||||
|
local template = H.get_cycled(schedule.records, template_index)
|
||||||
|
local copy = H.copy(template)
|
||||||
|
|
||||||
|
local is_temporary = 0 == H.get_signal_count(control, signals.option_infinite)
|
||||||
|
copy.temporary = is_temporary
|
||||||
|
|
||||||
|
local extend = H.get_signal_count(control, signals.option_extend)
|
||||||
|
|
||||||
|
if extend > 0 and copy.station then
|
||||||
|
copy.station = copy.station .. " " .. tostring(extend)
|
||||||
|
end
|
||||||
|
|
||||||
|
H.list_insert(schedule.records, target_index, copy)
|
||||||
|
|
||||||
|
train.schedule = schedule
|
||||||
|
end
|
||||||
|
|
||||||
|
if jump > 0 and #schedule.records > 0 then
|
||||||
|
schedule.current = (schedule.current + jump - 1) % #schedule.records + 1
|
||||||
|
|
||||||
|
train.schedule = schedule
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- }}}
|
||||||
|
-- {{{ OnTick
|
||||||
|
function OnTick()
|
||||||
|
for _, v in pairs(global.tws_dispatchers or {}) do
|
||||||
|
UpdateSchedule(v)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- }}}
|
||||||
|
|
||||||
|
function M.setup()
|
||||||
|
local filters_on_built = { { filter = "type", type = "train-stop" } }
|
||||||
|
local filters_on_mined = { { filter = "type", type = "train-stop" } }
|
||||||
|
|
||||||
|
-- {{{ On create events
|
||||||
|
local on_create_events = {
|
||||||
|
defines.events.on_built_entity,
|
||||||
|
defines.events.on_robot_built_entity,
|
||||||
|
defines.events.script_raised_built,
|
||||||
|
defines.events.script_raised_revive,
|
||||||
|
defines.events.on_entity_cloned,
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, event in pairs(on_create_events) do
|
||||||
|
script.on_event(event, OnEntityCreated, filters_on_built)
|
||||||
|
end
|
||||||
|
-- }}}
|
||||||
|
-- {{{ On remove events
|
||||||
|
local on_remove_events = {
|
||||||
|
defines.events.on_pre_player_mined_item,
|
||||||
|
defines.events.on_robot_pre_mined,
|
||||||
|
defines.events.script_raised_destroy,
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, event in pairs(on_remove_events) do
|
||||||
|
script.on_event(event, OnEntityRemoved, filters_on_mined)
|
||||||
|
end
|
||||||
|
|
||||||
|
script.on_event(defines.events.on_entity_died, function(event)
|
||||||
|
OnEntityRemoved(event, true)
|
||||||
|
end, filters_on_mined)
|
||||||
|
-- }}}
|
||||||
|
-- {{{ On surface removed
|
||||||
|
script.on_event({
|
||||||
|
defines.events.on_pre_surface_deleted,
|
||||||
|
defines.events.on_pre_surface_cleared,
|
||||||
|
}, OnSurfaceRemoved)
|
||||||
|
-- }}}
|
||||||
|
|
||||||
|
script.on_event(defines.events.on_tick, OnTick)
|
||||||
|
end
|
||||||
|
|
||||||
|
return M
|
16
lua/prescient-trains/settings_.lua
Normal file
16
lua/prescient-trains/settings_.lua
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
data:extend({
|
||||||
|
{
|
||||||
|
type = "bool-setting",
|
||||||
|
name = "tws-interface-debug-logfile",
|
||||||
|
order = "ah",
|
||||||
|
setting_type = "runtime-global",
|
||||||
|
default_value = false
|
||||||
|
}, {
|
||||||
|
type = "string-setting",
|
||||||
|
name = "tws-interface-console-level",
|
||||||
|
order = "ad",
|
||||||
|
setting_type = "runtime-global",
|
||||||
|
default_value = "2",
|
||||||
|
allowed_values = {"0", "1", "2", "3"}
|
||||||
|
}
|
||||||
|
})
|
3
lua/prescient-trains/stylua.toml
Normal file
3
lua/prescient-trains/stylua.toml
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
column_width = 80
|
||||||
|
indent_width = 2
|
||||||
|
indent_type = "Spaces"
|
Loading…
Reference in a new issue