Skip to content

Instantly share code, notes, and snippets.

@jonathanvdc
Last active March 9, 2022 00:42
Show Gist options
  • Save jonathanvdc/f98fdf3b683b894f511f83456c8ce24f to your computer and use it in GitHub Desktop.
Save jonathanvdc/f98fdf3b683b894f511f83456c8ce24f to your computer and use it in GitHub Desktop.
A minetest mesecons 'luacontroller' for train station info signs.
-- This is 'luacontroller' code for train station signs.
--
-- It was designed for the 'advtrains' and 'textline' mods,
-- but it does not have any dependencies on them.
--
-- Usage:
--
-- 1. Tweak the 'stops', 'destination', 'train_type',
-- 'at_platform_duration' and 'train_at_platform_pin'
-- constants to suit your needs.
--
-- 2. Create a mesecon line that starts at a detector rail
-- triggered by the train just before it rolls into the
-- station and ends at the luacontroller that runs this
-- code.
--
-- 3. Connect the luacontroller to the a 'textline' sign and
-- configure the 'textline' sign to listen to channel
-- 'info'.
-- A list of the train's stops.
stops = "Lissewege, Brugge-Sint-Pieters, Brugge, Oostkamp, Beernem, Maria-Aalter, Aalter, Bellem, " ..
"Hansbeke, Landegem, Drongen, Gent-Sint-Pieters, Merelbeke, Melle, Kwatrecht, Wetteren, Schellebelle, " ..
"Wichelen, Schoonaarde, Oudegem, Dendermonde, Baasrode-Zuid, Bruggenhout, Malderen, Londerzeel, " ..
"Kapelle-Op-Den-Bos, Mechelen"
-- The train's destination. Should be short enough to fit
-- on a line along with the train type.
destination = "Mechelen"
-- The type of train. Should be short: it's printed right
-- next to the destination.
train_type = "L"
-- The amount of seconds the train stays at the platform.
at_platform_duration = 13
-- The pin that fires when the train arrives at the platform.
train_at_platform_pin = "d"
-- The amount of seconds to display a "don't board the train
-- anymore" message for.
missed_it_duration = 2
-- The interval between interrupts.
interrupt_interval = 0.2
-- Pads 'str' to length 'len' with 'char'.
string.lpad = function(str, len, char)
if char == nil then
char = ' '
end
return string.rep(char, len - #str) .. str
end
-- Generates a slice of the list of stops.
generate_stops_slice = function()
if #stops < 17 then
-- No need to scroll through the list of stops
-- if they all fit on the same line.
return stops
end
if mem.stop_slice_offset == nil or mem.stop_slice_offset > #stops then
mem.stop_slice_offset = 1
end
local slice = stops:sub(
mem.stop_slice_offset,
math.min(mem.stop_slice_offset + 16, #stops))
mem.stop_slice_offset = (mem.stop_slice_offset % #stops) + 1
return slice
end
-- Subtracts a single interrupt interval from an in-memory countdown
-- timer if the countdown has not ended yet and tells if the countdown
-- is still in progress.
countdown_tick = function(name)
if mem[name] == nil then
mem[name] = 0
end
if mem[name] > 0 then
mem[name] = mem[name] - interrupt_interval
return true
else
return false
end
end
-- Generates a single line of text that explains where the train
-- is headed.
generate_identifier_line = function()
return destination .. string.lpad(train_type, 17 - #destination, nil)
end
-- Generates two lines of text. The first says "Train stops at..."
-- or equivalent and the second is a slice of all stops.
generate_stops_lines = function()
return "Trein stopt in\n" .. generate_stops_slice()
end
-- Generates the contents of the entire sign.
generate_sign_contents = function()
if pin[train_at_platform_pin] then
mem.at_platform_counter = at_platform_duration
mem.missed_it_counter = missed_it_duration
end
if countdown_tick("at_platform_counter") then
return generate_identifier_line() ..
"\n>>> Aan perron >>>\n" .. generate_stops_lines()
elseif countdown_tick("missed_it_counter") then
return "NIET MEER\n INSTAPPEN"
else
return generate_identifier_line() .. "\n \n" .. generate_stops_lines()
end
end
if event.type == "program" or event.type == "interrupt" then
-- Schedule a new interrupt after the previous interrupt
-- expires. Also schedule a first interrupt when the program
-- starts to set things in motion.
interrupt(interrupt_interval)
end
-- Update the sign(s).
digiline_send("info", generate_sign_contents())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment