Codechange: Move Ticks into their own class

This commit is contained in:
Tyler Trahan 2023-08-16 09:01:24 -04:00
parent 30172fc037
commit fca2b37726
34 changed files with 132 additions and 116 deletions

View File

@ -453,7 +453,7 @@ void Aircraft::OnNewDay()
if (this->running_ticks == 0) return; if (this->running_ticks == 0) return;
CommandCost cost(EXPENSES_AIRCRAFT_RUN, this->GetRunningCost() * this->running_ticks / (DAYS_IN_YEAR * DAY_TICKS)); CommandCost cost(EXPENSES_AIRCRAFT_RUN, this->GetRunningCost() * this->running_ticks / (DAYS_IN_YEAR * Ticks::DAY_TICKS));
this->profit_this_year -= cost.GetCost(); this->profit_this_year -= cost.GetCost();
this->running_ticks = 0; this->running_ticks = 0;

View File

@ -659,7 +659,7 @@ static void HandleBankruptcyTakeover(Company *c)
* number of companies. The minimum number of days in a quarter * number of companies. The minimum number of days in a quarter
* is 90: 31 in January, 28 in February and 31 in March. * is 90: 31 in January, 28 in February and 31 in March.
* Note that the company going bankrupt can't buy itself. */ * Note that the company going bankrupt can't buy itself. */
static const int TAKE_OVER_TIMEOUT = 3 * 30 * DAY_TICKS / (MAX_COMPANIES - 1); static const int TAKE_OVER_TIMEOUT = 3 * 30 * Ticks::DAY_TICKS / (MAX_COMPANIES - 1);
assert(c->bankrupt_asked != 0); assert(c->bankrupt_asked != 0);
@ -717,7 +717,7 @@ void OnTick_Companies()
} }
if (_new_competitor_timeout.HasFired() && _game_mode != GM_MENU && AI::CanStartNew()) { if (_new_competitor_timeout.HasFired() && _game_mode != GM_MENU && AI::CanStartNew()) {
int32_t timeout = _settings_game.difficulty.competitors_interval * 60 * TICKS_PER_SECOND; int32_t timeout = _settings_game.difficulty.competitors_interval * 60 * Ticks::TICKS_PER_SECOND;
/* If the interval is zero, start as many competitors as needed then check every ~10 minutes if a company went bankrupt and needs replacing. */ /* If the interval is zero, start as many competitors as needed then check every ~10 minutes if a company went bankrupt and needs replacing. */
if (timeout == 0) { if (timeout == 0) {
/* count number of competitors */ /* count number of competitors */
@ -731,7 +731,7 @@ void OnTick_Companies()
if (n++ >= _settings_game.difficulty.max_no_competitors) break; if (n++ >= _settings_game.difficulty.max_no_competitors) break;
Command<CMD_COMPANY_CTRL>::Post(CCA_NEW_AI, INVALID_COMPANY, CRR_NONE, INVALID_CLIENT_ID); Command<CMD_COMPANY_CTRL>::Post(CCA_NEW_AI, INVALID_COMPANY, CRR_NONE, INVALID_CLIENT_ID);
} }
timeout = 10 * 60 * TICKS_PER_SECOND; timeout = 10 * 60 * Ticks::TICKS_PER_SECOND;
} }
/* Randomize a bit when the AI is actually going to start; ranges from 87.5% .. 112.5% of indicated value. */ /* Randomize a bit when the AI is actually going to start; ranges from 87.5% .. 112.5% of indicated value. */
timeout += ScriptObject::GetRandomizer(OWNER_NONE).Next(timeout / 4) - timeout / 8; timeout += ScriptObject::GetRandomizer(OWNER_NONE).Next(timeout / 4) - timeout / 8;

View File

@ -12,31 +12,12 @@
#include "timer/timer_game_calendar.h" #include "timer/timer_game_calendar.h"
typedef int32_t Ticks; ///< The type to store ticks in
/**
* 1 day is 74 ticks; TimerGameCalendar::date_fract used to be uint16_t and incremented by 885. On
* an overflow the new day begun and 65535 / 885 = 74.
* 1 tick is approximately 27 ms.
* 1 day is thus about 2 seconds (74 * 27 = 1998) on a machine that can run OpenTTD normally
*/
static const int DAY_TICKS = 74; ///< ticks per day
static const int DAYS_IN_YEAR = 365; ///< days per year static const int DAYS_IN_YEAR = 365; ///< days per year
static const int DAYS_IN_LEAP_YEAR = 366; ///< sometimes, you need one day more... static const int DAYS_IN_LEAP_YEAR = 366; ///< sometimes, you need one day more...
static const int MONTHS_IN_YEAR = 12; ///< months per year static const int MONTHS_IN_YEAR = 12; ///< months per year
static const int SECONDS_PER_DAY = 2; ///< approximate seconds per day, not for precise calculations static const int SECONDS_PER_DAY = 2; ///< approximate seconds per day, not for precise calculations
static const int STATION_RATING_TICKS = 185; ///< cycle duration for updating station rating
static const int STATION_ACCEPTANCE_TICKS = 250; ///< cycle duration for updating station acceptance
static const int STATION_LINKGRAPH_TICKS = 504; ///< cycle duration for cleaning dead links
static const int CARGO_AGING_TICKS = 185; ///< cycle duration for aging cargo
static const int INDUSTRY_PRODUCE_TICKS = 256; ///< cycle duration for industry production
static const int TOWN_GROWTH_TICKS = 70; ///< cycle duration for towns trying to grow. (this originates from the size of the town array in TTD
static const int INDUSTRY_CUT_TREE_TICKS = INDUSTRY_PRODUCE_TICKS * 2; ///< cycle duration for lumber mill's extra action
/* /*
* ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR and DAYS_TILL_ORIGINAL_BASE_YEAR are * ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR and DAYS_TILL_ORIGINAL_BASE_YEAR are
* primarily used for loading newgrf and savegame data and returning some * primarily used for loading newgrf and savegame data and returning some
@ -98,6 +79,5 @@ static constexpr TimerGameCalendar::Date MAX_DATE = DateAtStartOfYear(MAX_YEAR +
static constexpr TimerGameCalendar::Year INVALID_YEAR = -1; ///< Representation of an invalid year static constexpr TimerGameCalendar::Year INVALID_YEAR = -1; ///< Representation of an invalid year
static constexpr TimerGameCalendar::Date INVALID_DATE = -1; ///< Representation of an invalid date static constexpr TimerGameCalendar::Date INVALID_DATE = -1; ///< Representation of an invalid date
static constexpr Ticks INVALID_TICKS = -1; ///< Representation of an invalid number of ticks
#endif /* DATE_TYPE_H */ #endif /* DATE_TYPE_H */

View File

@ -30,6 +30,7 @@
#include "error.h" #include "error.h"
#include "engine_base.h" #include "engine_base.h"
#include "timer/timer.h" #include "timer/timer.h"
#include "timer/timer_game_tick.h"
#include "timer/timer_game_calendar.h" #include "timer/timer_game_calendar.h"
#include "table/strings.h" #include "table/strings.h"
@ -94,7 +95,7 @@ Engine::Engine(VehicleType type, EngineID base)
default: break; // The aircraft, disasters and especially visual effects have no NewGRF configured visual effects default: break; // The aircraft, disasters and especially visual effects have no NewGRF configured visual effects
} }
/* Set cargo aging period to the default value. */ /* Set cargo aging period to the default value. */
this->info.cargo_age_period = CARGO_AGING_TICKS; this->info.cargo_age_period = Ticks::CARGO_AGING_TICKS;
/* Not a variant */ /* Not a variant */
this->info.variant_id = INVALID_ENGINE; this->info.variant_id = INVALID_ENGINE;
return; return;

View File

@ -22,6 +22,7 @@
#include "currency.h" #include "currency.h"
#include "timer/timer.h" #include "timer/timer.h"
#include "timer/timer_window.h" #include "timer/timer_window.h"
#include "timer/timer_game_tick.h"
#include "timer/timer_game_calendar.h" #include "timer/timer_game_calendar.h"
#include "zoom_func.h" #include "zoom_func.h"
@ -1130,7 +1131,7 @@ struct PerformanceRatingDetailWindow : Window {
UpdateCompanyRatingAndValue(c, false); UpdateCompanyRatingAndValue(c, false);
} }
this->timeout = DAY_TICKS * 5; this->timeout = Ticks::DAY_TICKS * 5;
} }
uint score_info_left; uint score_info_left;

View File

