Increase per-vehicle order limit to 64k

See: #110
pull/199/head
Jonathan G Rennison 4 years ago
parent 781fd14205
commit 6dd7b2869c

@ -230,7 +230,7 @@ CommandProc CmdSetGroupReplaceProtection;
CommandProc CmdSetGroupLivery; CommandProc CmdSetGroupLivery;
CommandProc CmdMoveOrder; CommandProc CmdMoveOrder;
CommandProc CmdChangeTimetable; CommandProcEx CmdChangeTimetable;
CommandProc CmdBulkChangeTimetable; CommandProc CmdBulkChangeTimetable;
CommandProc CmdSetVehicleOnTime; CommandProc CmdSetVehicleOnTime;
CommandProc CmdAutofillTimetable; CommandProc CmdAutofillTimetable;

@ -944,7 +944,7 @@ uint GetOrderDistance(const Order *prev, const Order *cur, const Vehicle *v, int
* @param flags operation to perform * @param flags operation to perform
* @param p1 various bitstuffed elements * @param p1 various bitstuffed elements
* - p1 = (bit 0 - 19) - ID of the vehicle * - p1 = (bit 0 - 19) - ID of the vehicle
* - p1 = (bit 20 - 27) - the selected order (if any). If the last order is given, * - p1 = (bit 20 - 35) - the selected order (if any). If the last order is given,
* the order will be inserted before that one * the order will be inserted before that one
* the maximum vehicle order id is 254. * the maximum vehicle order id is 254.
* @param p2 packed order to insert * @param p2 packed order to insert
@ -954,7 +954,7 @@ uint GetOrderDistance(const Order *prev, const Order *cur, const Vehicle *v, int
CommandCost CmdInsertOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) CommandCost CmdInsertOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{ {
VehicleID veh = GB(p1, 0, 20); VehicleID veh = GB(p1, 0, 20);
VehicleOrderID sel_ord = GB(p1, 20, 8); VehicleOrderID sel_ord = GB(p1, 20, 16);
Order new_order(p2); Order new_order(p2);
return CmdInsertOrderIntl(flags, Vehicle::GetIfValid(veh), sel_ord, new_order, false); return CmdInsertOrderIntl(flags, Vehicle::GetIfValid(veh), sel_ord, new_order, false);
@ -1247,7 +1247,7 @@ void InsertOrder(Vehicle *v, Order *new_o, VehicleOrderID sel_ord)
} }
} }
/* Update any possible open window of the vehicle */ /* Update any possible open window of the vehicle */
InvalidateVehicleOrder(u, INVALID_VEH_ORDER_ID | (sel_ord << 8)); InvalidateVehicleOrder(u, INVALID_VEH_ORDER_ID | (sel_ord << 16));
} }
/* As we insert an order, the order to skip to will be 'wrong'. */ /* As we insert an order, the order to skip to will be 'wrong'. */
@ -1310,14 +1310,14 @@ static CargoID GetFirstValidCargo()
* @param tile unused * @param tile unused
* @param flags operation to perform * @param flags operation to perform
* @param p1 the ID of the vehicle * @param p1 the ID of the vehicle
* @param p2 the order to delete (max 255) * @param p2 the order to delete
* @param text unused * @param text unused
* @return the cost of this operation or an error * @return the cost of this operation or an error
*/ */
CommandCost CmdDeleteOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) CommandCost CmdDeleteOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{ {
VehicleID veh_id = GB(p1, 0, 20); VehicleID veh_id = GB(p1, 0, 20);
VehicleOrderID sel_ord = GB(p2, 0, 8); VehicleOrderID sel_ord = GB(p2, 0, 16);
Vehicle *v = Vehicle::GetIfValid(veh_id); Vehicle *v = Vehicle::GetIfValid(veh_id);
@ -1404,7 +1404,7 @@ void DeleteOrder(Vehicle *v, VehicleOrderID sel_ord)
} }
/* Update any possible open window of the vehicle */ /* Update any possible open window of the vehicle */
InvalidateVehicleOrder(u, sel_ord | (INVALID_VEH_ORDER_ID << 8)); InvalidateVehicleOrder(u, sel_ord | (INVALID_VEH_ORDER_ID << 16));
} }
/* As we delete an order, the order to skip to will be 'wrong'. */ /* As we delete an order, the order to skip to will be 'wrong'. */
@ -1440,7 +1440,7 @@ void DeleteOrder(Vehicle *v, VehicleOrderID sel_ord)
CommandCost CmdSkipToOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) CommandCost CmdSkipToOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{ {
VehicleID veh_id = GB(p1, 0, 20); VehicleID veh_id = GB(p1, 0, 20);
VehicleOrderID sel_ord = GB(p2, 0, 8); VehicleOrderID sel_ord = GB(p2, 0, 16);
Vehicle *v = Vehicle::GetIfValid(veh_id); Vehicle *v = Vehicle::GetIfValid(veh_id);
@ -1547,7 +1547,7 @@ CommandCost CmdMoveOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
assert(v->orders.list == u->orders.list); assert(v->orders.list == u->orders.list);
/* Update any possible open window of the vehicle */ /* Update any possible open window of the vehicle */
InvalidateVehicleOrder(u, moving_order | (target_order << 8)); InvalidateVehicleOrder(u, moving_order | (target_order << 16));
} }
/* As we move an order, the order to skip to will be 'wrong'. */ /* As we move an order, the order to skip to will be 'wrong'. */
@ -1580,9 +1580,8 @@ CommandCost CmdMoveOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
* @param flags operation to perform * @param flags operation to perform
* @param p1 various bitstuffed elements * @param p1 various bitstuffed elements
* - p1 = (bit 0 - 19) - ID of the vehicle * - p1 = (bit 0 - 19) - ID of the vehicle
* - p1 = (bit 20 - 27) - the selected order (if any). If the last order is given, * - p1 = (bit 20 - 35) - the selected order (if any). If the last order is given,
* the order will be inserted before that one * the order will be inserted before that one.
* the maximum vehicle order id is 254.
* @param p2 various bitstuffed elements * @param p2 various bitstuffed elements
* - p2 = (bit 0 - 3) - what data to modify (@see ModifyOrderFlags) * - p2 = (bit 0 - 3) - what data to modify (@see ModifyOrderFlags)
* - p2 = (bit 4 - 19) - the data to modify * - p2 = (bit 4 - 19) - the data to modify
@ -1592,7 +1591,7 @@ CommandCost CmdMoveOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
*/ */
CommandCost CmdModifyOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) CommandCost CmdModifyOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{ {
VehicleOrderID sel_ord = GB(p1, 20, 8); VehicleOrderID sel_ord = GB(p1, 20, 16);
VehicleID veh = GB(p1, 0, 20); VehicleID veh = GB(p1, 0, 20);
ModifyOrderFlags mof = Extract<ModifyOrderFlags, 0, 4>(p2); ModifyOrderFlags mof = Extract<ModifyOrderFlags, 0, 4>(p2);
uint16 data = GB(p2, 4, 16); uint16 data = GB(p2, 4, 16);
@ -2320,14 +2319,14 @@ CommandCost CmdCloneOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
* @param p1 VehicleIndex of the vehicle having the order * @param p1 VehicleIndex of the vehicle having the order
* @param p2 bitmask * @param p2 bitmask
* - bit 0-7 CargoID * - bit 0-7 CargoID
* - bit 16-23 number of order to modify * - bit 16-31 number of order to modify
* @param text unused * @param text unused
* @return the cost of this operation or an error * @return the cost of this operation or an error
*/ */
CommandCost CmdOrderRefit(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) CommandCost CmdOrderRefit(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{ {
VehicleID veh = GB(p1, 0, 20); VehicleID veh = GB(p1, 0, 20);
VehicleOrderID order_number = GB(p2, 16, 8); VehicleOrderID order_number = GB(p2, 16, 16);
CargoID cargo = GB(p2, 0, 8); CargoID cargo = GB(p2, 0, 8);
if (cargo >= NUM_CARGO && cargo != CT_NO_REFIT && cargo != CT_AUTO_REFIT) return CMD_ERROR; if (cargo >= NUM_CARGO && cargo != CT_NO_REFIT && cargo != CT_AUTO_REFIT) return CMD_ERROR;

@ -68,8 +68,8 @@ restart:
for (const Vehicle *w = v->FirstShared(); w != nullptr; w = w->NextShared()) { for (const Vehicle *w = v->FirstShared(); w != nullptr; w = w->NextShared()) {
/* In GUI, simulate by removing the order and adding it back */ /* In GUI, simulate by removing the order and adding it back */
InvalidateVehicleOrder(w, id | (INVALID_VEH_ORDER_ID << 8)); InvalidateVehicleOrder(w, id | (INVALID_VEH_ORDER_ID << 16));
InvalidateVehicleOrder(w, (INVALID_VEH_ORDER_ID << 8) | id); InvalidateVehicleOrder(w, (INVALID_VEH_ORDER_ID << 16) | id);
} }
} }
} }

@ -12,14 +12,14 @@
#include "core/enum_type.hpp" #include "core/enum_type.hpp"
typedef byte VehicleOrderID; ///< The index of an order within its current vehicle (not pool related) typedef uint16 VehicleOrderID; ///< The index of an order within its current vehicle (not pool related)
typedef uint32 OrderID; typedef uint32 OrderID;
typedef uint16 OrderListID; typedef uint16 OrderListID;
typedef uint16 DestinationID; typedef uint16 DestinationID;
typedef uint32 TimetableTicks; typedef uint32 TimetableTicks;
/** Invalid vehicle order index (sentinel) */ /** Invalid vehicle order index (sentinel) */
static const VehicleOrderID INVALID_VEH_ORDER_ID = 0xFF; static const VehicleOrderID INVALID_VEH_ORDER_ID = 0xFFFF;
/** Last valid VehicleOrderID. */ /** Last valid VehicleOrderID. */
static const VehicleOrderID MAX_VEH_ORDER_ID = INVALID_VEH_ORDER_ID - 1; static const VehicleOrderID MAX_VEH_ORDER_ID = INVALID_VEH_ORDER_ID - 1;

@ -134,6 +134,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = {
{ XSLFI_BUILD_OBJECT_RATE_LIMIT,XSCF_NULL, 1, 1, "build_object_rate_limit", nullptr, nullptr, nullptr }, { XSLFI_BUILD_OBJECT_RATE_LIMIT,XSCF_NULL, 1, 1, "build_object_rate_limit", nullptr, nullptr, nullptr },
{ XSLFI_LOCAL_COMPANY, XSCF_IGNORABLE_ALL, 1, 1, "local_company", saveLC, loadLC, nullptr }, { XSLFI_LOCAL_COMPANY, XSCF_IGNORABLE_ALL, 1, 1, "local_company", saveLC, loadLC, nullptr },
{ XSLFI_THROUGH_TRAIN_DEPOT, XSCF_NULL, 1, 1, "drive_through_train_depot", nullptr, nullptr, nullptr }, { XSLFI_THROUGH_TRAIN_DEPOT, XSCF_NULL, 1, 1, "drive_through_train_depot", nullptr, nullptr, nullptr },
{ XSLFI_MORE_VEHICLE_ORDERS, XSCF_NULL, 1, 1, "more_veh_orders", nullptr, nullptr, nullptr },
{ XSLFI_NULL, XSCF_NULL, 0, 0, nullptr, nullptr, nullptr, nullptr },// This is the end marker { XSLFI_NULL, XSCF_NULL, 0, 0, nullptr, nullptr, nullptr, nullptr },// This is the end marker
}; };

