mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2025-02-04 21:33:51 +00:00
(svn r13752) -Fix [FS#2130]: correctly restore conditional orders when they are put 'into' backup.
This commit is contained in:
parent
7c3fc13087
commit
a6e314bbba
@ -375,8 +375,8 @@ CommandCost CmdInsertOrder(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
|||||||
/* Non stop not allowed for non-trains. */
|
/* Non stop not allowed for non-trains. */
|
||||||
if (new_order.GetNonStopType() != ONSF_STOP_EVERYWHERE && v->type != VEH_TRAIN && v->type != VEH_ROAD) return CMD_ERROR;
|
if (new_order.GetNonStopType() != ONSF_STOP_EVERYWHERE && v->type != VEH_TRAIN && v->type != VEH_ROAD) return CMD_ERROR;
|
||||||
|
|
||||||
/* Full load and unload are mutual exclusive. */
|
/* No load and no unload are mutual exclusive. */
|
||||||
if ((new_order.GetLoadType() & OLFB_FULL_LOAD) && (new_order.GetUnloadType() & OUFB_UNLOAD)) return CMD_ERROR;
|
if ((new_order.GetLoadType() & OLFB_NO_LOAD) && (new_order.GetUnloadType() & OUFB_NO_UNLOAD)) return CMD_ERROR;
|
||||||
|
|
||||||
/* Filter invalid load/unload types. */
|
/* Filter invalid load/unload types. */
|
||||||
switch (new_order.GetLoadType()) {
|
switch (new_order.GetLoadType()) {
|
||||||
@ -437,7 +437,6 @@ CommandCost CmdInsertOrder(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
|||||||
}
|
}
|
||||||
|
|
||||||
case OT_GOTO_WAYPOINT: {
|
case OT_GOTO_WAYPOINT: {
|
||||||
|
|
||||||
if (v->type != VEH_TRAIN) return CMD_ERROR;
|
if (v->type != VEH_TRAIN) return CMD_ERROR;
|
||||||
|
|
||||||
if (!IsValidWaypointID(new_order.GetDestination())) return CMD_ERROR;
|
if (!IsValidWaypointID(new_order.GetDestination())) return CMD_ERROR;
|
||||||
@ -453,11 +452,30 @@ CommandCost CmdInsertOrder(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
|||||||
}
|
}
|
||||||
|
|
||||||
case OT_CONDITIONAL: {
|
case OT_CONDITIONAL: {
|
||||||
if (!IsPlayerBuildableVehicleType(v)) return CMD_ERROR;
|
|
||||||
|
|
||||||
VehicleOrderID skip_to = new_order.GetConditionSkipToOrder();
|
VehicleOrderID skip_to = new_order.GetConditionSkipToOrder();
|
||||||
if (skip_to >= v->num_orders) return CMD_ERROR;
|
if (skip_to != 0 && skip_to >= v->num_orders) {printf("%i: %i\n", skip_to, __LINE__); return CMD_ERROR;} // Always allow jumping to the first (even when there is no order).
|
||||||
if (new_order.GetNonStopType() != ONSF_STOP_EVERYWHERE) return CMD_ERROR;
|
if (new_order.GetConditionVariable() > OCV_END) {printf("%i\n", __LINE__); return CMD_ERROR;}
|
||||||
|
|
||||||
|
OrderConditionComparator occ = new_order.GetConditionComparator();
|
||||||
|
if (occ > OCC_END) {printf("%i\n", __LINE__); return CMD_ERROR;}
|
||||||
|
switch (new_order.GetConditionVariable()) {
|
||||||
|
case OCV_REQUIRES_SERVICE:
|
||||||
|
if (occ != OCC_IS_TRUE && occ != OCC_IS_FALSE) {printf("%i\n", __LINE__); return CMD_ERROR;}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OCV_UNCONDITIONALLY:
|
||||||
|
if (occ != OCC_EQUALS) {printf("%i\n", __LINE__); return CMD_ERROR;}
|
||||||
|
if (new_order.GetConditionValue() != 0) {printf("%i\n", __LINE__); return CMD_ERROR;}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OCV_LOAD_PERCENTAGE:
|
||||||
|
case OCV_RELIABILITY:
|
||||||
|
if (new_order.GetConditionValue() > 100) {printf("%i\n", __LINE__); return CMD_ERROR;}
|
||||||
|
/* FALL THROUGH */
|
||||||
|
default:
|
||||||
|
if (occ == OCC_IS_TRUE || occ == OCC_IS_FALSE) {printf("%i\n", __LINE__); return CMD_ERROR;}
|
||||||
|
break;
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
default: return CMD_ERROR;
|
default: return CMD_ERROR;
|
||||||
@ -938,6 +956,10 @@ CommandCost CmdModifyOrder(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MOF_COND_DESTINATION:
|
||||||
|
if (data >= v->num_orders) return CMD_ERROR;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & DC_EXEC) {
|
if (flags & DC_EXEC) {
|
||||||
@ -997,6 +1019,10 @@ CommandCost CmdModifyOrder(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
|||||||
order->SetConditionValue(data);
|
order->SetConditionValue(data);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MOF_COND_DESTINATION:
|
||||||
|
order->SetConditionSkipToOrder(data);
|
||||||
|
break;
|
||||||
|
|
||||||
default: NOT_REACHED();
|
default: NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1280,15 +1306,31 @@ void RestoreVehicleOrders(const Vehicle *v, const BackuppedOrders *bak)
|
|||||||
* in network the commands are queued before send, the second insert always
|
* in network the commands are queued before send, the second insert always
|
||||||
* fails in test mode. By bypassing the test-mode, that no longer is a problem. */
|
* fails in test mode. By bypassing the test-mode, that no longer is a problem. */
|
||||||
for (uint i = 0; bak->order[i].IsValid(); i++) {
|
for (uint i = 0; bak->order[i].IsValid(); i++) {
|
||||||
if (!DoCommandP(0, v->index + (i << 16), bak->order[i].Pack(), NULL,
|
Order o = bak->order[i];
|
||||||
|
/* Conditional orders need to have their destination to be valid on insertion. */
|
||||||
|
if (o.IsType(OT_CONDITIONAL)) o.SetConditionSkipToOrder(0);
|
||||||
|
|
||||||
|
if (!DoCommandP(0, v->index + (i << 16), o.Pack(), NULL,
|
||||||
CMD_INSERT_ORDER | CMD_NO_TEST_IF_IN_NETWORK)) {
|
CMD_INSERT_ORDER | CMD_NO_TEST_IF_IN_NETWORK)) {
|
||||||
|
printf("huh?\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy timetable if enabled */
|
/* Copy timetable if enabled */
|
||||||
if (_settings_game.order.timetabling && !DoCommandP(0, v->index | (i << 16) | (1 << 25),
|
if (_settings_game.order.timetabling && !DoCommandP(0, v->index | (i << 16) | (1 << 25),
|
||||||
bak->order[i].wait_time << 16 | bak->order[i].travel_time, NULL,
|
o.wait_time << 16 | o.travel_time, NULL,
|
||||||
CMD_CHANGE_TIMETABLE | CMD_NO_TEST_IF_IN_NETWORK)) {
|
CMD_CHANGE_TIMETABLE | CMD_NO_TEST_IF_IN_NETWORK)) {
|
||||||
|
printf("umh?\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fix the conditional orders' destination. */
|
||||||
|
for (uint i = 0; bak->order[i].IsValid(); i++) {
|
||||||
|
if (!bak->order[i].IsType(OT_CONDITIONAL)) continue;
|
||||||
|
|
||||||
|
if (!DoCommandP(0, v->index + (i << 16), MOF_LOAD | (bak->order[i].GetConditionSkipToOrder() << 4), NULL,
|
||||||
|
CMD_MODIFY_ORDER | CMD_NO_TEST_IF_IN_NETWORK)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -126,6 +126,7 @@ enum ModifyOrderFlags {
|
|||||||
MOF_COND_VARIABLE, ///< A conditional variable changes.
|
MOF_COND_VARIABLE, ///< A conditional variable changes.
|
||||||
MOF_COND_COMPARATOR, ///< A comparator changes.
|
MOF_COND_COMPARATOR, ///< A comparator changes.
|
||||||
MOF_COND_VALUE, ///< The value to set the condition to.
|
MOF_COND_VALUE, ///< The value to set the condition to.
|
||||||
|
MOF_COND_DESTINATION,///< Change the destination of a conditional order.
|
||||||
MOF_END
|
MOF_END
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -68,16 +68,36 @@ CommandCost CmdChangeTimetable(TileIndex tile, uint32 flags, uint32 p1, uint32 p
|
|||||||
|
|
||||||
bool packed_time = HasBit(p1, 25);
|
bool packed_time = HasBit(p1, 25);
|
||||||
bool is_journey = HasBit(p1, 24) || packed_time;
|
bool is_journey = HasBit(p1, 24) || packed_time;
|
||||||
if (!is_journey) {
|
|
||||||
if (!order->IsType(OT_GOTO_STATION) && !order->IsType(OT_CONDITIONAL)) return_cmd_error(STR_TIMETABLE_ONLY_WAIT_AT_STATIONS);
|
uint16 wait_time = 0;
|
||||||
if (order->GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION) return_cmd_error(STR_TIMETABLE_NOT_STOPPING_HERE);
|
uint16 travel_time = 0;
|
||||||
|
if (packed_time) {
|
||||||
|
travel_time = GB(p2, 0, 16);
|
||||||
|
wait_time = GB(p2, 16, 16);;
|
||||||
|
} else if (is_journey) {
|
||||||
|
travel_time = GB(p2, 0, 16);
|
||||||
} else {
|
} else {
|
||||||
if (order->IsType(OT_CONDITIONAL)) return CMD_ERROR;
|
wait_time = GB(p2, 0, 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (wait_time != 0) {
|
||||||
|
switch (order->GetType()) {
|
||||||
|
case OT_GOTO_STATION:
|
||||||
|
if (order->GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION) return_cmd_error(STR_TIMETABLE_NOT_STOPPING_HERE);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OT_CONDITIONAL:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: return_cmd_error(STR_TIMETABLE_ONLY_WAIT_AT_STATIONS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (travel_time != 0 && order->IsType(OT_CONDITIONAL)) return CMD_ERROR;
|
||||||
|
|
||||||
if (flags & DC_EXEC) {
|
if (flags & DC_EXEC) {
|
||||||
ChangeTimetable(v, order_number, GB(p2, 0, 16), is_journey);
|
if (wait_time != 0) ChangeTimetable(v, order_number, wait_time, false);
|
||||||
if (packed_time) ChangeTimetable(v, order_number, GB(p2, 16, 16), false);
|
if (travel_time != 0) ChangeTimetable(v, order_number, travel_time, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return CommandCost();
|
return CommandCost();
|
||||||
|
@ -86,7 +86,7 @@ struct TimetableWindow : Window {
|
|||||||
if (v->owner == _local_player) {
|
if (v->owner == _local_player) {
|
||||||
bool disable = true;
|
bool disable = true;
|
||||||
if (selected != -1) {
|
if (selected != -1) {
|
||||||
const Order *order = GetVehicleOrder(v, (selected + 1) / 2);
|
const Order *order = GetVehicleOrder(v, ((selected + 1) / 2) % v->num_orders);
|
||||||
if (selected % 2 == 1) {
|
if (selected % 2 == 1) {
|
||||||
disable = order != NULL && order->IsType(OT_CONDITIONAL);
|
disable = order != NULL && order->IsType(OT_CONDITIONAL);
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user