@ -1155,7 +1155,7 @@ static void ProduceIndustryGoods(Industry *i)
i->counter--; i->counter--;
/* produce some cargo */ /* produce some cargo */
if ((i->counter % INDUSTRY_PRODUCE_TICKS) == 0) { if ((i->counter % Ticks::INDUSTRY_PRODUCE_TICKS) == 0) {
if (HasBit(indsp->callback_mask, CBM_IND_PRODUCTION_256_TICKS)) IndustryProductionCallback(i, 1); if (HasBit(indsp->callback_mask, CBM_IND_PRODUCTION_256_TICKS)) IndustryProductionCallback(i, 1);
IndustryBehaviour indbehav = indsp->behaviour; IndustryBehaviour indbehav = indsp->behaviour;
@ -1188,7 +1188,7 @@ static void ProduceIndustryGoods(Industry *i)
if (cb_res != CALLBACK_FAILED) { if (cb_res != CALLBACK_FAILED) {
cut = ConvertBooleanCallback(indsp->grf_prop.grffile, CBID_INDUSTRY_SPECIAL_EFFECT, cb_res); cut = ConvertBooleanCallback(indsp->grf_prop.grffile, CBID_INDUSTRY_SPECIAL_EFFECT, cb_res);
} else { } else {
cut = ((i->counter % INDUSTRY_CUT_TREE_TICKS) == 0); cut = ((i->counter % Ticks::INDUSTRY_CUT_TREE_TICKS) == 0);
} }
if (cut) ChopLumberMillTrees(i); if (cut) ChopLumberMillTrees(i);

View File

@ -12,6 +12,7 @@
#include "../window_func.h" #include "../window_func.h"
#include "../company_base.h" #include "../company_base.h"
#include "../company_gui.h" #include "../company_gui.h"
#include "../timer/timer_game_tick.h"
#include "../timer/timer_game_calendar.h" #include "../timer/timer_game_calendar.h"
#include "../viewport_func.h" #include "../viewport_func.h"
#include "../zoom_func.h" #include "../zoom_func.h"
@ -221,7 +222,7 @@ void LinkGraphOverlay::AddLinks(const Station *from, const Station *to)
ConstEdge &edge = lg[ge.node][to->goods[c].node]; ConstEdge &edge = lg[ge.node][to->goods[c].node];
this->AddStats(c, lg.Monthly(edge.capacity), lg.Monthly(edge.usage), this->AddStats(c, lg.Monthly(edge.capacity), lg.Monthly(edge.usage),
ge.flows.GetFlowVia(to->index), ge.flows.GetFlowVia(to->index),
edge.TravelTime() / DAY_TICKS, edge.TravelTime() / Ticks::DAY_TICKS,
from->owner == OWNER_NONE || to->owner == OWNER_NONE, from->owner == OWNER_NONE || to->owner == OWNER_NONE,
this->cached_links[from->index][to->index]); this->cached_links[from->index][to->index]);
} }

View File

@ -2,6 +2,7 @@
#include "../stdafx.h" #include "../stdafx.h"
#include "../core/math_func.hpp" #include "../core/math_func.hpp"
#include "../timer/timer_game_tick.h"
#include "mcf.h" #include "mcf.h"
#include "../safeguards.h" #include "../safeguards.h"
@ -290,7 +291,7 @@ void MultiCommodityFlow::Dijkstra(NodeID source_node, PathVector &paths)
IsCargoInClass(this->job.Cargo(), CC_EXPRESS); IsCargoInClass(this->job.Cargo(), CC_EXPRESS);
uint distance = DistanceMaxPlusManhattan(this->job[from].base.xy, this->job[to].base.xy) + 1; uint distance = DistanceMaxPlusManhattan(this->job[from].base.xy, this->job[to].base.xy) + 1;
/* Compute a default travel time from the distance and an average speed of 1 tile/day. */ /* Compute a default travel time from the distance and an average speed of 1 tile/day. */
uint time = (edge.base.TravelTime() != 0) ? edge.base.TravelTime() + DAY_TICKS : distance * DAY_TICKS; uint time = (edge.base.TravelTime() != 0) ? edge.base.TravelTime() + Ticks::DAY_TICKS : distance * Ticks::DAY_TICKS;
uint distance_anno = express ? time : distance; uint distance_anno = express ? time : distance;
Tannotation *dest = static_cast<Tannotation *>(paths[to]); Tannotation *dest = static_cast<Tannotation *>(paths[to]);

View File

@ -234,7 +234,7 @@ void LinkRefresher::RefreshStats(const Order *cur, const Order *next)
if (this->is_full_loading && this->vehicle->orders != nullptr && if (this->is_full_loading && this->vehicle->orders != nullptr &&
st->index == vehicle->last_station_visited && st->index == vehicle->last_station_visited &&
this->vehicle->orders->GetTotalDuration() > this->vehicle->orders->GetTotalDuration() >
(Ticks)this->vehicle->current_order_time) { (TimerGameTick::Ticks)this->vehicle->current_order_time) {
uint effective_capacity = cargo_quantity * this->vehicle->load_unload_ticks; uint effective_capacity = cargo_quantity * this->vehicle->load_unload_ticks;
if (effective_capacity > (uint)this->vehicle->orders->GetTotalDuration()) { if (effective_capacity > (uint)this->vehicle->orders->GetTotalDuration()) {
IncreaseStats(st, c, next_station, effective_capacity / IncreaseStats(st, c, next_station, effective_capacity /

View File

@ -573,7 +573,7 @@ void ShowCostOrIncomeAnimation(int x, int y, int z, Money cost)
msg = STR_INCOME_FLOAT_INCOME; msg = STR_INCOME_FLOAT_INCOME;
} }
SetDParam(0, cost); SetDParam(0, cost);
AddTextEffect(msg, pt.x, pt.y, DAY_TICKS, TE_RISING); AddTextEffect(msg, pt.x, pt.y, Ticks::DAY_TICKS, TE_RISING);
} }
/** /**
@ -590,7 +590,7 @@ void ShowFeederIncomeAnimation(int x, int y, int z, Money transfer, Money income
SetDParam(0, transfer); SetDParam(0, transfer);
if (income == 0) { if (income == 0) {
AddTextEffect(STR_FEEDER, pt.x, pt.y, DAY_TICKS, TE_RISING); AddTextEffect(STR_FEEDER, pt.x, pt.y, Ticks::DAY_TICKS, TE_RISING);
} else { } else {
StringID msg = STR_FEEDER_COST; StringID msg = STR_FEEDER_COST;
if (income < 0) { if (income < 0) {
@ -598,7 +598,7 @@ void ShowFeederIncomeAnimation(int x, int y, int z, Money transfer, Money income
msg = STR_FEEDER_INCOME; msg = STR_FEEDER_INCOME;
} }
SetDParam(1, income); SetDParam(1, income);
AddTextEffect(msg, pt.x, pt.y, DAY_TICKS, TE_RISING); AddTextEffect(msg, pt.x, pt.y, Ticks::DAY_TICKS, TE_RISING);
} }
} }

View File

@ -11,6 +11,7 @@
#include "../strings_func.h" #include "../strings_func.h"
#include "../command_func.h" #include "../command_func.h"
#include "../timer/timer_game_tick.h"
#include "../timer/timer_game_calendar.h" #include "../timer/timer_game_calendar.h"
#include "network_admin.h" #include "network_admin.h"
#include "network_client.h" #include "network_client.h"
@ -274,8 +275,8 @@ uint NetworkCalculateLag(const NetworkClientSocket *cs)
/* This client has missed their ACK packet after 1 DAY_TICKS.. /* This client has missed their ACK packet after 1 DAY_TICKS..
* so we increase their lag for every frame that passes! * so we increase their lag for every frame that passes!
* The packet can be out by a max of _net_frame_freq */ * The packet can be out by a max of _net_frame_freq */
if (cs->last_frame_server + DAY_TICKS + _settings_client.network.frame_freq < _frame_counter) { if (cs->last_frame_server + Ticks::DAY_TICKS + _settings_client.network.frame_freq < _frame_counter) {
lag += _frame_counter - (cs->last_frame_server + DAY_TICKS + _settings_client.network.frame_freq); lag += _frame_counter - (cs->last_frame_server + Ticks::DAY_TICKS + _settings_client.network.frame_freq);
} }
return lag; return lag;
} }

View File

@ -20,6 +20,7 @@
#include "../company_gui.h" #include "../company_gui.h"
#include "../company_cmd.h" #include "../company_cmd.h"
#include "../core/random_func.hpp" #include "../core/random_func.hpp"
#include "../timer/timer_game_tick.h"
#include "../timer/timer_game_calendar.h" #include "../timer/timer_game_calendar.h"
#include "../gfx_func.h" #include "../gfx_func.h"
#include "../error.h" #include "../error.h"
@ -876,7 +877,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_FRAME(Packet *p
/* Let the server know that we received this frame correctly /* Let the server know that we received this frame correctly
* We do this only once per day, to save some bandwidth ;) */ * We do this only once per day, to save some bandwidth ;) */
if (!_network_first_time && last_ack_frame < _frame_counter) { if (!_network_first_time && last_ack_frame < _frame_counter) {
last_ack_frame = _frame_counter + DAY_TICKS; last_ack_frame = _frame_counter + Ticks::DAY_TICKS;
Debug(net, 7, "Sent ACK at {}", _frame_counter); Debug(net, 7, "Sent ACK at {}", _frame_counter);
SendAck(); SendAck();
} }

View File