@ -88,6 +88,7 @@ enum SlXvFeatureIndex {
XSLFI_BUILD_OBJECT_RATE_LIMIT, ///< Build object rate limit XSLFI_BUILD_OBJECT_RATE_LIMIT, ///< Build object rate limit
XSLFI_LOCAL_COMPANY, ///< Local company ID XSLFI_LOCAL_COMPANY, ///< Local company ID
XSLFI_THROUGH_TRAIN_DEPOT, ///< Drive-through train depots XSLFI_THROUGH_TRAIN_DEPOT, ///< Drive-through train depots
XSLFI_MORE_VEHICLE_ORDERS, ///< More vehicle orders - VehicleOrderID is 16 bits instead of 8
XSLFI_RIFF_HEADER_60_BIT, ///< Size field in RIFF chunk header is 60 bit XSLFI_RIFF_HEADER_60_BIT, ///< Size field in RIFF chunk header is 60 bit
XSLFI_HEIGHT_8_BIT, ///< Map tile height is 8 bit instead of 4 bit, but savegame version may be before this became true in trunk XSLFI_HEIGHT_8_BIT, ///< Map tile height is 8 bit instead of 4 bit, but savegame version may be before this became true in trunk

@ -1131,7 +1131,7 @@ static const OldChunks vehicle_chunk[] = {
OCL_VAR ( OC_UINT16, 1, &_old_order ), OCL_VAR ( OC_UINT16, 1, &_old_order ),
OCL_NULL ( 1 ), ///< num_orders, now calculated OCL_NULL ( 1 ), ///< num_orders, now calculated
OCL_SVAR( OC_UINT8, Vehicle, cur_implicit_order_index ), OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Vehicle, cur_implicit_order_index ),
OCL_SVAR( OC_TILE, Vehicle, dest_tile ), OCL_SVAR( OC_TILE, Vehicle, dest_tile ),
OCL_SVAR( OC_UINT16, Vehicle, load_unload_ticks ), OCL_SVAR( OC_UINT16, Vehicle, load_unload_ticks ),
OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Vehicle, date_of_last_service ), OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Vehicle, date_of_last_service ),
@ -1243,6 +1243,7 @@ bool LoadOldVehicle(LoadgameState *ls, int num)
if (!LoadChunk(ls, v, vehicle_chunk)) return false; if (!LoadChunk(ls, v, vehicle_chunk)) return false;
if (v == nullptr) continue; if (v == nullptr) continue;
v->refit_cap = v->cargo_cap; v->refit_cap = v->cargo_cap;
if (v->cur_implicit_order_index == 0xFF) v->cur_implicit_order_index == INVALID_VEH_ORDER_ID;
SpriteID sprite = v->sprite_seq.seq[0].sprite; SpriteID sprite = v->sprite_seq.seq[0].sprite;
/* no need to override other sprites */ /* no need to override other sprites */
@ -1321,6 +1322,7 @@ bool LoadOldVehicle(LoadgameState *ls, int num)
if (!LoadChunk(ls, v, vehicle_chunk)) return false; if (!LoadChunk(ls, v, vehicle_chunk)) return false;
if (v == nullptr) continue; if (v == nullptr) continue;
if (v->cur_implicit_order_index == 0xFF) v->cur_implicit_order_index == INVALID_VEH_ORDER_ID;
_old_vehicle_names[_current_vehicle_id] = RemapOldStringID(_old_string_id); _old_vehicle_names[_current_vehicle_id] = RemapOldStringID(_old_string_id);

