Changeset - r28176:bf82dbbfec4e
[Not reviewed]
master
0 7 0
Tyler Trahan - 6 months ago 2023-11-11 13:31:27
tyler@tylertrahan.com
Codechange: Use ticks for timetable start date
7 files changed with 63 insertions and 11 deletions:
0 comments (0 inline, 0 general)
src/base_consist.h
Show inline comments
 
@@ -11,7 +11,7 @@
 
#define BASE_CONSIST_H
 

	
 
#include "order_type.h"
 
#include "timer/timer_game_calendar.h"
 
#include "timer/timer_game_tick.h"
 

	
 
/** Various front vehicle properties that are preserved when autoreplacing, using order-backup or switching front engines within a consist. */
 
struct BaseConsist {
 
@@ -20,7 +20,7 @@ struct BaseConsist {
 
	/* Used for timetabling. */
 
	uint32_t current_order_time;               ///< How many ticks have passed since this order started.
 
	int32_t lateness_counter;                  ///< How many ticks late (or early if negative) this vehicle is.
 
	TimerGameCalendar::Date timetable_start; ///< When the vehicle is supposed to start the timetable.
 
	TimerGameTick::TickCounter timetable_start; ///< At what tick of TimerGameTick::counter the vehicle should start its timetable.
 

	
 
	uint16_t service_interval;            ///< The interval for (automatic) servicing; either in days or %.
 

	
src/saveload/saveload.h
Show inline comments
 
@@ -363,6 +363,7 @@ enum SaveLoadVersion : uint16_t {
 
	SLV_CARGO_TRAVELLED,                    ///< 319  PR#11283 CargoPacket now tracks how far it travelled inside a vehicle.
 

	
 
	SLV_STATION_RATING_CHEAT,               ///< 320  PR#11346 Add cheat to fix station ratings at 100%.
 
	SLV_TIMETABLE_START_TICKS,              ///< 321  PR#11468 Convert timetable start from a date to ticks.
 

	
 
	SL_MAX_VERSION,                         ///< Highest possible saveload version
 
};
src/saveload/vehicle_sl.cpp
Show inline comments
 
@@ -17,6 +17,7 @@
 
#include "../roadveh.h"
 
#include "../ship.h"
 
#include "../aircraft.h"
 
#include "../timetable.h"
 
#include "../station_base.h"
 
#include "../effectvehicle_base.h"
 
#include "../company_base.h"
 
@@ -373,6 +374,16 @@ void AfterLoadVehicles(bool part_of_load
 
				s->rotation_y_pos = s->y_pos;
 
			}
 
		}
 

	
 
		if (IsSavegameVersionBefore(SLV_TIMETABLE_START_TICKS)) {
 
			/* Convert timetable start from a date to an absolute tick in TimerGameTick::counter. */
 
			for (Vehicle *v : Vehicle::Iterate()) {
 
				/* If the start date is 0, the vehicle is not waiting to start and can be ignored. */
 
				if (v->timetable_start == 0) continue;
 

	
 
				v->timetable_start = GetStartTickFromDate(v->timetable_start);
 
			}
 
		}
 
	}
 

	
 
	CheckValidVehicles();
 
@@ -663,7 +674,8 @@ public:
 
		SLE_CONDVAR(Vehicle, current_order.wait_time,     SLE_UINT16,            SLV_67, SL_MAX_VERSION),
 
		SLE_CONDVAR(Vehicle, current_order.travel_time,   SLE_UINT16,            SLV_67, SL_MAX_VERSION),
 
		SLE_CONDVAR(Vehicle, current_order.max_speed,     SLE_UINT16,           SLV_174, SL_MAX_VERSION),
 
		SLE_CONDVAR(Vehicle, timetable_start,       SLE_INT32,                  SLV_129, SL_MAX_VERSION),
 
		SLE_CONDVAR(Vehicle, timetable_start,       SLE_FILE_I32 | SLE_VAR_U64, SLV_129, SLV_TIMETABLE_START_TICKS),
 
		SLE_CONDVAR(Vehicle, timetable_start,       SLE_UINT64,                 SLV_TIMETABLE_START_TICKS, SL_MAX_VERSION),
 

	
 
		SLE_CONDREF(Vehicle, orders,                REF_ORDER,                    SL_MIN_VERSION, SLV_105),
 
		SLE_CONDREF(Vehicle, orders,                REF_ORDERLIST,              SLV_105, SL_MAX_VERSION),
