1
0
Fork 0

Compare commits

..

2 Commits

Author SHA1 Message Date
Peter Nelson 894e6bb087
Change: Add support for different horizontal graph scales. 2025-07-20 14:10:11 +01:00
Peter Nelson c677c40d53
Codechange: Extend industry cargo history to 24 years.
Monthly data is stored for the current 24 months.
Quarterly data is stored for a further 2-6 years.
Yearly data is stored for a further 6-24 years.
2025-07-20 14:10:10 +01:00
15 changed files with 70 additions and 78 deletions

View File

@ -410,7 +410,7 @@ void VehicleCargoList::AgeCargo()
return (accepted && cp->first_station != current_station) ? MTA_DELIVER : MTA_KEEP; return (accepted && cp->first_station != current_station) ? MTA_DELIVER : MTA_KEEP;
} else if (cargo_next == current_station) { } else if (cargo_next == current_station) {
return MTA_DELIVER; return MTA_DELIVER;
} else if (next_station.Contains(cargo_next)) { } else if (next_station.Contains(cargo_next.base())) {
return MTA_KEEP; return MTA_KEEP;
} else { } else {
return MTA_TRANSFER; return MTA_TRANSFER;
@ -470,7 +470,7 @@ bool VehicleCargoList::Stage(bool accepted, StationID current_station, StationID
new_shares.ChangeShare(current_station, INT_MIN); new_shares.ChangeShare(current_station, INT_MIN);
StationIDStack excluded = next_station; StationIDStack excluded = next_station;
while (!excluded.IsEmpty() && !new_shares.GetShares()->empty()) { while (!excluded.IsEmpty() && !new_shares.GetShares()->empty()) {
new_shares.ChangeShare(excluded.Pop(), INT_MIN); new_shares.ChangeShare(StationID{excluded.Pop()}, INT_MIN);
} }
if (new_shares.GetShares()->empty()) { if (new_shares.GetShares()->empty()) {
cargo_next = StationID::Invalid(); cargo_next = StationID::Invalid();
@ -743,7 +743,7 @@ uint StationCargoList::ShiftCargo(Taction action, StationIDStack next, bool incl
{ {
uint max_move = action.MaxMove(); uint max_move = action.MaxMove();
while (!next.IsEmpty()) { while (!next.IsEmpty()) {
this->ShiftCargo(action, next.Pop()); this->ShiftCargo(action, StationID{next.Pop()});
if (action.MaxMove() == 0) break; if (action.MaxMove() == 0) break;
} }
if (include_invalid && action.MaxMove() > 0) { if (include_invalid && action.MaxMove() > 0) {
@ -853,7 +853,7 @@ uint StationCargoList::Load(uint max_move, VehicleCargoList *dest, StationIDStac
*/ */
uint StationCargoList::Reroute(uint max_move, StationCargoList *dest, StationID avoid, StationID avoid2, const GoodsEntry *ge) uint StationCargoList::Reroute(uint max_move, StationCargoList *dest, StationID avoid, StationID avoid2, const GoodsEntry *ge)
{ {
return this->ShiftCargo(StationCargoReroute(this, dest, max_move, avoid, avoid2, ge), avoid, false); return this->ShiftCargo(StationCargoReroute(this, dest, max_move, avoid, avoid2, ge), avoid.base(), false);
} }
/* /*

View File

@ -555,7 +555,7 @@ public:
inline bool HasCargoFor(StationIDStack next) const inline bool HasCargoFor(StationIDStack next) const
{ {
while (!next.IsEmpty()) { while (!next.IsEmpty()) {
if (this->packets.find(next.Pop()) != this->packets.end()) return true; if (this->packets.find(StationID{next.Pop()}) != this->packets.end()) return true;
} }
/* Packets for StationID::Invalid() can go anywhere. */ /* Packets for StationID::Invalid() can go anywhere. */
return this->packets.find(StationID::Invalid()) != this->packets.end(); return this->packets.find(StationID::Invalid()) != this->packets.end();

View File

@ -113,14 +113,13 @@ struct SmallStackItem {
* index types of the same length. * index types of the same length.
* @tparam Titem Value type to be used. * @tparam Titem Value type to be used.
* @tparam Tindex Index type to use for the pool. * @tparam Tindex Index type to use for the pool.
* @tparam Tinvalid_value Value to construct invalid item to keep at the bottom of each stack. * @tparam Tinvalid Invalid item to keep at the bottom of each stack.
* @tparam Tgrowth_step Growth step for pool. * @tparam Tgrowth_step Growth step for pool.
* @tparam Tmax_size Maximum size for pool. * @tparam Tmax_size Maximum size for pool.
*/ */
template <typename Titem, typename Tindex, auto Tinvalid_value, Tindex Tgrowth_step, Tindex Tmax_size> template <typename Titem, typename Tindex, Titem Tinvalid, Tindex Tgrowth_step, Tindex Tmax_size>
class SmallStack : public SmallStackItem<Titem, Tindex> { class SmallStack : public SmallStackItem<Titem, Tindex> {
public: public:
static constexpr Titem Tinvalid{Tinvalid_value};
typedef SmallStackItem<Titem, Tindex> Item; typedef SmallStackItem<Titem, Tindex> Item;

View File

@ -580,11 +580,10 @@ static int DrawLayoutLine(const ParagraphLayouter::Line &line, int y, int left,
const uint shadow_offset = ScaleGUITrad(1); const uint shadow_offset = ScaleGUITrad(1);
auto draw_line = [&](const ParagraphLayouter::Line &line, bool do_shadow, int left, int min_x, int max_x, bool truncation, TextColour initial_colour) { auto draw_line = [&](const ParagraphLayouter::Line &line, bool do_shadow, int left, int min_x, int max_x, bool truncation, TextColour &last_colour) {
const DrawPixelInfo *dpi = _cur_dpi; const DrawPixelInfo *dpi = _cur_dpi;
int dpi_left = dpi->left; int dpi_left = dpi->left;
int dpi_right = dpi->left + dpi->width - 1; int dpi_right = dpi->left + dpi->width - 1;
TextColour last_colour = initial_colour;
for (int run_index = 0; run_index < line.CountRuns(); run_index++) { for (int run_index = 0; run_index < line.CountRuns(); run_index++) {
const ParagraphLayouter::VisualRun &run = line.GetVisualRun(run_index); const ParagraphLayouter::VisualRun &run = line.GetVisualRun(run_index);
@ -594,10 +593,13 @@ static int DrawLayoutLine(const ParagraphLayouter::Line &line, int y, int left,
FontCache *fc = f->fc; FontCache *fc = f->fc;
TextColour colour = f->colour; TextColour colour = f->colour;
if (colour == TC_INVALID || HasFlag(initial_colour, TC_FORCED)) colour = initial_colour; if (colour == TC_INVALID || HasFlag(last_colour, TC_FORCED)) {
colour = last_colour;
} else {
/* Update the last colour for the truncation ellipsis. */
last_colour = colour;
}
bool colour_has_shadow = (colour & TC_NO_SHADE) == 0 && colour != TC_BLACK; bool colour_has_shadow = (colour & TC_NO_SHADE) == 0 && colour != TC_BLACK;
/* Update the last colour for the truncation ellipsis. */
last_colour = colour;
if (do_shadow && (!fc->GetDrawGlyphShadow() || !colour_has_shadow)) continue; if (do_shadow && (!fc->GetDrawGlyphShadow() || !colour_has_shadow)) continue;
SetColourRemap(do_shadow ? TC_BLACK : colour); SetColourRemap(do_shadow ? TC_BLACK : colour);
@ -623,16 +625,16 @@ static int DrawLayoutLine(const ParagraphLayouter::Line &line, int y, int left,
GfxMainBlitter(sprite, begin_x + (do_shadow ? shadow_offset : 0), top + (do_shadow ? shadow_offset : 0), BlitterMode::ColourRemap); GfxMainBlitter(sprite, begin_x + (do_shadow ? shadow_offset : 0), top + (do_shadow ? shadow_offset : 0), BlitterMode::ColourRemap);
} }
} }
return last_colour;
}; };
/* Draw shadow, then foreground */ /* Draw shadow, then foreground */
for (bool do_shadow : {true, false}) { for (bool do_shadow : {true, false}) {
TextColour colour = draw_line(line, do_shadow, left - offset_x, min_x, max_x, truncation, default_colour); TextColour last_colour = default_colour;
draw_line(line, do_shadow, left - offset_x, min_x, max_x, truncation, last_colour);
if (truncation) { if (truncation) {
int x = (_current_text_dir == TD_RTL) ? left : (right - truncation_width); int x = (_current_text_dir == TD_RTL) ? left : (right - truncation_width);
draw_line(*truncation_layout->front(), do_shadow, x, INT32_MIN, INT32_MAX, false, colour); draw_line(*truncation_layout->front(), do_shadow, x, INT32_MIN, INT32_MAX, false, last_colour);
} }
} }

View File

@ -1842,7 +1842,7 @@ static void DoCreateNewIndustry(Industry *i, TileIndex tile, IndustryType type,
p.history[LAST_MONTH].production += ScaleByCargoScale(p.rate * 8, false); p.history[LAST_MONTH].production += ScaleByCargoScale(p.rate * 8, false);
} }
UpdateValidHistory(i->valid_history, HISTORY_YEAR, TimerGameEconomy::month); UpdateValidHistory(i->valid_history, TimerGameEconomy::month);
} }
if (indspec->callback_mask.Test(IndustryCallbackMask::DecideColour)) { if (indspec->callback_mask.Test(IndustryCallbackMask::DecideColour)) {
@ -2519,13 +2519,13 @@ Industry::AcceptedHistory SumHistory(std::span<const Industry::AcceptedHistory>
static void UpdateIndustryStatistics(Industry *i) static void UpdateIndustryStatistics(Industry *i)
{ {
auto month = TimerGameEconomy::month; auto month = TimerGameEconomy::month;
UpdateValidHistory(i->valid_history, HISTORY_YEAR, month); UpdateValidHistory(i->valid_history, month);
for (auto &p : i->produced) { for (auto &p : i->produced) {
if (IsValidCargoType(p.cargo)) { if (IsValidCargoType(p.cargo)) {
if (p.history[THIS_MONTH].production != 0) i->last_prod_year = TimerGameEconomy::year; if (p.history[THIS_MONTH].production != 0) i->last_prod_year = TimerGameEconomy::year;
RotateHistory(p.history, i->valid_history, HISTORY_YEAR, month); RotateHistory(p.history, i->valid_history, month);
} }
} }
@ -2534,7 +2534,7 @@ static void UpdateIndustryStatistics(Industry *i)
if (a.history == nullptr) continue; if (a.history == nullptr) continue;
(*a.history)[THIS_MONTH].waiting = GetAndResetAccumulatedAverage<uint16_t>(a.accumulated_waiting); (*a.history)[THIS_MONTH].waiting = GetAndResetAccumulatedAverage<uint16_t>(a.accumulated_waiting);
RotateHistory(*a.history, i->valid_history, HISTORY_YEAR, month); RotateHistory(*a.history, i->valid_history, month);
} }
} }

View File

@ -42,13 +42,13 @@ LinkGraphJob::LinkGraphJob(const LinkGraph &orig) :
} }
/** /**
* Erase all flows originating at a specific station. * Erase all flows originating at a specific node.
* @param from StationID to erase flows for. * @param from Node to erase flows for.
*/ */
void LinkGraphJob::EraseFlows(StationID from) void LinkGraphJob::EraseFlows(NodeID from)
{ {
for (NodeID node_id = 0; node_id < this->Size(); ++node_id) { for (NodeID node_id = 0; node_id < this->Size(); ++node_id) {
(*this)[node_id].flows.erase(from); (*this)[node_id].flows.erase(StationID{from});
} }
} }
@ -106,7 +106,7 @@ LinkGraphJob::~LinkGraphJob()
/* The station can have been deleted. Remove all flows originating from it then. */ /* The station can have been deleted. Remove all flows originating from it then. */
Station *st = Station::GetIfValid(from.base.station); Station *st = Station::GetIfValid(from.base.station);
if (st == nullptr) { if (st == nullptr) {
this->EraseFlows(from.base.station); this->EraseFlows(node_id);
continue; continue;
} }
@ -114,7 +114,7 @@ LinkGraphJob::~LinkGraphJob()
* sure that everything is still consistent or ignore it otherwise. */ * sure that everything is still consistent or ignore it otherwise. */
GoodsEntry &ge = st->goods[this->Cargo()]; GoodsEntry &ge = st->goods[this->Cargo()];
if (ge.link_graph != this->link_graph.index || ge.node != node_id) { if (ge.link_graph != this->link_graph.index || ge.node != node_id) {
this->EraseFlows(from.base.station); this->EraseFlows(node_id);
continue; continue;
} }
@ -136,7 +136,7 @@ LinkGraphJob::~LinkGraphJob()
/* Delete old flows for source stations which have been deleted /* Delete old flows for source stations which have been deleted
* from the new flows. This avoids flow cycles between old and * from the new flows. This avoids flow cycles between old and
* new flows. */ * new flows. */
while (!erased.IsEmpty()) geflows.erase(erased.Pop()); while (!erased.IsEmpty()) geflows.erase(StationID{erased.Pop()});
} else if ((*lg)[node_id][dest_id].last_unrestricted_update == EconomyTime::INVALID_DATE) { } else if ((*lg)[node_id][dest_id].last_unrestricted_update == EconomyTime::INVALID_DATE) {
/* Edge is fully restricted. */ /* Edge is fully restricted. */
flows.RestrictFlows(to); flows.RestrictFlows(to);

View File

@ -167,7 +167,7 @@ protected:
std::atomic<bool> job_completed = false; ///< Is the job still running. This is accessed by multiple threads and reads may be stale. std::atomic<bool> job_completed = false; ///< Is the job still running. This is accessed by multiple threads and reads may be stale.
std::atomic<bool> job_aborted = false; ///< Has the job been aborted. This is accessed by multiple threads and reads may be stale. std::atomic<bool> job_aborted = false; ///< Has the job been aborted. This is accessed by multiple threads and reads may be stale.
void EraseFlows(StationID from); void EraseFlows(NodeID from);
void JoinThread(); void JoinThread();
void SpawnThread(); void SpawnThread();

View File

@ -7,6 +7,9 @@
/** @file history.cpp Implementation of functions for storing historical data. */ /** @file history.cpp Implementation of functions for storing historical data. */
#ifndef HISTORY_CPP
#define HISTORY_CPP
#include "../stdafx.h" #include "../stdafx.h"
#include "../core/bitmath_func.hpp" #include "../core/bitmath_func.hpp"
@ -15,35 +18,26 @@
#include "../safeguards.h" #include "../safeguards.h"
/** static void UpdateValidHistory(ValidHistoryMask &valid_history, const HistoryRange &hr, uint cur_month)
* Update mask of valid records for a historical data.
* @note Call only for the largest history range sub-division.
* @param[in,out] valid_history Valid history records.
* @param hr History range to update mask for.
* @param cur_month Current economy month.
*/
void UpdateValidHistory(ValidHistoryMask &valid_history, const HistoryRange &hr, uint cur_month)
{ {
/* Update for subdivisions first. */
if (hr.hr != nullptr) UpdateValidHistory(valid_history, *hr.hr, cur_month);
/* No need to update if our last entry is marked valid. */
if (HasBit(valid_history, hr.last - 1)) return;
/* Is it the right time for this history range? */
if (cur_month % hr.total_division != 0) return; if (cur_month % hr.total_division != 0) return;
/* Is the previous history range valid yet? */
if (hr.division != 1 && !HasBit(valid_history, hr.first - hr.division)) return; if (hr.division != 1 && !HasBit(valid_history, hr.first - hr.division)) return;
SB(valid_history, hr.first, hr.records, GB(valid_history, hr.first, hr.records) << 1ULL | 1ULL); SB(valid_history, hr.first, hr.records, GB(valid_history, hr.first, hr.records) << 1ULL | 1ULL);
} }
/** /**
* Test if history data is valid, without extracting data. * Update mask of valid records.
* @param valid_history Mask of valid history records. * @param[in,out] valid_history Valid history records.
* @param hr History range to test. * @param age Current economy month.
* @param age Age of data to test.
* @return True iff the data for history range and age is valid.
*/ */
void UpdateValidHistory(ValidHistoryMask &valid_history, uint cur_month)
{
UpdateValidHistory(valid_history, HISTORY_MONTH, cur_month);
UpdateValidHistory(valid_history, HISTORY_QUARTER, cur_month);
UpdateValidHistory(valid_history, HISTORY_YEAR, cur_month);
}
bool IsValidHistory(ValidHistoryMask valid_history, const HistoryRange &hr, uint age) bool IsValidHistory(ValidHistoryMask valid_history, const HistoryRange &hr, uint age)
{ {
if (hr.hr == nullptr) { if (hr.hr == nullptr) {
@ -54,7 +48,7 @@ bool IsValidHistory(ValidHistoryMask valid_history, const HistoryRange &hr, uint
} else { } else {
if (age * hr.division < static_cast<uint>(hr.hr->periods - hr.division)) { if (age * hr.division < static_cast<uint>(hr.hr->periods - hr.division)) {
uint start = age * hr.division + ((TimerGameEconomy::month / hr.hr->division) % hr.division); uint start = age * hr.division + ((TimerGameEconomy::month / hr.hr->division) % hr.division);
return IsValidHistory(valid_history, *hr.hr, start); return IsValidHistory(valid_history, *hr.hr, start/* + hr.division - 1*/);
} }
if (age < hr.periods) { if (age < hr.periods) {
uint slot = hr.first + age - ((hr.hr->periods / hr.division) - 1); uint slot = hr.first + age - ((hr.hr->periods / hr.division) - 1);
@ -63,3 +57,5 @@ bool IsValidHistory(ValidHistoryMask valid_history, const HistoryRange &hr, uint
} }
return false; return false;
} }
#endif /* HISTORY_CPP */

View File

@ -15,7 +15,7 @@
#include "../timer/timer_game_economy.h" #include "../timer/timer_game_economy.h"
#include "history_type.hpp" #include "history_type.hpp"
void UpdateValidHistory(ValidHistoryMask &valid_history, const HistoryRange &hr, uint cur_month); void UpdateValidHistory(ValidHistoryMask &valid_history, uint cur_month);
bool IsValidHistory(ValidHistoryMask valid_history, const HistoryRange &hr, uint age); bool IsValidHistory(ValidHistoryMask valid_history, const HistoryRange &hr, uint age);
/** /**
@ -29,25 +29,19 @@ template <typename T>
T SumHistory(typename std::span<const T> history); T SumHistory(typename std::span<const T> history);
/** /**
* Rotate historical data. * Rotate history.
* @note Call only for the largest history range sub-division.
* @tparam T type of history data element. * @tparam T type of history data element.
* @param history Historical data to rotate. * @param history Historical data to rotate.
* @param valid_history Mask of valid history records.
* @param hr History range to rotate..
* @param cur_month Current economy month.
*/ */
template <typename T> template <typename T>
void RotateHistory(HistoryData<T> &history, ValidHistoryMask valid_history, const HistoryRange &hr, uint cur_month) void RotateHistory(HistoryData<T> &history, ValidHistoryMask valid_history, const HistoryRange &hr, uint cur_month)
{ {
if (hr.hr != nullptr) RotateHistory(history, valid_history, *hr.hr, cur_month);
if (cur_month % hr.total_division != 0) return; if (cur_month % hr.total_division != 0) return;
std::move_backward(std::next(std::begin(history), hr.first), std::next(std::begin(history), hr.last - 1), std::next(std::begin(history), hr.last)); std::move_backward(std::next(std::begin(history), hr.first), std::next(std::begin(history), hr.last - 1), std::next(std::begin(history), hr.last));
if (hr.total_division == 1) { if (hr.division == 1) {
history[hr.first] = history[hr.first - 1]; history[hr.first] = history[hr.first - 1];
history.front() = {};
} else if (HasBit(valid_history, hr.first - hr.division)) { } else if (HasBit(valid_history, hr.first - hr.division)) {
auto first = std::next(std::begin(history), hr.first - hr.division); auto first = std::next(std::begin(history), hr.first - hr.division);
auto last = std::next(first, hr.division); auto last = std::next(first, hr.division);
@ -55,6 +49,15 @@ void RotateHistory(HistoryData<T> &history, ValidHistoryMask valid_history, cons
} }
} }
template <typename T>
void RotateHistory(HistoryData<T> &history, ValidHistoryMask valid_history, uint cur_month)
{
RotateHistory(history, valid_history, HISTORY_MONTH, cur_month);
RotateHistory(history, valid_history, HISTORY_QUARTER, cur_month);
RotateHistory(history, valid_history, HISTORY_YEAR, cur_month);
history.front() = {};
}
/** /**
* Get an average value for the previous month, as reset for the next month. * Get an average value for the previous month, as reset for the next month.
* @param total Accrued total to average. Will be reset to zero. * @param total Accrued total to average. Will be reset to zero.
@ -68,17 +71,6 @@ T GetAndResetAccumulatedAverage(Taccrued &total)
return result; return result;
} }
/**
* Get historical data.
* @tparam T type of history data element.
* @param history History data to extract from.
* @param valid_history Mask of valid history records.
* @param hr History range to get.
* @param age Age of data to get.
* @param cur_month Current economy month.
* @param[out] result Extracted historical data.
* @return True iff the data for this history range and age is valid.
*/
template <typename T> template <typename T>
bool GetHistory(const HistoryData<T> &history, ValidHistoryMask valid_history, const HistoryRange &hr, uint age, T &result) bool GetHistory(const HistoryData<T> &history, ValidHistoryMask valid_history, const HistoryRange &hr, uint age, T &result)
{ {

View File

@ -10,6 +10,10 @@
#ifndef HISTORY_TYPE_HPP #ifndef HISTORY_TYPE_HPP
#define HISTORY_TYPE_HPP #define HISTORY_TYPE_HPP
#include "../stdafx.h"
static constexpr uint8_t HISTORY_PERIODS = 24;
struct HistoryRange { struct HistoryRange {
const HistoryRange *hr; const HistoryRange *hr;
const uint8_t periods; ///< Number of periods for this range. const uint8_t periods; ///< Number of periods for this range.
@ -31,7 +35,6 @@ struct HistoryRange {
} }
}; };
static constexpr uint8_t HISTORY_PERIODS = 24;
static constexpr HistoryRange HISTORY_MONTH{HISTORY_PERIODS}; static constexpr HistoryRange HISTORY_MONTH{HISTORY_PERIODS};
static constexpr HistoryRange HISTORY_QUARTER{HISTORY_MONTH, 3, HISTORY_PERIODS}; static constexpr HistoryRange HISTORY_QUARTER{HISTORY_MONTH, 3, HISTORY_PERIODS};
static constexpr HistoryRange HISTORY_YEAR{HISTORY_QUARTER, 4, HISTORY_PERIODS}; static constexpr HistoryRange HISTORY_YEAR{HISTORY_QUARTER, 4, HISTORY_PERIODS};

View File

@ -368,7 +368,7 @@ StationIDStack OrderList::GetNextStoppingStation(const Vehicle *v, VehicleOrderI
next = v->cur_implicit_order_index; next = v->cur_implicit_order_index;
if (next >= this->GetNumOrders()) { if (next >= this->GetNumOrders()) {
next = this->GetFirstOrder(); next = this->GetFirstOrder();
if (next == INVALID_VEH_ORDER_ID) return StationID::Invalid(); if (next == INVALID_VEH_ORDER_ID) return StationID::Invalid().base();
} else { } else {
/* GetNext never returns INVALID_VEH_ORDER_ID if there is a valid station in the list. /* GetNext never returns INVALID_VEH_ORDER_ID if there is a valid station in the list.
* As the given "next" is already valid and a station in the list, we * As the given "next" is already valid and a station in the list, we
@ -404,11 +404,11 @@ StationIDStack OrderList::GetNextStoppingStation(const Vehicle *v, VehicleOrderI
if (next == INVALID_VEH_ORDER_ID || ((orders[next].IsType(OT_GOTO_STATION) || orders[next].IsType(OT_IMPLICIT)) && if (next == INVALID_VEH_ORDER_ID || ((orders[next].IsType(OT_GOTO_STATION) || orders[next].IsType(OT_IMPLICIT)) &&
orders[next].GetDestination() == v->last_station_visited && orders[next].GetDestination() == v->last_station_visited &&
(orders[next].GetUnloadType() & (OUFB_TRANSFER | OUFB_UNLOAD)) != 0)) { (orders[next].GetUnloadType() & (OUFB_TRANSFER | OUFB_UNLOAD)) != 0)) {
return StationID::Invalid(); return StationID::Invalid().base();
} }
} while (orders[next].IsType(OT_GOTO_DEPOT) || orders[next].GetDestination() == v->last_station_visited); } while (orders[next].IsType(OT_GOTO_DEPOT) || orders[next].GetDestination() == v->last_station_visited);
return orders[next].GetDestination().ToStationID(); return orders[next].GetDestination().ToStationID().base();
} }
/** /**

View File

@ -5079,7 +5079,7 @@ StationIDStack FlowStatMap::DeleteFlows(StationID via)
FlowStat &s_flows = f_it->second; FlowStat &s_flows = f_it->second;
s_flows.ChangeShare(via, INT_MIN); s_flows.ChangeShare(via, INT_MIN);
if (s_flows.GetShares()->empty()) { if (s_flows.GetShares()->empty()) {
ret.Push(f_it->first); ret.Push(f_it->first.base());
this->erase(f_it++); this->erase(f_it++);
} else { } else {
++f_it; ++f_it;

View File

@ -26,7 +26,7 @@ struct RoadStop;
struct StationSpec; struct StationSpec;
struct Waypoint; struct Waypoint;
using StationIDStack = SmallStack<StationID, StationID::BaseType, StationID::Invalid().base(), 8, StationID::End().base()>; using StationIDStack = SmallStack<StationID::BaseType, StationID::BaseType, StationID::Invalid().base(), 8, StationID::End().base()>;
/** Station types */ /** Station types */
enum class StationType : uint8_t { enum class StationType : uint8_t {

View File

@ -48,8 +48,8 @@ TEST_CASE("History Rotation and Reporting tests")
uint16_t i = 12 * HISTORY_PERIODS; uint16_t i = 12 * HISTORY_PERIODS;
for (uint date = 1; date <= 12 * HISTORY_PERIODS; ++date, --i) { for (uint date = 1; date <= 12 * HISTORY_PERIODS; ++date, --i) {
history[THIS_MONTH] = i; history[THIS_MONTH] = i;
UpdateValidHistory(valid_history, HISTORY_YEAR, date % 12); UpdateValidHistory(valid_history, date % 12);
RotateHistory(history, valid_history, HISTORY_YEAR, date % 12); RotateHistory(history, valid_history, date % 12);
} }
/* With the decreasing sequence, the expected value is triangle number (x*x+n)/2 and the square of the total divisions. /* With the decreasing sequence, the expected value is triangle number (x*x+n)/2 and the square of the total divisions.

View File

@ -741,7 +741,7 @@ public:
*/ */
inline StationIDStack GetNextStoppingStation() const inline StationIDStack GetNextStoppingStation() const
{ {
return (this->orders == nullptr) ? StationID::Invalid() : this->orders->GetNextStoppingStation(this); return (this->orders == nullptr) ? StationID::Invalid().base() : this->orders->GetNextStoppingStation(this);
} }
void ResetRefitCaps(); void ResetRefitCaps();