@ -1141,7 +1141,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_ACK(Packet *p)
/* The client is trying to catch up with the server */ /* The client is trying to catch up with the server */
if (this->status == STATUS_PRE_ACTIVE) { if (this->status == STATUS_PRE_ACTIVE) {
/* The client is not yet caught up? */ /* The client is not yet caught up? */
if (frame + DAY_TICKS < _frame_counter) return NETWORK_RECV_STATUS_OKAY; if (frame + Ticks::DAY_TICKS < _frame_counter) return NETWORK_RECV_STATUS_OKAY;
/* Now it is! Unpause the game */ /* Now it is! Unpause the game */
this->status = STATUS_ACTIVE; this->status = STATUS_ACTIVE;
@ -1724,7 +1724,7 @@ void NetworkServer_Tick(bool send_frame)
* did not receive a packet, then the client is not just * did not receive a packet, then the client is not just
* slow, but the connection is likely severed. Mentioning * slow, but the connection is likely severed. Mentioning
* frame_freq is not useful in this case. */ * frame_freq is not useful in this case. */
if (lag > (uint)DAY_TICKS && cs->lag_test == 0 && cs->last_packet + std::chrono::seconds(2) > std::chrono::steady_clock::now()) { if (lag > (uint)Ticks::DAY_TICKS && cs->lag_test == 0 && cs->last_packet + std::chrono::seconds(2) > std::chrono::steady_clock::now()) {
IConsolePrint(CC_WARNING, "[{}] Client #{} is slow, try increasing [network.]frame_freq to a higher value!", _frame_counter, cs->client_id); IConsolePrint(CC_WARNING, "[{}] Client #{} is slow, try increasing [network.]frame_freq to a higher value!", _frame_counter, cs->client_id);
cs->lag_test = 1; cs->lag_test = 1;
} }

View File

@ -11,6 +11,7 @@
#include "debug.h" #include "debug.h"
#include "town.h" #include "town.h"
#include "newgrf_town.h" #include "newgrf_town.h"
#include "timer/timer_game_tick.h"
#include "safeguards.h" #include "safeguards.h"
@ -47,7 +48,7 @@
case 0x81: return GB(static_cast<uint32_t>(this->t->xy), 8, 8); case 0x81: return GB(static_cast<uint32_t>(this->t->xy), 8, 8);
case 0x82: return ClampTo<uint16_t>(this->t->cache.population); case 0x82: return ClampTo<uint16_t>(this->t->cache.population);
case 0x83: return GB(ClampTo<uint16_t>(this->t->cache.population), 8, 8); case 0x83: return GB(ClampTo<uint16_t>(this->t->cache.population), 8, 8);
case 0x8A: return this->t->grow_counter / TOWN_GROWTH_TICKS; case 0x8A: return this->t->grow_counter / Ticks::TOWN_GROWTH_TICKS;
case 0x92: return this->t->flags; // In original game, 0x92 and 0x93 are really one word. Since flags is a byte, this is to adjust case 0x92: return this->t->flags; // In original game, 0x92 and 0x93 are really one word. Since flags is a byte, this is to adjust
case 0x93: return 0; case 0x93: return 0;
case 0x94: return ClampTo<uint16_t>(this->t->cache.squared_town_zone_radius[0]); case 0x94: return ClampTo<uint16_t>(this->t->cache.squared_town_zone_radius[0]);
@ -79,7 +80,7 @@
case 0xAE: return this->t->have_ratings; case 0xAE: return this->t->have_ratings;
case 0xB2: return this->t->statues; case 0xB2: return this->t->statues;
case 0xB6: return ClampTo<uint16_t>(this->t->cache.num_houses); case 0xB6: return ClampTo<uint16_t>(this->t->cache.num_houses);
case 0xB9: return this->t->growth_rate / TOWN_GROWTH_TICKS; case 0xB9: return this->t->growth_rate / Ticks::TOWN_GROWTH_TICKS;
case 0xBA: return ClampTo<uint16_t>(this->t->supplied[CT_PASSENGERS].new_max); case 0xBA: return ClampTo<uint16_t>(this->t->supplied[CT_PASSENGERS].new_max);
case 0xBB: return GB(ClampTo<uint16_t>(this->t->supplied[CT_PASSENGERS].new_max), 8, 8); case 0xBB: return GB(ClampTo<uint16_t>(this->t->supplied[CT_PASSENGERS].new_max), 8, 8);
case 0xBC: return ClampTo<uint16_t>(this->t->supplied[CT_MAIL].new_max); case 0xBC: return ClampTo<uint16_t>(this->t->supplied[CT_MAIL].new_max);

View File

@ -17,6 +17,7 @@
#include "depot_type.h" #include "depot_type.h"
#include "station_type.h" #include "station_type.h"
#include "vehicle_type.h" #include "vehicle_type.h"
#include "timer/timer_game_tick.h"
#include "date_type.h" #include "date_type.h"
#include "saveload/saveload.h" #include "saveload/saveload.h"
@ -268,8 +269,8 @@ private:
uint num_vehicles; ///< NOSAVE: Number of vehicles that share this order list. uint num_vehicles; ///< NOSAVE: Number of vehicles that share this order list.
Vehicle *first_shared; ///< NOSAVE: pointer to the first vehicle in the shared order chain. Vehicle *first_shared; ///< NOSAVE: pointer to the first vehicle in the shared order chain.
Ticks timetable_duration; ///< NOSAVE: Total timetabled duration of the order list. TimerGameTick::Ticks timetable_duration; ///< NOSAVE: Total timetabled duration of the order list.
Ticks total_duration; ///< NOSAVE: Total (timetabled or not) duration of the order list. TimerGameTick::Ticks total_duration; ///< NOSAVE: Total (timetabled or not) duration of the order list.
public: public:
/** Default constructor producing an invalid order list. */ /** Default constructor producing an invalid order list. */
@ -366,34 +367,34 @@ public:
bool IsCompleteTimetable() const; bool IsCompleteTimetable() const;
/** /**
* Gets the total duration of the vehicles timetable or INVALID_TICKS is the timetable is not complete. * Gets the total duration of the vehicles timetable or Tick::INVALID_TICKS is the timetable is not complete.
* @return total timetable duration or INVALID_TICKS for incomplete timetables * @return total timetable duration or Tick::INVALID_TICKS for incomplete timetables
*/ */
inline Ticks GetTimetableTotalDuration() const { return this->IsCompleteTimetable() ? this->timetable_duration : INVALID_TICKS; } inline TimerGameTick::Ticks GetTimetableTotalDuration() const { return this->IsCompleteTimetable() ? this->timetable_duration : Ticks::INVALID_TICKS; }
/** /**
* Gets the known duration of the vehicles timetable even if the timetable is not complete. * Gets the known duration of the vehicles timetable even if the timetable is not complete.
* @return known timetable duration * @return known timetable duration
*/ */
inline Ticks GetTimetableDurationIncomplete() const { return this->timetable_duration; } inline TimerGameTick::Ticks GetTimetableDurationIncomplete() const { return this->timetable_duration; }
/** /**
* Gets the known duration of the vehicles orders, timetabled or not. * Gets the known duration of the vehicles orders, timetabled or not.
* @return known order duration. * @return known order duration.
*/ */
inline Ticks GetTotalDuration() const { return this->total_duration; } inline TimerGameTick::Ticks GetTotalDuration() const { return this->total_duration; }
/** /**
* Must be called if an order's timetable is changed to update internal book keeping. * Must be called if an order's timetable is changed to update internal book keeping.
* @param delta By how many ticks has the timetable duration changed * @param delta By how many ticks has the timetable duration changed
*/ */
void UpdateTimetableDuration(Ticks delta) { this->timetable_duration += delta; } void UpdateTimetableDuration(TimerGameTick::Ticks delta) { this->timetable_duration += delta; }
/** /**
* Must be called if an order's timetable is changed to update internal book keeping. * Must be called if an order's timetable is changed to update internal book keeping.
* @param delta By how many ticks has the total duration changed * @param delta By how many ticks has the total duration changed
*/ */
void UpdateTotalDuration(Ticks delta) { this->total_duration += delta; } void UpdateTotalDuration(TimerGameTick::Ticks delta) { this->total_duration += delta; }
void FreeChain(bool keep_orderlist = false); void FreeChain(bool keep_orderlist = false);

View File

@ -619,8 +619,8 @@ void OrderList::DebugCheckSanity() const
VehicleOrderID check_num_orders = 0; VehicleOrderID check_num_orders = 0;
VehicleOrderID check_num_manual_orders = 0; VehicleOrderID check_num_manual_orders = 0;
uint check_num_vehicles = 0; uint check_num_vehicles = 0;
Ticks check_timetable_duration = 0; TimerGameTick::Ticks check_timetable_duration = 0;
Ticks check_total_duration = 0; TimerGameTick::Ticks check_total_duration = 0;
Debug(misc, 6, "Checking OrderList {} for sanity...", this->index); Debug(misc, 6, "Checking OrderList {} for sanity...", this->index);

View File

@ -1720,7 +1720,7 @@ void RoadVehicle::OnNewDay()
if (this->running_ticks == 0) return; if (this->running_ticks == 0) return;
CommandCost cost(EXPENSES_ROADVEH_RUN, this->GetRunningCost() * this->running_ticks / (DAYS_IN_YEAR * DAY_TICKS)); CommandCost cost(EXPENSES_ROADVEH_RUN, this->GetRunningCost() * this->running_ticks / (DAYS_IN_YEAR * Ticks::DAY_TICKS));
this->profit_this_year -= cost.GetCost(); this->profit_this_year -= cost.GetCost();
this->running_ticks = 0; this->running_ticks = 0;

View File

@ -727,7 +727,7 @@ bool AfterLoadGame()
} }
/* The value of TimerGameCalendar::date_fract got divided, so make sure that old games are converted correctly. */ /* The value of TimerGameCalendar::date_fract got divided, so make sure that old games are converted correctly. */
if (IsSavegameVersionBefore(SLV_11, 1) || (IsSavegameVersionBefore(SLV_147) && TimerGameCalendar::date_fract > DAY_TICKS)) TimerGameCalendar::date_fract /= 885; if (IsSavegameVersionBefore(SLV_11, 1) || (IsSavegameVersionBefore(SLV_147) && TimerGameCalendar::date_fract > Ticks::DAY_TICKS)) TimerGameCalendar::date_fract /= 885;
/* Update current year /* Update current year
* must be done before loading sprites as some newgrfs check it */ * must be done before loading sprites as some newgrfs check it */
@ -2999,7 +2999,7 @@ bool AfterLoadGame()
t->growth_rate = TownTicksToGameTicks(t->growth_rate & ~0x8000); t->growth_rate = TownTicksToGameTicks(t->growth_rate & ~0x8000);
} }
/* Add t->index % TOWN_GROWTH_TICKS to spread growth across ticks. */ /* Add t->index % TOWN_GROWTH_TICKS to spread growth across ticks. */
t->grow_counter = TownTicksToGameTicks(t->grow_counter) + t->index % TOWN_GROWTH_TICKS; t->grow_counter = TownTicksToGameTicks(t->grow_counter) + t->index % Ticks::TOWN_GROWTH_TICKS;
} }
} }

