Infrastruktur¶
Gleise, Straßen, Kanten-Add-ons, Brücken, Tunnel, Signale, Bahnübergänge und Ampeln sind eigene Ressourcentypen mit jeweils eigener Dateiendung. Das Basisspiel legt sie unter base/content/infrastructure/ ab (die doppelten Ordnernamen wie track/track/ entstehen beim Entpacken der Zips, siehe Aufbau eines Mods). Jede Datei gibt aus data() eine Tabelle zurück. Das Spiel lädt sie in ein Repository unter api.res, und ein Mod kann sie beim Laden über addModifier ändern.
| Was | Datei | Anzahl im Basisspiel | Repository | Typ |
|---|---|---|---|---|
| Gleis- oder Straßenvorlage | .street_template.lua |
87 (davon 6 Gleise) | streetTemplateRep |
StreetTemplate |
| Gleis- oder Straßenstil | .street.lua |
28 | streetStyleRep |
StreetStyle |
| Kanten-Add-on | .edge.lua |
6 | edgeDecorationRep |
EdgeDecoration |
| Brücke | .bridge.lua |
9 | bridgeTypeRep |
BridgeType |
| Tunnel | .tunnel.lua |
6 | tunnelTypeRep |
ebenfalls BridgeType |
| Signal | .con.lua mit edgeObject |
2 | constructionRep |
ConstructionDesc |
| Bahnübergang | .rcr.lua |
10 | railroadCrossingTypeRep |
RailroadCrossingType |
| Ampel | .trl.lua |
4 | trafficLightTypeRep |
TrafficLightType |
Die Zahlen beziehen sich auf base/content/infrastructure/. Unter den 81 Straßenvorlagen sind auch Start- und Rollbahnen von Flughäfen und die kurzen Zufahrtsstraßen, die innerhalb von Konstruktionen verwendet werden.
Die Modifier-Schlüssel für diese Dateien heißen loadStreetTemplate, loadStreet, loadTrack, loadEdgeDecoration, loadBridge, loadTunnel, loadRailroadCrossing und loadTrafficLight (aufgeführt in base/content/base/base/mod.lua; Signale laufen über loadConstruction). Die eigenen Modifier des Basisspiels in base/content/base/base/base_mod.lua übersetzen ältere Feldnamen. Deshalb funktionieren bei manchen Feldern beide Schreibweisen:
loadStreetTemplatebautavailabilityausyearFrom/yearToauf oberster Ebene unddescriptionausname,desc,iconundpreviewIcon, wenn diese Tabellen fehlen. Eine Spur ohnespeedbekommt dasspeedder Vorlage geteilt durch 3,6. Das alte Feld war also in km/h angegeben.streetFillGroundTexwird nachfillGroundTexkopiert.loadStreetmacht aus dem Stringmaterials.ballastMaterialeines Stilsmaterials.ballast = { name = ..., size = { 8.0, 8.0 } }.loadBridge,loadTunnelundloadRailroadCrossingwandelnavailabilityunddescriptionauf dieselbe Weise um.loadConstructionmacht aus einem altenisEdgeObject = trueeinedgeObject = { snapToStreet = true, snapToTrack = true, minDistToCrossing = 10 }.
description, availability und menuCategory funktionieren in all diesen Dateien wie bei Konstruktionen (siehe Konstruktionen). Laut Wiki ist ein Typ mit einem yearTo unter 1900 in availability nie verfügbar, und 0 oder ein fehlender Wert bedeutet kein Ende.
Gleise und Straßen¶
Gleise und Straßen verwenden dieselben zwei Dateitypen. Die .street_template.lua enthält, was die Simulation braucht: Spuren, Geschwindigkeiten, Kosten, Steigungen, Emissionen. Die .street.lua, auf die sie mit streetStyle verweist, bestimmt das Aussehen mit Materialien, Modellen und Oberleitung. Mehrere Vorlagen können sich einen Stil teilen. So verwenden 15 town_old_*-Vorlagen (die Größen mit ihren Varianten _barriers, _trees und _tram) alle town_old.street. roadType ist in beiden Dateien "STREET" oder "TRACK". Die Wiki-Seite beschreibt jedes Feld. Dieser Abschnitt behandelt die Felder, die ein neuer Typ braucht.
Eine Gleisvorlage¶
base/content/infrastructure/track/track/standard/standard.street_template.lua (gekürzt, Kommazahlen gerundet):
function data()
return {
availability = { yearFrom = 1930, yearTo = 0, },
catenaryAdd = "::/infrastructure/track/standard/standard_catenary.street_template",
cost = 180,
maintenanceCost = 30,
laneConfigs = {
{
forward = true,
height = 0.53,
offset = 0,
speed = 44.44,
transportModes = { "TRAIN", "TRAM_TRACK", },
width = 4,
},
},
maxSlope = 0.13,
maxSlopeBuild = 0.085,
maxSlopeShape = 0.16,
minCurveRadius = 40,
minCurveRadiusBuild = 55,
roadType = "TRACK",
speedCoeffs = { 0.85, 30, 0.6, },
streetStyle = "::/infrastructure/track/standard/standard.street",
trackDistance = 5,
-- description, emissions, modifiers, Bodentexturen, menuCategory, builderAudioRes
}
end
Die elektrifizierte Fassung ist eine zweite Vorlage, standard_catenary.street_template.lua. Ihre Spur hat zusätzlich "ELECTRIC_TRAIN" und "ELECTRIC_TRAM_TRACK", und sie verweist mit catenaryRemove zurück. Wer Oberleitung baut oder entfernt, tauscht die eine Vorlage gegen die andere.
| Feld | Bedeutung (laut Wiki) |
|---|---|
laneConfigs |
Ein Eintrag pro Spur: speed in m/s, width, offset, height (hebt bei Straßen den Gehweg an), forward (in der Richtung, in die der Spieler gezogen hat), transportModes |
transportModes |
"PERSON", "CARGO" für Gehwege; "CAR", "BUS", "TRUCK" für Fahrspuren; "TRAM", "ELECTRIC_TRAM" für Straßenbahn auf der Straße; "TRAM_TRACK", "ELECTRIC_TRAM_TRACK" für Straßenbahnen auf Eisenbahngleisen; "TRAIN", "ELECTRIC_TRAIN" |
cost, maintenanceCost |
pro Meter |
maxSlopeBuild, maxSlope, maxSlopeShape |
Steigung der geraden Linie zwischen den Endpunkten; der Kurve, die den Steigungen an den Enden folgt; der gebauten Form, wenn Kreuzungen sie verschieben |
speedCoeffs |
Die Höchstgeschwindigkeit in Kurven ist a * (radius + b) ^ c |
minCurveRadiusBuild, minCurveRadius |
kleinster Radius beim freien Ziehen und beim Einrasten an bestehendes Gleis |
trackDistance |
Abstand paralleler Gleise; das Wiki warnt, dass andere Werte als 5 das Schotterbett und die Oberleitungsjoche stören können |
emissions, modifiers |
Lärm und Verschmutzung der Kante sowie Faktoren für Höchstgeschwindigkeit, Lärm und Verschmutzung der Fahrzeuge darauf |
defaultEdgeDecorations |
.edge-Verweise mit einem Boolean für die linke Seite, siehe Kanten-Add-ons |
Eine Straßenvorlage¶
Eine Straße führt auch ihre Gehwege als Spuren. base/content/infrastructure/street/street/town/town_old_small.street_template.lua hat vier Spuren, in Baurichtung von links nach rechts:
laneConfigs = {
{ forward = false, height = 0.15, offset = 0.15, speed = 11.11, transportModes = { "PERSON", "CARGO", }, width = 3, },
{ forward = false, height = 0, offset = -0.5, speed = 11.11, transportModes = { "CAR", "BUS", "TRUCK", }, width = 5, },
{ forward = true, height = 0, offset = 0.5, speed = 11.11, transportModes = { "CAR", "BUS", "TRUCK", }, width = 5, },
{ forward = true, height = 0.15, offset = -0.15, speed = 11.11, transportModes = { "PERSON", "CARGO", }, width = 3, },
},
priority = 510,
roadType = "STREET",
simBuildable = true,
streetStyle = "::/infrastructure/street/town/town_old.street",
Laut Wiki gibt es nur bei Straßen diese Felder: simBuildable (Städte dürfen auf diesen Typ ausbauen), country (an ihr entstehen keine Häuser), priority (wessen Markierungen an einer Kreuzung gelten), busAndTramRight, defaultWithCrosswalk, pedestrianWalkPenalty und transportModesStreet. Das Wiki nennt außerdem aiLock, das die Stadtentwicklung daran hindert, gebaute Abschnitte zu ändern. Keine Datei des Basisspiels setzt aiLock. Die sechs Autobahnvorlagen und die sechs Zufahrtsstraßen für Konstruktionen setzen stattdessen initiallyLocked = true, was die Referenz als Anfangswert des Sperren-Werkzeugs beschreibt.
Stile¶
Ein Gleisstil (base/content/infrastructure/track/track/standard/standard.street.lua, gekürzt) nennt die Modelle und die Maße der prozedural erzeugten Teile:
return {
roadType = "TRACK",
ballastHeight = 0.3,
ballastCutOff = 0.35,
trackStraightModel = { "2m_standard.mdl", "4m_standard.mdl", "8m_standard.mdl", "16m_standard.mdl", },
sleeperModel = "single_sleeper_standard.mdl",
railModel = "::/infrastructure/track/shared/single_rail.mdl",
railTrackWidth = 1.435,
shapeStep = 2.0,
bumperModel = "bumper_standard.mdl",
switchSignalModel = "switch_box_standard.mdl",
catenary = {
catenaryPoleDistance = 24,
catenaryMaxPoleDistance = 3.33,
catenaryMinPoleDistance = 0.9,
catenaryPoleModel = "power_pole_2_standard.mdl",
catenaryMultiPoleModel = "power_pole_1_standard.mdl",
catenaryMultiGirderModel = "power_pole_1a_standard.mdl",
catenaryMultiInnerPoleModel = "power_pole_1b_standard.mdl",
-- catenaryBase, catenaryHeight
},
materials = {
ballast = { name = "::/infrastructure/track/shared/mat/ballast.mtl", size = { 7.0, 7.0 } },
sleeperMaterial = "mat/sleeper_standard_tileable.mtl",
railMaterial = "::/infrastructure/track/shared/mat/rail_tileable.mtl",
catenaryMaterial = "::/infrastructure/shared/mat/catenary.mtl",
},
-- Maße von Schwellen und Schienen
}
trackStraightModel enthält Stücke von 2, 4, 8 und 16 m mit Schwellen. Kurze Abschnitte und enge Kurven entstehen aus einem sleeperModel und zwei railModels, und Weichen und Kreuzungen bekommen prozedurale Schwellen und Schienen nach den Maßfeldern. Laut Wiki liegt der Ursprung all dieser Modelle auf Geländehöhe, mittig in Länge und Breite. Für ein Gleis nimmt die Oberleitung den einfachen Mast, für zwei Gleise denselben Mast nach außen gedreht. Bei drei oder vier Gleisen kommen Mehrfachmasten mit Trägern dazu, bei mehr als vier zusätzliche innere Masten.
Wiki und Basisdateien nennen hier zwei Felder unterschiedlich. Das Wiki schreibt die Mastgrenzen als catenaryMaxPoleDistanceFactor und catenaryMinPoleDistanceFactor. Alle vier Gleisstile des Basisspiels (standard, simple, high_speed, industries/shared/shared/industry_track/industry.street.lua) verwenden catenaryMaxPoleDistance und catenaryMinPoleDistance, aber mit Werten in der Größenordnung von Faktoren (3,33 und 0,9). Das Wiki schreibt ballastMaterial = "...", die Basisdateien verwenden ballast = { name, size }, und der oben beschriebene Modifier loadStreet wandelt die Wiki-Form mit einer Kachelgröße von 8 m um.
Ein Straßenstil hat eine Tabelle materials mit Einträgen { name = "....mtl", size = { x, y } } für Belag, Spuren, Ränder, Streifen, Gehwege, Tramgleise, Busspuren, Kreuzungen und Einmündungen (das Wiki listet alle 25 Schlüssel auf). Fehlt ein Schlüssel, bleibt dieser Teil im Spiel unsichtbar; town_old.street.lua lässt sidewalkBorderOuter weg. Laut Wiki brauchen Belagmaterialien polygon_offset = { factor = -3, units = -1.2, forceDepthWrite = true } und Overlays { factor = -4, units = -1.3 }. Die Tabelle assets setzt Modelle entlang der Straße. Ihre Schlüssel sind Namen, damit Brücken und Tunnel einzelne Modelle ersetzen können. Aus base/content/infrastructure/street/street/town/town_old.street.lua:
assets = {
["street_light"] = {
name = "/assets/streets/street_light_eu_a.mdl",
offset = 6.0,
distance = 12.0,
prob = 1.0,
offsetOrth = 2.4,
randRot = false,
oneSideOnly = false,
alignToElevation = false,
avoidFaceEdges = false,
placeOnBridge = true,
},
-- "fireplug", "mailbox", "trash"
},
categoryList = {
categories = { "withSidewalk", "town", "old", }
},
Die categoryList des Stils gibt der Kante Tags, die Kanten-Add-ons voraussetzen können (siehe nächsten Abschnitt).
Gleismodule in Bahnhöfen¶
Die postRunFn des Basisspiels in base/content/base/base/mod.script.tl erzeugt für jede Vorlage mit roadType TRACK ein Gleismodul für Bahnhöfe, auch für die Varianten mit Oberleitung, und fügt es mit api.res.moduleRep.add hinzu. Der Dateiname des Moduls ist "::/trainstation_", gefolgt vom Vorlagennamen, in dem :: durch __ ersetzt ist. Ein neuer Gleistyp erscheint deshalb von selbst im modularen Bahnhof.
Das Wiki zeigt, wie ein Mod solche Module in seiner eigenen postRunFn mit api.res.moduleRep.setVisible ausblendet. Sein Beispiel nennt die Module ::trainstation_<tracktypename>.lua und ...luacatenary, was nicht der Benennung im Basisskript oben entspricht, und läuft mit ipairs und index - 1 über getAll(). getAll gibt eine Tabelle von ID zu Name zurück. Wer wie das Basisskript mit pairs iteriert und den Schlüssel als ID nimmt, muss den Versatz um eins nicht raten:
postRunFn = function()
local hide = { ["::/trainstation___/my_track/my_track.street_template"] = true } -- den echten Namen im Log oder mit getAll() prüfen
for id, name in pairs(api.res.moduleRep.getAll()) do
if hide[name] then api.res.moduleRep.setVisible(id, false) end
end
end,
Der genaue Modulname für das Gleis eines Mods hängt davon ab, wie der Vorlagenname in streetTemplateRep geschrieben ist. Die Dateien enthalten kein Mod-Gleis, also gib getAll() einmal aus, bevor du dich auf einen Namen verlässt.
Kanten-Add-ons¶
Kanten-Add-ons (die Referenz nennt sie Edge Decorations) sind die Lärmschutzwände und Alleen, die der Spieler auf bestehende Kanten malt. base/content/infrastructure/edge_addons/edge_addons/barrier_a.edge.lua (gekürzt):
function data()
return {
availability = { yearFrom = 0, yearTo = 1940, },
cost = { price = 100, priceScale = 1, },
maintenance = { runningCosts = 10, },
desc = {
icon = "barrier_a.tga",
previewIcon = "barrier_a_preview.tga",
name = _("INFRA_EDGE_ADDON_BARRIER_A_NAME"),
description = _("INFRA_EDGE_ADDON_BARRIER_A_DESCRIPTION"),
},
categoryList = { categories = { "barrier" } },
menuCategory = { categories = { { category = "roads_tools", order = 400, }, } },
repModel = "barrier_a.mdl",
length = 3.0,
stretch = true,
verticalAlignment = "Shear", -- "Vertical", "Rotate"
offset = 0.0,
snapMode = "Side", -- "Side", "Center"
skipSameInParallelStrip = true,
incompatibleTags = {"track", "tunnel", "decorated"},
modifiers = { noiseModifier = -0.65, },
preventParcels = true,
}
end
Die Beschreibungstabelle heißt hier desc und nicht description. Ein Add-on lässt sich platzieren, wenn die Kante jedes Tag aus requiredTags und keines aus incompatibleTags hat. Die Engine setzt track, street, bridge, tunnel und decorated (mindestens ein Add-on vorhanden). Weitere Tags kommen aus der categoryList des Straßenstils und aus der categoryList der Add-ons, die schon auf der Kante liegen. alley.edge.lua nutzt das: Es verlangt withSidewalk, und das liefern town_old.street, town_new.street und town_new_large.street. barrier_track_a.edge.lua ist dieselbe Wand für Gleise, mit "street" statt "track" in incompatibleTags.
Das Modell repModel wird alle length Meter im Abstand offset von der Kantenachse gesetzt. snapMode ist "Side" (jede Seite für sich) oder "Center". modifiers ändern Lärm, Verschmutzung und Höchstgeschwindigkeit der Fahrzeuge auf der Kante, und preventParcels verhindert Stadtgebäude auf dieser Seite.
Das Wiki beschreibt weder stretch und verticalAlignment, die die vier Wände des Basisspiels setzen, noch order, das alle sechs setzen. Die Referenz erklärt sie: stretch streckt das Modell, um Lücken zu schließen, und verticalAlignment hält das Modell senkrecht, schert es entlang der Steigung oder dreht es zur Straße. Die Referenz gibt snapMode und verticalAlignment als Ganzzahlen an, die Basisdateien schreiben die Strings "Side", "Center" und "Shear". Die Alleen (alley.edge.lua, alley_old.edge.lua) drehen ihre Bäume mit modelRotation = "RandomXY" zufällig um die z-Achse, wie es das Wiki beschreibt. Der Typ EdgeDecoration in der Referenz hat kein solches Feld.
Eine Straßenvorlage kann Add-ons vorgeben, zum Beispiel town_old_small_barriers.street_template.lua:
defaultEdgeDecorations = {
{ "::/infrastructure/edge_addons/barrier_a.edge", false, },
{ "::/infrastructure/edge_addons/barrier_a.edge", true, },
},
Die _trees-Varianten machen dasselbe mit alley.edge.
Brücken und Tunnel¶
Ein Brückentyp legt die Kosten, den Pfeilerabstand und den Ersatz für die Materialien der Straße oder des Gleises obendrauf fest. Die Geometrie liefert eine Funktion updateScript. Sie bekommt die Pfeilerhöhen und die Geländerabschnitte und gibt Modelllisten zurück. base/content/infrastructure/bridge/bridge/stone.bridge.lua (Modelltabellen gekürzt):
function data()
local dir = "stone/"
local pillar_btm_rep = {
dir .. "pillar_btm_rep.mdl",
{ { -2.0, 0.0, 0.0, }, { 2.0, 4.0, 4.0, } }, -- bounding box
}
-- ... etwa 40 weitere Modelleinträge
local config = {
pillarBase = { pillar_btm_side, pillar_btm_rep, pillar_btm_side2 },
pillarRepeat = { pillar_rep_side, pillar_rep_rep, pillar_rep_side2 },
pillarTop = { pillar_top_side, pillar_top_rep, pillar_top_side2 },
railingBegin = { ... }, -- 8 Modelle
railingRepeat = { ... },
railingEnd = { ... },
abutmentBase = { stone_abut_bot_l, stone_abut_bot_rep, stone_abut_bot_r },
abutmentRepeat = { stone_abut_rep_l, stone_abut_rep_rep, stone_abut_rep_r },
abutmentTop = { stone_abut_top_l, stone_abut_top_rep, stone_abut_top_r },
}
return {
description = { name = _("INFRA_BRIDGE_STONE_NAME"), icon = "stone.tga", },
availability = { yearFrom = 0, yearTo = 0, },
carriers = { "RAIL" , "ROAD"},
speedLimit = 90.0 / 3.6,
pillarLen = 3,
pillarMinDist = 12.0,
pillarMaxDist = 48.0,
pillarTargetDist = 12.0,
abutmentLen = 5.0,
cost = 200.0,
costFactors = { 10.0, 2.5, 1.0 },
pillarGroundTexture = "/terrain/materials/dirt/dirt.gtex",
pillarGroundTextureOffset = 2.0,
materialsToReplace = {
streetPaving = { name = "::/infrastructure/street/town/mat/old_town_paving.mtl", size = { 6.0, 6.0 } },
streetStripe = { },
-- ...
},
updateScript = {
fileName = "bridge.script@stone.updateFn",
params = config
},
}
end
bridge.script.lua im selben Ordner ordnet stone, steel, trestle und placeholder der Funktion bridgeutil2.makeDefaultUpdateFn() zu, tarch, cable und suspension dagegen eigenen Funktionen in bridgeutil2.lua. Jeder Modelleintrag ist { Pfad, Bounding Box }. Eine Ebenenliste mit einem Modell setzt es in die Mitte. Bei zwei Modellen steht das erste an beiden Rändern und das zweite wird wiederholt, drei ergeben linken Rand, wiederholte Mitte und rechten Rand. Eine Geländerliste hat 5 oder 8 Modelle für die Fälle Seite, Seite mit Kollision, Mitte und Gegenseite (bei 5 werden die ersten drei gedreht und für die Gegenseite wiederverwendet). Die Einzelheiten stehen im Wiki, auch die params, die die Update-Funktion bekommt (pillarHeights, railingIntervals, hasAbutment und weitere), und die pillarModels/railingModels, die sie zurückgeben muss.
Was das Wiki zu den Feldern ergänzt: cost und maintenanceCost werden mit der Fläche unter der Brücke multipliziert. Diese wird etwa alle 5 m als 5 * (a * heightDiff ^ b + c) aus costFactors berechnet (mit a = 1 / (costFactors[1] ^ costFactors[2])). Die Straße oder das Gleis obendrauf kostet extra. Die Referenz beschreibt BridgeType.cost als „Cost per unit length“, also knapper als die Flächenregel im Wiki. speedLimit greift nur, wenn die Kante selbst schneller ist. Brückenabschnitte sind höchstens 100 m lang. Mit noParallelStripSubdivision = true entsteht die ganze Brücke in einem Aufruf; cable, suspension und trestle setzen das. cable und suspension setzen außerdem autoGeneration = false (nicht für Kartengenerierung und Stadtstraßen verwendet) und ignoreWaterCollision = true (Pfeiler stehen gleichmäßig verteilt, auch im Wasser). In materialsToReplace entfernt eine leere Tabelle ein Material (die Steinbrücke lässt streetStripe weg), in assetsToReplace entfernt eine leere Tabelle das Straßen-Asset mit diesem Schlüssel.
Das Wiki gibt den Pfad des Helfers als /infrastructure/bridges/bridgeutil2.lua an. Im Basisspiel liegt er unter base/content/infrastructure/bridge/bridge/bridgeutil2.lua, und tunnel.script.lua lädt ihn als "::/infrastructure/bridge/bridgeutil2.lua".
Tunnel verwenden denselben Typ, BridgeType, mit padding (Abstand der äußeren Spuren zur Wand, daraus ergibt sich, wo sich abzweigende Tunnel trennen) und height (tiefer lässt sich das Gelände darüber nicht absenken). base/content/infrastructure/tunnel/tunnel/tunnel_a.tunnel.lua (Modelltabellen gekürzt):
local config = {
railingBegin = startrailing,
railingRepeat = railing,
railingEnd = endrailing,
portalsConfig = { tunnel_a_startportal_rgt, tunnel_a_startportal_rep, tunnel_a_startportal_lft },
endPortalsConfig= { tunnel_a_endportal_rgt, tunnel_a_endportal_rep, tunnel_a_endportal_lft },
deadConfig = { tunnel_a_dead_rgt, tunnel_a_dead_rep, tunnel_a_dead_lft, tunnel_a_dead_rgt_end, tunnel_a_dead_lft_end },
assetsConfig = {
{ tunnel_a_m1_side_lft[1], tunnel_a_m1_add_lamp_lft1[1], 15, 3},-- first value = each n step ,second value = initial offset step
-- ...
}
}
return {
description = { name = _("INFRA_TUNNEL_ROCK_NAME"), icon = newdir .."icon/a.tga", },
carriers = { "RAIL"},
cost = 600.0,
updateScript = {
fileName = "tunnel.script@tunnel.updateFn",
params = config
},
padding = 2,
height = 8.66 + 1.0,
version = 1,
}
portalsConfig und endPortalsConfig sind rechtes, wiederholtes und linkes Portalmodell, deadConfig deckt Wände am Tunnelende ab, und jeder Eintrag in assetsConfig setzt ein Asset-Modell an jede n-te Instanz eines Elternmodells, beginnend bei einem Versatz. Straßentunnel sind eigene Dateien (tunnel_a_car.tunnel.lua, tunnel_b_car.tunnel.lua).
Signale¶
Die Wiki-Seite zu Signalen behandelt nur die Animationsereignisse. Im Basisspiel ist ein Signal eine Konstruktion, die auf ein Gleis gesetzt wird. base/content/infrastructure/signal/signal/signal_path_a.con.lua (gekürzt):
description = {
name = _("INFRA_SIGNAL_PATH_A_NAME"),
description = _("INFRA_SIGNAL_PATH_A_DESCRIPTION"),
icon = "signal_path_a.tga",
previewIcon = "signal_path_a_preview.tga",
attributes = { cost = { 9000, -1, }, maintenanceCost = { 1500, -1, }, },
},
menuCategory = { categories = { { category = "rail_tools", order = 1000, }, }, },
updateScript = {
fileName = "signal_path_a.script@updateFn",
params = { }
},
edgeObject = {
snapToTrack = true,
},
params = {
{ key = "oneWay", name = _("One-Way"), values = { _("Yes"), _("No") }, defaultIndex = 2, },
},
edgeObject ist ConstructionDesc.EdgeObject, das außerdem snapToStreet, minDistToCrossing und Felder für das Einzugsgebiet hat. Welche Ergebnisfelder ein Kantenobjekt zurückgeben darf, steht unter Kantenobjekte. Die Update-Funktion in signal_path_a.script.lua gibt eine Tabelle signal und das Modell auf der Kante zurück:
updateFn = function(captureParams, params)
local result = {}
result.signal = {
soundevent = "",
type = "PATH_SIGNAL",
}
result.edgeModels = {
{ model = { id = resolve("signal_path_a.mdl"), transf = { 1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1, }, } }
}
result.cost = 9000
result.maintenanceCost = 1500
return result
end
Die Signaltypen stehen in SignalType: PATH_SIGNAL, ONE_WAY_PATH_SIGNAL und WAYPOINT. Das Signalskript des Basisspiels gibt unabhängig vom Parameter oneWay immer PATH_SIGNAL zurück. Wie man umschaltet, zeigen die Flughafenschilder: base/content/assets/stations/stations/air/signs/sign.script.lua gibt captureParams.oneWay and "ONE_WAY_PATH_SIGNAL" or "PATH_SIGNAL" zurück, wobei oneWay in den updateScript.params der .con.lua gesetzt ist. Wie die oneWay-Wahl des Spielers bei den Eisenbahnsignalen zur Engine gelangt, geht aus den Dateien nicht hervor.
Das Modell wechselt seinen Zustand über Animationsereignisse an seinen Mesh-Knoten. Das Wiki nennt forever, idle_red, green, idle_green und red: Das Signal spielt idle_red in einer Schleife, einmal green, wenn es auf Fahrt schaltet, dann idle_green in einer Schleife und einmal red, wenn es wieder schließt. signal_path_a.mdl verwendet nur green und red:
animations = {
green = { params = { id = "ani/green/signal_path_temperate_a_light_red.ani", }, type = "FILE_REF", },
red = { params = { id = "ani/red/signal_path_temperate_a_light_red.ani", }, type = "FILE_REF", },
},
mesh = "msh/signal_path_temperate_a_light_red_lod0.msh",
Bahnübergänge¶
Ein Bahnübergangstyp wählt das linke und das rechte Modell nach der Straßenbreite. base/content/infrastructure/railroad_crossing/railroad_crossing/era_b_eu/era_b_eu.rcr.lua:
function data()
return {
description = {
name = _("INFRA_RCR_ERA_B_NAME"),
icon = "era_b_eu.tga",
description = _("INFRA_RCR_ERA_B_NAME")
},
soundFileName = "/infrastructure/railroad_crossing/shared/railroad_crossing.wav",
config = {
{ modelLeft = "/infrastructure/railroad_crossing/shared/eu_a_simple.mdl", modelRight = "eu_b_barrier_small.mdl", streetWidth = 12.0 },
{ modelLeft = "/infrastructure/railroad_crossing/shared/eu_a_simple.mdl", modelRight = "eu_b_barrier_small.mdl", streetWidth = 18.0 },
{ modelLeft = "/infrastructure/railroad_crossing/shared/eu_a_simple.mdl", modelRight = "eu_b_barrier_medium.mdl", streetWidth = 22.0 },
{ modelLeft = "/infrastructure/railroad_crossing/shared/eu_a_simple.mdl", modelRight = "eu_b_barrier_large.mdl", streetWidth = 28.0 },
},
speedLimit = 160.0 / 3.6,
availability = { yearFrom = 1925, yearTo = 1975, },
menuCategory = { categories = { { order = 40, }, }, },
cost = 16000,
trafficDelay = 2500,
categoryList = { categories = { "temperate.clima", }, },
}
end
Das Spiel nimmt den Eintrag aus config, dessen streetWidth der tatsächlichen Straße am nächsten kommt. modelLeft und modelRight stehen links und rechts der Straße, gesehen in Fahrtrichtung auf den Übergang zu. Laut Wiki ist trafficDelay die Zeit in Millisekunden vom Beginn der Öffnungsanimation, bis der Straßenverkehr wieder fährt (ohne Angabe 2500, und alle zehn Bahnübergänge des Basisspiels setzen 2500). soundFileName läuft, während der Übergang schließt oder geschlossen ist, crossingMaterial ist die Oberfläche zwischen den Schienen (Standard infrastructure/railroad_crossing/shared/mat/railroad_crossing.mtl), und ein Eintrag in categoryList, der dem Dateinamen eines Klimas entspricht, beschränkt den Typ auf dieses Klima. Die Basisdateien setzen außerdem speedLimit (120 oder 160 km/h), das im Wiki fehlt.
Die Modellereignisse heißen forever, idle_open, close, idle_closed und open. Das Schrankenmodell eu_b_barrier_small.mdl im selben Ordner verwendet close und open an seinen Knoten für Schranke und Rad:
animations = {
close = { params = { id = "ani/close/crossing_eu_b_barrier_small.ani", }, type = "FILE_REF", },
open = { params = { id = "ani/open/crossing_eu_b_barrier_small.ani", }, type = "FILE_REF", },
},
Einige US-Modelle verwenden auch idle_closed, zum Beispiel era_b_us/us_b_barrier_small.mdl. Zur Laufzeit steckt der Zustand in Engine.Component.RailroadCrossing.
Ampeln¶
Ein Ampeltyp hat keine festen Modelle. Sein modelScript wird an einer Kreuzung für jede Straße aufgerufen und gibt die Modelle zurück, die dort stehen sollen. base/content/infrastructure/traffic_light/traffic_light/traffic_light_a.trl.lua:
local trafficlightutil = require "/infrastructure/traffic_light/trafficlightutil.lua"
-- in einem Mod: require "::/infrastructure/traffic_light/trafficlightutil.lua"
function data()
local input = {
models = {
trafficLightPole = "traffic_light_a/pole.mdl",
pedestrianPole = "traffic_light_a/pedestrian_pole.mdl",
beam = { "traffic_light_a/beam_1.mdl", "traffic_light_a/beam_r.mdl", }, -- last model is repeated
trafficLight = { "traffic_light_a/traffic_light_1.mdl", "traffic_light_a/traffic_light_r.mdl", },
pedestrianLight = "traffic_light_a/pedestrian_light.mdl",
},
params = {
offset = -0.25,
beamWidth = { 6 + .25, 3 },
lightOffset = { 4.5, 1.5 },
poleTrafficLight = true
}
}
return {
availability = { yearFrom = 0, },
description = { name = _("Type A"), icon = "traffic_light_a_eu.tga" },
tryOpposite = false,
modelScript = {
fileName = "traffic_light.script@traffic_light_a.modelFn",
params = input
},
categoryList = { categories = { "temperate.clima", "subarctic.clima" }, },
}
end
traffic_light.script.lua setzt traffic_light_a.modelFn und traffic_light_c.modelFn auf trafficlightutil.standardLights(). Dieser Helfer liest die models und params von oben: ein Mast rechts, Ausleger von rechts nach links, wobei der letzte wiederholt wird, eine Ampel pro Spur bei lightOffset und Fußgängerampeln an eigenen Masten dort, wo kein Ampelmast steht. Mit poleTrafficLight = true hängt die Ampel der Spur ganz rechts am Mast statt am Ausleger. tryOpposite = true setzt die Ampeln wie in den USA auf die gegenüberliegende Seite der Kreuzung, wenn dort eine Straße ist.
Das Wiki verortet diesen Helfer unter res/scripts/trafficlightutil.lua. Im Basisspiel liegt er unter base/content/infrastructure/traffic_light/traffic_light/trafficlightutil.lua und wird wie oben gezeigt geladen.
Ein eigenes modelScript bekommt captureParams (die params aus dem Verweis) und args für eine Straße: needsLight und pedestrian (pro Spur, von rechts nach links, Gehwege eingeschlossen), widths, position (rechte Straßenseite neben der äußersten Spur) und oppositePosition. Es gibt für jede Spur, die eine Ampel braucht, eine Liste zurück, jeweils aus { id = "....mdl", transf = { ... } } mit globalen Transformationen. Ein vollständiges Beispielergebnis steht im Wiki.
Modelle für Verkehrs- und Fußgängerampeln verwenden die Ereignisse idle_red, green, idle_green und red im selben Ablauf wie Signale. Ab welchem Jahr Städte Ampeln bekommen, steht nicht in den .trl.lua-Dateien. traffic_light_config.res.lua legt es als Spielkonfiguration fest, data = { trafficLightYearFrom = 1950 }, und es wird in TrafficLightConfig eingelesen.
Offizielles Wiki: Tracks and streets, Edge addons, Bridges and tunnels, Signals, Railroad crossings, Traffic lights. Die alte Seite Infrastructure leitet nur auf Tracks and streets weiter.