Index: src/lang/english.txt =================================================================== --- src/lang/english.txt (revision 15552) +++ src/lang/english.txt (working copy) @@ -2612,6 +2612,10 @@ STR_ORDER_DROP_FULL_LOAD_ALL :Full load all cargo STR_ORDER_DROP_FULL_LOAD_ANY :Full load any cargo STR_ORDER_DROP_NO_LOADING :No loading +STR_ORDER_DROP_SOME_LOAD :Wait for some cargo +STR_ORDER_DROP_25_LOAD :Wait for 25% load +STR_ORDER_DROP_50_LOAD :Wait for 50% load +STR_ORDER_DROP_75_LOAD :Wait for 75% load STR_ORDER_TOGGLE_UNLOAD :{BLACK}Unload all STR_ORDER_DROP_UNLOAD_IF_ACCEPTED :Unload if accepted STR_ORDER_DROP_UNLOAD :Unload all @@ -2620,14 +2624,20 @@ STR_ORDER_FULL_LOAD :(Full load) STR_ORDER_FULL_LOAD_ANY :(Full load any cargo) STR_ORDER_NO_LOAD :(No loading) +STR_ORDER_UNITS_LOAD :(Wait for {WEIGHT_S} of cargo) +STR_ORDER_PERCENT_LOAD :(Wait for {NUM}% cargo) STR_ORDER_UNLOAD :(Unload and take cargo) STR_ORDER_UNLOAD_FULL_LOAD :(Unload and wait for full load) STR_ORDER_UNLOAD_FULL_LOAD_ANY :(Unload and wait for any full load) STR_ORDER_UNLOAD_NO_LOAD :(Unload and leave empty) +STR_ORDER_UNLOAD_UNITS_LOAD :(Unload and wait for {WEIGHT_S} of cargo) +STR_ORDER_UNLOAD_PERCENT_LOAD :(Unload and wait for {NUM}% cargo) STR_ORDER_TRANSFER :(Transfer and take cargo) STR_ORDER_TRANSFER_FULL_LOAD :(Transfer and wait for full load) STR_ORDER_TRANSFER_FULL_LOAD_ANY :(Transfer and wait for any full load) STR_ORDER_TRANSFER_NO_LOAD :(Transfer and leave empty) +STR_ORDER_TRANSFER_UNITS_LOAD :(Transfer and wait for {WEIGHT_S} of cargo) +STR_ORDER_TRANSFER_PERCENT_LOAD :(Transfer and wait for {NUM}% cargo) STR_ORDER_NO_UNLOAD :(No unload and take cargo) STR_ORDER_NO_UNLOAD_FULL_LOAD :(No unload and wait for full load) STR_ORDER_NO_UNLOAD_FULL_LOAD_ANY :(No unload and wait for any full load) Index: src/order_base.h =================================================================== --- src/order_base.h (revision 15552) +++ src/order_base.h (working copy) @@ -30,6 +30,7 @@ uint8 type; ///< The type of order + non-stop flags uint8 flags; ///< Load/unload types, depot order/action types. + uint8 load_arg; ///< Argument to load type, for load by units/percent. DestinationID dest; ///< The destination of the order. CargoID refit_cargo; ///< Refit CargoID @@ -164,6 +165,8 @@ /** How must the consist be loaded? */ inline OrderLoadFlags GetLoadType() const { return (OrderLoadFlags)GB(this->flags, 4, 4); } + /** Argument to load type, for load by units/percent. */ + inline uint8 GetLoadArg() const { return this->load_arg; } /** How must the consist be unloaded? */ inline OrderUnloadFlags GetUnloadType() const { return (OrderUnloadFlags)GB(this->flags, 0, 4); } /** Where must we stop? */ @@ -183,6 +186,8 @@ /** Set how the consist must be loaded. */ inline void SetLoadType(OrderLoadFlags load_type) { SB(this->flags, 4, 4, load_type); } + /** Set argument to load type, for load by units/percent. */ + inline void SetLoadArg(uint8 arg) { this->load_arg = arg; } /** Set how the consist must be unloaded. */ inline void SetUnloadType(OrderUnloadFlags unload_type) { SB(this->flags, 0, 4, unload_type); } /** Set whether we must stop at stations or not. */ Index: src/order_type.h =================================================================== --- src/order_type.h (revision 15552) +++ src/order_type.h (working copy) @@ -58,9 +58,25 @@ OLFB_FULL_LOAD = 1 << 1, ///< Full load the complete the consist. OLF_FULL_LOAD_ANY = 3, ///< Full load the a single cargo of the consist. OLFB_NO_LOAD = 4, ///< Do not load anything. + OLF_LOAD_UNITS = 5, ///< Load at least (arg) units. + OLF_LOAD_PERCENT = 6, ///< Load at least (arg)% }; /** + * Loading orders in the GUI drop-down box. + */ +enum OrderLoadDropdown { + OLD_LOAD_IF_POSSIBLE = 0, ///< Load if available + OLD_FULL_LOAD_ALL = 2, ///< Full load all cargo + OLD_FULL_LOAD_ANY = 3, ///< Full load any cargo + OLD_NO_LOADING = 4, ///< No loading + OLD_SOME_LOAD = 5, ///< Wait for some cargo + OLD_25_LOAD = 6, ///< Wait for 25% load + OLD_50_LOAD = 7, ///< Wait for 50% load + OLD_75_LOAD = 8, ///< Wait for 75% load +}; + +/** * Non-stop order flags. */ enum OrderNonStopFlags { Index: src/order_cmd.cpp =================================================================== --- src/order_cmd.cpp (revision 15552) +++ src/order_cmd.cpp (working copy) @@ -40,6 +40,7 @@ { this->type = OT_NOTHING; this->flags = 0; + this->load_arg = 0; this->dest = 0; this->next = NULL; } @@ -119,6 +120,7 @@ return this->type == other.type && this->flags == other.flags && + this->load_arg == other.load_arg && this->dest == other.dest; } @@ -131,6 +133,7 @@ { this->type = (OrderType)GB(packed, 0, 8); this->flags = GB(packed, 8, 8); + this->load_arg = 0; this->dest = GB(packed, 16, 16); this->next = NULL; this->refit_cargo = CT_NO_REFIT; @@ -169,6 +172,7 @@ { this->type = other.type; this->flags = other.flags; + this->load_arg = other.load_arg; this->dest = other.dest; this->refit_cargo = other.refit_cargo; @@ -447,7 +451,7 @@ /* Filter invalid load/unload types. */ switch (new_order.GetLoadType()) { - case OLF_LOAD_IF_POSSIBLE: case OLFB_FULL_LOAD: case OLF_FULL_LOAD_ANY: case OLFB_NO_LOAD: break; + case OLF_LOAD_IF_POSSIBLE: case OLFB_FULL_LOAD: case OLF_FULL_LOAD_ANY: case OLFB_NO_LOAD: case OLF_LOAD_PERCENT: break; default: return CMD_ERROR; } switch (new_order.GetUnloadType()) { @@ -837,6 +841,7 @@ VehicleID veh = GB(p1, 0, 16); ModifyOrderFlags mof = (ModifyOrderFlags)GB(p2, 0, 4); uint16 data = GB(p2, 4, 11); + uint8 arg = 0; if (mof >= MOF_END) return CMD_ERROR; if (!IsValidVehicleID(veh)) return CMD_ERROR; @@ -886,8 +891,31 @@ break; case MOF_LOAD: - if (data > OLFB_NO_LOAD || data == 1) return CMD_ERROR; - if (data == order->GetLoadType()) return CMD_ERROR; + if (data > OLD_75_LOAD || data == 1) return CMD_ERROR; + switch (data) { + case OLD_SOME_LOAD: + data = OLF_LOAD_UNITS; + arg = 1; + break; + + case OLD_25_LOAD: + data = OLF_LOAD_PERCENT; + arg = 25; + break; + + case OLD_50_LOAD: + data = OLF_LOAD_PERCENT; + arg = 50; + break; + + case OLD_75_LOAD: + data = OLF_LOAD_PERCENT; + arg = 75; + break; + + default: break; + } + if (data == order->GetLoadType() && arg == order->GetLoadArg()) return CMD_ERROR; break; case MOF_DEPOT_ACTION: @@ -941,14 +969,15 @@ case MOF_UNLOAD: order->SetUnloadType((OrderUnloadFlags)data); - if ((data & OUFB_NO_UNLOAD) != 0 && (order->GetLoadType() & OLFB_NO_LOAD) != 0) { + if ((data & OUFB_NO_UNLOAD) != 0 && (order->GetLoadType() == OLFB_NO_LOAD)) { order->SetLoadType((OrderLoadFlags)(order->GetLoadType() & ~OLFB_NO_LOAD)); } break; case MOF_LOAD: order->SetLoadType((OrderLoadFlags)data); - if ((data & OLFB_NO_LOAD) != 0 && (order->GetUnloadType() & OUFB_NO_UNLOAD) != 0) { + order->SetLoadArg(arg); + if ((data == OLFB_NO_LOAD) && (order->GetUnloadType() & OUFB_NO_UNLOAD) != 0) { /* No load + no unload isn't compatible */ order->SetUnloadType((OrderUnloadFlags)(order->GetUnloadType() & ~OUFB_NO_UNLOAD)); } @@ -1030,8 +1059,9 @@ */ if (sel_ord == u->cur_order_index && (u->current_order.IsType(OT_GOTO_STATION) || u->current_order.IsType(OT_LOADING)) && - u->current_order.GetLoadType() != order->GetLoadType()) { + (u->current_order.GetLoadType() != order->GetLoadType() || u->current_order.GetLoadArg() != order->GetLoadArg())) { u->current_order.SetLoadType(order->GetLoadType()); + u->current_order.SetLoadArg(order->GetLoadArg()); } InvalidateVehicleOrder(u, 0); } Index: src/order_gui.cpp =================================================================== --- src/order_gui.cpp (revision 15552) +++ src/order_gui.cpp (working copy) @@ -57,37 +57,47 @@ }; /** Order load types that could be given to station orders. */ -static const StringID _station_load_types[][5] = { +static const StringID _station_load_types[][7] = { { STR_EMPTY, INVALID_STRING_ID, STR_ORDER_FULL_LOAD, STR_ORDER_FULL_LOAD_ANY, STR_ORDER_NO_LOAD, + STR_ORDER_UNITS_LOAD, + STR_ORDER_PERCENT_LOAD, }, { STR_ORDER_UNLOAD, INVALID_STRING_ID, STR_ORDER_UNLOAD_FULL_LOAD, STR_ORDER_UNLOAD_FULL_LOAD_ANY, STR_ORDER_UNLOAD_NO_LOAD, + STR_ORDER_UNLOAD_UNITS_LOAD, + STR_ORDER_UNLOAD_PERCENT_LOAD, }, { STR_ORDER_TRANSFER, INVALID_STRING_ID, STR_ORDER_TRANSFER_FULL_LOAD, STR_ORDER_TRANSFER_FULL_LOAD_ANY, STR_ORDER_TRANSFER_NO_LOAD, + STR_ORDER_TRANSFER_UNITS_LOAD, + STR_ORDER_TRANSFER_PERCENT_LOAD, }, { /* Unload and transfer do not work together. */ INVALID_STRING_ID, INVALID_STRING_ID, INVALID_STRING_ID, INVALID_STRING_ID, + INVALID_STRING_ID, + INVALID_STRING_ID, }, { STR_ORDER_NO_UNLOAD, INVALID_STRING_ID, STR_ORDER_NO_UNLOAD_FULL_LOAD, STR_ORDER_NO_UNLOAD_FULL_LOAD_ANY, INVALID_STRING_ID, + INVALID_STRING_ID, + INVALID_STRING_ID, } }; @@ -105,6 +115,10 @@ STR_ORDER_DROP_FULL_LOAD_ALL, STR_ORDER_DROP_FULL_LOAD_ANY, STR_ORDER_DROP_NO_LOADING, + STR_ORDER_DROP_SOME_LOAD, + STR_ORDER_DROP_25_LOAD, + STR_ORDER_DROP_50_LOAD, + STR_ORDER_DROP_75_LOAD, INVALID_STRING_ID }; @@ -202,6 +216,7 @@ } } else { SetDParam(4, (order->GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION) ? STR_EMPTY : _station_load_types[unload][load]); + SetDParam(5, order->GetLoadArg()); } } break; Index: src/economy.cpp =================================================================== --- src/economy.cpp (revision 15552) +++ src/economy.cpp (working copy) @@ -1619,7 +1619,7 @@ } /* Do not pick up goods when we have no-load set. */ - if (u->current_order.GetLoadType() & OLFB_NO_LOAD) continue; + if (u->current_order.GetLoadType() == OLFB_NO_LOAD) continue; /* update stats */ int t; @@ -1694,7 +1694,7 @@ * all wagons at the same time instead of using the same 'improved' * loading algorithm for the wagons (only fill wagon when there is * enough to fill the previous wagons) */ - if (_settings_game.order.improved_load && (u->current_order.GetLoadType() & OLFB_FULL_LOAD)) { + if (_settings_game.order.improved_load && (u->current_order.GetLoadType() & OLFB_FULL_LOAD || u->current_order.GetLoadType() > OLFB_NO_LOAD)) { /* Update left cargo */ for (v = u; v != NULL; v = v->Next()) { int cap_left = v->cargo_cap - v->cargo.Count(); @@ -1714,8 +1714,22 @@ } } else { bool finished_loading = true; - if (v->current_order.GetLoadType() & OLFB_FULL_LOAD) { - if (v->current_order.GetLoadType() == OLF_FULL_LOAD_ANY) { + OrderLoadFlags load_type = v->current_order.GetLoadType(); + if (load_type > OLFB_NO_LOAD && cargo_not_full != 0) { + switch (load_type) { + case OLF_LOAD_PERCENT: { + unsigned int cargo_target = v->cargo_cap * v->current_order.GetLoadArg() / 100; + if (v->cargo.Count() < cargo_target) finished_loading = false; + } break; + + case OLF_LOAD_UNITS: + if (v->cargo.Count() < v->current_order.GetLoadArg()) finished_loading = false; + break; + + default: break; + } + } else if (load_type & OLFB_FULL_LOAD) { + if (load_type == OLF_FULL_LOAD_ANY) { /* if the aircraft carries passengers and is NOT full, then * continue loading, no matter how much mail is in */ if ((v->type == VEH_AIRCRAFT && IsCargoInClass(v->cargo_type, CC_PASSENGERS) && v->cargo_cap > v->cargo.Count()) || Index: src/saveload/saveload.cpp =================================================================== --- src/saveload/saveload.cpp (revision 15552) +++ src/saveload/saveload.cpp (working copy) @@ -38,7 +38,7 @@ #include "saveload_internal.h" -extern const uint16 SAVEGAME_VERSION = 113; +extern const uint16 SAVEGAME_VERSION = 114; SavegameType _savegame_type; ///< type of savegame we are loading Index: src/saveload/order_sl.cpp =================================================================== --- src/saveload/order_sl.cpp (revision 15552) +++ src/saveload/order_sl.cpp (working copy) @@ -95,6 +95,7 @@ SLE_CONDVAR(Order, refit_subtype, SLE_UINT8, 36, SL_MAX_VERSION), SLE_CONDVAR(Order, wait_time, SLE_UINT16, 67, SL_MAX_VERSION), SLE_CONDVAR(Order, travel_time, SLE_UINT16, 67, SL_MAX_VERSION), + SLE_CONDVAR(Order, load_arg, SLE_UINT8, 114, SL_MAX_VERSION), /* Leftover from the minor savegame version stuff * We will never use those free bytes, but we have to keep this line to allow loading of old savegames */