@ -305,9 +305,9 @@ const SaveLoad *GetOrderBackupDescription()
SLE_STR(OrderBackup, name, SLE_STR, 0), SLE_STR(OrderBackup, name, SLE_STR, 0),
SLE_CONDNULL(2, SL_MIN_VERSION, SLV_192), // clone (2 bytes of pointer, i.e. garbage) SLE_CONDNULL(2, SL_MIN_VERSION, SLV_192), // clone (2 bytes of pointer, i.e. garbage)
SLE_CONDREF(OrderBackup, clone, REF_VEHICLE, SLV_192, SL_MAX_VERSION), SLE_CONDREF(OrderBackup, clone, REF_VEHICLE, SLV_192, SL_MAX_VERSION),
SLE_VAR(OrderBackup, cur_real_order_index, SLE_UINT8), SLE_VAR(OrderBackup, cur_real_order_index, SLE_VEHORDERID),
SLE_CONDVAR(OrderBackup, cur_implicit_order_index, SLE_UINT8, SLV_176, SL_MAX_VERSION), SLE_CONDVAR(OrderBackup, cur_implicit_order_index, SLE_VEHORDERID, SLV_176, SL_MAX_VERSION),
SLE_CONDVAR_X(OrderBackup, cur_timetable_order_index, SLE_UINT8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_TIMETABLE_EXTRA)), SLE_CONDVAR_X(OrderBackup, cur_timetable_order_index, SLE_VEHORDERID, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_TIMETABLE_EXTRA)),
SLE_CONDVAR(OrderBackup, current_order_time, SLE_UINT32, SLV_176, SL_MAX_VERSION), SLE_CONDVAR(OrderBackup, current_order_time, SLE_UINT32, SLV_176, SL_MAX_VERSION),
SLE_CONDVAR(OrderBackup, lateness_counter, SLE_INT32, SLV_176, SL_MAX_VERSION), SLE_CONDVAR(OrderBackup, lateness_counter, SLE_INT32, SLV_176, SL_MAX_VERSION),
SLE_CONDVAR(OrderBackup, timetable_start, SLE_INT32, SLV_176, SL_MAX_VERSION), SLE_CONDVAR(OrderBackup, timetable_start, SLE_INT32, SLV_176, SL_MAX_VERSION),

