Last active
March 9, 2022 00:42
-
-
Save jonathanvdc/f98fdf3b683b894f511f83456c8ce24f to your computer and use it in GitHub Desktop.
A minetest mesecons 'luacontroller' for train station info signs.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- 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