From 2b9c633d5033f779d7a02dda14bf61cd8fa0ad09 Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Wed, 19 Aug 2020 18:51:47 +0100 Subject: [PATCH] Add leave early if any/all cargoes fully loaded timetable modes --- src/economy.cpp | 28 +++++++++++++++++++++++++++- src/lang/english.txt | 6 +++++- src/order_gui.cpp | 4 ++-- src/order_type.h | 2 ++ src/saveload/extended_ver_sl.cpp | 2 +- src/timetable_gui.cpp | 2 ++ 6 files changed, 39 insertions(+), 5 deletions(-) diff --git a/src/economy.cpp b/src/economy.cpp index 4671f68e3e..81d43224f3 100644 --- a/src/economy.cpp +++ b/src/economy.cpp @@ -2045,6 +2045,25 @@ static void LoadUnloadVehicle(Vehicle *front) } } } + auto may_leave_early = [&]() -> bool { + switch (front->current_order.GetLeaveType()) { + case OLT_NORMAL: + return false; + + case OLT_LEAVE_EARLY: + return true; + + case OLT_LEAVE_EARLY_FULL_ANY: + return !((front->type == VEH_AIRCRAFT && IsCargoInClass(front->cargo_type, CC_PASSENGERS) && front->cargo_cap > front->cargo.StoredCount()) || + ((cargo_not_full | not_yet_in_station_cargo_not_full) != 0 && ((cargo_full | beyond_platform_end_cargo_full) & ~(cargo_not_full | not_yet_in_station_cargo_not_full)) == 0)); + + case OLT_LEAVE_EARLY_FULL_ALL: + return (cargo_not_full | not_yet_in_station_cargo_not_full) == 0; + + default: + NOT_REACHED(); + } + }; if (anything_loaded || anything_unloaded) { if (_settings_game.order.gradual_loading) { /* The time it takes to load one 'slice' of cargo or passengers depends @@ -2057,8 +2076,11 @@ static void LoadUnloadVehicle(Vehicle *front) * load and we're not supposed to wait any longer: stop loading. */ if (!anything_unloaded && full_load_amount == 0 && reservation_left == 0 && full_load_cargo_mask == 0 && (front->current_order_time >= (uint)max(front->current_order.GetTimetabledWait() - front->lateness_counter, 0) || - front->current_order.GetLeaveType() == OLT_LEAVE_EARLY)) { + may_leave_early())) { SetBit(front->vehicle_flags, VF_STOP_LOADING); + if (may_leave_early()) { + front->current_order.SetLeaveType(OLT_LEAVE_EARLY); + } } UpdateLoadUnloadTicks(front, st, new_load_unload_ticks, platform_length_left); @@ -2104,6 +2126,10 @@ static void LoadUnloadVehicle(Vehicle *front) if (!finished_loading) LinkRefresher::Run(front, true, true); SB(front->vehicle_flags, VF_LOADING_FINISHED, 1, finished_loading); + + if (finished_loading && may_leave_early()) { + front->current_order.SetLeaveType(OLT_LEAVE_EARLY); + } } /* Calculate the loading indicator fill percent and display diff --git a/src/lang/english.txt b/src/lang/english.txt index 01bcc43755..5576369575 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -4994,11 +4994,15 @@ STR_TIMETABLE_EXPECTED_TOOLTIP :{BLACK}Switch b STR_TIMETABLE_LOCK_ORDER_TIME_TOOLTIP :{BLACK}Lock/unlock the amount of time for the highlighted order (Ctrl+Click set lock state for all orders).{}When locked the time will not be changed by timetable autofill or automate. STR_TIMETABLE_LEAVE_EARLY_ORDER :[leave early] +STR_TIMETABLE_LEAVE_EARLY_ORDER_FULL_ANY :[leave early if any cargo full] +STR_TIMETABLE_LEAVE_EARLY_ORDER_FULL_ALL :[leave early if all cargoes full] STR_TIMETABLE_LEAVE_NORMAL :Leave as timetabled STR_TIMETABLE_LEAVE_EARLY :Leave early +STR_TIMETABLE_LEAVE_EARLY_FULL_ANY :Leave early if any full +STR_TIMETABLE_LEAVE_EARLY_FULL_ALL :Leave early if all full STR_TIMETABLE_EXTRA_DROP_DOWN :{BLACK}Extra -STR_TIMETABLE_EXTRA_DROP_DOWN_TOOLTIP :{BLACK}Extra Options{}{}Leave as timetabled: Vehicles wait until their timetabled departure time before leaving (default).{}Leave Early: Vehicles leave as soon as loading/unloading is done, possibly before the timetabled departure time. +STR_TIMETABLE_EXTRA_DROP_DOWN_TOOLTIP :{BLACK}Extra Options{}{}Leave as timetabled: Vehicles wait until their timetabled departure time before leaving (default).{}Leave Early: Vehicles leave as soon as loading/unloading is done, possibly before the timetabled departure time.{}Leave Early if Any Full: As above, if any cargo is fully loaded.{}Leave Early if All Full: As above, if all cargoes are fully loaded. STR_TIMETABLE_ARRIVAL_ABBREVIATION :A: STR_TIMETABLE_DEPARTURE_ABBREVIATION :D: diff --git a/src/order_gui.cpp b/src/order_gui.cpp index f528a5ad32..0d8b1a63ad 100644 --- a/src/order_gui.cpp +++ b/src/order_gui.cpp @@ -990,8 +990,8 @@ void DrawOrderString(const Vehicle *v, const Order *order, int order_index, int int edge = DrawString(rtl ? left : middle, rtl ? middle : right, y, STR_ORDER_TEXT, colour); - if (timetable && timetable_wait_time_valid && order->GetLeaveType() == OLT_LEAVE_EARLY && edge != 0) { - edge = DrawString(rtl ? left : edge + 3, rtl ? edge - 3 : right, y, STR_TIMETABLE_LEAVE_EARLY_ORDER, colour); + if (timetable && timetable_wait_time_valid && order->GetLeaveType() != OLT_NORMAL && edge != 0) { + edge = DrawString(rtl ? left : edge + 3, rtl ? edge - 3 : right, y, STR_TIMETABLE_LEAVE_EARLY_ORDER + order->GetLeaveType() - OLT_LEAVE_EARLY, colour); } if (timetable && HasBit(v->vehicle_flags, VF_SCHEDULED_DISPATCH) && v->GetFirstWaitingLocation(false) == order_index && edge != 0) { StringID str = order->IsWaitTimetabled() ? STR_TIMETABLE_SCHEDULED_DISPATCH_ORDER : STR_TIMETABLE_SCHEDULED_DISPATCH_ORDER_NO_WAIT_TIME; diff --git a/src/order_type.h b/src/order_type.h index 33ad984d86..54eadce213 100644 --- a/src/order_type.h +++ b/src/order_type.h @@ -203,6 +203,8 @@ enum OrderDepotAction { enum OrderLeaveType { OLT_NORMAL = 0, ///< Leave when timetabled OLT_LEAVE_EARLY = 1, ///< Leave as soon as possible + OLT_LEAVE_EARLY_FULL_ANY = 2, ///< Leave as soon as possible, if any cargoes fully loaded + OLT_LEAVE_EARLY_FULL_ALL = 3, ///< Leave as soon as possible, if all cargoes fully loaded OLT_END }; diff --git a/src/saveload/extended_ver_sl.cpp b/src/saveload/extended_ver_sl.cpp index 09b9b624ff..6978fd2041 100644 --- a/src/saveload/extended_ver_sl.cpp +++ b/src/saveload/extended_ver_sl.cpp @@ -101,7 +101,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = { { XSLFI_SCHEDULED_DISPATCH, XSCF_NULL, 2, 2, "scheduled_dispatch", nullptr, nullptr, nullptr }, { XSLFI_MORE_TOWN_GROWTH_RATES, XSCF_NULL, 1, 1, "more_town_growth_rates", nullptr, nullptr, nullptr }, { XSLFI_MULTIPLE_DOCKS, XSCF_NULL, 2, 2, "multiple_docks", nullptr, nullptr, nullptr }, - { XSLFI_TIMETABLE_EXTRA, XSCF_NULL, 6, 6, "timetable_extra", nullptr, nullptr, "ORDX" }, + { XSLFI_TIMETABLE_EXTRA, XSCF_NULL, 7, 7, "timetable_extra", nullptr, nullptr, "ORDX" }, { XSLFI_TRAIN_FLAGS_EXTRA, XSCF_NULL, 1, 1, "train_flags_extra", nullptr, nullptr, nullptr }, { XSLFI_TRAIN_THROUGH_LOAD, XSCF_NULL, 2, 2, "train_through_load", nullptr, nullptr, nullptr }, { XSLFI_ORDER_EXTRA_DATA, XSCF_NULL, 1, 1, "order_extra_data", nullptr, nullptr, nullptr }, diff --git a/src/timetable_gui.cpp b/src/timetable_gui.cpp index 4bbf9f74ab..28cae22d94 100644 --- a/src/timetable_gui.cpp +++ b/src/timetable_gui.cpp @@ -889,6 +889,8 @@ struct TimetableWindow : Window { DropDownList list; list.emplace_back(new DropDownListStringItem(STR_TIMETABLE_LEAVE_NORMAL, OLT_NORMAL, leave_type_disabled)); list.emplace_back(new DropDownListStringItem(STR_TIMETABLE_LEAVE_EARLY, OLT_LEAVE_EARLY, leave_type_disabled)); + list.emplace_back(new DropDownListStringItem(STR_TIMETABLE_LEAVE_EARLY_FULL_ANY, OLT_LEAVE_EARLY_FULL_ANY, leave_type_disabled || !order->IsType(OT_GOTO_STATION))); + list.emplace_back(new DropDownListStringItem(STR_TIMETABLE_LEAVE_EARLY_FULL_ALL, OLT_LEAVE_EARLY_FULL_ALL, leave_type_disabled || !order->IsType(OT_GOTO_STATION))); ShowDropDownList(this, std::move(list), order != nullptr ? order->GetLeaveType() : -1, WID_VT_EXTRA); break; }