@ -920,6 +920,7 @@ static void SlSaveLoadConvGeneric(void *ptr, VarType conv)
case SLE_FILE_U8: assert(x >= 0 && x <= 255); SlWriteByte(x);break; case SLE_FILE_U8: assert(x >= 0 && x <= 255); SlWriteByte(x);break;
case SLE_FILE_I16:assert(x >= -32768 && x <= 32767); SlWriteUint16(x);break; case SLE_FILE_I16:assert(x >= -32768 && x <= 32767); SlWriteUint16(x);break;
case SLE_FILE_STRINGID: case SLE_FILE_STRINGID:
case SLE_FILE_VEHORDERID:
case SLE_FILE_U16:assert(x >= 0 && x <= 65535); SlWriteUint16(x);break; case SLE_FILE_U16:assert(x >= 0 && x <= 65535); SlWriteUint16(x);break;
case SLE_FILE_I32: case SLE_FILE_I32:
case SLE_FILE_U32: SlWriteUint32((uint32)x);break; case SLE_FILE_U32: SlWriteUint32((uint32)x);break;
@ -943,6 +944,14 @@ static void SlSaveLoadConvGeneric(void *ptr, VarType conv)
case SLE_FILE_I64: x = (int64 )SlReadUint64(); break; case SLE_FILE_I64: x = (int64 )SlReadUint64(); break;
case SLE_FILE_U64: x = (uint64)SlReadUint64(); break; case SLE_FILE_U64: x = (uint64)SlReadUint64(); break;
case SLE_FILE_STRINGID: x = RemapOldStringID((uint16)SlReadUint16()); break; case SLE_FILE_STRINGID: x = RemapOldStringID((uint16)SlReadUint16()); break;
case SLE_FILE_VEHORDERID:
if (SlXvIsFeaturePresent(XSLFI_MORE_VEHICLE_ORDERS)) {
x = (uint16)SlReadUint16();
} else {
VehicleOrderID id = (byte)SlReadByte();
x = (id == 0xFF) ? INVALID_VEH_ORDER_ID : id;
}
break;
default: NOT_REACHED(); default: NOT_REACHED();
} }

