mirror of https://github.com/OpenTTD/OpenTTD
(svn r22391) [1.1] -Backport from trunk:
- Fix: Vehicles skipped orders when inserting automatic orders failed (r22324) - Fix: [NewGRF] When determining refittability use the cargo translation table of the GRF setting the refitmask instead of the GRF defining the action 3 (r22316) - Fix: Make road vehicles, ships and aircraft skip orders if they are leaving a depot and heading to the same one again; just like trains (r22309) - Fix: Waiting on a server could kick the client, or rather the client would kick itself due to an unexpected packet [FS#4574] (r22308)release/1.1
parent
41fe2dea36
commit
3330813d95
|
@ -1311,6 +1311,12 @@ static void AircraftEventHandler_InHangar(Aircraft *v, const AirportFTAClass *ap
|
||||||
!v->current_order.IsType(OT_GOTO_DEPOT))
|
!v->current_order.IsType(OT_GOTO_DEPOT))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/* We are leaving a hangar, but have to go to the exact same one; re-enter */
|
||||||
|
if (v->current_order.IsType(OT_GOTO_DEPOT) && v->current_order.GetDestination() == v->targetairport) {
|
||||||
|
VehicleEnterDepot(v);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* if the block of the next position is busy, stay put */
|
/* if the block of the next position is busy, stay put */
|
||||||
if (AirportHasBlock(v, &apc->layout[v->pos], apc)) return;
|
if (AirportHasBlock(v, &apc->layout[v->pos], apc)) return;
|
||||||
|
|
||||||
|
|
|
@ -719,17 +719,14 @@ DEF_GAME_RECEIVE_COMMAND(Client, PACKET_SERVER_WELCOME)
|
||||||
|
|
||||||
DEF_GAME_RECEIVE_COMMAND(Client, PACKET_SERVER_WAIT)
|
DEF_GAME_RECEIVE_COMMAND(Client, PACKET_SERVER_WAIT)
|
||||||
{
|
{
|
||||||
if (this->status != STATUS_AUTHORIZED) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
|
/* We set the internal wait state when requesting the map. */
|
||||||
this->status = STATUS_MAP_WAIT;
|
if (this->status != STATUS_MAP_WAIT) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
|
||||||
|
|
||||||
|
/* But... only now we set the join status to waiting, instead of requesting. */
|
||||||
_network_join_status = NETWORK_JOIN_STATUS_WAITING;
|
_network_join_status = NETWORK_JOIN_STATUS_WAITING;
|
||||||
_network_join_waiting = p->Recv_uint8();
|
_network_join_waiting = p->Recv_uint8();
|
||||||
SetWindowDirty(WC_NETWORK_STATUS_WINDOW, 0);
|
SetWindowDirty(WC_NETWORK_STATUS_WINDOW, 0);
|
||||||
|
|
||||||
/* We are put on hold for receiving the map.. we need GUI for this ;) */
|
|
||||||
DEBUG(net, 1, "The server is currently busy sending the map to someone else, please wait..." );
|
|
||||||
DEBUG(net, 1, "There are %d clients in front of you", _network_join_waiting);
|
|
||||||
|
|
||||||
return NETWORK_RECV_STATUS_OKAY;
|
return NETWORK_RECV_STATUS_OKAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -539,9 +539,11 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendMap()
|
||||||
if (this->status == STATUS_MAP) {
|
if (this->status == STATUS_MAP) {
|
||||||
if (this->savegame_mutex != NULL) this->savegame_mutex->BeginCritical();
|
if (this->savegame_mutex != NULL) this->savegame_mutex->BeginCritical();
|
||||||
|
|
||||||
|
bool last_packet = false;
|
||||||
|
|
||||||
for (uint i = 0; i < sent_packets && this->savegame_packets != NULL; i++) {
|
for (uint i = 0; i < sent_packets && this->savegame_packets != NULL; i++) {
|
||||||
Packet *p = this->savegame_packets;
|
Packet *p = this->savegame_packets;
|
||||||
bool last_packet = p->buffer[2] == PACKET_SERVER_MAP_DONE;
|
last_packet = p->buffer[2] == PACKET_SERVER_MAP_DONE;
|
||||||
|
|
||||||
/* Remove the packet from the savegame queue and put it in the real queue. */
|
/* Remove the packet from the savegame queue and put it in the real queue. */
|
||||||
this->savegame_packets = p->next;
|
this->savegame_packets = p->next;
|
||||||
|
@ -549,7 +551,16 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendMap()
|
||||||
this->NetworkTCPSocketHandler::SendPacket(p);
|
this->NetworkTCPSocketHandler::SendPacket(p);
|
||||||
|
|
||||||
if (last_packet) {
|
if (last_packet) {
|
||||||
/* Done reading! */
|
/* There is no more data, so break the for */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->savegame_mutex != NULL) this->savegame_mutex->EndCritical();
|
||||||
|
|
||||||
|
if (last_packet) {
|
||||||
|
/* Done reading, make sure saving is done as well */
|
||||||
|
WaitTillSaved();
|
||||||
|
|
||||||
/* Set the status to DONE_MAP, no we will wait for the client
|
/* Set the status to DONE_MAP, no we will wait for the client
|
||||||
* to send it is ready (maybe that happens like never ;)) */
|
* to send it is ready (maybe that happens like never ;)) */
|
||||||
|
@ -573,13 +584,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendMap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* There is no more data, so break the for */
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (this->savegame_mutex != NULL) this->savegame_mutex->EndCritical();
|
|
||||||
|
|
||||||
switch (this->SendPackets()) {
|
switch (this->SendPackets()) {
|
||||||
case SPS_CLOSED:
|
case SPS_CLOSED:
|
||||||
|
|
|
@ -188,6 +188,7 @@ struct GRFTempEngineData {
|
||||||
uint16 cargo_allowed;
|
uint16 cargo_allowed;
|
||||||
uint16 cargo_disallowed;
|
uint16 cargo_disallowed;
|
||||||
RailTypeLabel railtypelabel;
|
RailTypeLabel railtypelabel;
|
||||||
|
const GRFFile *refitmask_grf; ///< GRF providing the cargo translation table for the refitmask.
|
||||||
bool refitmask_valid; ///< Did the newgrf set any refittability property? If not, default refittability will be applied.
|
bool refitmask_valid; ///< Did the newgrf set any refittability property? If not, default refittability will be applied.
|
||||||
bool prop27_set; ///< Did the NewGRF set property 27 (misc flags)?
|
bool prop27_set; ///< Did the NewGRF set property 27 (misc flags)?
|
||||||
uint8 rv_max_speed; ///< Temporary storage of RV prop 15, maximum speed in mph/0.8
|
uint8 rv_max_speed; ///< Temporary storage of RV prop 15, maximum speed in mph/0.8
|
||||||
|
@ -700,6 +701,7 @@ static ChangeInfoResult RailVehicleChangeInfo(uint engine, int numinfo, int prop
|
||||||
case 0x1D: // Refit cargo
|
case 0x1D: // Refit cargo
|
||||||
ei->refit_mask = buf->ReadDWord();
|
ei->refit_mask = buf->ReadDWord();
|
||||||
_gted[e->index].refitmask_valid = true;
|
_gted[e->index].refitmask_valid = true;
|
||||||
|
_gted[e->index].refitmask_grf = _cur_grffile;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1E: // Callback
|
case 0x1E: // Callback
|
||||||
|
@ -857,6 +859,7 @@ static ChangeInfoResult RoadVehicleChangeInfo(uint engine, int numinfo, int prop
|
||||||
case 0x16: // Cargos available for refitting
|
case 0x16: // Cargos available for refitting
|
||||||
ei->refit_mask = buf->ReadDWord();
|
ei->refit_mask = buf->ReadDWord();
|
||||||
_gted[e->index].refitmask_valid = true;
|
_gted[e->index].refitmask_valid = true;
|
||||||
|
_gted[e->index].refitmask_grf = _cur_grffile;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x17: // Callback mask
|
case 0x17: // Callback mask
|
||||||
|
@ -986,6 +989,7 @@ static ChangeInfoResult ShipVehicleChangeInfo(uint engine, int numinfo, int prop
|
||||||
case 0x11: // Cargos available for refitting
|
case 0x11: // Cargos available for refitting
|
||||||
ei->refit_mask = buf->ReadDWord();
|
ei->refit_mask = buf->ReadDWord();
|
||||||
_gted[e->index].refitmask_valid = true;
|
_gted[e->index].refitmask_valid = true;
|
||||||
|
_gted[e->index].refitmask_grf = _cur_grffile;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x12: // Callback mask
|
case 0x12: // Callback mask
|
||||||
|
@ -1116,6 +1120,7 @@ static ChangeInfoResult AircraftVehicleChangeInfo(uint engine, int numinfo, int
|
||||||
case 0x13: // Cargos available for refitting
|
case 0x13: // Cargos available for refitting
|
||||||
ei->refit_mask = buf->ReadDWord();
|
ei->refit_mask = buf->ReadDWord();
|
||||||
_gted[e->index].refitmask_valid = true;
|
_gted[e->index].refitmask_valid = true;
|
||||||
|
_gted[e->index].refitmask_grf = _cur_grffile;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x14: // Callback mask
|
case 0x14: // Callback mask
|
||||||
|
@ -7431,7 +7436,8 @@ static void CalculateRefitMasks()
|
||||||
/* Did the newgrf specify any refitting? If not, use defaults. */
|
/* Did the newgrf specify any refitting? If not, use defaults. */
|
||||||
if (_gted[engine].refitmask_valid) {
|
if (_gted[engine].refitmask_valid) {
|
||||||
if (ei->refit_mask != 0) {
|
if (ei->refit_mask != 0) {
|
||||||
const GRFFile *file = e->grf_prop.grffile;
|
const GRFFile *file = _gted[engine].refitmask_grf;
|
||||||
|
if (file == NULL) file = e->grf_prop.grffile;
|
||||||
if (file != NULL && file->cargo_max != 0) {
|
if (file != NULL && file->cargo_max != 0) {
|
||||||
/* Apply cargo translation table to the refit mask */
|
/* Apply cargo translation table to the refit mask */
|
||||||
uint num_cargo = min(32, file->cargo_max);
|
uint num_cargo = min(32, file->cargo_max);
|
||||||
|
|
|
@ -941,6 +941,12 @@ static bool RoadVehLeaveDepot(RoadVehicle *v, bool first)
|
||||||
int y = TileY(v->tile) * TILE_SIZE + (rdp[RVC_DEPOT_START_FRAME].y & 0xF);
|
int y = TileY(v->tile) * TILE_SIZE + (rdp[RVC_DEPOT_START_FRAME].y & 0xF);
|
||||||
|
|
||||||
if (first) {
|
if (first) {
|
||||||
|
/* We are leaving a depot, but have to go to the exact same one; re-enter */
|
||||||
|
if (v->current_order.IsType(OT_GOTO_DEPOT) && v->tile == v->dest_tile) {
|
||||||
|
VehicleEnterDepot(v);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (RoadVehFindCloseTo(v, x, y, v->direction, false) != NULL) return true;
|
if (RoadVehFindCloseTo(v, x, y, v->direction, false) != NULL) return true;
|
||||||
|
|
||||||
VehicleServiceInDepot(v);
|
VehicleServiceInDepot(v);
|
||||||
|
|
|
@ -266,9 +266,16 @@ static const TileIndexDiffC _ship_leave_depot_offs[] = {
|
||||||
{ 0, -1}
|
{ 0, -1}
|
||||||
};
|
};
|
||||||
|
|
||||||
static void CheckShipLeaveDepot(Ship *v)
|
static bool CheckShipLeaveDepot(Ship *v)
|
||||||
{
|
{
|
||||||
if (!v->IsInDepot()) return;
|
if (!v->IsInDepot()) return false;
|
||||||
|
|
||||||
|
/* We are leaving a depot, but have to go to the exact same one; re-enter */
|
||||||
|
if (v->current_order.IsType(OT_GOTO_DEPOT) &&
|
||||||
|
IsShipDepotTile(v->tile) && GetDepotIndex(v->tile) == v->current_order.GetDestination()) {
|
||||||
|
VehicleEnterDepot(v);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
TileIndex tile = v->tile;
|
TileIndex tile = v->tile;
|
||||||
Axis axis = GetShipDepotAxis(tile);
|
Axis axis = GetShipDepotAxis(tile);
|
||||||
|
@ -280,7 +287,7 @@ static void CheckShipLeaveDepot(Ship *v)
|
||||||
} else if (DiagdirReachesTracks((DiagDirection)(axis + 2)) & GetTileShipTrackStatus(TILE_ADD(tile, -2 * ToTileIndexDiff(_ship_leave_depot_offs[axis])))) {
|
} else if (DiagdirReachesTracks((DiagDirection)(axis + 2)) & GetTileShipTrackStatus(TILE_ADD(tile, -2 * ToTileIndexDiff(_ship_leave_depot_offs[axis])))) {
|
||||||
v->direction = AxisToDirection(axis);
|
v->direction = AxisToDirection(axis);
|
||||||
} else {
|
} else {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
v->state = AxisToTrackBits(axis);
|
v->state = AxisToTrackBits(axis);
|
||||||
|
@ -294,6 +301,8 @@ static void CheckShipLeaveDepot(Ship *v)
|
||||||
VehicleServiceInDepot(v);
|
VehicleServiceInDepot(v);
|
||||||
InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
|
InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
|
||||||
SetWindowClassesDirty(WC_SHIPS_LIST);
|
SetWindowClassesDirty(WC_SHIPS_LIST);
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ShipAccelerate(Vehicle *v)
|
static bool ShipAccelerate(Vehicle *v)
|
||||||
|
@ -446,7 +455,7 @@ static void ShipController(Ship *v)
|
||||||
|
|
||||||
if (v->current_order.IsType(OT_LOADING)) return;
|
if (v->current_order.IsType(OT_LOADING)) return;
|
||||||
|
|
||||||
CheckShipLeaveDepot(v);
|
if (CheckShipLeaveDepot(v)) return;
|
||||||
|
|
||||||
v->ShowVisualEffect();
|
v->ShowVisualEffect();
|
||||||
|
|
||||||
|
|
|
@ -1919,6 +1919,13 @@ void Vehicle::HandleLoading(bool mode)
|
||||||
|
|
||||||
this->LeaveStation();
|
this->LeaveStation();
|
||||||
|
|
||||||
|
/* Only advance to next order if we just loaded at the current one */
|
||||||
|
const Order *order = this->GetOrder(this->cur_auto_order_index);
|
||||||
|
if (order == NULL ||
|
||||||
|
(!order->IsType(OT_AUTOMATIC) && !order->IsType(OT_GOTO_STATION)) ||
|
||||||
|
order->GetDestination() != this->last_station_visited) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue