-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathcontrol.lua
More file actions
177 lines (167 loc) · 6.68 KB
/
control.lua
File metadata and controls
177 lines (167 loc) · 6.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
local settings_enabled = settings.global["Noxys_Multidirectional_Trains-enabled"].value
local settings_nth_tick = settings.global["Noxys_Multidirectional_Trains-on_nth_tick"].value
local settings_station_limits = settings.global["Noxys_Multidirectional_Trains-station_limits"].value
local function rotate(loco)
-- todo: This is a hack since you can't rotate stock when it is connected.
local disconnected_back = loco.disconnect_rolling_stock(defines.rail_direction.back)
local disconnected_front = loco.disconnect_rolling_stock(defines.rail_direction.front)
loco.rotate()
if disconnected_back then
loco.connect_rolling_stock(defines.rail_direction.front)
end
if disconnected_front then
loco.connect_rolling_stock(defines.rail_direction.back)
end
-- Error handling removed since a meaningfull error message is difficult (or too noisy) to produce.
end
-- Rotate all locomotives to face driving direction, rotated locomotives are added to storage.rotated_locos.
local function train_rotate(train)
local schedule_index = train.schedule.current
local manual_mode = train.manual_mode
if manual_mode then return end -- never rotate manual mode trains
for _, locos in pairs(train.locomotives) do
for _, loco in pairs(locos) do
if not storage.rotated_locos[loco.unit_number] and loco.speed < 0 then -- prevent double rotates
storage.rotated_locos[loco.unit_number] = true
rotate(loco)
train = loco.train -- Ensure that this reference is valid for restoring manual mode.
end
end
end
if train.manual_mode ~= manual_mode then
train.manual_mode = manual_mode
end
if schedule_index and train.valid then
train.go_to_station(schedule_index)
end
end
-- Hack to get locomotive orientation through speed some ticks after it started moving.
local function on_nth_tick()
for trainID, train in pairs(storage.trains_to_rotate) do
if train.valid then
if train.speed ~= 0 then
train_rotate(train)
storage.trains_to_rotate[trainID] = nil
end
else
storage.trains_to_rotate[trainID] = nil
end
end
for stationID, station in pairs(storage.station_limits) do
if station.valid then
station.trains_limit = 1
end
storage.station_limits[stationID] = nil
end
-- Unsubscribe once all trains are rotated.
if not next(storage.trains_to_rotate) and not next(storage.station_limits) then
script.on_nth_tick(nil)
end
end
-- Revert the rotated locomotives listed in storage.rotated_locos.
local function train_unrotate(train)
local schedule_index = train.schedule.current
local manual_mode = train.manual_mode
local station = train.station
if settings_station_limits and station and station.trains_limit == 1 then
station.trains_limit = 2
storage.station_limits[station.unit_number] = station
script.on_nth_tick(settings_nth_tick, on_nth_tick)
end
for _, locos in pairs(train.locomotives) do
for _, loco in pairs(locos) do
if storage.rotated_locos[loco.unit_number] then
rotate(loco)
storage.rotated_locos[loco.unit_number] = nil
train = loco.train -- Ensure that this reference is valid for restoring manual mode.
end
end
end
if train.manual_mode ~= manual_mode then
train.manual_mode = manual_mode
end
if schedule_index and train.valid then
train.go_to_station(schedule_index)
end
end
local function on_train_changed_state(event)
local train = event.train
if train.state == defines.train_state.wait_station or
train.state == defines.train_state.no_path or
train.state == defines.train_state.path_lost or
(train.manual_mode and event.old_state ~= defines.train_state.manual_control_stop and
event.old_state ~= defines.train_state.manual_control)
then
storage.trains_to_rotate[train.id] = nil
if not next(storage.trains_to_rotate) and not next(storage.station_limits) then
script.on_nth_tick(nil)
end
train_unrotate(train)
elseif not train.manual_mode and
(event.old_state == defines.train_state.wait_station or
event.old_state == defines.train_state.manual_control)
then
if (#train.locomotives.front_movers + #train.locomotives.back_movers) > 1 then
storage.trains_to_rotate[train.id] = train
script.on_nth_tick(settings_nth_tick, on_nth_tick)
end
end
end
local function init_events()
if settings_enabled then
script.on_event(defines.events.on_train_changed_state, on_train_changed_state)
else
script.on_event(defines.events.on_train_changed_state, nil)
end
if storage.trains_to_rotate and next(storage.trains_to_rotate) then
script.on_nth_tick(settings_nth_tick, on_nth_tick)
end
if storage.station_limits and next(storage.station_limits) then
script.on_nth_tick(settings_nth_tick, on_nth_tick)
end
end
script.on_event(defines.events.on_runtime_mod_setting_changed, function(event)
if event.setting == "Noxys_Multidirectional_Trains-enabled" then
settings_enabled = settings.global["Noxys_Multidirectional_Trains-enabled"].value
if settings_enabled then
script.on_event(defines.events.on_train_changed_state, on_train_changed_state)
script.on_nth_tick(settings_nth_tick, on_nth_tick)
else
script.on_event(defines.events.on_train_changed_state, nil)
script.on_nth_tick(nil)
-- Revert the rotated trains.
local trains = game.train_manager.get_trains {}
for _, train in pairs(trains) do
train_unrotate(train)
end
-- Clean globals.
storage.rotated_locos = {}
storage.trains_to_rotate = {}
end
end
if event.setting == "Noxys_Multidirectional_Trains-on_nth_tick" then
settings_nth_tick = settings.global["Noxys_Multidirectional_Trains-on_nth_tick"].value
script.on_nth_tick(nil)
if next(storage.trains_to_rotate) or next(storage.station_limits) then
script.on_nth_tick(settings_nth_tick, on_nth_tick)
end
end
if event.setting == "Noxys_Multidirectional_Trains-station_limits" then
settings_station_limits = settings.global["Noxys_Multidirectional_Trains-station_limits"].value
end
end)
script.on_load(function()
init_events()
end)
script.on_init(function()
storage.rotated_locos = storage.rotated_locos or {}
storage.trains_to_rotate = storage.trains_to_rotate or {}
storage.station_limits = storage.station_limits or {}
init_events()
end)
script.on_configuration_changed(function()
storage.rotated_locos = storage.rotated_locos or {}
storage.trains_to_rotate = storage.trains_to_rotate or {}
storage.station_limits = storage.station_limits or {}
init_events()
end)