@ -449,7 +449,8 @@ enum VarTypes {
SLE_FILE_U64 = 7, SLE_FILE_U64 = 7,
SLE_FILE_STRINGID = 8, ///< StringID offset into strings-array SLE_FILE_STRINGID = 8, ///< StringID offset into strings-array
SLE_FILE_STRING = 9, SLE_FILE_STRING = 9,
/* 6 more possible file-primitives */ SLE_FILE_VEHORDERID = 10,
/* 5 more possible file-primitives */
/* 4 bits allocated a maximum of 16 types for NumberType */ /* 4 bits allocated a maximum of 16 types for NumberType */
SLE_VAR_BL = 0 << 4, SLE_VAR_BL = 0 << 4,
@ -493,6 +494,7 @@ enum VarTypes {
SLE_STRINGQUOTE = SLE_FILE_STRING | SLE_VAR_STRQ, SLE_STRINGQUOTE = SLE_FILE_STRING | SLE_VAR_STRQ,
SLE_NAME = SLE_FILE_STRINGID | SLE_VAR_NAME, SLE_NAME = SLE_FILE_STRINGID | SLE_VAR_NAME,
SLE_CNAME = SLE_FILE_STRINGID | SLE_VAR_CNAME, SLE_CNAME = SLE_FILE_STRINGID | SLE_VAR_CNAME,
SLE_VEHORDERID = SLE_FILE_VEHORDERID | SLE_VAR_U16,
/* Shortcut values */ /* Shortcut values */
SLE_UINT = SLE_UINT32, SLE_UINT = SLE_UINT32,

@ -680,9 +680,9 @@ const SaveLoad *GetVehicleDescription(VehicleType vt)
return version_in_range && (SlXvIsFeaturePresent(XSLFI_SPRINGPP, 2) || SlXvIsFeaturePresent(XSLFI_JOKERPP) || SlXvIsFeaturePresent(XSLFI_CHILLPP) || SlXvIsFeaturePresent(XSLFI_VARIABLE_DAY_LENGTH, 2)); return version_in_range && (SlXvIsFeaturePresent(XSLFI_SPRINGPP, 2) || SlXvIsFeaturePresent(XSLFI_JOKERPP) || SlXvIsFeaturePresent(XSLFI_CHILLPP) || SlXvIsFeaturePresent(XSLFI_VARIABLE_DAY_LENGTH, 2));
})), })),
SLE_VAR(Vehicle, cur_implicit_order_index, SLE_UINT8), SLE_VAR(Vehicle, cur_implicit_order_index, SLE_VEHORDERID),
SLE_CONDVAR(Vehicle, cur_real_order_index, SLE_UINT8, SLV_158, SL_MAX_VERSION), SLE_CONDVAR(Vehicle, cur_real_order_index, SLE_VEHORDERID, SLV_158, SL_MAX_VERSION),
SLE_CONDVAR_X(Vehicle, cur_timetable_order_index, SLE_UINT8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_TIMETABLE_EXTRA)), SLE_CONDVAR_X(Vehicle, cur_timetable_order_index, SLE_VEHORDERID, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_TIMETABLE_EXTRA)),
/* num_orders is now part of OrderList and is not saved but counted */ /* num_orders is now part of OrderList and is not saved but counted */
SLE_CONDNULL(1, SL_MIN_VERSION, SLV_105), SLE_CONDNULL(1, SL_MIN_VERSION, SLV_105),