View File

@ -171,9 +171,9 @@
break; break;
default: default:
EnforcePrecondition(false, (days_between_town_growth * DAY_TICKS / TOWN_GROWTH_TICKS) <= MAX_TOWN_GROWTH_TICKS); EnforcePrecondition(false, (days_between_town_growth * ::Ticks::DAY_TICKS / ::Ticks::TOWN_GROWTH_TICKS) <= MAX_TOWN_GROWTH_TICKS);
/* Don't use growth_rate 0 as it means GROWTH_NORMAL */ /* Don't use growth_rate 0 as it means GROWTH_NORMAL */
growth_rate = std::max<SQInteger>(days_between_town_growth * DAY_TICKS, 2u) - 1; growth_rate = std::max<SQInteger>(days_between_town_growth * ::Ticks::DAY_TICKS, 2u) - 1;
break; break;
} }
@ -188,7 +188,7 @@
if (t->growth_rate == TOWN_GROWTH_RATE_NONE) return TOWN_GROWTH_NONE; if (t->growth_rate == TOWN_GROWTH_RATE_NONE) return TOWN_GROWTH_NONE;
return RoundDivSU(t->growth_rate + 1, DAY_TICKS); return RoundDivSU(t->growth_rate + 1, ::Ticks::DAY_TICKS);
} }
/* static */ SQInteger ScriptTown::GetDistanceManhattanToTile(TownID town_id, TileIndex tile) /* static */ SQInteger ScriptTown::GetDistanceManhattanToTile(TownID town_id, TileIndex tile)

View File

@ -236,7 +236,7 @@ void Ship::OnNewDay()
if (this->running_ticks == 0) return; if (this->running_ticks == 0) return;
CommandCost cost(EXPENSES_SHIP_RUN, this->GetRunningCost() * this->running_ticks / (DAYS_IN_YEAR * DAY_TICKS)); CommandCost cost(EXPENSES_SHIP_RUN, this->GetRunningCost() * this->running_ticks / (DAYS_IN_YEAR * Ticks::DAY_TICKS));
this->profit_this_year -= cost.GetCost(); this->profit_this_year -= cost.GetCost();
this->running_ticks = 0; this->running_ticks = 0;

View File

