The renderer draws nothing at all while simulation::is_ready is false, and that
flag only goes up once the local player's cab is built.
The previous commit made walking into a cab a crew request, so the cab of a
claimed vehicle is created by Crews::reconcile() rather than by the command
itself. reconcile() runs from the network housekeeping, which was gated on
simulation::is_ready - so a host started with -v had its entervehicle turned
into a claim, and then the cab waited for is_ready while is_ready waited for
the cab. Black screen on both ends, since a client whose server never gets
going has nothing to show either.
- the housekeeping now waits for Global.simulation_loaded, which says the world
exists, instead of simulation::is_ready, which says the player has a cab
- in a session, a player with no cab counts as ready: they are an observer in
the lobby, not a game still loading, and the world has to be drawn for them
- entervehicle is only taken as a crew request when the session actually lists
that vehicle; anything else stays an ordinary command, so a scenario that
starts its host in something the roster does not cover still works
A vehicle is not owned by one player: two people share a cab, so the session
needs a crew relation rather than an owner field. The server keeps it and is
the only one allowed to change it.
- network/session: vehicle_crew { entity_id, crew, ai_before_claim } and a
crew_registry holding the roster. the host goes through exactly the same
path as a remote peer (claim -> crew -> grant), only without transport
- CLAIM_VEHICLE / CLAIM_GRANTED / CLAIM_DENIED / LEAVE_VEHICLE / CREW_UPDATE;
the server validates the vehicle exists, is present in the scenario and has
room in the crew, and answers a refusal with a reason the lobby shows
- the cab of a claimed vehicle is created by the authority posting the
ordinary replicated entervehicle, so every peer builds it and the vehicle is
never moved. the claiming peer only walks in once the cab appears locally
- AI transitions follow the crew size: 0 -> 1 remembers whether an AI was
really driving and takes the vehicle over, 1 -> 2 and 2 -> 1 change nothing,
1 -> 0 hands the vehicle back but only if there was an AI driver to begin
with. driver mode no longer fires aidriverdisable of its own in multiplayer
- losing a connection removes that peer from every crew it was on; a vehicle
with somebody still on board carries on untouched
- the lobby lists who is on board, offers "join crew" for a vehicle another
player already occupies, and lets a player step off
The AI and cab handling runs as a reconciliation pass rather than as edge
triggered actions, so a request that has not taken effect yet (the cab needs a
frame to appear) is simply repeated, with a cooldown to keep it off the wire.
TTrain::id() numbers cabs with a local counter, in the order each peer happens
to create them, so it cannot address a vehicle across the session. Neither was
there any way for a player to see what is available to drive.
- network/entities: PeerId (the host is peer 1, remote peers are numbered from
2, so it is a participant rather than a special case) and NetworkEntityId,
plus a registry that numbers the drivable vehicles of the loaded scenario in
name order and resolves ids back to TDynamicObject
- the server owns the numbering and publishes it as VEHICLE_LIST - name, crew
occupancy, crew capacity, AI state, availability - on every change and at
least every 120 frames, out of band so it stays out of the replay backbuffer;
a client binds the received ids to its own copy of the scenario by name
- SERVER_HELLO hands the joining peer its PeerId
- a multiplayer lobby listing that roster, with vehicles taken by other players
shown as such rather than hidden; entering one goes through the existing
entervehicle command, the vehicle is never moved
The lobby lives inside the driver mode instead of a mode of its own: the world
has to keep running while somebody is choosing (a client stops consuming the
server's frames the moment its mode is not a command processor), and the same
screen is what a player needs to change vehicles later on.
Crew occupancy is still derived from the presence of a cab instance; the real
crew model, claim handshake and AI takeover follow in stage 3.
Three additions, all driven from the simulator debug panel.
DEVICE_LOG lets a controller send text lines; they reach the simulator log
and a per connection view in the panel which keeps the last 64 of them.
Diagnostic routines: a controller lists the procedures it offers, the
operator picks one from a drop down and starts it, and the controller
reports progress and the result. While a routine runs the controller can
ask the simulator to show a message box with its own text and buttons and
gets back which one was pressed, which is what a valve or gauge
calibration needs. The message box appears whether the debug panel is
open or not.
Links can now be disconnected and reconnected by hand: disconnecting
closes the serial port so the controller can be reprogrammed, and the
session is rebuilt from scratch on reconnect. Ports which appear while
the simulation runs can be picked from a refreshed list, given a baud
rate and added as a new controller, so the manager now starts even with
no uart2 entries in eu07.ini.
Adds the WITH_HARDWARE_PROTOCOL_V2 build option and the eu07.ini entries
which configure it: uart2 declares a serial link and may be repeated for
several controllers, the remaining uart2* entries tune frame size,
heartbeat, rate limits and logging. UART v1 is untouched and both may be
active at the same time on different ports.
The driver mode starts the manager when at least one link is configured
and pumps it from the input polling loop, and the debug panel gains a
Hardware Protocol v2 section reporting link and session condition,
packet rates, round trip time, protocol and transport error counters and
whatever diagnostics the device itself reports, with switches for
protocol and frame logging.
Pressing Alt toggles picking mode. This is fine for keyboard and mouse usage,
but some use cases, such as disabling picking mode when a finger is placed
on a thumbstick and enabling it back when it's lifted, require finer control.
Allow to always enable picking mode when pressing Alt with Shift, and to always
disable picking mode when pressing Alt with Ctrl.