@ -19,6 +19,7 @@
#include "company_base.h" #include "company_base.h"
#include "settings_type.h" #include "settings_type.h"
#include "scope.h" #include "scope.h"
#include "core/endian_func.hpp"
#include "table/strings.h" #include "table/strings.h"
@ -133,16 +134,16 @@ static void ChangeTimetable(Vehicle *v, VehicleOrderID order_number, uint32 val,
* @param flags Operation to perform. * @param flags Operation to perform.
* @param p1 Various bitstuffed elements * @param p1 Various bitstuffed elements
* - p1 = (bit 0-19) - Vehicle with the orders to change. * - p1 = (bit 0-19) - Vehicle with the orders to change.
* - p1 = (bit 20-27) - Order index to modify. * - p1 = (bit 20-27) - unused
* - p1 = (bit 28-30) - Timetable data to change (@see ModifyTimetableFlags) * - p1 = (bit 28-30) - Timetable data to change (@see ModifyTimetableFlags)
* - p1 = (bit 31) - 0 to set timetable wait/travel time, 1 to clear it * - p1 = (bit 31) - 0 to set timetable wait/travel time, 1 to clear it
* @param p2 The amount of time to wait. * @param p2 The amount of time to wait.
* - p2 = - The data to modify as specified by p1 bits 28-30. * - p2 = - The data to modify as specified by p1 bits 28-30.
* 0 to clear times, UINT16_MAX to clear speed limit. * 0 to clear times, UINT16_MAX to clear speed limit.
* @param text unused * @param text LE uint16 Order index to modify.
* @return the cost of this operation or an error * @return the cost of this operation or an error
*/ */
CommandCost CmdChangeTimetable(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) CommandCost CmdChangeTimetable(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text, uint32 binary_length)
{ {
VehicleID veh = GB(p1, 0, 20); VehicleID veh = GB(p1, 0, 20);
@ -152,7 +153,9 @@ CommandCost CmdChangeTimetable(TileIndex tile, DoCommandFlag flags, uint32 p1, u
CommandCost ret = CheckOwnership(v->owner); CommandCost ret = CheckOwnership(v->owner);
if (ret.Failed()) return ret; if (ret.Failed()) return ret;
VehicleOrderID order_number = GB(p1, 20, 8); if (binary_length != 2) return CMD_ERROR;
VehicleOrderID order_number = FROM_LE16(*reinterpret_cast<const uint16 *>(text));
Order *order = v->GetOrder(order_number); Order *order = v->GetOrder(order_number);
if (order == nullptr || order->IsType(OT_IMPLICIT)) return CMD_ERROR; if (order == nullptr || order->IsType(OT_IMPLICIT)) return CMD_ERROR;
@ -308,9 +311,9 @@ CommandCost CmdBulkChangeTimetable(TileIndex tile, DoCommandFlag flags, uint32 p
// Exclude waypoints from set all wait times command // Exclude waypoints from set all wait times command
if (Extract<ModifyTimetableFlags, 28, 3>(p1) == MTF_WAIT_TIME && GB(p1, 31, 1) == 0 && order->IsType(OT_GOTO_WAYPOINT)) continue; if (Extract<ModifyTimetableFlags, 28, 3>(p1) == MTF_WAIT_TIME && GB(p1, 31, 1) == 0 && order->IsType(OT_GOTO_WAYPOINT)) continue;
uint32 new_p1 = p1; char text[2];
SB(new_p1, 20, 8, order_number); *reinterpret_cast<uint16 *>(&text) = TO_LE16(order_number);
DoCommand(tile, new_p1, p2, flags, CMD_CHANGE_TIMETABLE); DoCommand(tile, p1, p2, flags, CMD_CHANGE_TIMETABLE, text, 2);
} }
} }

@ -25,6 +25,7 @@
#include "viewport_func.h" #include "viewport_func.h"
#include "schdispatch.h" #include "schdispatch.h"
#include "vehiclelist.h" #include "vehiclelist.h"
#include "core/endian_func.hpp"
#include "widgets/timetable_widget.h" #include "widgets/timetable_widget.h"
@ -303,8 +304,8 @@ struct TimetableWindow : Window {
* the order is being created / removed */ * the order is being created / removed */
if (this->sel_index == -1) break; if (this->sel_index == -1) break;
VehicleOrderID from = GB(data, 0, 8); VehicleOrderID from = GB(data, 0, 16);
VehicleOrderID to = GB(data, 8, 8); VehicleOrderID to = GB(data, 16, 16);
if (from == to) break; // no need to change anything if (from == to) break; // no need to change anything
@ -704,14 +705,19 @@ struct TimetableWindow : Window {
} }
} }
static inline uint32 PackTimetableArgs(const Vehicle *v, uint selected, bool speed, bool clear = false) static inline void ExecuteTimetableCommand(const Vehicle *v, bool bulk, uint selected, ModifyTimetableFlags mtf, uint p2, bool clear)
{ {
uint order_number = (selected + 1) / 2; uint order_number = (selected + 1) / 2;
ModifyTimetableFlags mtf = (selected % 2 == 1) ? (speed ? MTF_TRAVEL_SPEED : MTF_TRAVEL_TIME) : MTF_WAIT_TIME;
if (order_number >= v->GetNumOrders()) order_number = 0; if (order_number >= v->GetNumOrders()) order_number = 0;
return v->index | (order_number << 20) | (mtf << 28) | (clear ? 1 << 31 : 0); uint p1 = v->index | (mtf << 28) | (clear ? 1 << 31 : 0);
if (bulk) {
DoCommandP(0, p1, p2, CMD_BULK_CHANGE_TIMETABLE | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE));
} else {
char text[2];
*reinterpret_cast<uint16 *>(&text) = TO_LE16(order_number);
DoCommandP(0, p1, p2, CMD_CHANGE_TIMETABLE | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE), nullptr, text, true, 2);
}
} }
void OnClick(Point pt, int widget, int click_count) override void OnClick(Point pt, int widget, int click_count) override
@ -806,14 +812,12 @@ struct TimetableWindow : Window {
} }
case WID_VT_CLEAR_TIME: { // Clear waiting time. case WID_VT_CLEAR_TIME: { // Clear waiting time.
uint32 p1 = PackTimetableArgs(v, this->sel_index, false, true); ExecuteTimetableCommand(v, _ctrl_pressed, this->sel_index, MTF_WAIT_TIME, 0, true);
DoCommandP(0, p1, 0, (_ctrl_pressed ? CMD_BULK_CHANGE_TIMETABLE : CMD_CHANGE_TIMETABLE) | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE));
break; break;
} }
case WID_VT_CLEAR_SPEED: { // Clear max speed button. case WID_VT_CLEAR_SPEED: { // Clear max speed button.
uint32 p1 = PackTimetableArgs(v, this->sel_index, true); ExecuteTimetableCommand(v, _ctrl_pressed, this->sel_index, MTF_TRAVEL_SPEED, UINT16_MAX, false);
DoCommandP(0, p1, UINT16_MAX, (_ctrl_pressed ? CMD_BULK_CHANGE_TIMETABLE : CMD_CHANGE_TIMETABLE) | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE));
break; break;
} }
@ -829,8 +833,7 @@ struct TimetableWindow : Window {
locked = (selected % 2 == 1) ? order->IsTravelFixed() : order->IsWaitFixed(); locked = (selected % 2 == 1) ? order->IsTravelFixed() : order->IsWaitFixed();
} }
uint32 p1 = v->index | (order_number << 20) | (((selected % 2 == 1) ? MTF_SET_TRAVEL_FIXED : MTF_SET_WAIT_FIXED) << 28); ExecuteTimetableCommand(v, _ctrl_pressed, this->sel_index, ((selected % 2 == 1) ? MTF_SET_TRAVEL_FIXED : MTF_SET_WAIT_FIXED), locked ? 0 : 1, false);
DoCommandP(0, p1, locked ? 0 : 1, (_ctrl_pressed ? CMD_BULK_CHANGE_TIMETABLE : CMD_CHANGE_TIMETABLE) | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE));
break; break;
} }
@ -903,11 +906,7 @@ struct TimetableWindow : Window {
{ {
switch (widget) { switch (widget) {
case WID_VT_EXTRA: { case WID_VT_EXTRA: {
VehicleOrderID order_number = (this->sel_index + 1) / 2; ExecuteTimetableCommand(this->vehicle, false, this->sel_index, MTF_SET_LEAVE_TYPE, index, false);
if (order_number >= this->vehicle->GetNumOrders()) order_number = 0;
uint32 p1 = this->vehicle->index | (order_number << 20) | (MTF_SET_LEAVE_TYPE << 28);
DoCommandP(0, p1, index, CMD_CHANGE_TIMETABLE | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE));
} }
default: default:
@ -926,8 +925,6 @@ struct TimetableWindow : Window {
case WID_VT_CHANGE_SPEED: case WID_VT_CHANGE_SPEED:
case WID_VT_CHANGE_TIME: { case WID_VT_CHANGE_TIME: {
uint32 p1 = PackTimetableArgs(v, this->sel_index, this->query_is_speed_query);
uint64 val = StrEmpty(str) ? 0 : strtoul(str, nullptr, 10); uint64 val = StrEmpty(str) ? 0 : strtoul(str, nullptr, 10);
uint32 p2; uint32 p2;
if (this->query_is_speed_query) { if (this->query_is_speed_query) {
@ -938,7 +935,7 @@ struct TimetableWindow : Window {
p2 = val; p2 = val;
} }
DoCommandP(0, p1, p2, (this->change_timetable_all ? CMD_BULK_CHANGE_TIMETABLE : CMD_CHANGE_TIMETABLE) | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE)); ExecuteTimetableCommand(v, this->change_timetable_all, this->sel_index, (this->sel_index % 2 == 1) ? (this->query_is_speed_query ? MTF_TRAVEL_SPEED : MTF_TRAVEL_TIME) : MTF_WAIT_TIME, p2, false);
break; break;
} }

@ -1213,7 +1213,7 @@ struct RefitWindow : public Window {
delete this; delete this;
} }
} else { } else {
if (DoCommandP(v->tile, v->index, this->cargo->cargo | this->cargo->subtype << 8 | this->order << 16 | this->is_virtual_train << 31, CMD_ORDER_REFIT)) delete this; if (DoCommandP(v->tile, v->index, this->cargo->cargo | this->cargo->subtype << 8 | this->order << 16, CMD_ORDER_REFIT)) delete this;
} }
} }
break; break;

Loading…
Cancel
Save