src/timetable.h
Show inline comments
 
@@ -16,6 +16,9 @@
 

	
 
static const TimerGameCalendar::Year MAX_TIMETABLE_START_YEARS = 15; ///< The maximum start date offset, in years.
 

	
 
TimerGameTick::TickCounter GetStartTickFromDate(TimerGameCalendar::Date start_date);
 
TimerGameCalendar::Date GetDateFromStartTick(TimerGameTick::TickCounter start_tick);
 

	
 
void ShowTimetableWindow(const Vehicle *v);
 
void UpdateVehicleTimetable(Vehicle *v, bool travelling);
 
void SetTimetableParams(int param1, int param2, TimerGameTick::Ticks ticks);
src/timetable_cmd.cpp
Show inline comments
 
@@ -22,6 +22,40 @@
 
#include "safeguards.h"
 

	
 
/**
 
 * Get the TimerGameTick::TickCounter tick of a given date.
 
 * @param start_date The date when the timetable starts.
 
 * @return The first tick of this date.
 
 */
 
TimerGameTick::TickCounter GetStartTickFromDate(TimerGameCalendar::Date start_date)
 
{
 
	/* Calculate the offset in ticks from the current date. */
 
	TimerGameTick::Ticks tick_offset = (start_date - TimerGameCalendar::date).base() * Ticks::DAY_TICKS;
 

	
 
	/* Compensate for the current date_fract. */
 
	tick_offset -= TimerGameCalendar::date_fract;
 

	
 
	/* Return the current tick plus the offset. */
 
	return TimerGameTick::counter + tick_offset;
 
}
 

	
 
/**
 
 * Get a date from a given start tick of timetable.
 
 * @param start_tick The TimerGameTick::TickCounter when the timetable starts.
 
 * @return The date when we reach this tick.
 
 */
 
TimerGameCalendar::Date GetDateFromStartTick(TimerGameTick::TickCounter start_tick)
 
{
 
	/* Calculate the offset in ticks from the current counter tick. */
 
	TimerGameTick::Ticks tick_offset = start_tick - TimerGameTick::counter;
 

	
 
	/* Compensate for the current date_fract. */
 
	tick_offset += TimerGameCalendar::date_fract;
 

	
 
	/* Return the current date plus the offset in days. */
 
	return TimerGameCalendar::date + (tick_offset / Ticks::DAY_TICKS);
 
}
 

	
 
/**
 
 * Change/update a particular timetable entry.
 
 * @param v            The vehicle to change the timetable of.
 
 * @param order_number The index of the timetable in the order list.
 
@@ -300,10 +334,10 @@ static bool VehicleTimetableSorter(Vehic
 
 * @param flags Operation to perform.
 
 * @param veh_id Vehicle ID.
 
 * @param timetable_all Set to set timetable start for all vehicles sharing this order
 
 * @param start_date The timetable start date.
 
 * @param start_tick The TimerGameTick::counter tick when the timetable starts.
 
 * @return The error or cost of the operation.
 
 */
 
CommandCost CmdSetTimetableStart(DoCommandFlag flags, VehicleID veh_id, bool timetable_all, TimerGameCalendar::Date start_date)
 
CommandCost CmdSetTimetableStart(DoCommandFlag flags, VehicleID veh_id, bool timetable_all, TimerGameTick::TickCounter start_tick)
 
