Merge tag '14.0-beta1' into jgrpp

# Conflicts:
#	src/3rdparty/squirrel/squirrel/sqcompiler.cpp
#	src/aircraft.h
#	src/animated_tile.h
#	src/base_consist.h
#	src/cargotype.h
#	src/company_gui.cpp
#	src/console_cmds.cpp
#	src/core/overflowsafe_type.hpp
#	src/engine_gui.cpp
#	src/industry_gui.cpp
#	src/lang/english.txt
#	src/music/extmidi.cpp
#	src/network/core/network_game_info.cpp
#	src/network/network_server.cpp
#	src/newgrf.cpp
#	src/newgrf_industries.cpp
#	src/order_base.h
#	src/order_cmd.cpp
#	src/order_gui.cpp
#	src/order_type.h
#	src/os/macosx/misc_osx.cpp
#	src/os/windows/crashlog_win.cpp
#	src/rail_gui.cpp
#	src/rail_gui.h
#	src/roadveh.h
#	src/roadveh_cmd.cpp
#	src/saveload/afterload.cpp
#	src/saveload/company_sl.cpp
#	src/saveload/saveload.cpp
#	src/saveload/saveload.h
#	src/saveload/saveload_error.hpp
#	src/script/api/script_town.cpp
#	src/settingsgen/settingsgen.cpp
#	src/ship.h
#	src/ship_cmd.cpp
#	src/smallmap_gui.cpp
#	src/spritecache.cpp
#	src/stdafx.h
#	src/strgen/strgen.cpp
#	src/strgen/strgen.h
#	src/table/settings/script_settings.ini
#	src/timetable_cmd.cpp
#	src/timetable_gui.cpp
#	src/town.h
#	src/town_cmd.cpp
#	src/town_cmd.h
#	src/town_gui.cpp
#	src/train.h
#	src/train_cmd.cpp
#	src/tree_cmd.cpp
#	src/vehicle.cpp
#	src/vehicle_base.h
#	src/vehicle_cmd.cpp
#	src/vehicle_gui.cpp
#	src/vehiclelist.cpp
#	src/waypoint_base.h
#	src/widget.cpp
This commit is contained in:
Jonathan G Rennison
2024-02-18 20:58:18 +00:00
140 changed files with 1265 additions and 582 deletions

View File

