diff --git a/economy.c b/economy.c index b013ad816d..de2e4c19b1 100644 --- a/economy.c +++ b/economy.c @@ -1208,10 +1208,12 @@ int LoadUnloadVehicle(Vehicle *v) GoodsEntry *ge; int t; uint count, cap; + byte old_player; assert((v->next_order&0x1F) == OT_LOADING); v->cur_speed = 0; + old_player = _current_player; _current_player = v->owner; st = DEREF_STATION(last_visited = v->last_station_visited); @@ -1318,6 +1320,7 @@ next_vehicle:; } } + _current_player = old_player; return result; } diff --git a/misc.c b/misc.c index f3ccb5953f..f9a0593b0a 100644 --- a/misc.c +++ b/misc.c @@ -15,15 +15,20 @@ static INLINE uint32 ROR(uint32 x, int n) return (x >> n) + (x << ((sizeof(x)*8)-n)); } -/* Fuck bitch code, most probably one of the loops (tileloop, vehicleloop, etc.) - * doesn't set up/reset _current_player so the normal random below fails #$%@$#! - * The old code below is prune to desyncs because randoms interfere. - * SO FIND THE OFFENDING LOOP AND FIX IT ONCE AND FOR ALL */ -#undef NORMAL_RANDOM // unuseable game, desyncs way too fast +// For multiplayer, we introduced this new way of random-seeds +// It is player-based, so 2 clients can do 2 commands at the same time +// without the game desyncing. +// It is not used for non-multiplayer games +#ifdef ENABLE_NETWORK + #define PLAYER_SEED_RANDOM +#else + #undef PLAYER_SEED_RANDOM +#endif + uint32 Random() { -#ifdef NORMAL_RANDOM - if (_current_player>=MAX_PLAYERS) { +#ifdef PLAYER_SEED_RANDOM + if (_current_player>=MAX_PLAYERS || !_networking) { uint32 s = _random_seeds[0][0]; uint32 t = _random_seeds[0][1]; _random_seeds[0][0] = s + ROR(t ^ 0x1234567F, 7); diff --git a/network.c b/network.c index fde0091029..c9aa2a7853 100644 --- a/network.c +++ b/network.c @@ -365,6 +365,7 @@ void NetworkProcessCommands() { CommandQueue *nq; QueuedCommand *qp; + byte old_player; // queue mode ? if (_networking_queuing) @@ -380,11 +381,13 @@ void NetworkProcessCommands() } // run the command + old_player = _current_player; _current_player = qp->cp.player; memcpy(_decode_parameters, qp->cp.dp, (qp->cp.packet_length - COMMAND_PACKET_BASE_SIZE)); DoCommandP(qp->cp.tile, qp->cp.p1, qp->cp.p2, qp->callback, qp->cmd | CMD_DONT_NETWORK); free(qp); + _current_player = old_player; } if (!_networking_server) { @@ -508,7 +511,7 @@ void NetworkSendEvent(uint16 type, uint16 data_len, void * data) { EventPacket * ep; ClientState *cs; - + // encode the event ... add its data ep=malloc(data_len+sizeof(EventPacket)-1); ep->event_type = type; diff --git a/town_cmd.c b/town_cmd.c index ee5de74f37..54237df999 100644 --- a/town_cmd.c +++ b/town_cmd.c @@ -694,6 +694,7 @@ bool GrowTown(Town *t) const TileIndexDiff *ptr; int offs; TileInfo ti; + byte old_player; static const TileIndexDiff _town_coord_mod[] = { TILE_XY(-1,0), @@ -712,6 +713,7 @@ bool GrowTown(Town *t) }; // Current player is a town + old_player = _current_player; _current_player = OWNER_TOWN; // Find a road that we can base the construction on. @@ -719,7 +721,9 @@ bool GrowTown(Town *t) ptr = _town_coord_mod; do { if (GetRoadBitsByTile(tile) != 0) { - return GrowTownAtRoad(t, tile); + int r = GrowTownAtRoad(t, tile); + _current_player = old_player; + return r; } offs = *ptr++; @@ -737,6 +741,7 @@ bool GrowTown(Town *t) if (ti.tileh == 0 && !(ti.type==MP_HOUSE && ti.map5==0)) { if (DoCommandByTile(tile, 0, 0, DC_AUTO, CMD_LANDSCAPE_CLEAR) != CMD_ERROR) { DoCommandByTile(tile, GenRandomRoadBits(), 0, DC_EXEC | DC_AUTO, CMD_BUILD_ROAD); + _current_player = old_player; return true; } } @@ -744,6 +749,7 @@ bool GrowTown(Town *t) tile = TILE_ADD(tile, offs); } while (offs != 0); + _current_player = old_player; return false; } diff --git a/vehicle.c b/vehicle.c index e8f82d6a4c..31e9888bb9 100644 --- a/vehicle.c +++ b/vehicle.c @@ -1378,6 +1378,8 @@ void MaybeRenewVehicle(Vehicle *v, int32 build_cost) v->value = build_cost; InvalidateWindow(WC_VEHICLE_DETAILS, v->index); + + _current_player = OWNER_NONE; }