The spawn count of the smoke source of a vehicle moves out of
smoke_source::update() into smoke::vehicle_spawn_count() (vehicle/smoke.h),
a free function on the mover state, which joins the core library so the
unit tests can call it the way the source does. The rates are the same as
before, the steady rate of the source still counted in before the share of
the engine.
Tests: tests/unit/test_smoke.cpp. A vehicle taken off the tracks spawns no
smoke and drops the pending particles, with the engine starting, idling or
under load; a road vehicle back from the pool puffs again; the engine adds
to the steady rate; the pending count stays within the room of the source.
Two of the four fail without the fix.
Checked again on td.scn with the SM42 driven into a portal: the smoke
source keeps puffing on the run and drops to 0 particles once the vehicle
is taken off the tracks.
* fix: automatic coupler crashes, horns, compressor start delay, radio and cab lever sounds
fix(cab): the line contactors lamp goes out with the pressure switch (eu07/maszyna#470)
The lamp of the open line contactors, which tells the start can be made, went out at 1 bar in the brake
cylinders, while the pressure switch cuts the start off only at 2 bar (or below 3.6 bar in the main pipe), so
with the brakes partly applied the start could be made with the lamp out. With a pressure switch fitted the lamp
now follows it; without one it goes out at 1 bar as before. The same holds for the lamp of the second unit, which
used to keep its last state between 1 bar and the cut-off. The condition is
TMoverParameters::LineContactorsLampLit().
Tests: tests/unit/test_line_contactors.cpp.
refactor: Sonar findings of PR 217
- horn_supply::pneumatic shadowed the pneumatic enumerator of the sound flags (cpp:S1117), it's horn_supply::air;
the supplies read with using enum (S6177),
- CouplerForce(): the automatic coupling refused or caught without another level of nested ifs (S134), the
same outcome: too fast, the coupling is locked; caught, coupled and locked; otherwise left to try again,
- CompressorCheck(): the power the compressor doesn't draw yet noted without a TODO (S1135),
- tests: the previous crash damage setting in an in-class initializer (S3230), the loops which stop early with
break rather than in their conditions (S886), the stand-ins of test::pair in a std::vector rather than an array
(S5945), units in the comments of the example without /* */ (S1103).
test: the cases the changes of the branch left without a test
- Cntrl.: BDelay1 to BDelay4 reach the brake delays (now through std::format), the default start types of the
ground and converter overload relays of a multiple unit and of other vehicles (out of the nested conditionals),
- the compressor: fed from the low voltage it waits from the low voltage coming on; the pressure switch stops it
above the cut-out pressure, without one the excess air is vented (the vented fraction rewritten),
- the horns: a vehicle without any air sounds as before, the threshold pressure, an electric horn on 110 V,
- the positions of a cab control below zero, and a control without position sounds.
refactor(cab): the kind of the train heating switch as a flag
Read once with the vehicle definition, rather than compared as text in each of the switch commands.
feat(cab): train heating switch springing back (MaSzyna-EU07/maszyna#85)
TrainHeating=[toggle]|impulse in the Switches: section of the vehicle definition makes the train heating switch
an unstable one: it goes up to switch the heating on, down to switch it off, and back to the middle once let go,
instead of staying where it was put. The position of such a switch isn't set from the heating state when the cab
is entered.
Tests: tests/unit/test_switches.cpp.
feat(sound): mirror sounds (MaSzyna-EU07/maszyna#84, eu07/maszyna#322)
The sound definitions of a vehicle (.mmd) take mirroropen: and mirrorclose:, played as a mirror sets off
unfolding or folding, and the locations section mirrors: <offset>... end, the offsets along the vehicle of the
mirror pairs, as for the doors (negative ahead of the centre), each pair at the sides of the vehicle. As the
animation, only the mirrors at the occupied cab sound. The start of a move is mirror_moves::motion in
vehicle/mirrors.h.
Tests: tests/unit/test_mirrors.cpp.
feat(cab): joint oil and fuel pump switch (MaSzyna-EU07/maszyna#81)
A cab control oilfuelpump_sw: switches both the oil and the fuel pump at once, with the new command
oilfuelpumptoggle (no key by default). As a two-state switch it turns both pumps off when both are on and both on
otherwise; as an impulse switch it's held to start them, like the separate pump switches. Its position follows
the pumps when the cab is entered.
refactor(editor): text fields filled without strncpy (MaSzyna-EU07/maszyna#112)
The last three strncpy calls Sonar flags (cpp:S5816), in the road and track editors, copy the text into the
ImGui field buffers with std::string::copy and terminate it right after; the text gets cut to the buffer as
before.
fix: automatic coupler crashes, horns, compressor start delay, radio and cab lever sounds
- automatic couplers don't catch above the safe collision speed (#86): with crash damage on they couple at a
closing speed of 15 km/h at most, a faster hit locks the coupling until the vehicles part and the collision
runs its course. On the way: CollisionVelocity() read a head-on 10 + 10 km/h as 14.1 km/h (quaternions turn
by half the angle), it's now taken from the touching ends; CollisionDetect() took the other vehicle's speed
the wrong way round for vehicles facing each other. Head-on hits now derail sooner, at the intended limit,
- a single horn lever can't sound both tones at once (eu07/maszyna#392),
- a skid ends once the vehicle stops on locked wheels (eu07/maszyna#479),
- electronic destination signs are blanked at the end of the timetable (eu07/maszyna#446),
- horns need the air or the voltage to sound (eu07/maszyna#290, #76): HornType=[Pneumatic]|Electric and
Horn3Type in Cntrl.; a pneumatic horn needs 0.2 MPa in the main reservoir (or the main pipe without one),
an electric one the low voltage; the lever stays where it was put,
- compressor start delay (#67): CompressorStartDelay [s] in Brake., counted from the compressor getting its
power, after the engine starts say; none by default,
- the channel and volume buttons of a radio without power do nothing (eu07/maszyna#429); the power check of
the radio is TMoverParameters::RadioPowered(),
- a lever moved smoothly sounds the positions it passes (#83).
Sonar findings in the functions changed: nesting, nested conditionals, commented-out code, std::format,
references to const. Unit tests: test::pair for two vehicles running into each other, test_couplers,
test_horn, test_wheelslip, test_compressor, test_radio, test_gauge_positions.
* fix: review findings of PR 217
- the pressures of the mover are in bar (MinCP=7.0 in the vehicle definitions), so the 0.2 the pneumatic horns
needed was 0.2 bar; it's 2 bar now, and the tests take their pressures in bar too,
- the lamps of the ground relay and of the motor overload relays follow the pressure switch as the line
contactors one does, TMoverParameters::MainCircuitLampsEnabled(), so the lamps of one cab go out together,
- the joint oil and fuel pump switch leaves out a pump started automatically, which ignores the switching:
with one, it couldn't turn the other off, and showed off with both running (OilFuelPumpsEnabled()),
- the kind of the train heating switch comes from the occupied vehicle on entering the cab too, as in the
switch commands; in a multiple unit these are different vehicles,
- CouplerForce() put the force taken back by the other vehicle on its far coupler when the vehicles faced each
other (Couplers[1 - End] rather than the coupler it's coupled with),
- the velocity difference along the coupler axis computed once, CouplerVelocityDifference(), for CouplerForce()
and CollisionVelocity(),
- the attachcoupler flag added without the SetFlag() call with 0, the index of the mirror moves noted as by side.
Tests: the coupler force of vehicles facing each other, the joint switch with an automatic pump, the lamps of
the main circuit, the horn and compressor pressures in bar.
* fix: coupler force of vehicles facing each other taken back along the other vehicle's axis
CForce runs along the axis of its own vehicle, so the force the other vehicle takes back on its coupler of the pair
is turned around once more when the vehicles face each other (-CF * DirPatch()), as that vehicle computes it itself.
Tests: the coupler forces of the pair facing each other and facing the same way.
The rules stay in TrackUneven.h with no dependence on the engine, as they can
be tested. Their use on the tracks moves out of Track.cpp to TrackUneven.cpp,
split into steps: the group of switches, the values of its paths, the meeting
of two ends. One set of helpers for the paths of a track takes the place of
the same conditions written out in several places, and the value at the ends
of a switch is worked out in one place. The clatter of an axle leaves the long
Update of a vehicle. The fields in the editor say themselves when they show.
No change in behaviour.
The track mode Kilometrage (X, under More) puts a point of the km where a track is clicked: the line, the km and, at a jump,
the km on from it. The axis of a line follows the main paths of the switches through the tracks of its points; on a
double-track line it runs between the tracks, and where they part on formations of their own and come together again it
runs along the longer one, the shorter one going by its own length with its last hectometre before they meet taking up
the difference (PKP GK-1 6.1.12). The km between the points are stretched to the length of the scenery evenly; the panel
lists the points with the stretch, the 3D view shows the axis, a tick at each hectometre, the points with their km and
the km of the lines by the mouse. Read the km from the posts turns the hectometre posts along the line into the points
of its km, a jump where two runs of numbers meet, and warns of a jump on a curve or at a station (Id-1 § 19). Each change
is a step of undo.
Labels:
- every button, field, tooltip and message of the editor reread for a beginner: short nouns for the fields with the
sentence in the tooltip, the less used options under More settings, one glossary (field of work, template, track,
grade), sides told from directions, degrees and per mille as signs, messages built from one format string
- plural forms through STR_P; the last entry of a po file is read too, and the Polish plural rule is in the header
- lang/editor_pl.po: the code pass entries merged, 391 entries no code uses and 3 duplicates dropped
- roads: the notes and errors naming a road translated; the build options and the layout fold the texture length,
kerb sizes, traffic share, roundabout part, height over the ground and junction speed limit under More settings, the
lanes start folded
Grade lines fitted to the terrain model (NMT), a line or the whole scenery at once:
- fit_ground: a robust fit on nodes 5 m apart; the ground parting from the line (a bridge, a viaduct, a wall) is gone
past rather than followed, the bends keep off the switches as far as their curves reach, a run of bends the same way
is one point of intersection, a curve with no room is as sharp as the room lets it be
- the ends of the line and the other paths of its switches leading into lines fitted already bound the line by what
the tracks between can climb; ends meeting in the plan, laid apart in height by hand, are joined before the run
- apply_profile: the paths are split where split_path takes the parameter (a straight was cut in the wrong place, into
pieces of a few centimetres the game takes for zero length), no piece shorter than the margin; the paths off the
ends of the route are brought to its height
- Bytom: 1600 lines, grade breaks at the joints 89 -> 20; Tarnowskie Gory: 848 lines, 223 -> 3; no step over 2 cm
- editorNmt: squares of 500 m of the NMT at 1 m from the WCS service of geoportal.gov.pl, as GeoTIFF, fetched in the
background, kept in editor/cache/nmt and sampled in the coordinates of the scenery, placed as its orthophoto is
- the terrain panel's Terrain model section: Fit to the tracks moves the model up or down by the median of the
differences to the formation of the tracks (Biała Podlaska, built at 0: -145.73 m, 0.28 m around it); Along the tracks
and Around the camera make the chunks as the model comes in; each path gets its formation and slopes 1:1.5 as a modifier
of the terrain, laid over each other into one corridor, bridges and tunnels keep the model; the orthophoto is turned
on and laid onto the new ground
- the http client of the orthophoto in editorHttp, shared; fill_from_nearest in editormodeshared.h
- after the generator of Hirek (MaszynaTerrainGenerator): the WCS requests, the cache of squares, the corridor by envelopes
- self-tests nmtfit, nmtmake, nmtwait
- editormoderoute.cpp: the route design, its kept records and digitizing
- editormodestraights.cpp: the plan tool: straights, the detour, the curve fit
- editormodelay.cpp: laying track, free ends and extending, the build tools
- editormodeswitchplace.cpp: placing switches, crossovers and links, double slips, curved switches
- editormodetrack.cpp keeps the selection, the snapshots, the tabs, the inspector and the path panel, the hints
- the sizes of the handles and reaches and the small helpers they all use in editormodetrackshared.h
The code is moved as it was.
editormodeselftest.cpp keeps the dispatch, the list of the commands and the step; the groups go to
editormodeselftest{scene,sleepers,sweep,track,switch,join,signal,terrain,rails}.cpp, the sleeper commands (beams,
sharedzones, sleepersbg, beamsnear, sleepercheck) in a group of their own; the frame count and one_line shared through
editormodeselftest.h. The output of geomhash, sleepercheck, wings, space, guards, crossings and switches is the same on the
seven sceneries of the regression.
- the switch tool asks what to place: a switch, a slip switch, a crossing or a connection of tracks (crossover, double,
scissors, ladder), with the templates and the options of that kind only and one line of how to place it with the mouse;
the bar of hints says the same, the wheel keys of a connection included; panel in its own editormodeswitchtool.cpp
- templates are listed by their names, the lengths a and b and the rest of the label in the tooltip
- the panel of a selected switch shows its length, its type and its drive; the name, number, rail, kilometre and angle are
under Details
- one toolbar: the tools are no longer drawn a second time down the edge of the view; the track tools show select, lay,
plan, switch and parallel, the others behind More, which starts closed again (setting track_tools_all)
- the infrastructure tool has no button nor key
- the gizmo options start closed, the node bank isn't drawn in the track mode
- no drive models: said in plain words
- self-test switchkind
- SleeperRules: the rules beams are laid by and the faults counted where the layout breaks them
- SleeperGeometry: plan helpers, beam boxes with their overlap and support tests and a grid of cells, shared by laying, filling
gaps, keeping beams apart and checking instead of three copies of each
- SleeperPaths: sampled paths, how near they run and whether one carries another; the tracks near a track and the stretches of
a path where a test holds, shared by paths_around/unsettle_around and shared_zones/zones_of
- SleeperFeatures: frogs and crossings the timbers turn to; SleeperLines: lines of beams, the rails they carry, where they part
- SleeperLayout: clusters and their layout, given the epoch instead of reading it; SleeperModels: the models of the beams
- SleeperWorker: the layouts kept per epoch and worked out in the background, behind a small interface
- TrackSleepers: the facade, laying the instances, the shared zones and the check
- sleepercheck reports a digest of all beams; geomhash skips empty chunks instead of crashing
The layout is unchanged: geomhash, sleepercheck with the digest, wings, space, guards, crossings and switches give the same
output on baltyk, zz_rozjazdy_id4, zz_rf_slips, zz_rf_wide, zz_slips_s42, zz_demo_przechylka and zz_connections.
- sleepers3d / sleepers3dplain / sleepers3dbed in eu07.ini: timbers put together from the begin, main and end parts of a model
and stretched to their length, plain sleepers of their own model; tracks whose plain sleepers would touch are laid as one
cluster, lines of timbers led by priority and turned to the bisectors of frogs and crossings at a limited rate, whole timbers
under crossings, split ones between tracks with room to part them, gaps filled per rail and overlaps shortened or dropped;
clusters worked out in a background thread while driving, on demand in the editor
- the ballast can be left out under the beams (sleepers3dbed no)
- blades get their heel and throw from the switch template or blades <heel> <throw> in the scenery; blades of double switches
run on into the track linking them to the next switch
- rail cutting at frogs, wing rails, movable noses and switch crossings done by one carving pass (RailCarve)
- tint of the rail treads applied to the colour only, without the matte band at the frog
- a switch trailed through with a movable nose set the other way derails the vehicle
- self-tests: sleepercheck, sharedzones, beamsnear, throw, sleepersbg