A driver without movePrimary no longer just idles. UpdateSecondary() cuts
BrakeValveActive so a secondary AI stops fighting the primary over the brake
pipe, and - as long as no driver in the consist has iEngineActive - keeps
scanning ahead of CabOccupied, so it can take movePrimary and start the engine
once a signal permits.
scan_route() orients by CabOccupied when DirActive is 0, and
ClaimConsistPrimary() clears movePrimary on every other driver in the consist,
then calls TableClear() and CheckVehicles(), so sSpeedTable is rebuilt for the
new front and ctOwner follows it.
- walk the consist with FirstFind()/Neighbour() instead of Next()/Prev(), which
stopped at the starting vehicle and mishandled reversed members;
- ReassignConsistPrimary() picks a single driver after any coupling change,
both from TDynamicObject::couple() and from the AI path;
- IsOccupiedByAnotherConsist() decides membership with BelongsToConsist() and
takes a signed distance, so a consist left behind no longer cuts the scan
short. DistanceToAnotherConsist() hands back the gap it already computes, so
OtherConsistAtSignal() counts a foreign vehicle only while it stands closer
than the signal itself, instead of comparing track starts;
- TSpeedPos::Set() marks an entry with spNotOurShuntSignal when a
spShuntSemaphor was already permitting as the entry was added. A shunting
signal does not address its permission to a particular consist, so a dormant
driver does not wake up on a permission it did not see light up; the flag
drops once the signal shows stop, so its own turn is never blocked. spSemaphor
is excluded: a semaphore sets a route for us and permits us even when found
already lit. The check reads SemPermitIndex - the entry that produced the
permitting command - because SemNextIndex can point at an earlier signal.
The flag is also stamped whenever the permission turns out to belong to a
consist standing in front of us - both where TableUpdateEvent() already knows
the signal is for the vehicle ahead, and in check_route_ahead() - so the
addressee pulling away does not hand the still-lit signal over to whoever
waited behind it;
- the scantable debug panel lists the flags by name (spNotOurShuntSignal shows
as not-ours) and folds the nearest vehicle ahead into the table by its own
distance.
The dumb3d->glm / utilities-simplification refactor replaced the old custom
clamp() (which tolerated Lo>Hi, returning the upper bound) with std::clamp,
where inverted bounds are undefined behaviour. Only a few sites were patched
afterwards, by hand, with std::minmax plumbing (incl. a stray `static` inside
a per-axle loop). Others silently produced wrong results in the AI braking /
acceleration path.
Add a safe_clamp() helper (normalizes inverted bounds) and use it ONLY where
Lo<=Hi cannot be proven at compile time (config min/max pairs, sign-dependent
expressions, container underflow). Sites with constant bounds or [0, x>=0]
keep std::clamp. Remove the manual std::minmax workarounds and rewrite the
damaged-track jolt code value-first.
- The `TMoverParameters::derail()` function has been renamed to `::Derail()`, with a capital D.
- All derail events now use that function.
- Simplified and unified the logic behind different derail types.
- The `dtrack_freerail` track type is now slightly increasing the chance of derailing on a tight curve, as it was the intention.
- A new `DerailReason` enum has been created which holds all derail types.
- The `DerailReason` field in the `TMoverParameters` class has been removed.
- This was a transient field which is not necessary anymore.
- The logging functionality as such has been moved from `DynObj.cpp` to `Mover.cpp`.
Add engine temperature monitoring to diesel locomotive heat management system:
- Add engine field to heat_data struct (fluid_circuit_t type)
- Add EngineMaxTemperature config extraction in .fiz files
- Add engine overheat detection logic (is_hot check)
- Include engine.is_hot in PT status check
Implements issue #77: Oil, water and engine overheat lamps for diesel locomotives
- Add engine_max_temp and engine_is_hot fields to heat_data structure
- Add EngineMaxTemperature field extraction from .fiz files
- Add engine overheat check comparing Ts with engine_max_temp
- Add four new overheat lamp indicators:
- i-oil_overheat
- i-water_overheat
- i-wateraux_overheat
- i-engine_overheat
- Add lamp update logic to turn on/off based on is_hot flags
- Add lamp initialization in clear_cab_controls()
This implements issue #77 - overheat lamps for diesel engines.
The lamps will turn on when:
- Oil temperature exceeds OilMaxTemperature
- Water temperature exceeds WaterMaxTemperature
- Auxiliary water temperature exceeds WaterAuxMaxTemperature
- Engine temperature exceeds EngineMaxTemperature
Each check includes 8-degree hysteresis to prevent rapid on/off cycling.
Added a new optional section to .fiz files: `ffBrakeList`. It is used instead of `ffList` whenever the vehicle has its ED braking engaged.
Example (dynamic/pkp/elf_v1/inverter_kp.fiz):
```
ffList: Size=3
0 2.0
33.7 2.08
34.0 2.12
130.4 8.10
endff
ffBrakeList: Size=4
0 2.0
33.7 2.08
34.8 2.08
34.8 2.17
130.4 8.10
endff
```
```/home/debian/autobuilder/output/build/maszyna/application.h:41:10: error: extra qualification ‘eu07_application::’ on member ‘DiscordRPCService’ [-fpermissive]
41 | void eu07_application::DiscordRPCService(); // discord rich presence service function (runs as separate thread)
| ^~~~~~~~~~~~~~~~```
Czy C++20 jest nam potrzebne?
```/home/debian/autobuilder/output/build/maszyna/McZapkie/Mover.cpp:11346:34: error: ‘std::string’ {aka ‘class std::__cxx11::basic_string<char>’} has no member named ‘_Starts_with’
11346 | if (PantType._Starts_with("DSA")) // zakladam ze wszystkie pantografy DSA sa takie same
| ^~~~~~~~~~~~```
Kompletny absurd z 7cac46d:
```/home/debian/autobuilder/output/build/maszyna/particles.cpp:477:29: error: cannot bind non-const lvalue reference of type ‘cParser&’ to an rvalue of type ‘cParser’
477 | if( source.deserialize( cParser( templatepath + templatename + ".txt", cParser::buffer_FILE ) ) ) {
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~```