{
 
	Vehicle *v = Vehicle::GetIfValid(veh_id);
 
	if (v == nullptr || !v->IsPrimaryVehicle() || v->orders == nullptr) return CMD_ERROR;
 
@@ -313,6 +347,8 @@ CommandCost CmdSetTimetableStart(DoComma
 

	
 
	TimerGameTick::Ticks total_duration = v->orders->GetTimetableTotalDuration();
 

	
 
	TimerGameCalendar::Date start_date = GetDateFromStartTick(start_tick);
 

	
 
	/* Don't let a timetable start at an invalid date. */
 
	if (start_date < 0 || start_date > CalendarTime::MAX_DATE) return CMD_ERROR;
 

	
 
@@ -351,7 +387,7 @@ CommandCost CmdSetTimetableStart(DoComma
 
			w->lateness_counter = 0;
 
			ClrBit(w->vehicle_flags, VF_TIMETABLE_STARTED);
 
			/* Do multiplication, then division to reduce rounding errors. */
 
			w->timetable_start = start_date + idx * total_duration / num_vehs / Ticks::DAY_TICKS;
 
			w->timetable_start = start_tick + (idx * total_duration / num_vehs);
 
			SetWindowDirty(WC_VEHICLE_TIMETABLE, w->index);
 
			++idx;
 
		}
 
@@ -444,7 +480,7 @@ void UpdateVehicleTimetable(Vehicle *v, 
 
		just_started = !HasBit(v->vehicle_flags, VF_TIMETABLE_STARTED);
 

	
 
		if (v->timetable_start != 0) {
 
			v->lateness_counter = (TimerGameCalendar::date - v->timetable_start).base() * Ticks::DAY_TICKS + TimerGameCalendar::date_fract;
 
			v->lateness_counter = TimerGameTick::counter - v->timetable_start;
 
			v->timetable_start = 0;
 
		}
 

	
src/timetable_cmd.h
Show inline comments
 
@@ -11,13 +11,13 @@
 
#define TIMETABLE_CMD_H
 

	
 
#include "command_type.h"
 
#include "timer/timer_game_calendar.h"
 
#include "timer/timer_game_tick.h"
 

	
 
CommandCost CmdChangeTimetable(DoCommandFlag flags, VehicleID veh, VehicleOrderID order_number, ModifyTimetableFlags mtf, uint16_t data);
 
CommandCost CmdBulkChangeTimetable(DoCommandFlag flags, VehicleID veh, ModifyTimetableFlags mtf, uint16_t data);
 
CommandCost CmdSetVehicleOnTime(DoCommandFlag flags, VehicleID veh, bool apply_to_group);
 
CommandCost CmdAutofillTimetable(DoCommandFlag flags, VehicleID veh, bool autofill, bool preserve_wait_time);
 
CommandCost CmdSetTimetableStart(DoCommandFlag flags, VehicleID veh_id, bool timetable_all, TimerGameCalendar::Date start_date);
 
CommandCost CmdSetTimetableStart(DoCommandFlag flags, VehicleID veh_id, bool timetable_all, TimerGameTick::TickCounter start_tick);
 

	
 
DEF_CMD_TRAIT(CMD_CHANGE_TIMETABLE,      CmdChangeTimetable,     0, CMDT_ROUTE_MANAGEMENT)
 
DEF_CMD_TRAIT(CMD_BULK_CHANGE_TIMETABLE, CmdBulkChangeTimetable, 0, CMDT_ROUTE_MANAGEMENT)
src/timetable_gui.cpp
Show inline comments
 
@@ -145,7 +145,7 @@ static void FillTimetableArrivalDepartur
 
 */
 
static void ChangeTimetableStartCallback(const Window *w, TimerGameCalendar::Date date, void *data)
 
{
 
	Command<CMD_SET_TIMETABLE_START>::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, (VehicleID)w->window_number, reinterpret_cast<std::uintptr_t>(data) != 0, date);
 
	Command<CMD_SET_TIMETABLE_START>::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, (VehicleID)w->window_number, reinterpret_cast<std::uintptr_t>(data) != 0, GetStartTickFromDate(date));
 
}
 

	
 

	
 
@@ -494,7 +494,7 @@ struct TimetableWindow : Window {
 
			/* We are running towards the first station so we can start the
 
			 * timetable at the given time. */
 
			SetDParam(0, STR_JUST_DATE_TINY);
 
			SetDParam(1, v->timetable_start);
 
			SetDParam(1, GetDateFromStartTick(v->timetable_start));
 
			DrawString(tr, STR_TIMETABLE_STATUS_START_AT);
 
		} else if (!HasBit(v->vehicle_flags, VF_TIMETABLE_STARTED)) {
 
			/* We aren't running on a timetable yet, so how can we be "on time"
0 comments (0 inline, 0 general)