Posts by Benny (BH2)

    Hallo Sebastian,

    unabhängig zu den vorherigen Antworten:

    wenn ich aus einem virtuellen Depot die Züge alle 10 min ausfahren lassen möchte, kann ich das dann so machen?

    LUA Source Code
    1. function DepotSWest()
    2. if EEPTimeM % 10 == 0 then
    3. EEPGetTrainFromTrainyard(1, "", 1)
    4. end
    5. end

    Dein Code schickt bei jedem Aufruf der Funktion einen Zug los, falls die aktuelle Minute durch 10 teilbar ist.

    Wenn die Funktion in der EEPMain aufgerufen wird, bedeutet das, dass von 0:00:00 bis 0:00:59 fünfmal pro Sekunde ein Zug abgefeuert wird (sofern das Depot 300 Züge enthält). Dann ist für 9 Minuten Pause, bis um 0:10:00 wieder eine Chaos-Minute losgeht.


    Falls das nicht das ist, was du willst, solltest du zu der Bedingung noch hinzufügen, dass sich die Minutenzahl seit dem letzten Aufruf geändert hat (dazu musst du sie in einer weiteren Variable zwischenspeichern):

    LUA Source Code
    1. function DepotSWest()
    2. if EEPTimeM ~= MinuteBeiLetztemAufruf and EEPTimeM % 10 == 0 then
    3. EEPGetTrainFromTrainyard(1, "", 1)
    4. end
    5. MinuteBeiLetztemAufruf = EEPTimeM
    6. end


    Viele Grüße

    Benny

    Hallo Fried,

    bei deinem ersten Verbesserungsvorschlag gehe ich mit.

    Beim zweiten gehe ich nicht mit, denn der verändert ungewollt die Logik.

    Nehmen wir als Beispiel EEPTime = 10000 und pZ = -10.

    Wenn wir das in die Bedingungen einsetzen, ergibt sich

    LUA Source Code
    1. if true then
    2. if false then
    3. -- wird nicht ausgeführt, weil inneres if false ist
    4. end
    5. else
    6. if true then
    7. -- wird nicht ausgeführt, weil äußeres if true ist
    8. end
    9. end

    bzw.

    LUA Source Code
    1. if true and false then
    2. -- wird nicht ausgeführt
    3. elseif true then
    4. -- wird ausgeführt :-O
    5. end


    Auch ohne diese Logikänderung würde ich vermutlich die Variante nach dem ersten Verbesserungsvorschlag bevorzugen, weil so (meiner Meinung nach) leichter zu lesen (also die Logik leichter zu verstehen) ist.


    Viele Grüße

    Benny

    Abhilfe schaffen im Prinzip Blockstrecken, doch kommt es fürdie Simulation der Seilbahn nicht infrage, dass Gondeln auf offener Strecke vor (unsichtbaren) Signalen stehenbleiben. [...] Ich kann in der Berg- und Talstation jeweils zwei Blockstreckenunterbringen – für mehr würde es zu eng. Das würde aber bedeuten, dass nur sehrwenige Gondeln unterwegs sein dürfen (drei Gondeln!), und zwar unabhängig vonder Gesamtlänge der Seilbahn, die ja durchaus mehr als einen Kilometer betragenkann.

    Wie du erkannt hast, helfen dir Blockstrecken im klassischen Sinne (in jedem Block darf sich maximal ein Zug gleichzeitig aufhalten) nicht weiter. Dann bräuchte man entweder sehr viele Blockabschnitte (was zum "Halt auf offener Strecke" führen könnte), oder es können nur wenige Gondeln unterwegs sein.

    Mein Vorschlag (den Lars schon zuvor gemacht hat) ist eher eine Art "Pförtnerampel", wie ich sie einmal an einer Autobahnzufahrt gesehen habe: Diese Ampel/unsichtbares Signal schaltet nicht erst dann auf grün, wenn der komplette vorausliegende Blockabschnitt komplett frei ist, sondern sobald die nächsten x Meter frei (oder x Sekunden vergangen) sind. Auf offener Strecke "fahren" die Gondeln dann wieder auf eigene Faust, ohne Blockregelung. Dadurch, dass alle die gleiche Geschwindigkeit haben, sollte es aber trotzdem nicht zu Auffahrunfällen kommen.

    Die Pförtnerampel dient nur dazu, die kleinen Abweichungen im Abstand wieder "geradezubiegen".


    Ich hoffe, die Beschreibung/Erklärung war verständlich. Wenn nicht, bitte nochmal nachfragen. Kongo485 kann bestimmt auch helfen, er hatte ja die gleiche idee.


    Viele Grüße

    Benny

    Also ich habe verstanden (aber das hast du vermutlich auch nicht angezweifelt).

    Was mir auf den Bildern noch auffällt, was du aber nicht (explizit) geschrieben hast: Die Modelle, die auf den Grenzen der 150x150m-Kacheln stehen (also zu zwei Kacheln gleichzeitig gehören), werden anscheinend nochmal separat berechnet und ausgeblendet. So erkläre ich mir diese "Schneisen", die auf deinen Bildern nahe der Umschaltgrenzen zu sehen sind.


    Viele Grüße

    Benny


    Nachtrag mit einer weiteren Experimentier-Idee: Was passiert, wenn die Modelle zufällig skaliert werden? Dann sollten die Umschaltentfernungen ja auch entsprechend unterschiedlich sein. Werden die 150x150m-Raster also nur für die Abstandsberechnung zur Kamera verwendet, oder zum tatsächlichen Ausblenden?

    Ich hoffe, dass sich durch leicht zufällige Skalierung das "Plopping" verringern lässt.

    Hallo Jerome,

    LUA Source Code
    1. Tabelle["NameFahrzeug_1"]["NameFrachtgut_1"] = { [3] = "StringFür_ENV_Funktion_2a" },

    Damit wird auch alles gelöscht verworfen, was vorher in der Untertabelle stand.

    Was du willst, ist vermutlich das hier:

    LUA Source Code
    1. Tabelle["NameFahrzeug_1"]["NameFrachtgut_1"][3] = "StringFür_ENV_Funktion_2a"

    Oder da es am Ende um durchnummerierte Einträge geht, wäre table.insert sinnvoll:

    LUA Source Code
    1. table.insert(Tabelle["NameFahrzeug_1"]["NameFrachtgut_1"], "StringFür_ENV_Funktion_2a")



    Dein "Hauptproblem" ist ungefähr das gleiche:

    LUA Source Code
    1. function eintragTabelle (_nameFahrzeug, _nameFrachtgut, _neuAufgabe)
    2. if Tabelle[_nameFahrzeug] == nil then
    3. Tabelle = { [_nameFahrzeug] = { [_nameFrachtgut] = {_neuAufgabe} } }
    4.     end
    5. end

    Wenn der Tabelleneintrag _nameFahrzeug nicht existiert, überschreibst du Tabelle mit einer neuen Tabelle, die nur _nameFahrzeug enthält, alle vorherigen Einträge aber nicht mehr.

    Hier sieht die Lösung ähnlich aus: Nicht die gesamte Tabelle überschreiben, sondern nur den einen gewünschten Eintrag setzen:

    LUA Source Code
    1. function eintragTabelle (_nameFahrzeug, _nameFrachtgut, _neuAufgabe)
    2. if Tabelle[_nameFahrzeug] == nil then
    3. Tabelle[_nameFahrzeug] = { [_nameFrachtgut] = {_neuAufgabe} }
    4. end
    5. end

    Ich würde das ganze aufteilen in "noch nicht existierende Tabellen bei Bedarf anlegen" und "den gewünschten Eintrag in die nun existierenden Tabellen einfügen". Dann sähe das so aus:

    LUA Source Code
    1. function eintragTabelle (_nameFahrzeug, _nameFrachtgut, _neuAufgabe)
    2. if Tabelle == nil then Tabelle = {} end
    3. if Tabelle[_nameFahrzeug] == nil then Tabelle[_nameFahrzeug] = {} end
    4. if Tabelle[_nameFahrzeug][_nameFrachtgut] == nil then Tabelle[_nameFahrzeug][_nameFrachtgut] = {} end
    5. -- jetzt ist sichergestellt, dass Tabelle[_nameFahrzeug][_nameFrachtgut] eine Tabelle ist
    6. table.insert(Tabelle[_nameFahrzeug][_nameFrachtgut], _neuAufgabe)
    7. end


    Wenn du diese Aufteilung verwendest, gilt für alle "dynamischen Tabellenoperationen" folgende Faustregel: Zugewiesen (mit =) werden nur leere Tabellen {} oder die eigentlichen Inhalte, aber keine Tabellen mit Inhalt. Letzteres birgt nämlich immer die Gefahr, bereits vorhandene Tabelleninhalte wegzuwerfen.


    Viele Grüße

    Benny


    PS: Ich empfehle dir, einen besseren Variablennamen zu suchen als Tabelle.

    PPS: Noch ein Hinweis, weil ich des öfteren "StringFür_ENV_Funktion" lese: Du kannst auch direkt die gewünschte Funktion in die Tabelle speichern.

    Hallo Jerome,

    du machst es dir zu kompliziert.

    table.insert brauchst du nur für durchnummerierte Tabellen (="Arrays"), um die darauffolgenden Tabelleneinträge weiterzuschieben.


    Wenn du Strings als Tabellenindex haben willst, kannst du die Tabellenstelle einfach direkt beschreiben:

    LUA Source Code
    1. Tabelle = {}
    2. Tabelle["NameFahrzeug_1"] = {}
    3. Tabelle["NameFahrzeug_1"]["NameFrachtgut_1"] = {
    4. [1] = "StringFür_ENV_Funktion_1",
    5. [2] = "StringFür_ENV_Funktion_2"
    6. },


    Das hattest du so auch schon gemacht, bist anschließend aber über die überflüssigen (durch table.insert erzeugten) nummerierten Einträge gestolpert, die Strings statt Tabellen enthielten. Die werden bei pairs auch durchiteriert (aber in einer zufälligen Reihenfolge).


    Viele Grüße

    Benny

    Hast du denn auch einen Zug aktiv, dessen Geschwindigkeit angezeigt werden kann?

    Und bist du im Vollbildmodus? Sonst werden Zugname, Zuggeschwindigkeit und Kameraname nicht im 3D-Fenster angezeigt, weil sie bereits an anderen Stellen angezeigt werden.


    Viele Grüße

    Benny

    Wenn die Modelle auf die falsche Registriernummer signiert sind, kommt bei Gleisobjekten diese Fehlermeldung (vermutlich, weil das Blaues-Fragezeichen-Dummy-Modell keine Gleise enthält).

    Ignoriere diese Meldung also erstmal und kümmer dich darum, die blauen Fragezeichen loszuwerden (siehe #17). Wenn du das geschafft hast, sollte auch die enthält-keine-Gleise-Fehlermeldung verschwunden sein.


    Viele Grüße

    Benny

    Um sowas unfallfrei zu steuern, brauchst du eine Instanz, die entscheidet, welches der drei Signale auf Fahrt gestellt wird. Das kann ein Schaltkringel mit drei "Ohren" sein, in dem ein Schaltauto fährt. Mit Lua geht das ganze auch.

    Aber ganz so einfach wie eine simple Blocksteuerung (nur Kontaktpunkte auf der Strecke) geht das leider nicht.


    Viele Grüße

    Benny

    Danke für die Bilder vom Experiment :be_1:

    Genau das hatte ich erwartet: Die Spiegelung wird nur einmal berechnet, dementsprechend passt es bei der anderen Höhe dann nicht.

    Was ich nicht erwartet hatte ist, dass sich die "Spiegelhöhe" scheinbar je nach Blickwinkel ändert.


    Da bei mir bisher keinerlei Frameverluste zu verzeichnen waren, wenn eine Spiegelung im Fluss

    in den Sichtbereich kam, gehe ich davon aus, das die Framebelastung auch nicht sonderlich hoch ist.

    Naja, die Framebelastung durch die Spiegelung dürfte ähnlich hoch sein wie die Framebelastung durch die Anlage, weil die gesamte Anlage ein zweites Mal gerendert werden muss (aus einem anderen Blickwinkel).

    Wenn auf der Anlage kaum was steht, gibts natürlich auch wenig (zusätzlich) zu berechnen. Und wenn die Framerate bei 60fps liegt, ist sie eh am Anschlag, da kannst du zusätzliche Framebelastungen also gar nicht feststellen.


    Im Prinzip müsste sich die Framerate durch die Spiegelung halbieren. Wenn auf zwei Ebenen gespiegelt wird, müsste sie sich dritteln. Bei drei Spiegelebenen vierteln, und so weiter.

    Vermutlich ist der Effekt der Spiegelung nicht ganz so groß, weil bei der Spiegelung die Sichtweite stark eingeschränkt ist und sich die Programmierer vielleicht auch noch andere Optimierungen haben einfallen lassen.

    Trotzdem denke ich, dass die Beschränkung durchaus sinnvoll ist und nicht nur daher kommt, dass Trend euch "gängeln" will. (Auch wenn mich die Beschränkung auch schon gestört hat)


    Viele Grüße

    Benny