@ -14,6 +14,7 @@
#include "core/bitmath_func.hpp" #include "core/bitmath_func.hpp"
#include "core/mem_func.hpp" #include "core/mem_func.hpp"
#include "date_type.h" #include "date_type.h"
#include "timer/timer_game_tick.h"
/** Flags of the sort list. */ /** Flags of the sort list. */
enum SortListFlags { enum SortListFlags {
@ -72,7 +73,7 @@ protected:
void ResetResortTimer() void ResetResortTimer()
{ {
/* Resort every 10 days */ /* Resort every 10 days */
this->resort_timer = DAY_TICKS * 10; this->resort_timer = Ticks::DAY_TICKS * 10;
} }
public: public:

View File

@ -3964,7 +3964,7 @@ static void StationHandleSmallTick(BaseStation *st)
if ((st->facilities & FACIL_WAYPOINT) != 0 || !st->IsInUse()) return; if ((st->facilities & FACIL_WAYPOINT) != 0 || !st->IsInUse()) return;
byte b = st->delete_ctr + 1; byte b = st->delete_ctr + 1;
if (b >= STATION_RATING_TICKS) b = 0; if (b >= Ticks::STATION_RATING_TICKS) b = 0;
st->delete_ctr = b; st->delete_ctr = b;
if (b == 0) UpdateStationRating(Station::From(st)); if (b == 0) UpdateStationRating(Station::From(st));
@ -3978,18 +3978,18 @@ void OnTick_Station()
StationHandleSmallTick(st); StationHandleSmallTick(st);
/* Clean up the link graph about once a week. */ /* Clean up the link graph about once a week. */
if (Station::IsExpected(st) && (TimerGameTick::counter + st->index) % STATION_LINKGRAPH_TICKS == 0) { if (Station::IsExpected(st) && (TimerGameTick::counter + st->index) % Ticks::STATION_LINKGRAPH_TICKS == 0) {
DeleteStaleLinks(Station::From(st)); DeleteStaleLinks(Station::From(st));
}; };
/* Spread out big-tick over STATION_ACCEPTANCE_TICKS ticks. */ /* Spread out big-tick over STATION_ACCEPTANCE_TICKS ticks. */
if ((TimerGameTick::counter + st->index) % STATION_ACCEPTANCE_TICKS == 0) { if ((TimerGameTick::counter + st->index) % Ticks::STATION_ACCEPTANCE_TICKS == 0) {
/* Stop processing this station if it was deleted */ /* Stop processing this station if it was deleted */
if (!StationHandleBigTick(st)) continue; if (!StationHandleBigTick(st)) continue;
} }
/* Spread out station animation over STATION_ACCEPTANCE_TICKS ticks. */ /* Spread out station animation over STATION_ACCEPTANCE_TICKS ticks. */
if ((TimerGameTick::counter + st->index) % STATION_ACCEPTANCE_TICKS == 0) { if ((TimerGameTick::counter + st->index) % Ticks::STATION_ACCEPTANCE_TICKS == 0) {
TriggerStationAnimation(st, st->xy, SAT_250_TICKS); TriggerStationAnimation(st, st->xy, SAT_250_TICKS);
TriggerRoadStopAnimation(st, st->xy, SAT_250_TICKS); TriggerRoadStopAnimation(st, st->xy, SAT_250_TICKS);
if (Station::IsExpected(st)) AirportAnimationTrigger(Station::From(st), AAT_STATION_250_TICKS); if (Station::IsExpected(st)) AirportAnimationTrigger(Station::From(st), AAT_STATION_250_TICKS);

View File

@ -24,7 +24,7 @@
* @param f Bitmask of the climates * @param f Bitmask of the climates
* @note the 5 between b and f is the load amount * @note the 5 between b and f is the load amount
*/ */
#define MT(a, b, c, d, e, f) { DAYS_TILL_ORIGINAL_BASE_YEAR + a, c, d, b, 5, f, e, 0, 8, 0, 0, 0, STR_EMPTY, CARGO_AGING_TICKS, INVALID_ENGINE, ExtraEngineFlags::None } #define MT(a, b, c, d, e, f) { DAYS_TILL_ORIGINAL_BASE_YEAR + a, c, d, b, 5, f, e, 0, 8, 0, 0, 0, STR_EMPTY, Ticks::CARGO_AGING_TICKS, INVALID_ENGINE, ExtraEngineFlags::None }
/** /**
* Writes the properties of a multiple-unit train into the EngineInfo struct. * Writes the properties of a multiple-unit train into the EngineInfo struct.
@ -37,7 +37,7 @@
* @param f Bitmask of the climates * @param f Bitmask of the climates
* @note the 5 between b and f is the load amount * @note the 5 between b and f is the load amount
*/ */
#define MM(a, b, c, d, e, f) { DAYS_TILL_ORIGINAL_BASE_YEAR + a, c, d, b, 5, f, e, 0, 8, 1 << EF_RAIL_IS_MU, 0, 0, STR_EMPTY, CARGO_AGING_TICKS, INVALID_ENGINE, ExtraEngineFlags::None } #define MM(a, b, c, d, e, f) { DAYS_TILL_ORIGINAL_BASE_YEAR + a, c, d, b, 5, f, e, 0, 8, 1 << EF_RAIL_IS_MU, 0, 0, STR_EMPTY, Tick::CARGO_AGING_TICKS, INVALID_ENGINE, ExtraEngineFlags::None }
/** /**
* Writes the properties of a train carriage into the EngineInfo struct. * Writes the properties of a train carriage into the EngineInfo struct.
@ -50,7 +50,7 @@
* @see MT * @see MT
* @note the 5 between b and f is the load amount * @note the 5 between b and f is the load amount
*/ */
#define MW(a, b, c, d, e, f) { DAYS_TILL_ORIGINAL_BASE_YEAR + a, c, d, b, 5, f, e, 0, 8, 0, 0, 0, STR_EMPTY, CARGO_AGING_TICKS, INVALID_ENGINE, ExtraEngineFlags::None } #define MW(a, b, c, d, e, f) { DAYS_TILL_ORIGINAL_BASE_YEAR + a, c, d, b, 5, f, e, 0, 8, 0, 0, 0, STR_EMPTY, Tick::CARGO_AGING_TICKS, INVALID_ENGINE, ExtraEngineFlags::None }
/** /**
* Writes the properties of a road vehicle into the EngineInfo struct. * Writes the properties of a road vehicle into the EngineInfo struct.
@ -63,7 +63,7 @@
* @param f Bitmask of the climates * @param f Bitmask of the climates
* @note the 5 between b and f is the load amount * @note the 5 between b and f is the load amount
*/ */
#define MR(a, b, c, d, e, f) { DAYS_TILL_ORIGINAL_BASE_YEAR + a, c, d, b, 5, f, e, 0, 8, 0, 0, 0, STR_EMPTY, CARGO_AGING_TICKS, INVALID_ENGINE, ExtraEngineFlags::None } #define MR(a, b, c, d, e, f) { DAYS_TILL_ORIGINAL_BASE_YEAR + a, c, d, b, 5, f, e, 0, 8, 0, 0, 0, STR_EMPTY, Tick::CARGO_AGING_TICKS, INVALID_ENGINE, ExtraEngineFlags::None }
/** /**
* Writes the properties of a ship into the EngineInfo struct. * Writes the properties of a ship into the EngineInfo struct.
@ -75,7 +75,7 @@
* @param f Bitmask of the climates * @param f Bitmask of the climates
* @note the 10 between b and f is the load amount * @note the 10 between b and f is the load amount
*/ */
#define MS(a, b, c, d, e, f) { DAYS_TILL_ORIGINAL_BASE_YEAR + a, c, d, b, 10, f, e, 0, 8, 0, 0, 0, STR_EMPTY, CARGO_AGING_TICKS, INVALID_ENGINE, ExtraEngineFlags::None } #define MS(a, b, c, d, e, f) { DAYS_TILL_ORIGINAL_BASE_YEAR + a, c, d, b, 10, f, e, 0, 8, 0, 0, 0, STR_EMPTY, Tick::CARGO_AGING_TICKS, INVALID_ENGINE, ExtraEngineFlags::None }
/** /**
* Writes the properties of an aeroplane into the EngineInfo struct. * Writes the properties of an aeroplane into the EngineInfo struct.
@ -86,7 +86,7 @@
* @param e Bitmask of the climates * @param e Bitmask of the climates
* @note the 20 between b and e is the load amount * @note the 20 between b and e is the load amount
*/ */
#define MA(a, b, c, d, e) { DAYS_TILL_ORIGINAL_BASE_YEAR + a, c, d, b, 20, e, CT_INVALID, 0, 8, 0, 0, 0, STR_EMPTY, CARGO_AGING_TICKS, INVALID_ENGINE, ExtraEngineFlags::None } #define MA(a, b, c, d, e) { DAYS_TILL_ORIGINAL_BASE_YEAR + a, c, d, b, 20, e, CT_INVALID, 0, 8, 0, 0, 0, STR_EMPTY, Tick::CARGO_AGING_TICKS, INVALID_ENGINE, ExtraEngineFlags::None }
/* Climates /* Climates
* T = Temperate * T = Temperate

View File

@ -151,7 +151,7 @@ static const uint16_t _accum_days_for_month[] = {
*/ */
/* static */ void TimerGameCalendar::SetDate(TimerGameCalendar::Date date, TimerGameCalendar::DateFract fract) /* static */ void TimerGameCalendar::SetDate(TimerGameCalendar::Date date, TimerGameCalendar::DateFract fract)
{ {
assert(fract < DAY_TICKS); assert(fract < Ticks::DAY_TICKS);
YearMonthDay ymd; YearMonthDay ymd;
@ -189,7 +189,7 @@ void TimerManager<TimerGameCalendar>::Elapsed(TimerGameCalendar::TElapsed delta)
if (_game_mode == GM_MENU) return; if (_game_mode == GM_MENU) return;
TimerGameCalendar::date_fract++; TimerGameCalendar::date_fract++;
if (TimerGameCalendar::date_fract < DAY_TICKS) return; if (TimerGameCalendar::date_fract < Ticks::DAY_TICKS) return;
TimerGameCalendar::date_fract = 0; TimerGameCalendar::date_fract = 0;
/* increase day counter */ /* increase day counter */

View File

@ -14,9 +14,6 @@
#include <chrono> #include <chrono>
/** Estimation of how many ticks fit in a single second. */
static const uint TICKS_PER_SECOND = 1000 / MILLISECONDS_PER_TICK;
/** /**
* Timer that represents the game-ticks. It will pause when the game is paused. * Timer that represents the game-ticks. It will pause when the game is paused.
* *
@ -24,6 +21,8 @@ static const uint TICKS_PER_SECOND = 1000 / MILLISECONDS_PER_TICK;
*/ */
class TimerGameTick { class TimerGameTick {
public: public:
using Ticks = int32_t; ///< The type to store ticks in
using TPeriod = uint; using TPeriod = uint;
using TElapsed = uint; using TElapsed = uint;
struct TStorage { struct TStorage {
@ -33,4 +32,28 @@ public:
static uint64_t counter; ///< Monotonic counter, in ticks, since start of game. static uint64_t counter; ///< Monotonic counter, in ticks, since start of game.
}; };
/**
* Storage class for Ticks constants.
*/
class Ticks {
public:
static constexpr TimerGameTick::Ticks INVALID_TICKS = -1; ///< Representation of an invalid number of ticks.
/**
* 1 day is 74 ticks; TimerGameCalendar::date_fract used to be uint16_t and incremented by 885. On an overflow the new day begun and 65535 / 885 = 74.
* 1 tick is approximately 27 ms.
* 1 day is thus about 2 seconds (74 * 27 = 1998) on a machine that can run OpenTTD normally
*/
static constexpr TimerGameTick::Ticks DAY_TICKS = 74; ///< ticks per day
static constexpr TimerGameTick::Ticks TICKS_PER_SECOND = 1000 / MILLISECONDS_PER_TICK; ///< Estimation of how many ticks fit in a single second.
static constexpr TimerGameTick::Ticks STATION_RATING_TICKS = 185; ///< Cycle duration for updating station rating.
static constexpr TimerGameTick::Ticks STATION_ACCEPTANCE_TICKS = 250; ///< Cycle duration for updating station acceptance.
static constexpr TimerGameTick::Ticks STATION_LINKGRAPH_TICKS = 504; ///< Cycle duration for cleaning dead links.
static constexpr TimerGameTick::Ticks CARGO_AGING_TICKS = 185; ///< Cycle duration for aging cargo.
static constexpr TimerGameTick::Ticks INDUSTRY_PRODUCE_TICKS = 256; ///< Cycle duration for industry production.
static constexpr TimerGameTick::Ticks TOWN_GROWTH_TICKS = 70; ///< Cycle duration for towns trying to grow (this originates from the size of the town array in TTD).
static constexpr TimerGameTick::Ticks INDUSTRY_CUT_TREE_TICKS = INDUSTRY_PRODUCE_TICKS * 2; ///< Cycle duration for lumber mill's extra action.
};
#endif /* TIMER_GAME_TICK_H */ #endif /* TIMER_GAME_TICK_H */

View File

@ -10,6 +10,7 @@
#ifndef TIMETABLE_H #ifndef TIMETABLE_H
#define TIMETABLE_H #define TIMETABLE_H
#include "timer/timer_game_tick.h"
#include "date_type.h" #include "date_type.h"
#include "timer/timer_game_calendar.h" #include "timer/timer_game_calendar.h"
#include "vehicle_type.h" #include "vehicle_type.h"
@ -18,6 +19,6 @@ static const TimerGameCalendar::Year MAX_TIMETABLE_START_YEARS = 15; ///< The ma
void ShowTimetableWindow(const Vehicle *v); void ShowTimetableWindow(const Vehicle *v);
void UpdateVehicleTimetable(Vehicle *v, bool travelling); void UpdateVehicleTimetable(Vehicle *v, bool travelling);
void SetTimetableParams(int param1, int param2, Ticks ticks); void SetTimetableParams(int param1, int param2, TimerGameTick::Ticks ticks);
#endif /* TIMETABLE_H */ #endif /* TIMETABLE_H */

View File

@ -10,6 +10,7 @@
#include "stdafx.h" #include "stdafx.h"
#include "command_func.h" #include "command_func.h"
#include "company_func.h" #include "company_func.h"
#include "timer/timer_game_tick.h"
#include "timer/timer_game_calendar.h" #include "timer/timer_game_calendar.h"
#include "window_func.h" #include "window_func.h"
#include "vehicle_base.h" #include "vehicle_base.h"
@ -307,7 +308,7 @@ CommandCost CmdSetTimetableStart(DoCommandFlag flags, VehicleID veh_id, bool tim
if (start_date - TimerGameCalendar::date > DateAtStartOfYear(MAX_TIMETABLE_START_YEARS)) return CMD_ERROR; if (start_date - TimerGameCalendar::date > DateAtStartOfYear(MAX_TIMETABLE_START_YEARS)) return CMD_ERROR;
if (TimerGameCalendar::date - start_date > DAYS_IN_LEAP_YEAR) return CMD_ERROR; if (TimerGameCalendar::date - start_date > DAYS_IN_LEAP_YEAR) return CMD_ERROR;
if (timetable_all && !v->orders->IsCompleteTimetable()) return CommandCost(STR_ERROR_TIMETABLE_INCOMPLETE); if (timetable_all && !v->orders->IsCompleteTimetable()) return CommandCost(STR_ERROR_TIMETABLE_INCOMPLETE);
if (timetable_all && start_date + total_duration / DAY_TICKS > MAX_DATE) return CMD_ERROR; if (timetable_all && start_date + total_duration / Ticks::DAY_TICKS > MAX_DATE) return CMD_ERROR;
if (flags & DC_EXEC) { if (flags & DC_EXEC) {
std::vector<Vehicle *> vehs; std::vector<Vehicle *> vehs;
@ -333,7 +334,7 @@ CommandCost CmdSetTimetableStart(DoCommandFlag flags, VehicleID veh_id, bool tim
w->lateness_counter = 0; w->lateness_counter = 0;
ClrBit(w->vehicle_flags, VF_TIMETABLE_STARTED); ClrBit(w->vehicle_flags, VF_TIMETABLE_STARTED);
/* Do multiplication, then division to reduce rounding errors. */ /* Do multiplication, then division to reduce rounding errors. */
w->timetable_start = start_date + idx * total_duration / num_vehs / DAY_TICKS; w->timetable_start = start_date + idx * total_duration / num_vehs / Ticks::DAY_TICKS;
SetWindowDirty(WC_VEHICLE_TIMETABLE, w->index); SetWindowDirty(WC_VEHICLE_TIMETABLE, w->index);
++idx; ++idx;
} }
@ -426,7 +427,7 @@ void UpdateVehicleTimetable(Vehicle *v, bool travelling)
just_started = !HasBit(v->vehicle_flags, VF_TIMETABLE_STARTED); just_started = !HasBit(v->vehicle_flags, VF_TIMETABLE_STARTED);
if (v->timetable_start != 0) { if (v->timetable_start != 0) {
v->lateness_counter = static_cast<int32_t>(TimerGameCalendar::date - v->timetable_start) * DAY_TICKS + TimerGameCalendar::date_fract; v->lateness_counter = static_cast<int32_t>(TimerGameCalendar::date - v->timetable_start) * Ticks::DAY_TICKS + TimerGameCalendar::date_fract;
v->timetable_start = 0; v->timetable_start = 0;
} }
@ -460,7 +461,7 @@ void UpdateVehicleTimetable(Vehicle *v, bool travelling)
* the timetable entry like is done for road vehicles/ships. * the timetable entry like is done for road vehicles/ships.
* Thus always make sure at least one tick is used between the * Thus always make sure at least one tick is used between the
* processing of different orders when filling the timetable. */ * processing of different orders when filling the timetable. */
uint time_to_set = CeilDiv(std::max(time_taken, 1U), DAY_TICKS) * DAY_TICKS; uint time_to_set = CeilDiv(std::max(time_taken, 1U), Ticks::DAY_TICKS) * Ticks::DAY_TICKS;
if (travelling && (autofilling || !real_current_order->IsTravelTimetabled())) { if (travelling && (autofilling || !real_current_order->IsTravelTimetabled())) {
ChangeTimetable(v, v->cur_real_order_index, time_to_set, MTF_TRAVEL_TIME, autofilling); ChangeTimetable(v, v->cur_real_order_index, time_to_set, MTF_TRAVEL_TIME, autofilling);
@ -493,10 +494,10 @@ void UpdateVehicleTimetable(Vehicle *v, bool travelling)
* check how many ticks the (fully filled) timetable has. If a timetable cycle is * check how many ticks the (fully filled) timetable has. If a timetable cycle is
* shorter than the amount of ticks we are late we reduce the lateness by the * shorter than the amount of ticks we are late we reduce the lateness by the
* length of a full cycle till lateness is less than the length of a timetable * length of a full cycle till lateness is less than the length of a timetable
* cycle. When the timetable isn't fully filled the cycle will be INVALID_TICKS. */ * cycle. When the timetable isn't fully filled the cycle will be Tick::INVALID_TICKS. */
if (v->lateness_counter > (int)timetabled) { if (v->lateness_counter > (int)timetabled) {
Ticks cycle = v->orders->GetTimetableTotalDuration(); TimerGameTick::Ticks cycle = v->orders->GetTimetableTotalDuration();
if (cycle != INVALID_TICKS && v->lateness_counter > cycle) { if (cycle != Ticks::INVALID_TICKS && v->lateness_counter > cycle) {
v->lateness_counter %= cycle; v->lateness_counter %= cycle;
} }
} }

View File

@ -18,6 +18,7 @@
#include "string_func.h" #include "string_func.h"
#include "gfx_func.h" #include "gfx_func.h"
#include "company_func.h" #include "company_func.h"
#include "timer/timer_game_tick.h"
#include "timer/timer_game_calendar.h" #include "timer/timer_game_calendar.h"
#include "date_gui.h" #include "date_gui.h"
#include "vehicle_gui.h" #include "vehicle_gui.h"
@ -34,8 +35,8 @@
/** Container for the arrival/departure dates of a vehicle */ /** Container for the arrival/departure dates of a vehicle */
struct TimetableArrivalDeparture { struct TimetableArrivalDeparture {
Ticks arrival; ///< The arrival time TimerGameTick::Ticks arrival; ///< The arrival time
Ticks departure; ///< The departure time TimerGameTick::Ticks departure; ///< The departure time
}; };
/** /**
@ -44,14 +45,14 @@ struct TimetableArrivalDeparture {
* @param param2 the second DParam to fill * @param param2 the second DParam to fill
* @param ticks the number of ticks to 'draw' * @param ticks the number of ticks to 'draw'
*/ */
void SetTimetableParams(int param1, int param2, Ticks ticks) void SetTimetableParams(int param1, int param2, TimerGameTick::Ticks ticks)
{ {
if (_settings_client.gui.timetable_in_ticks) { if (_settings_client.gui.timetable_in_ticks) {
SetDParam(param1, STR_TIMETABLE_TICKS); SetDParam(param1, STR_TIMETABLE_TICKS);
SetDParam(param2, ticks); SetDParam(param2, ticks);
} else { } else {
SetDParam(param1, STR_TIMETABLE_DAYS); SetDParam(param1, STR_TIMETABLE_DAYS);
SetDParam(param2, ticks / DAY_TICKS); SetDParam(param2, ticks / Ticks::DAY_TICKS);
} }
} }
@ -85,7 +86,7 @@ static bool CanDetermineTimeTaken(const Order *order, bool travelling)
* @param table Fill in arrival and departures including intermediate orders * @param table Fill in arrival and departures including intermediate orders
* @param offset Add this value to result and all arrivals and departures * @param offset Add this value to result and all arrivals and departures
*/ */
static void FillTimetableArrivalDepartureTable(const Vehicle *v, VehicleOrderID start, bool travelling, std::vector<TimetableArrivalDeparture> &table, Ticks offset) static void FillTimetableArrivalDepartureTable(const Vehicle *v, VehicleOrderID start, bool travelling, std::vector<TimetableArrivalDeparture> &table, TimerGameTick::Ticks offset)
{ {
assert(!table.empty()); assert(!table.empty());
assert(v->GetNumOrders() >= 2); assert(v->GetNumOrders() >= 2);
@ -93,10 +94,10 @@ static void FillTimetableArrivalDepartureTable(const Vehicle *v, VehicleOrderID
/* Pre-initialize with unknown time */ /* Pre-initialize with unknown time */
for (int i = 0; i < v->GetNumOrders(); ++i) { for (int i = 0; i < v->GetNumOrders(); ++i) {
table[i].arrival = table[i].departure = INVALID_TICKS; table[i].arrival = table[i].departure = Ticks::INVALID_TICKS;
} }
Ticks sum = offset; TimerGameTick::Ticks sum = offset;
VehicleOrderID i = start; VehicleOrderID i = start;
const Order *order = v->GetOrder(i); const Order *order = v->GetOrder(i);
@ -182,7 +183,7 @@ struct TimetableWindow : Window {
assert(HasBit(v->vehicle_flags, VF_TIMETABLE_STARTED)); assert(HasBit(v->vehicle_flags, VF_TIMETABLE_STARTED));
bool travelling = (!v->current_order.IsType(OT_LOADING) || v->current_order.GetNonStopType() == ONSF_STOP_EVERYWHERE); bool travelling = (!v->current_order.IsType(OT_LOADING) || v->current_order.GetNonStopType() == ONSF_STOP_EVERYWHERE);
Ticks start_time = TimerGameCalendar::date_fract - v->current_order_time; TimerGameTick::Ticks start_time = TimerGameCalendar::date_fract - v->current_order_time;
FillTimetableArrivalDepartureTable(v, v->cur_real_order_index % v->GetNumOrders(), travelling, table, start_time); FillTimetableArrivalDepartureTable(v, v->cur_real_order_index % v->GetNumOrders(), travelling, table, start_time);
@ -425,7 +426,7 @@ struct TimetableWindow : Window {
/* Arrival and departure times are handled in an all-or-nothing approach, /* Arrival and departure times are handled in an all-or-nothing approach,
* i.e. are only shown if we can calculate all times. * i.e. are only shown if we can calculate all times.
* Excluding order lists with only one order makes some things easier. */ * Excluding order lists with only one order makes some things easier. */
Ticks total_time = v->orders != nullptr ? v->orders->GetTimetableDurationIncomplete() : 0; TimerGameTick::Ticks total_time = v->orders != nullptr ? v->orders->GetTimetableDurationIncomplete() : 0;
if (total_time <= 0 || v->GetNumOrders() <= 1 || !HasBit(v->vehicle_flags, VF_TIMETABLE_STARTED)) return; if (total_time <= 0 || v->GetNumOrders() <= 1 || !HasBit(v->vehicle_flags, VF_TIMETABLE_STARTED)) return;
std::vector<TimetableArrivalDeparture> arr_dep(v->GetNumOrders()); std::vector<TimetableArrivalDeparture> arr_dep(v->GetNumOrders());
@ -435,8 +436,8 @@ struct TimetableWindow : Window {
int selected = this->sel_index; int selected = this->sel_index;
Rect tr = r.Shrink(WidgetDimensions::scaled.framerect); Rect tr = r.Shrink(WidgetDimensions::scaled.framerect);
bool show_late = this->show_expected && v->lateness_counter > DAY_TICKS; bool show_late = this->show_expected && v->lateness_counter > Ticks::DAY_TICKS;
Ticks offset = show_late ? 0 : -v->lateness_counter; TimerGameTick::Ticks offset = show_late ? 0 : -v->lateness_counter;
for (int i = this->vscroll->GetPosition(); i / 2 < v->GetNumOrders(); ++i) { // note: i is also incremented in the loop for (int i = this->vscroll->GetPosition(); i / 2 < v->GetNumOrders(); ++i) { // note: i is also incremented in the loop
/* Don't draw anything if it extends past the end of the window. */ /* Don't draw anything if it extends past the end of the window. */
@ -446,9 +447,9 @@ struct TimetableWindow : Window {
SetDParam(0, show_late ? TC_RED : TC_INVALID); SetDParam(0, show_late ? TC_RED : TC_INVALID);
if (i % 2 == 0) { if (i % 2 == 0) {
/* Draw an arrival time. */ /* Draw an arrival time. */
if (arr_dep[i / 2].arrival != INVALID_TICKS) { if (arr_dep[i / 2].arrival != Ticks::INVALID_TICKS) {
/* First set the offset and text colour based on the expected/scheduled mode and some other things. */ /* First set the offset and text colour based on the expected/scheduled mode and some other things. */
Ticks this_offset; TimerGameTick::Ticks this_offset;
if (this->show_expected && i / 2 == earlyID) { if (this->show_expected && i / 2 == earlyID) {
/* Show expected arrival. */ /* Show expected arrival. */
this_offset = 0; this_offset = 0;
@ -459,13 +460,13 @@ struct TimetableWindow : Window {
} }
/* Now actually draw the arrival time. */ /* Now actually draw the arrival time. */
SetDParam(1, TimerGameCalendar::date + (arr_dep[i / 2].arrival + this_offset) / DAY_TICKS); SetDParam(1, TimerGameCalendar::date + (arr_dep[i / 2].arrival + this_offset) / Ticks::DAY_TICKS);
DrawString(tr.left, tr.right, tr.top, STR_TIMETABLE_ARRIVAL, i == selected ? TC_WHITE : TC_BLACK); DrawString(tr.left, tr.right, tr.top, STR_TIMETABLE_ARRIVAL, i == selected ? TC_WHITE : TC_BLACK);
} }
} else { } else {
/* Draw a departure time. */ /* Draw a departure time. */
if (arr_dep[i / 2].departure != INVALID_TICKS) { if (arr_dep[i / 2].departure != Ticks::INVALID_TICKS) {
SetDParam(1, TimerGameCalendar::date + (arr_dep[i / 2].departure + offset) / DAY_TICKS); SetDParam(1, TimerGameCalendar::date + (arr_dep[i / 2].departure + offset) / Ticks::DAY_TICKS);
DrawString(tr.left, tr.right, tr.top, STR_TIMETABLE_DEPARTURE, i == selected ? TC_WHITE : TC_BLACK); DrawString(tr.left, tr.right, tr.top, STR_TIMETABLE_DEPARTURE, i == selected ? TC_WHITE : TC_BLACK);
} }
} }
@ -482,7 +483,7 @@ struct TimetableWindow : Window {
const Vehicle *v = this->vehicle; const Vehicle *v = this->vehicle;
Rect tr = r.Shrink(WidgetDimensions::scaled.framerect); Rect tr = r.Shrink(WidgetDimensions::scaled.framerect);
Ticks total_time = v->orders != nullptr ? v->orders->GetTimetableDurationIncomplete() : 0; TimerGameTick::Ticks total_time = v->orders != nullptr ? v->orders->GetTimetableDurationIncomplete() : 0;
if (total_time != 0) { if (total_time != 0) {
SetTimetableParams(0, 1, total_time); SetTimetableParams(0, 1, total_time);
DrawString(tr, v->orders->IsCompleteTimetable() ? STR_TIMETABLE_TOTAL_TIME : STR_TIMETABLE_TOTAL_TIME_INCOMPLETE); DrawString(tr, v->orders->IsCompleteTimetable() ? STR_TIMETABLE_TOTAL_TIME : STR_TIMETABLE_TOTAL_TIME_INCOMPLETE);
@ -499,7 +500,7 @@ struct TimetableWindow : Window {
/* We aren't running on a timetable yet, so how can we be "on time" /* We aren't running on a timetable yet, so how can we be "on time"
* when we aren't even "on service"/"on duty"? */ * when we aren't even "on service"/"on duty"? */
DrawString(tr, STR_TIMETABLE_STATUS_NOT_STARTED); DrawString(tr, STR_TIMETABLE_STATUS_NOT_STARTED);
} else if (v->lateness_counter == 0 || (!_settings_client.gui.timetable_in_ticks && v->lateness_counter / DAY_TICKS == 0)) { } else if (v->lateness_counter == 0 || (!_settings_client.gui.timetable_in_ticks && v->lateness_counter / Ticks::DAY_TICKS == 0)) {
DrawString(tr, STR_TIMETABLE_STATUS_ON_TIME); DrawString(tr, STR_TIMETABLE_STATUS_ON_TIME);
} else { } else {
SetTimetableParams(0, 1, abs(v->lateness_counter)); SetTimetableParams(0, 1, abs(v->lateness_counter));
@ -570,7 +571,7 @@ struct TimetableWindow : Window {
if (order != nullptr) { if (order != nullptr) {
uint time = (selected % 2 != 0) ? order->GetTravelTime() : order->GetWaitTime(); uint time = (selected % 2 != 0) ? order->GetTravelTime() : order->GetWaitTime();
if (!_settings_client.gui.timetable_in_ticks) time /= DAY_TICKS; if (!_settings_client.gui.timetable_in_ticks) time /= Ticks::DAY_TICKS;
if (time != 0) { if (time != 0) {
SetDParam(0, time); SetDParam(0, time);
@ -666,7 +667,7 @@ struct TimetableWindow : Window {
} }
case WID_VT_CHANGE_TIME: case WID_VT_CHANGE_TIME:
if (!_settings_client.gui.timetable_in_ticks) val *= DAY_TICKS; if (!_settings_client.gui.timetable_in_ticks) val *= Ticks::DAY_TICKS;
if (this->change_timetable_all) { if (this->change_timetable_all) {
Command<CMD_BULK_CHANGE_TIMETABLE>::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, v->index, mtf, ClampTo<uint16_t>(val)); Command<CMD_BULK_CHANGE_TIMETABLE>::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, v->index, mtf, ClampTo<uint16_t>(val));

View File

@ -12,6 +12,7 @@
#include "viewport_type.h" #include "viewport_type.h"
#include "date_type.h" #include "date_type.h"
#include "timer/timer_game_tick.h"
#include "town_map.h" #include "town_map.h"
#include "subsidy_type.h" #include "subsidy_type.h"
#include "newgrf_storage.h" #include "newgrf_storage.h"
@ -305,7 +306,7 @@ void MakeDefaultName(T *obj)
* tick 0 is a valid tick so actual amount is one more than the counter value. * tick 0 is a valid tick so actual amount is one more than the counter value.
*/ */
static inline uint16_t TownTicksToGameTicks(uint16_t ticks) { static inline uint16_t TownTicksToGameTicks(uint16_t ticks) {
return (std::min(ticks, MAX_TOWN_GROWTH_TICKS) + 1) * TOWN_GROWTH_TICKS - 1; return (std::min(ticks, MAX_TOWN_GROWTH_TICKS) + 1) * Ticks::TOWN_GROWTH_TICKS - 1;
} }

View File

@ -822,7 +822,7 @@ static void TownTickHandler(Town *t)
i = t->growth_rate; i = t->growth_rate;
} else { } else {
/* If growth failed wait a bit before retrying */ /* If growth failed wait a bit before retrying */
i = std::min<uint16_t>(t->growth_rate, TOWN_GROWTH_TICKS - 1); i = std::min<uint16_t>(t->growth_rate, Ticks::TOWN_GROWTH_TICKS - 1);
} }
} }
t->grow_counter = i; t->grow_counter = i;
@ -1868,7 +1868,7 @@ static void DoCreateTown(Town *t, TileIndex tile, uint32_t townnameparts, TownSi
t->cache.population = 0; t->cache.population = 0;
/* Spread growth across ticks so even if there are many /* Spread growth across ticks so even if there are many
* similar towns they're unlikely to grow all in one tick */ * similar towns they're unlikely to grow all in one tick */
t->grow_counter = t->index % TOWN_GROWTH_TICKS; t->grow_counter = t->index % Ticks::TOWN_GROWTH_TICKS;
t->growth_rate = TownTicksToGameTicks(250); t->growth_rate = TownTicksToGameTicks(250);
t->show_zone = false; t->show_zone = false;
@ -3236,7 +3236,7 @@ static CommandCost TownActionFundBuildings(Town *t, DoCommandFlag flags)
* tick-perfect and gives player some time window where they can * tick-perfect and gives player some time window where they can
* spam funding with the exact same efficiency. * spam funding with the exact same efficiency.
*/ */
t->grow_counter = std::min<uint16_t>(t->grow_counter, 2 * TOWN_GROWTH_TICKS - (t->growth_rate - t->grow_counter) % TOWN_GROWTH_TICKS); t->grow_counter = std::min<uint16_t>(t->grow_counter, 2 * Ticks::TOWN_GROWTH_TICKS - (t->growth_rate - t->grow_counter) % Ticks::TOWN_GROWTH_TICKS);
SetWindowDirty(WC_TOWN_VIEW, t->index); SetWindowDirty(WC_TOWN_VIEW, t->index);
} }

View File

@ -453,7 +453,7 @@ public:
} }
if (HasBit(this->town->flags, TOWN_IS_GROWING)) { if (HasBit(this->town->flags, TOWN_IS_GROWING)) {
SetDParam(0, RoundDivSU(this->town->growth_rate + 1, DAY_TICKS)); SetDParam(0, RoundDivSU(this->town->growth_rate + 1, Ticks::DAY_TICKS));
DrawString(tr, this->town->fund_buildings_months == 0 ? STR_TOWN_VIEW_TOWN_GROWS_EVERY : STR_TOWN_VIEW_TOWN_GROWS_EVERY_FUNDED); DrawString(tr, this->town->fund_buildings_months == 0 ? STR_TOWN_VIEW_TOWN_GROWS_EVERY : STR_TOWN_VIEW_TOWN_GROWS_EVERY_FUNDED);
tr.top += FONT_HEIGHT_NORMAL; tr.top += FONT_HEIGHT_NORMAL;
} else { } else {

View File

@ -3353,12 +3353,12 @@ bool TrainController(Train *v, Vehicle *nomove, bool reverse)
v->cur_speed = 0; v->cur_speed = 0;
v->subspeed = 0; v->subspeed = 0;
v->progress = 255; // make sure that every bit of acceleration will hit the signal again, so speed stays 0. v->progress = 255; // make sure that every bit of acceleration will hit the signal again, so speed stays 0.
if (!_settings_game.pf.reverse_at_signals || ++v->wait_counter < _settings_game.pf.wait_oneway_signal * DAY_TICKS * 2) return false; if (!_settings_game.pf.reverse_at_signals || ++v->wait_counter < _settings_game.pf.wait_oneway_signal * Ticks::DAY_TICKS * 2) return false;
} else if (HasSignalOnTrackdir(gp.new_tile, i)) { } else if (HasSignalOnTrackdir(gp.new_tile, i)) {
v->cur_speed = 0; v->cur_speed = 0;
v->subspeed = 0; v->subspeed = 0;
v->progress = 255; // make sure that every bit of acceleration will hit the signal again, so speed stays 0. v->progress = 255; // make sure that every bit of acceleration will hit the signal again, so speed stays 0.
if (!_settings_game.pf.reverse_at_signals || ++v->wait_counter < _settings_game.pf.wait_twoway_signal * DAY_TICKS * 2) { if (!_settings_game.pf.reverse_at_signals || ++v->wait_counter < _settings_game.pf.wait_twoway_signal * Ticks::DAY_TICKS * 2) {
DiagDirection exitdir = TrackdirToExitdir(i); DiagDirection exitdir = TrackdirToExitdir(i);
TileIndex o_tile = TileAddByDiagDir(gp.new_tile, exitdir); TileIndex o_tile = TileAddByDiagDir(gp.new_tile, exitdir);
@ -3978,14 +3978,14 @@ static bool TrainLocoHandler(Train *v, bool mode)
++v->wait_counter; ++v->wait_counter;
/* Should we try reversing this tick if still stuck? */ /* Should we try reversing this tick if still stuck? */
bool turn_around = v->wait_counter % (_settings_game.pf.wait_for_pbs_path * DAY_TICKS) == 0 && _settings_game.pf.reverse_at_signals; bool turn_around = v->wait_counter % (_settings_game.pf.wait_for_pbs_path * Ticks::DAY_TICKS) == 0 && _settings_game.pf.reverse_at_signals;
if (!turn_around && v->wait_counter % _settings_game.pf.path_backoff_interval != 0 && v->force_proceed == TFP_NONE) return true; if (!turn_around && v->wait_counter % _settings_game.pf.path_backoff_interval != 0 && v->force_proceed == TFP_NONE) return true;
if (!TryPathReserve(v)) { if (!TryPathReserve(v)) {
/* Still stuck. */ /* Still stuck. */
if (turn_around) ReverseTrainDirection(v); if (turn_around) ReverseTrainDirection(v);
if (HasBit(v->flags, VRF_TRAIN_STUCK) && v->wait_counter > 2 * _settings_game.pf.wait_for_pbs_path * DAY_TICKS) { if (HasBit(v->flags, VRF_TRAIN_STUCK) && v->wait_counter > 2 * _settings_game.pf.wait_for_pbs_path * Ticks::DAY_TICKS) {
/* Show message to player. */ /* Show message to player. */
if (_settings_client.gui.lost_vehicle_warn && v->owner == _local_company) { if (_settings_client.gui.lost_vehicle_warn && v->owner == _local_company) {
SetDParam(0, v->index); SetDParam(0, v->index);
@ -4179,7 +4179,7 @@ void Train::OnNewDay()
if (this->running_ticks != 0) { if (this->running_ticks != 0) {
/* running costs */ /* running costs */
CommandCost cost(EXPENSES_TRAIN_RUN, this->GetRunningCost() * this->running_ticks / (DAYS_IN_YEAR * DAY_TICKS)); CommandCost cost(EXPENSES_TRAIN_RUN, this->GetRunningCost() * this->running_ticks / (DAYS_IN_YEAR * Ticks::DAY_TICKS));
this->profit_this_year -= cost.GetCost(); this->profit_this_year -= cost.GetCost();
this->running_ticks = 0; this->running_ticks = 0;

View File

@ -918,7 +918,7 @@ static void RunVehicleDayProc()
if (_game_mode != GM_NORMAL) return; if (_game_mode != GM_NORMAL) return;
/* Run the day_proc for every DAY_TICKS vehicle starting at TimerGameCalendar::date_fract. */ /* Run the day_proc for every DAY_TICKS vehicle starting at TimerGameCalendar::date_fract. */
for (size_t i = TimerGameCalendar::date_fract; i < Vehicle::GetPoolSize(); i += DAY_TICKS) { for (size_t i = TimerGameCalendar::date_fract; i < Vehicle::GetPoolSize(); i += Ticks::DAY_TICKS) {
Vehicle *v = Vehicle::Get(i); Vehicle *v = Vehicle::Get(i);
if (v == nullptr) continue; if (v == nullptr) continue;
@ -2108,7 +2108,7 @@ void Vehicle::BeginLoading()
{ {
assert(IsTileType(this->tile, MP_STATION) || this->type == VEH_SHIP); assert(IsTileType(this->tile, MP_STATION) || this->type == VEH_SHIP);
Ticks travel_time = TimerGameTick::counter - this->last_loading_tick; TimerGameTick::Ticks travel_time = TimerGameTick::counter - this->last_loading_tick;
if (this->current_order.IsType(OT_GOTO_STATION) && if (this->current_order.IsType(OT_GOTO_STATION) &&
this->current_order.GetDestination() == this->last_station_visited) { this->current_order.GetDestination() == this->last_station_visited) {
this->DeleteUnreachedImplicitOrders(); this->DeleteUnreachedImplicitOrders();

View File

@ -2809,7 +2809,7 @@ void CcStartStopVehicle(Commands cmd, const CommandCost &result, VehicleID veh_i
StringID msg = (v->vehstatus & VS_STOPPED) ? STR_VEHICLE_COMMAND_STOPPED : STR_VEHICLE_COMMAND_STARTED; StringID msg = (v->vehstatus & VS_STOPPED) ? STR_VEHICLE_COMMAND_STOPPED : STR_VEHICLE_COMMAND_STARTED;
Point pt = RemapCoords(v->x_pos, v->y_pos, v->z_pos); Point pt = RemapCoords(v->x_pos, v->y_pos, v->z_pos);
AddTextEffect(msg, pt.x, pt.y, DAY_TICKS, TE_RISING); AddTextEffect(msg, pt.x, pt.y, Ticks::DAY_TICKS, TE_RISING);
} }
/** /**