Beiträge von Unorthodox Paradox

Willkommen in der OMSI-WebDisk!
Als Gast kannst du nur Inhalte in deiner ausgewählten Sprache sehen. Registrierte Nutzer können die Sichtbarkeit anderer Sprachen in ihrem Kontrollzentrum aktivieren, weitere Infos hier.
Alle Themen sind in den Foren mit einer Sprachflagge gekennzeichnet: = Englisch [EN], = Deutsch [DE], = Französisch [FR]. Wenn du die angegebene Sprache nicht beherrschst, schreibe auf Englisch!

    One can also forego the need for continuous / per-frame timing, by opportunistically, on a per-trigger-invocation basis, comparing GetTime against its value recorded during the previous (completed) trigger run (if any):

    Pros:

    • Might spare the odd microsecond due to not running on each and every frame (can be improved even further by splitting the if-statement into a bunch of if-elses -- to the further detriment of readability)
    • Generally speaking (beyond triggers), GetTime-based timing is advantageous when it comes to AI vehicles, as these might experience halts in script execution owing to despawns / respawns, hence being provided with no hard guarantee that their {frame} will indeed run uninterruptedly once per game frame

    Cons:

    • (Subjectively) less readable
    • Extra logic needed to account for the edge case of the OMSI situation getting saved / reloaded during a cooldown period
    • Harder for other code to observe the state of timing and take concurrent action (think e.g. inter-trigger coordination)

    Then I'm afraid that our files are incompatible; I tested the aforementioned changes on the DL05 of a plain vanilla X10 installation (version 1.31) and they are at least at first glance working as intended. Unfortunately I can't attach the whole cockpit.osc due to copyright.


    Have you modded the script(s) yourself, or have you by chance introduced third-party mods affecting them? Have any new script-related error entries made an appearance in your logfile?


    Maybe try eliminating all comment lines from the patch above, for the unlikely case that the extra apostrophes or other special characters in there, in conjunction with our differing Windows locales and no support for UTF-8, are giving your OMSI a headache.

    Hello,


    This is somewhat complicated; for one because the script goes to some lengths to be efficient, by not updating the display's script-textures with each frame unless the content to be rendered has actually been modified; and for two because the font is not "modular" -- rather than offering primitive shapes (e.g. triangles and circles) for users to compose more complex ones off of, it provides ready-assembled composite shapes of varying widths --, thus necessitating some slightly more nuanced clearing logic when, as in this case, it's desired to alternate between multiple symbols at overlapping coordinates. I'll include some in-line commentary in case you're interested in the details.


    1. Revise the conditions under which the display's script-texture gets refreshed:


    a. Find:

    Code: cockpit.osc
    (L.L.vdv_blink) s0
    (L.S.GetTime) 1.6 % 1.1 < (S.L.vdv_blink) l0 = !
    {if}
        1 (S.L.vdv_refresh)
    {endif}

    Insert after:


    b. Optionally, find and delete (or comment out) the following line (to be found under the "Kriterien für Aktualisierung der Scripttextur" block), as it is now superfluous:

    Code
    (L.L.kneel_upsound) (L.L.kneel_downsound) || $IntToStr $+


    2. Replace (or comment out and insert after) the "Kneeling-Pfeile" section (i.e. all code referenced in your opening post above) with:

    Code
        (M.L.vdv_kneel_display_refresh)


    3. Insert the implementation of the revised kneeling-specific display handling at the very end of the file (after the closing {end} of the vdv_frame macro):


    4. a. Declare the following new variables (e.g. in cockpit_varlist.txt).

    Code
    vdv_kneel_display_target
    vdv_kneel_display

    b. ...as well as the string-variable vdv_kneel_display_str (e.g. in cockpit_stringvarlist.txt).


    Note that I didn't test the above extensively, let alone exhaustively -- there may be bugs. Feel free to ask if you run into issues (I do understand German, but am usually too lazy to write in it).

    A couple more thoughts on the original formula: There are more angles with a sine closer to ±1 than there are angles with a sine closer to 0; ±0.5 is already being reached at ±30 degrees, therefore ~66% of all angles, and by extension vehicle number inputs, produce an output that's at risk of being interpreted as either abnormally silent or abnormally loud.

    With real-world objects, by contrast, we generally expect kind of a bell-shaped distribution, with more observations gravitating toward the middle of the interval of previous observations than toward the edges.


    In this particular instance, a simple change in pursuit of such an effect might be the use of (for lack of a better

    term) "sine's complement": 1 - sine, when sine ≥ 0; -1 - sine, otherwise.


    Code-wise1:

    This in a sense "flips" the distribution of outputs. The output pattern will still be repeating with every 10th value (because (9 * 1000) mod 360 = 0), but now ~66% of outputs should fall under the normal range and only ~34% outside of it. The same effect could of course have been accomplished by adjusting the volcurve so as to produce outlier outputs for normal inputs and normal outputs for outlier inputs (but since bremse_quietsch_volume now also accounts for vehicle age and maintenance state, doing so wouldn't have the desired effect overall).

    Hello,


    I assume that this is the formula/block you speak of:


    Code
        (L.L.bremse_quietsch_volume) -1.5 <
        {if}
            (L.$.number) $StrToFloat 1000 * sin (S.L.bremse_quietsch_volume)
        {endif}


    As far as I can tell, its logic goes as follows:

    1. Check whether bremse_quietsch_volume is currently less than -1.5. During {init}, the variable gets initialized to -2, so this test guarantees that the assignment following will only be undertaken once -- given that, as we will see below, the value generated and assigned is always at least -1 (or greater). Why not just compare the variable to -2 then? Because floating point arithmetic is generally imprecise and OMSI is no exception, which in particular tends to become evident when reloading saved situations (if you peak inside *.osn files, the values stored are typically not exact integers even when so intended by the script assignments responsible). Why not just handle this in the {init} block? Because a) not all system and predefined variables (e.g., the vehicle's number) are available at that time, plus potentially because, if I recall correctly, b) {init} doesn't get re-executed upon stored situation reload, which sometimes leads to problems in code taking it for granted (in this particular case it probably wouldn't make a difference though). Anyhow, if bremse_quietsch_volume is less than -1.5, then:
    2. Take the vehicle number string, number, and convert it to numeric form. Doing so yields -1, when the vehicle happens to have no valid number (e.g. empty string ("") or string otherwise non-convertible to float), or otherwise the equivalent floating point representation of the string, essentially a random quantity as far as the script is concerned.
    3. Multiply that value by 1000. This means that the default of -1 becomes -1000, which is of significance when it comes to the next step.
    4. Now treat the previous value as an angle and compute its sine, resulting in a value between -1 (when angle = -90° or 270°, ± any multiple of 360°) and 1 (when angle = -270° or 90°, likewise). So, in the default case, sin(-1000) = sin(-280) = sin(80) ≈ 0.98.
    5. Lastly, map bremse_quietsch_volume according to the apposite volcurve defined in the sound.cfg:


    Now let's try to revise this to take vehicle age into account, as well as to always "spit out" a value no less than 0.05.

    (Also, maybe you'd like to additionally consult the game's maintenance setting, wearlifespan; note that in the case of AI vehicles, they always get assigned a wearlifespan to be interpreted as "infinite" / "perfect" by default.)



    Const-file additions (feel free to customize):



    Note that I haven't got OMSI installed at the moment and thus can't provide any assurance that the above is bug-free.

    Hello,


    Concerning script-influenced AI lighting, you might want to take a look at that older post, as well as at the CSB pack which includes a more comprehensive implementation of the same basic idea.


    What both of these accomplish, in a nutshell, is to:

    1. Assign, at initialization time, a random per-vehicle threshold for a) solar elevation angle (Sun_Alt), b) brightness (Envir_Brightness) and c) rain/snow rate (PrecipRate -- the system variable, not the local one, as the latter also depends on vehicle velocity, orientation and wind speed); and
    2. check, once per frame, whether these thresholds have been exceeded, and if so switch lights on or off (but with an asymmetrically timed delay -- shorter when lights are to be switched on, longer in the opposite case --, so as to avoid excessively frequent cycling when, say, the vehicle happens to have briefly entered the shadow of an isolated cloud, or, say, it has stopped raining but for merely half a minute).

    The model.cfg then simply references custom variable(s) for lighting state, rather than built-in AI_(Interior)Light.


    Note that, behind the scenes, AI_Light itself is still being taken into account as an additional factor, because it can serve as a heuristic for weather-/environment-related information which OMSI provides no explicit API for, such as visibility/fog, cloudiness and state of street lights. For instance, assuming the default <OMSI>\envir.cfg[1], under normal (clear and dry) weather conditions, OMSI instructs vehicles to turn their lights off/on at, IIRC, ~10 degrees solar elevation angle; thus, when Sun_Alt is greater than 10 and yet AI_Light is still equal to 1, a script can deduce that it's to some degree cloudy and/or rainy and/or foggy.


    As for the CSB adaptation in particular, it goes a little further, also addressing aspects such as varying usage of cabin lighting during the day, as well varying usage of both interior and exterior lighting at prolonged stops (stops with a duration in excess of 1 minute, at which OMSI requests that the engine be turned off).


    Likewise, when it comes to script-influenced AI acceleration, the premise is to define and reference custom Throttle and Brake variables instead of their native counterparts. For example, in that unfinished "mod-mod" for the CSB fleet (see cockpit_throttle_brake_frame macro), this very tactic is employed for simulating a more human-like driver's departure from a stop -- firstly just briefly tapping the throttle for the stop brake to disengage, waiting for a second or two (presumably for checking mirrors and ensuring no one intending to board got left behind), and only then proceeding to firmly depress the pedal to actually accelerate. Originally my intent had been broader and similarly ambitious to yours -- I was seeking to assign a distinct "aggressiveness factor" to each vehicle, based both on the driver's (random) personality as well as potential timetable deviation. Eventually I abandoned that goal, as it dawned on me that the game unfortunately doesn't expose the requisite contextual information for an acceptably realistic implementation, for instance bumper-to-bumper distances, whether an upcoming traffic light just turned yellow, or whether a pedestrian randomly decided to jaywalk Berlin-style. Surely some of these can be deduced by probing whether Brake suddenly spikes to 100% (normally OMSI likes to brake relatively gently, typically under 20%), but still, scripts just don't get a real chance to plan ahead like a regular old human would, by e.g. preemptively letting go of the accelerator so as to slow down say a hundred meters prior to reaching an obstacle, as opposed to slamming down the brake at the very last instant only to barely avoid a collision.


    TL;DR: As IREgio612 wrote, you would use your own logic to emulate/augment AI_(Interior)Light, Throttle and Brake, store the results of your calculations in your own variables, and replace all references to the original variables (in scripts as well as in model.cfg and potentially sound.cfg files) with your own variants. For AI cars this tends to be relatively painless, since they typically reuse <OMSI>\Scripts\AI_Cars\main_AI_xxx.osc and ~AI_varlist_xxx.txt, thus leaving only their model.cfg (plus potentially *.ovh/bus, if scripts/varlists were renamed/added) in need of revision.


    [1] As an aside, that file might be functioning as the "global switch" you mention. While I don't own the aforementioned DLC, I suspect that it alters the brightness (color transition by time of day) curves defined in that file, which in turn might be influencing the conditions under which OMSI sets AI_Light to 1.


    (Edit) Another possibility to consider are the cloud type definitions (<OMSI>\Weather\clouds.cfg), and by extension the weather scenarios (*.owt) referencing them: Clouds defined as "overcast" (ovc) always trigger AI_Light, regardless the time of day and other weather settings in effect. Consequently, even a fully transparent cloud texture, not affecting insolation/brightness at all, could be forcing AI vehicles to permanently leave their lights on.

    I don't own the Urbino add-on, so I can't beta-test. Nonetheless, while glancing over the latest version of the lighting script in search for changes, I remembered an ancient little quirk (technically an OMSI bug... or perhaps feature, who knows) that you might want to address if you too consider it a problem: When headlights are on, it is impossible to communicate priority assignment (Lichthupe) to nearby AI traffic by manually quickly switching the high beam on and off. That appears to be due to OMSI only picking up on the user's intent when AI_Light initially <= 0.5 (only standstill lights on, or no exterior lights active at all), before being increased to 2 (high beam on). Thus the workaround is to a) detect whether the user has rapidly (e.g. in less than 0.5 sec) switched the high beam on and back off in succession, and, when that is the case, b) set AI_Light temporarily to 0.5 (instead of 1) once the high beam has been switched back off, such that OMSI gets the message.


    In code (haven't tested these particular lines -- I just recall out of experience that the general idea works):


    For reasons unknown to me, the original script appends a line-break ("@" character) at the end of its IBIS string-variable (see AFR200\IBIS-2.osc, line 504). With that line-break, the string gets output at the proper height. Perhaps an expert on the field of text-textures and fonts could illuminate us both on why that is.


    Good catch on the Refresh_Strings callback variable!

    I'm sorry -- I thought that this would be a quick and painless bug hunt; I was wrong. Your script gave me a hard time to even get it to run last night. After a bit of banging my head against the wall, I realized it's probably due to the classic OMSI Unicode-related quirks (UTF-8-encoded file + non-ASCII (German) characters within the file + Windows configured with a non-German locale --> magic inexplicable Zugriffsverletzung + non-spawning bus); once I had removed everything from your file, leaving just two blank pairs of init and frame macros behind, the bus would at least spawn. Anyway, unless someone else helps you out meanwhile, I'll get back to you later today or tomorrow, once I've had some time to go over your code line-by-line to get rid of all non-ASCII characters.


    For the time being, some more syntax issues (line numbers as per your attached AFR.osc):

    • Line 262: You need an {endif} instead of an {end} there.
    • Line 349: By the time you reach the end of the ticketprinter_frame-macro, you still have 2 open {if}s, i.e., you are missing 2 complementing {endif}s. In the code you have directly included in your opening post, you seem to have fixed that.

    Hello,


    It's a little hard to give you any pointers without being able to test first. Is there a bus/mod that would allow me to easily/conveniently test your code (sorry -- I've lost track of all the different ticket printers)?


    One obvious little bug nonetheless: Your AFR_Codeeingabe-macro lacks a closing {end}. That might cause the script interpreter to also execute the next macro, AFR_Setmode_4, whenever the former gets called, in turn leading to erroneous side effects.


    As usual, feel free to respond in German.