Thu May 19 21:36:24 UTC 2022

This commit is contained in:
Nero 2022-05-19 21:36:24 +00:00
parent b8317c6016
commit a2aa3cdb8b
1 changed files with 172 additions and 118 deletions

290
init.lua
View File

@ -2,43 +2,67 @@
-- Ich weiss jetzt noch nicht, wie viele verschiedene Versionen von dem Script spaeter herumfliegen werden. -- Ich weiss jetzt noch nicht, wie viele verschiedene Versionen von dem Script spaeter herumfliegen werden.
KsKitVer=0 KsKitVer=0
-- Uebrige Konstanten Kennziffer=34
Vmax=400
-- Tabelle, in der alle Lambda-Funktionen gespeichert werden local Callbacks = {}
-- Die Eintragung erfolgt durch die MainFunktion() vom Zielort aus.
MainFunktionTabelle={}
-- Neues Main-Lambda registrieren function On(Name, Funktion)
function MainFunktion(Funktion) -- Erlaube es, Signal und Weichen via Nummer zu referenzieren
table.insert(MainFunktionTabelle, Funktion) if type(Name) == "number" then
end if EEPGetSwitch(Name) > 0 then
Name = "EEPOnSwitch_"..tostring(Name)
-- Alle Main-Lambda's ausfuehren elseif EEPGetSignal(Name) > 0 then
-- Dies ersetzt die Standard-EEP-Main Funktion. Name = "EEPOnSignal_"..tostring(Name)
function EEPMain()
for cnt = 1, #MainFunktionTabelle do
MainFunktionTabelle[cnt]()
end
return 1
end
-- Neues Signal-Lambda registrieren
SignalFunktionen = {}
function SignalFunktion(Signal, Funktion)
if not SignalFunktionen[Signal] then
EEPRegisterSignal(Signal)
-- Callback bei EEP registrieren
_G["EEPOnSignal_"..tostring(Signal)]=function(Stellung)
-- Alle registrierten Lambdas ausfuehren
for cnt = 1, #SignalFunktionen[Signal] do
SignalFunktionen[Signal][cnt](Stellung)
end
end end
SignalFunktionen[Signal]={}
end end
-- In unsere eigene Tabelle eintragen if type(Name) == "table" then
table.insert(SignalFunktionen[Signal], Funktion) for _, Newname in pairs(Name) do
On(Newname, Funktion)
end
return
end
if type(Name) ~= "string" or string.match(Name, "EEP.+") == nil then
print("Verweigere Callback von "..type(Name).." "..tostring(Name))
return
end
if not Callbacks[Name] then
Callbacks[Name] = {}
if _G[Name] ~= nil then
print("Warnung: "..Name.."() von KsKit adoptiert")
table.insert(Callbacks[Name], _G[Name])
end
_G[Name] = function(...)
for cnt = 1, #Callbacks[Name] do
Callbacks[Name][cnt](...)
end
-- Nur EEPMain braucht dies, aber dringends
return 1
end
-- Bei Weichen und Signalen muss EEP vorher informiert werden
-- Item ist normal "Switch" oder "Signal"
local Item, Number = string.match(Name, 'EEPOn(.+)_(%d+)')
if Number ~= nil then
_G["EEPRegister"..Item](Number)
end
end
table.insert(Callbacks[Name], Funktion)
end
-- EEPMain-Callback registrieren
function Main(Funktion)
On("EEPMain", Funktion)
end
-- Signal-Callback registrieren
function OnSignal(Signal, Funktion)
EEPRegisterSignal(Signal)
On("EEPOnSignal_"..tostring(Signal), Funktion)
end
-- Weichen-Callbacks registrieren
function OnSwitch(Switch, Funktion)
EEPRegisterSwitch(Switch)
On("EEPOnSwitch_"..tostring(Switch), Funktion)
end end
-- Lua-Serializer und Deserializer laden -- Lua-Serializer und Deserializer laden
@ -60,100 +84,130 @@ function speicherTabelle(Slot, Tabelle)
EEPSaveData(Slot, serpent.line(Tabelle, {comment = false})) EEPSaveData(Slot, serpent.line(Tabelle, {comment = false}))
end end
SignalLesenFunktionen={} -- Referenz-Datenbank mit Signalen, Fahrstrassen & Weichen
-- Geordnet nach Signal/Weichen-ID
KsSignale = {}
-- Definiere ein Signal -- KsSignale von GK3 sind sehr systematisch benannt, die moeglichen Stellungen lassen sich aus dem Namen herleiten
-- Signal: ID-Nummer function GK3KsBegriffe(Modell)
-- Haltstellung: Nummer der Haltstellung, meistens 1 local Teile = {}
-- SchaltFunk: Callback, wird wiederholt aufgerufen, um Fahrt-Stellung des Signals zu erwirken for str in string.gmatch(Modell, "([^_ ]+)") do
-- AbmeldeFunk: Wird nach Durchfahrt am Signal aufgerufen Teile[str]=true
function Basissignal(Signal, Haltstellung, SchaltFunk, AbmeldeFunk)
if EEPGetSignal(Signal)==0 then
print("Anlagen-Fehler: ID ",Signal," ist kein Signal")
return
end end
-- Funktion, damit anderer Programmcode das Signal lesen kann local Stellungen = {}
SignalLesenFunktionen[Signal]=function()
local Stellung = EEPGetSignal(Signal) -- Halt am Hauptsignal
if Stellung == 0 or Stellung == Haltstellung then if Teile["A"] or Teile["B"] then
return false, 0 table.insert(Stellungen, {"Hp0"})
end
-- Halt erwarten
-- ... am Wiederholer
if Teile["VSigWdh"] then
table.insert(Stellungen, {"Ks2","Kl"})
end
-- ... An MAS oder Vorsignalen
if Teile["MAS"] or Teile["VSig"] then
if Teile["verkuerzt"] then
table.insert(Stellungen, {"Ks2","Kl"})
end
table.insert(Stellungen, {"Ks2"})
if Teile["Kl"] then
table.insert(Stellungen, {"Ks2","Kl"})
end end
return true, Vmax
end end
-- Funktion fuer Kontaktpunkte: Zug an Signal anmelden
_G["Anmeldung_"..tostring(Signal)] = function(Zug) -- Fahrt/Fahrt erwarten
local Anmeldung table.insert(Stellungen, {"Ks1"})
Anmeldung = ladeTabelle(Signal)
if Anmeldung.train and Anmeldung.train ~= Zug then return end -- Langsamfahrt erwarten
Anmeldung.train = Zug -- ... am Wiederholer
speicherTabelle(Signal, Anmeldung) if Teile["VSigWdh"] then
table.insert(Stellungen, {"Ks1bl","Kl"})
end end
-- Auftragsstatus pollen -- ... am MAS oder Vorsignalen
MainFunktion(function() if Teile["MAS"] or Teile["VSig"] or Teile["VSigWdh"] then
local Anmeldung = ladeTabelle(Signal) if Teile["verkuerzt"] then
-- Wenn Zug vor Signal steht, Anmeldung ggf. nachholen table.insert(Stellungen, {"Ks1bl","Kl"})
if EEPGetSignalTrainsCount(Signal) > 0 then end
if Anmeldung.train == nil then table.insert(Stellungen, {"Ks1bl"})
Anmeldung.train = EEPGetSignalTrainName(Signal, 1) if Teile["Kl"] then
speicherTabelle(Signal, Anmeldung) table.insert(Stellungen, {"Ks1bl","Kl"})
end
end
-- Rangierfahrt an Ausfahrsignalen
if Teile["A"] then
table.insert(Stellungen, {"Sh1"})
end
-- Ersatzfahrt an Ausfahrsignalen und Blocksignalen ohne Vorsichtssignal
if Teile["A"] or (Teile["B"] and not Teile["V"]) then
table.insert(Stellungen, {"Zs1"})
end
-- Vorsichtssignal an Hauptsignalen
if Teile["V"] then
table.insert(Stellungen, {"Zs7"})
end
-- Kennlicht
if Teile["Kl"] or Teile["VSigWdh"] or Teile["verkuerzt"] then
table.insert(Stellungen, {"Kl"})
end
-- Dunkel geschaltet
table.insert(Stellungen, {})
return Stellungen
end
local GK3KsBauarten={
"Ks_Sig_A",
"Ks_Sig_A_MAS",
"Ks_Sig_A_MAS_Kl",
"Ks_Sig_A_V",
"Ks_Sig_A_V_MAS",
"Ks_Sig_A_V_MAS_Kl",
"Ks_Sig_B",
"Ks_Sig_B_MAS",
"Ks_Sig_B_V",
"Ks_Sig_B_V_MAS",
"Ks_Sig_B_V_MAS_Kl",
"Ks_Sig_VSig",
"Ks_Sig_VSigWdh",
"Ks_Sig_VSig_verkuerzt"
}
for cnt=1, #GK3KsBauarten do
_G[GK3KsBauarten[cnt]]=function(Signal, Meta)
-- Falls kein name gegeben, einen generieren
if Meta.Name == nil then
Meta.Name = string.format("%d", Signal)
end
Meta.Kennziffer = Kennziffer
Meta.Begriffe = GK3KsBegriffe(GK3KsBauarten[cnt])
for _, Var in ipairs({"Schild","Mastschild","Immobilie", "PZB"}) do
if type(Meta[Var]) == "number" then
Meta[Var]=tostring("#"..Meta[Var])
end end
-- Ankunftszeit merken, sobald Zug am Signal angekommen ist if Meta[Var] then
-- Wird im if von EEPGetSignalTrainsCount gemacht, local ok,x,y,z = EEPStructureGetPosition(Meta[Var])
-- damit nur Halte an diesem Signal zaehlen if ok then
if Anmeldung.arrival == nil then if not Meta.Ort then
ok, speed = EEPGetTrainSpeed(Anmeldung.train) Meta.Ort = {x,y,z}
if math.abs(speed) < 5 then end
Anmeldung.arrival = EEPTime else
speicherTabelle(Signal, Anmeldung) print("Warnung: Signal ",Signal," ",Var," ",Meta[Var]," nicht gefunden")
end end
end end
end end
-- Nichts tun wenn kein Zug da if not Meta.Ort then
if Anmeldung.train == nil then return end print("Warnung: Signal ",Signal," hat keine Immobilie, um die eigene Position zu ermitteln")
-- SchaltFunk
if SchaltFunk and EEPGetSignal(Signal) == Haltstellung then
r=SchaltFunk(Anmeldung.train)
if r and r > 0 and r ~= Haltstellung then
EEPSetSignal(Signal, r, 1)
end
end end
end) KsSignale[Signal] = Meta
-- Reaktion auf Signal-Umstellungen if Meta.Schild then
SignalFunktion(Signal, function(Stellung) EEPStructureSetTextureText(Meta.Schild, 1, Meta.Kennziffer)
if Stellung == Haltstellung then EEPStructureSetTextureText(Meta.Schild, 2, Meta.Name)
-- Wenn Signal auf Halt gestellt wurde, mache eine Abmeldung
if AbmeldeFunk then
local Anmeldung = ladeTabelle(Signal)
AbmeldeFunk(Anmeldung.train)
end
speicherTabelle(Signal, {})
end end
end) end
end
-- Funktion zum Erklaeren, was ein Signal gerade so tut
-- Nimmt die Nummer des Signals als Argument
-- Gibt einen Menschenlesbaren Text zurueck
function SignalBeschreibung(Signal)
local Anmeldung = ladeTabelle(Signal)
local Fahrt, V = SignalLesenFunktionen[Signal]()
Text = "Signal " .. tonumber(Signal) .. ": "
if Fahrt then
if V < Vmax then
Text = Text .. "Fahrt mit " .. tonumber(V) .. " Km/h\n"
else
Text = Text .. "Fahrt\n"
end
else
Text = Text .. "Halt\n"
end
if Anmeldung.train then
Text = Text .. "Zug angemeldet: " .. Anmeldung.train .. "\n"
end
if Anmeldung.arrival then
local Dauer = EEPTime - Anmeldung.arrival
if Dauer < 0 then Dauer = Dauer + 24*60*60 end
Text = Text .. "Ankunft vor " .. Dauer .. " Sekunden\n"
end
return Text
end end