mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-10-18 04:29:18 +02:00
multiplayer stage 5: the authority decides which events fire
Every peer used to evaluate event conditions for itself and put the results
straight into its own queue, so the same event could fire twice, or on one
machine only. Worse, the launchers were polled around Global.pCamera, which in
a session means "wherever one particular player happens to be looking".
Condition evaluation is now separated from execution:
authority: evaluate -> queueevent -> execute -> replicate
client: receive queueevent -> execute
- AddToQuery() takes the origin of the request. A locally evaluated launch on a
client is dropped, on the host it is handed to the session as the ordinary
queueevent command and comes back to be carried out by everybody, itself
included, so it happens exactly once per peer. Scenario init (onstart,
negative delay) and the children of an already replicated event are marked as
authority decisions and run in place, since they are identical everywhere.
With no session running, both branches collapse to the old behaviour
- queueevent now carries the delay as well
- event launchers are polled around every crewed vehicle instead of around the
local camera, and a cell is polled at most once per frame no matter how many
players stand near it - launcher activation counters are stateful
- Events.update() still services the queue on a client, with its delays and its
execution; only the condition checking is skipped there
An event whose request is still travelling is not requested again, with a
timeout so that a lost request cannot silence it for good. Instant (AddValues)
events are exempt from that guard, because every one of their additions has to
get through.
This commit is contained in:
@@ -295,16 +295,26 @@ void state_manager::process_commands() {
|
||||
|
||||
std::string event_name;
|
||||
std::string vehicle_name;
|
||||
std::string delay_text;
|
||||
std::getline(ss, event_name, '%');
|
||||
std::getline(ss, vehicle_name, '%');
|
||||
std::getline(ss, delay_text, '%');
|
||||
|
||||
basic_event *ev = Events.FindEvent(event_name);
|
||||
TDynamicObject *vehicle = nullptr;
|
||||
if (!vehicle_name.empty())
|
||||
vehicle = simulation::Vehicles.find(vehicle_name);
|
||||
|
||||
double delay = 0.0;
|
||||
if (!delay_text.empty()) {
|
||||
try { delay = std::stod(delay_text); }
|
||||
catch (std::exception const &) { delay = 0.0; }
|
||||
}
|
||||
|
||||
// this is the authority speaking, whether it reached us over the wire or came
|
||||
// straight from our own event manager
|
||||
if (ev)
|
||||
Events.AddToQuery(ev, vehicle);
|
||||
Events.AddToQuery(ev, vehicle, delay, event_launch::authority);
|
||||
}
|
||||
|
||||
if (commanddata.command == user_command::setlight) {
|
||||
|
||||
Reference in New Issue
Block a user