@@ -1135,6 +1135,9 @@ void Vehicle::HandlePathfindingResult(bool path_found)
DirtyVehicleListWindowForVehicle(this);
}
/* Unbunching data is no longer valid. */
this->ResetDepotUnbunching();
if (this->type == VEH_SHIP) {
SetBit(this->vehicle_flags, VF_PATHFINDER_LOST);
if (Ship::From(this)->lost_count == 255) return;
@@ -2453,7 +2456,7 @@ bool Vehicle::HandleBreakdown()
return (this->breakdown_type == BREAKDOWN_CRITICAL || this->breakdown_type == BREAKDOWN_EM_STOP);
}
FALLTHROUGH;
[[fallthrough]];
case 1:
/* Aircraft breakdowns end only when arriving at the airport */
if (this->type == VEH_AIRCRAFT) return false;
@@ -2758,12 +2761,23 @@ void VehicleEnterDepot(Vehicle *v)
* we shouldn't construct it when the vehicle visits the next stop. */
v->last_loading_station = INVALID_STATION;
ClrBit(v->vehicle_flags, VF_LAST_LOAD_ST_SEP);
/* Clear unbunching data. */
v->ResetDepotUnbunching();
/* Announce that the vehicle is waiting to players and AIs. */
if (v->owner == _local_company) {
SetDParam(0, v->index);
AddVehicleAdviceNewsItem(STR_NEWS_TRAIN_IS_WAITING + v->type, v->index);
}
AI::NewEvent(v->owner, new ScriptEventVehicleWaitingInDepot(v->index));
}
/* If we've entered our unbunching depot, record the round trip duration. */
if (v->current_order.GetDepotActionType() & ODATFB_UNBUNCH && v->unbunch_state != nullptr && v->unbunch_state->depot_unbunching_last_departure != INVALID_STATE_TICKS) {
v->unbunch_state->round_trip_time = (_state_ticks - v->unbunch_state->depot_unbunching_last_departure).AsTicks();
}
v->current_order.MakeDummy();
}
}
@@ -3767,6 +3781,88 @@ void Vehicle::HandleWaiting(bool stop_waiting, bool process_orders)
}
}
/**
* Check if the current vehicle has an unbunching order.
* @return true Iff this vehicle has an unbunching order.
*/
bool Vehicle::HasUnbunchingOrder() const
{
for (Order *o : this->Orders()) {
if (o->IsType(OT_GOTO_DEPOT) && o->GetDepotActionType() & ODATFB_UNBUNCH) return true;
}
return false;
}
/**
* Leave an unbunching depot and calculate the next departure time for shared order vehicles.
*/
void Vehicle::LeaveUnbunchingDepot()
{
if (this->unbunch_state == nullptr) this->unbunch_state.reset(new VehicleUnbunchState());
/* Set the start point for this round trip time. */
this->unbunch_state->depot_unbunching_last_departure = _state_ticks;
/* Tell the timetable we are now "on time." */
this->lateness_counter = 0;
SetWindowDirty(WC_VEHICLE_TIMETABLE, this->index);
/* Find the average travel time of vehicles that we share orders with. */
uint num_vehicles = 0;
Ticks total_travel_time = 0;
Vehicle *u = this->FirstShared();
for (; u != nullptr; u = u->NextShared()) {
/* Ignore vehicles that are manually stopped or crashed. */
if (u->vehstatus & (VS_STOPPED | VS_CRASHED)) continue;
num_vehicles++;
if (u->unbunch_state != nullptr) total_travel_time += u->unbunch_state->round_trip_time;
}
/* Make sure we cannot divide by 0. */
num_vehicles = std::max(num_vehicles, 1u);
/* Calculate the separation by finding the average travel time, then calculating equal separation (minimum 1 tick) between vehicles. */
Ticks separation = std::max((total_travel_time / num_vehicles / num_vehicles), 1u);
StateTicks next_departure = _state_ticks + separation;
/* Set the departure time of all vehicles that we share orders with. */
u = this->FirstShared();
for (; u != nullptr; u = u->NextShared()) {
/* Ignore vehicles that are manually stopped or crashed. */
if (u->vehstatus & (VS_STOPPED | VS_CRASHED)) continue;
if (u->unbunch_state == nullptr) u->unbunch_state.reset(new VehicleUnbunchState());
u->unbunch_state->depot_unbunching_next_departure = next_departure;
}
}
/**
* Check whether a vehicle inside a depot is waiting for unbunching.
* @return True if the vehicle must continue waiting, or false if it may try to leave the depot.
*/
bool Vehicle::IsWaitingForUnbunching() const
{
assert(this->IsInDepot());
/* Don't bother if there are no vehicles sharing orders. */
if (!this->IsOrderListShared()) return false;
/* Don't do anything if there aren't enough orders. */
if (this->GetNumOrders() <= 1) return false;
/*
* Make sure this is the correct depot for unbunching.
* If we are headed for the first order, we must wrap around back to the last order.
*/
bool is_first_order = (this->GetOrder(this->cur_real_order_index) == this->GetFirstOrder());
Order *previous_order = (is_first_order) ? this->GetLastOrder() : this->GetOrder(this->cur_real_order_index - 1);
if (previous_order == nullptr || !previous_order->IsType(OT_GOTO_DEPOT) || !(previous_order->GetDepotActionType() & ODATFB_UNBUNCH)) return false;
return (this->unbunch_state != nullptr) && (this->unbunch_state->depot_unbunching_next_departure > _state_ticks);
};
/**
* Send this vehicle to the depot using the given command(s).
* @param flags the command flags (like execute and such).
@@ -3803,6 +3899,9 @@ CommandCost Vehicle::SendToDepot(DoCommandFlag flags, DepotCommand command, Tile
return CMD_ERROR;
}
/* No matter why we're headed to the depot, unbunching data is no longer valid. */
if (flags & DC_EXEC) this->ResetDepotUnbunching();
auto cancel_order = [&]() {
if (flags & DC_EXEC) {
/* If the orders to 'goto depot' are in the orders list (forced servicing),
@@ -4748,6 +4847,10 @@ void AdjustVehicleStateTicksBase(StateTicksDelta delta)
for (Vehicle *v : Vehicle::Iterate()) {
if (v->timetable_start != 0) v->timetable_start += delta;
if (v->last_loading_tick != 0) v->last_loading_tick += delta;
if (v->unbunch_state != nullptr) {
if (v->unbunch_state->depot_unbunching_last_departure != INVALID_STATE_TICKS) v->unbunch_state->depot_unbunching_last_departure += delta;
if (v->unbunch_state->depot_unbunching_next_departure != INVALID_STATE_TICKS) v->unbunch_state->depot_unbunching_next_departure += delta;
}
}
for (OrderList *order_list : OrderList::Iterate()) {