mirror of https://github.com/OpenTTD/OpenTTD.git
Codechange: make TimerGameCalendar Date and Year types strongly typed (#10761)
This commit is contained in:
parent
0238a2b567
commit
299570b2c1
|
@ -105,7 +105,7 @@ static int32_t ClickChangeDateCheat(int32_t new_value, int32_t change_direction)
|
|||
{
|
||||
/* Don't allow changing to an invalid year, or the current year. */
|
||||
auto new_year = Clamp(TimerGameCalendar::Year(new_value), MIN_YEAR, MAX_YEAR);
|
||||
if (new_year == TimerGameCalendar::year) return TimerGameCalendar::year;
|
||||
if (new_year == TimerGameCalendar::year) return static_cast<int32_t>(TimerGameCalendar::year);
|
||||
|
||||
TimerGameCalendar::YearMonthDay ymd;
|
||||
TimerGameCalendar::ConvertDateToYMD(TimerGameCalendar::date, &ymd);
|
||||
|
@ -125,7 +125,7 @@ static int32_t ClickChangeDateCheat(int32_t new_value, int32_t change_direction)
|
|||
InvalidateWindowClassesData(WC_TRUCK_STATION, 0);
|
||||
InvalidateWindowClassesData(WC_BUILD_OBJECT, 0);
|
||||
ResetSignalVariant();
|
||||
return TimerGameCalendar::year;
|
||||
return static_cast<int32_t>(TimerGameCalendar::year);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -437,7 +437,7 @@ struct CompanyFinancesWindow : Window {
|
|||
auto age = std::min(TimerGameCalendar::year - c->inaugurated_year, TimerGameCalendar::Year(2));
|
||||
int wid_offset = widget - WID_CF_EXPS_PRICE1;
|
||||
if (wid_offset <= age) {
|
||||
DrawYearColumn(r, TimerGameCalendar::year - (age - wid_offset), c->yearly_expenses[age - wid_offset]);
|
||||
DrawYearColumn(r, TimerGameCalendar::year - (age - wid_offset), c->yearly_expenses[static_cast<int32_t>(age - wid_offset)]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -28,8 +28,8 @@ struct fmt::formatter<E, Char, std::enable_if_t<std::is_enum<E>::value>> : fmt::
|
|||
};
|
||||
|
||||
template <typename T, typename Char>
|
||||
struct fmt::formatter<T, Char, std::enable_if_t<std::is_base_of<StrongTypedefBase, T>::value>> : fmt::formatter<typename T::Type> {
|
||||
using underlying_type = typename T::Type;
|
||||
struct fmt::formatter<T, Char, std::enable_if_t<std::is_base_of<StrongTypedefBase, T>::value>> : fmt::formatter<typename T::BaseType> {
|
||||
using underlying_type = typename T::BaseType;
|
||||
using parent = typename fmt::formatter<underlying_type>;
|
||||
|
||||
constexpr fmt::format_parse_context::iterator parse(fmt::format_parse_context &ctx) {
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#ifndef MATH_FUNC_HPP
|
||||
#define MATH_FUNC_HPP
|
||||
|
||||
#include "strong_typedef_type.hpp"
|
||||
|
||||
/**
|
||||
* Returns the absolute value of (scalar) variable.
|
||||
|
@ -162,7 +163,7 @@ static inline uint ClampU(const uint a, const uint min, const uint max)
|
|||
* for the return type.
|
||||
* @see Clamp(int, int, int)
|
||||
*/
|
||||
template <typename To, typename From>
|
||||
template <typename To, typename From, std::enable_if_t<std::is_integral<From>::value, int> = 0>
|
||||
constexpr To ClampTo(From value)
|
||||
{
|
||||
static_assert(std::numeric_limits<To>::is_integer, "Do not clamp from non-integer values");
|
||||
|
@ -213,6 +214,15 @@ constexpr To ClampTo(From value)
|
|||
return static_cast<To>(std::min<BiggerType>(value, std::numeric_limits<To>::max()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Specialization of ClampTo for #StrongType::Typedef.
|
||||
*/
|
||||
template <typename To, typename From, std::enable_if_t<std::is_base_of<StrongTypedefBase, From>::value, int> = 0>
|
||||
constexpr To ClampTo(From value)
|
||||
{
|
||||
return ClampTo<To>(static_cast<typename From::BaseType>(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the (absolute) difference between two (scalar) variables
|
||||
*
|
||||
|
@ -254,10 +264,14 @@ static inline bool IsInsideBS(const T x, const size_t base, const size_t size)
|
|||
* @param max The maximum of the interval
|
||||
* @see IsInsideBS()
|
||||
*/
|
||||
template <typename T>
|
||||
template <typename T, std::enable_if_t<std::disjunction_v<std::is_convertible<T, size_t>, std::is_base_of<StrongTypedefBase, T>>, int> = 0>
|
||||
static constexpr inline bool IsInsideMM(const T x, const size_t min, const size_t max) noexcept
|
||||
{
|
||||
return (size_t)(x - min) < (max - min);
|
||||
if constexpr (std::is_base_of_v<StrongTypedefBase, T>) {
|
||||
return (size_t)(static_cast<typename T::BaseType>(x) - min) < (max - min);
|
||||
} else {
|
||||
return (size_t)(x - min) < (max - min);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -10,74 +10,199 @@
|
|||
#ifndef STRONG_TYPEDEF_TYPE_HPP
|
||||
#define STRONG_TYPEDEF_TYPE_HPP
|
||||
|
||||
/** Non-templated base for #StrongTypedef for use with type trait queries. */
|
||||
#include "../3rdparty/fmt/format.h"
|
||||
|
||||
/** Non-templated base for #StrongType::Typedef for use with type trait queries. */
|
||||
struct StrongTypedefBase {};
|
||||
|
||||
/**
|
||||
* Templated helper to make a type-safe 'typedef' representing a single POD value.
|
||||
* A normal 'typedef' is not distinct from its base type and will be treated as
|
||||
* identical in many contexts. This class provides a distinct type that can still
|
||||
* be assign from and compared to values of its base type.
|
||||
*
|
||||
* @note This is meant to be used as a base class, not directly.
|
||||
* @tparam T Storage type
|
||||
* @tparam Tthis Type of the derived class (i.e. the concrete usage of this class).
|
||||
*/
|
||||
template <class T, class Tthis>
|
||||
struct StrongTypedef : StrongTypedefBase {
|
||||
using Type = T;
|
||||
namespace StrongType {
|
||||
/**
|
||||
* Mix-in which makes the new Typedef comparable with itself and its base type.
|
||||
*/
|
||||
struct Compare {
|
||||
template <typename TType, typename TBaseType>
|
||||
struct mixin {
|
||||
friend constexpr bool operator ==(const TType &lhs, const TType &rhs) { return lhs.value == rhs.value; }
|
||||
friend constexpr bool operator ==(const TType &lhs, const TBaseType &rhs) { return lhs.value == rhs; }
|
||||
|
||||
T value{}; ///< Backing storage field.
|
||||
friend constexpr bool operator !=(const TType &lhs, const TType &rhs) { return lhs.value != rhs.value; }
|
||||
friend constexpr bool operator !=(const TType &lhs, const TBaseType &rhs) { return lhs.value != rhs; }
|
||||
|
||||
debug_inline constexpr StrongTypedef() = default;
|
||||
debug_inline constexpr StrongTypedef(const StrongTypedef &o) = default;
|
||||
debug_inline constexpr StrongTypedef(StrongTypedef &&o) = default;
|
||||
friend constexpr bool operator <=(const TType &lhs, const TType &rhs) { return lhs.value <= rhs.value; }
|
||||
friend constexpr bool operator <=(const TType &lhs, const TBaseType &rhs) { return lhs.value <= rhs; }
|
||||
|
||||
debug_inline constexpr StrongTypedef(const T &value) : value(value) {}
|
||||
friend constexpr bool operator <(const TType &lhs, const TType &rhs) { return lhs.value < rhs.value; }
|
||||
friend constexpr bool operator <(const TType &lhs, const TBaseType &rhs) { return lhs.value < rhs; }
|
||||
|
||||
debug_inline constexpr Tthis &operator =(const Tthis &rhs) { this->value = rhs.value; return static_cast<Tthis &>(*this); }
|
||||
debug_inline constexpr Tthis &operator =(Tthis &&rhs) { this->value = std::move(rhs.value); return static_cast<Tthis &>(*this); }
|
||||
debug_inline constexpr Tthis &operator =(const T &rhs) { this->value = rhs; return static_cast<Tthis &>(*this); }
|
||||
friend constexpr bool operator >=(const TType &lhs, const TType &rhs) { return lhs.value >= rhs.value; }
|
||||
friend constexpr bool operator >=(const TType &lhs, const TBaseType &rhs) { return lhs.value >= rhs; }
|
||||
|
||||
explicit constexpr operator T() const { return this->value; }
|
||||
friend constexpr bool operator >(const TType &lhs, const TType &rhs) { return lhs.value > rhs.value; }
|
||||
friend constexpr bool operator >(const TType &lhs, const TBaseType &rhs) { return lhs.value > rhs; }
|
||||
};
|
||||
};
|
||||
|
||||
constexpr bool operator ==(const Tthis &rhs) const { return this->value == rhs.value; }
|
||||
constexpr bool operator !=(const Tthis &rhs) const { return this->value != rhs.value; }
|
||||
constexpr bool operator ==(const T &rhs) const { return this->value == rhs; }
|
||||
constexpr bool operator !=(const T &rhs) const { return this->value != rhs; }
|
||||
};
|
||||
/**
|
||||
* Mix-in which makes the new Typedef behave more like an integer. This means you can add and subtract from it.
|
||||
*
|
||||
* Operators like divide, multiply and module are explicitly denied, as that often makes little sense for the
|
||||
* new type. If you want to do these actions on the new Typedef, you are better off first casting it to the
|
||||
* base type.
|
||||
*/
|
||||
struct Integer {
|
||||
template <typename TType, typename TBaseType>
|
||||
struct mixin {
|
||||
friend constexpr TType &operator ++(TType &lhs) { lhs.value++; return lhs; }
|
||||
friend constexpr TType &operator --(TType &lhs) { lhs.value--; return lhs; }
|
||||
friend constexpr TType operator ++(TType &lhs, int) { TType res = lhs; lhs.value++; return res; }
|
||||
friend constexpr TType operator --(TType &lhs, int) { TType res = lhs; lhs.value--; return res; }
|
||||
|
||||
/**
|
||||
* Extension of #StrongTypedef with operators for addition and subtraction.
|
||||
* @tparam T Storage type
|
||||
* @tparam Tthis Type of the derived class (i.e. the concrete usage of this class).
|
||||
*/
|
||||
template <class T, class Tthis>
|
||||
struct StrongIntegralTypedef : StrongTypedef<T, Tthis> {
|
||||
using StrongTypedef<T, Tthis>::StrongTypedef;
|
||||
friend constexpr TType &operator +=(TType &lhs, const TType &rhs) { lhs.value += rhs.value; return lhs; }
|
||||
friend constexpr TType operator +(const TType &lhs, const TType &rhs) { return TType{ lhs.value + rhs.value }; }
|
||||
friend constexpr TType operator +(const TType &lhs, const TBaseType &rhs) { return TType{ lhs.value + rhs }; }
|
||||
|
||||
debug_inline constexpr StrongIntegralTypedef() = default;
|
||||
debug_inline constexpr StrongIntegralTypedef(const StrongIntegralTypedef &o) = default;
|
||||
debug_inline constexpr StrongIntegralTypedef(StrongIntegralTypedef &&o) = default;
|
||||
friend constexpr TType &operator -=(TType &lhs, const TType &rhs) { lhs.value -= rhs.value; return lhs; }
|
||||
friend constexpr TType operator -(const TType &lhs, const TType &rhs) { return TType{ lhs.value - rhs.value }; }
|
||||
friend constexpr TType operator -(const TType &lhs, const TBaseType &rhs) { return TType{ lhs.value - rhs }; }
|
||||
|
||||
debug_inline constexpr StrongIntegralTypedef(const T &value) : StrongTypedef<T, Tthis>(value) {}
|
||||
/* For most new types, the rest of the operators make no sense. For example,
|
||||
* what does it actually mean to multiply a Year with a value. Or to do a
|
||||
* bitwise OR on a Date. Or to divide a TileIndex by 2. Conceptually, they
|
||||
* don't really mean anything. So force the user to first cast it to the
|
||||
* base type, so the operation no longer returns the new Typedef. */
|
||||
|
||||
debug_inline constexpr Tthis &operator =(const Tthis &rhs) { this->value = rhs.value; return static_cast<Tthis &>(*this); }
|
||||
debug_inline constexpr Tthis &operator =(Tthis &&rhs) { this->value = std::move(rhs.value); return static_cast<Tthis &>(*this); }
|
||||
debug_inline constexpr Tthis &operator =(const T &rhs) { this->value = rhs; return static_cast<Tthis &>(*this); }
|
||||
constexpr TType &operator *=(const TType &rhs) = delete;
|
||||
constexpr TType operator *(const TType &rhs) = delete;
|
||||
constexpr TType operator *(const TBaseType &rhs) = delete;
|
||||
|
||||
constexpr Tthis &operator ++() { this->value++; return static_cast<Tthis &>(*this); }
|
||||
constexpr Tthis &operator --() { this->value--; return static_cast<Tthis &>(*this); }
|
||||
constexpr Tthis operator ++(int) { auto res = static_cast<Tthis &>(*this); this->value++; return res; }
|
||||
constexpr Tthis operator --(int) { auto res = static_cast<Tthis &>(*this); this->value--; return res; }
|
||||
constexpr TType &operator /=(const TType &rhs) = delete;
|
||||
constexpr TType operator /(const TType &rhs) = delete;
|
||||
constexpr TType operator /(const TBaseType &rhs) = delete;
|
||||
|
||||
constexpr Tthis &operator +=(const Tthis &rhs) { this->value += rhs.value; return *static_cast<Tthis *>(this); }
|
||||
constexpr Tthis &operator -=(const Tthis &rhs) { this->value -= rhs.value; return *static_cast<Tthis *>(this); }
|
||||
constexpr TType &operator %=(const TType &rhs) = delete;
|
||||
constexpr TType operator %(const TType &rhs) = delete;
|
||||
constexpr TType operator %(const TBaseType &rhs) = delete;
|
||||
|
||||
constexpr Tthis operator +(const Tthis &rhs) const { return Tthis{ this->value + rhs.value }; }
|
||||
constexpr Tthis operator -(const Tthis &rhs) const { return Tthis{ this->value - rhs.value }; }
|
||||
constexpr Tthis operator +(const T &rhs) const { return Tthis{ this->value + rhs }; }
|
||||
constexpr Tthis operator -(const T &rhs) const { return Tthis{ this->value - rhs }; }
|
||||
};
|
||||
constexpr TType &operator &=(const TType &rhs) = delete;
|
||||
constexpr TType operator &(const TType &rhs) = delete;
|
||||
constexpr TType operator &(const TBaseType &rhs) = delete;
|
||||
|
||||
constexpr TType &operator |=(const TType &rhs) = delete;
|
||||
constexpr TType operator |(const TType &rhs) = delete;
|
||||
constexpr TType operator |(const TBaseType &rhs) = delete;
|
||||
|
||||
constexpr TType &operator ^=(const TType &rhs) = delete;
|
||||
constexpr TType operator ^(const TType &rhs) = delete;
|
||||
constexpr TType operator ^(const TBaseType &rhs) = delete;
|
||||
|
||||
constexpr TType &operator <<=(const TType &rhs) = delete;
|
||||
constexpr TType operator <<(const TType &rhs) = delete;
|
||||
constexpr TType operator <<(const TBaseType &rhs) = delete;
|
||||
|
||||
constexpr TType &operator >>=(const TType &rhs) = delete;
|
||||
constexpr TType operator >>(const TType &rhs) = delete;
|
||||
constexpr TType operator >>(const TBaseType &rhs) = delete;
|
||||
|
||||
constexpr TType operator ~() = delete;
|
||||
constexpr TType operator -() = delete;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Mix-in which makes the new Typedef compatible with another type (which is not the base type).
|
||||
*
|
||||
* @note The base type of the new Typedef will be cast to the other type; so make sure they are compatible.
|
||||
*
|
||||
* @tparam TCompatibleType The other type to be compatible with.
|
||||
*/
|
||||
template <typename TCompatibleType>
|
||||
struct Compatible {
|
||||
template <typename TType, typename TBaseType>
|
||||
struct mixin {
|
||||
friend constexpr bool operator ==(const TType &lhs, TCompatibleType rhs) { return lhs.value == static_cast<TBaseType>(rhs); }
|
||||
friend constexpr bool operator !=(const TType &lhs, TCompatibleType rhs) { return lhs.value != static_cast<TBaseType>(rhs); }
|
||||
|
||||
friend constexpr bool operator <=(const TType &lhs, TCompatibleType rhs) { return lhs.value <= static_cast<TBaseType>(rhs); }
|
||||
friend constexpr bool operator <(const TType &lhs, TCompatibleType rhs) { return lhs.value < static_cast<TBaseType>(rhs); }
|
||||
friend constexpr bool operator >=(const TType &lhs, TCompatibleType rhs) { return lhs.value >= static_cast<TBaseType>(rhs); }
|
||||
friend constexpr bool operator >(const TType &lhs, TCompatibleType rhs) { return lhs.value > static_cast<TBaseType>(rhs); }
|
||||
|
||||
friend constexpr TType operator +(const TType &lhs, TCompatibleType rhs) { return { static_cast<TBaseType>(lhs.value + rhs) }; }
|
||||
friend constexpr TType operator -(const TType &lhs, TCompatibleType rhs) { return { static_cast<TBaseType>(lhs.value - rhs) }; }
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Mix-in which makes the new Typedef implicitly convertible to its base type.
|
||||
*
|
||||
* Be careful: when allowing implicit conversion, you won't notice if this type is assigned to a compatible, but different, type.
|
||||
* For example:
|
||||
*
|
||||
* StrongType::Typedef<int, struct MyTypeTag, Implicit> a = 1;
|
||||
* StrongType::Typedef<int, struct MyTypeTag, Implicit> b = 2;
|
||||
* a = b; // OK
|
||||
*/
|
||||
struct Implicit {
|
||||
template <typename TType, typename TBaseType>
|
||||
struct mixin {
|
||||
constexpr operator TBaseType () const { return static_cast<const TType &>(*this).value; }
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Mix-in which makes the new Typedef explicitly convertible to its base type.
|
||||
*/
|
||||
struct Explicit {
|
||||
template <typename TType, typename TBaseType>
|
||||
struct mixin {
|
||||
explicit constexpr operator TBaseType () const { return static_cast<const TType &>(*this).value; }
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Templated helper to make a type-safe 'typedef' representing a single POD value.
|
||||
* A normal 'typedef' is not distinct from its base type and will be treated as
|
||||
* identical in many contexts. This class provides a distinct type that can still
|
||||
* be assign from and compared to values of its base type.
|
||||
*
|
||||
* Example usage:
|
||||
*
|
||||
* using MyType = StrongType::Typedef<int, struct MyTypeTag, StrongType::Explicit, StrongType::Compare, StrongType::Integer>;
|
||||
*
|
||||
* @tparam TBaseType Type of the derived class (i.e. the concrete usage of this class).
|
||||
* @tparam TTag An unique struct to keep types of the same TBaseType distinct.
|
||||
* @tparam TProperties A list of mixins to add to the class.
|
||||
*/
|
||||
template <typename TBaseType, typename TTag, typename... TProperties>
|
||||
struct EMPTY_BASES Typedef : public StrongTypedefBase, public TProperties::template mixin<Typedef<TBaseType, TTag, TProperties...>, TBaseType>... {
|
||||
using BaseType = TBaseType;
|
||||
|
||||
constexpr Typedef() = default;
|
||||
constexpr Typedef(const Typedef &) = default;
|
||||
constexpr Typedef(Typedef &&) = default;
|
||||
|
||||
constexpr Typedef(const TBaseType &value) : value(value) {}
|
||||
|
||||
constexpr Typedef &operator =(const Typedef &rhs) { this->value = rhs.value; return *this; }
|
||||
constexpr Typedef &operator =(Typedef &&rhs) { this->value = std::move(rhs.value); return *this; }
|
||||
constexpr Typedef &operator =(const TBaseType &rhs) { this->value = rhs; return *this; }
|
||||
|
||||
/* Only allow TProperties classes access to the internal value. Everyone else needs to do an explicit cast. */
|
||||
friend struct Explicit;
|
||||
friend struct Implicit;
|
||||
friend struct Compare;
|
||||
friend struct Integer;
|
||||
template <typename TCompatibleType> friend struct Compatible;
|
||||
|
||||
/* GCC / MSVC don't pick up on the "friend struct" above, where CLang does.
|
||||
* As in our CI we compile for all three targets, it is sufficient to have one
|
||||
* that errors on this; but nobody should be using "value" directly. Instead,
|
||||
* use a static_cast<> to convert to the base type. */
|
||||
#ifdef __clang__
|
||||
protected:
|
||||
#endif /* __clang__ */
|
||||
TBaseType value{};
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* STRONG_TYPEDEF_TYPE_HPP */
|
||||
|
|
|
@ -91,9 +91,9 @@ struct SetDateWindow : Window {
|
|||
case WID_SD_YEAR:
|
||||
for (TimerGameCalendar::Year i = this->min_year; i <= this->max_year; i++) {
|
||||
SetDParam(0, i);
|
||||
list.emplace_back(new DropDownListStringItem(STR_JUST_INT, i, false));
|
||||
list.emplace_back(new DropDownListStringItem(STR_JUST_INT, static_cast<int32_t>(i), false));
|
||||
}
|
||||
selected = this->date.year;
|
||||
selected = static_cast<int32_t>(this->date.year);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -58,9 +58,10 @@ static constexpr TimerGameCalendar::Year ORIGINAL_MAX_YEAR = 2090;
|
|||
*/
|
||||
static constexpr TimerGameCalendar::Date DateAtStartOfYear(TimerGameCalendar::Year year)
|
||||
{
|
||||
uint number_of_leap_years = (year == 0) ? 0 : ((year - 1) / 4 - (year - 1) / 100 + (year - 1) / 400 + 1);
|
||||
int32_t year_as_int = static_cast<int32_t>(year);
|
||||
uint number_of_leap_years = (year == 0) ? 0 : ((year_as_int - 1) / 4 - (year_as_int - 1) / 100 + (year_as_int - 1) / 400 + 1);
|
||||
|
||||
return (DAYS_IN_YEAR * year) + number_of_leap_years;
|
||||
return (DAYS_IN_YEAR * year_as_int) + number_of_leap_years;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -70,7 +71,7 @@ static constexpr TimerGameCalendar::Date DateAtStartOfYear(TimerGameCalendar::Ye
|
|||
*/
|
||||
static inline TimerGameCalendar::Year DateToYear(TimerGameCalendar::Date date)
|
||||
{
|
||||
return date / DAYS_IN_LEAP_YEAR;
|
||||
return static_cast<int32_t>(date) / DAYS_IN_LEAP_YEAR;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -360,7 +360,7 @@ struct DepotWindow : Window {
|
|||
DrawSpriteIgnorePadding((v->vehstatus & VS_STOPPED) ? SPR_FLAG_VEH_STOPPED : SPR_FLAG_VEH_RUNNING, PAL_NONE, flag, false, SA_CENTER);
|
||||
|
||||
SetDParam(0, v->unitnumber);
|
||||
DrawString(text, STR_JUST_COMMA, (uint16_t)(v->max_age - DAYS_IN_LEAP_YEAR) >= v->age ? TC_BLACK : TC_RED);
|
||||
DrawString(text, STR_JUST_COMMA, (v->max_age - DAYS_IN_LEAP_YEAR) >= v->age ? TC_BLACK : TC_RED);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -928,7 +928,7 @@ void StartupEconomy()
|
|||
|
||||
if (_settings_game.economy.inflation) {
|
||||
/* Apply inflation that happened before our game start year. */
|
||||
int months = (std::min(TimerGameCalendar::year, ORIGINAL_MAX_YEAR) - ORIGINAL_BASE_YEAR) * 12;
|
||||
int months = static_cast<int32_t>(std::min(TimerGameCalendar::year, ORIGINAL_MAX_YEAR) - ORIGINAL_BASE_YEAR) * 12;
|
||||
for (int i = 0; i < months; i++) {
|
||||
AddInflation(false);
|
||||
}
|
||||
|
|
|
@ -662,7 +662,7 @@ void SetYearEngineAgingStops()
|
|||
|
||||
/* Base year ending date on half the model life */
|
||||
TimerGameCalendar::YearMonthDay ymd;
|
||||
TimerGameCalendar::ConvertDateToYMD(ei->base_intro + DateAtStartOfYear(ei->lifelength) / 2, &ymd);
|
||||
TimerGameCalendar::ConvertDateToYMD(ei->base_intro + static_cast<int32_t>(DateAtStartOfYear(ei->lifelength)) / 2, &ymd);
|
||||
|
||||
_year_engine_aging_stops = std::max(_year_engine_aging_stops, ymd.year);
|
||||
}
|
||||
|
@ -688,7 +688,7 @@ void StartupOneEngine(Engine *e, TimerGameCalendar::Date aging_date, uint32_t se
|
|||
SavedRandomSeeds saved_seeds;
|
||||
SaveRandomSeeds(&saved_seeds);
|
||||
SetRandomSeed(_settings_game.game_creation.generation_seed ^ seed ^
|
||||
ei->base_intro ^
|
||||
static_cast<int32_t>(ei->base_intro) ^
|
||||
e->type ^
|
||||
e->GetGRFID());
|
||||
uint32_t r = Random();
|
||||
|
@ -698,7 +698,7 @@ void StartupOneEngine(Engine *e, TimerGameCalendar::Date aging_date, uint32_t se
|
|||
* Note: TTDP uses fixed 1922 */
|
||||
e->intro_date = ei->base_intro <= TimerGameCalendar::ConvertYMDToDate(_settings_game.game_creation.starting_year + 2, 0, 1) ? ei->base_intro : (TimerGameCalendar::Date)GB(r, 0, 9) + ei->base_intro;
|
||||
if (e->intro_date <= TimerGameCalendar::date) {
|
||||
e->age = (aging_date - e->intro_date) >> 5;
|
||||
e->age = static_cast<int32_t>(aging_date - e->intro_date) >> 5;
|
||||
e->company_avail = MAX_UVALUE(CompanyMask);
|
||||
e->flags |= ENGINE_AVAILABLE;
|
||||
}
|
||||
|
@ -710,8 +710,8 @@ void StartupOneEngine(Engine *e, TimerGameCalendar::Date aging_date, uint32_t se
|
|||
}
|
||||
|
||||
SetRandomSeed(_settings_game.game_creation.generation_seed ^ seed ^
|
||||
(re->index << 16) ^ (re->info.base_intro << 12) ^ (re->info.decay_speed << 8) ^
|
||||
(re->info.lifelength << 4) ^ re->info.retire_early ^
|
||||
(re->index << 16) ^ (static_cast<int32_t>(re->info.base_intro) << 12) ^ (re->info.decay_speed << 8) ^
|
||||
(static_cast<int32_t>(re->info.lifelength) << 4) ^ re->info.retire_early ^
|
||||
e->type ^
|
||||
e->GetGRFID());
|
||||
|
||||
|
@ -722,7 +722,7 @@ void StartupOneEngine(Engine *e, TimerGameCalendar::Date aging_date, uint32_t se
|
|||
r = Random();
|
||||
e->reliability_final = GB(r, 16, 14) + 0x3FFF;
|
||||
e->duration_phase_1 = GB(r, 0, 5) + 7;
|
||||
e->duration_phase_2 = GB(r, 5, 4) + ei->base_life * 12 - 96;
|
||||
e->duration_phase_2 = GB(r, 5, 4) + static_cast<int32_t>(ei->base_life) * 12 - 96;
|
||||
e->duration_phase_3 = GB(r, 9, 7) + 120;
|
||||
|
||||
RestoreRandomSeeds(saved_seeds);
|
||||
|
|
|
@ -968,7 +968,7 @@ struct GenerateLandscapeWindow : public Window {
|
|||
/* An empty string means revert to the default */
|
||||
switch (this->widget_id) {
|
||||
case WID_GL_HEIGHTMAP_HEIGHT_TEXT: value = MAP_HEIGHT_LIMIT_AUTO_MINIMUM; break;
|
||||
case WID_GL_START_DATE_TEXT: value = DEF_START_YEAR; break;
|
||||
case WID_GL_START_DATE_TEXT: value = static_cast<int32_t>(DEF_START_YEAR); break;
|
||||
case WID_GL_SNOW_COVERAGE_TEXT: value = DEF_SNOW_COVERAGE; break;
|
||||
case WID_GL_DESERT_COVERAGE_TEXT: value = DEF_DESERT_COVERAGE; break;
|
||||
case WID_GL_TOWN_PULLDOWN: value = 1; break;
|
||||
|
|
|
@ -787,7 +787,7 @@ void RunTileLoop()
|
|||
_tile_type_procs[GetTileType(tile)]->tile_loop_proc(tile);
|
||||
|
||||
/* Get the next tile in sequence using a Galois LFSR. */
|
||||
tile = (tile >> 1) ^ (-(int32_t)(tile & 1) & feedback);
|
||||
tile = (static_cast<uint32_t>(tile) >> 1) ^ (-(int32_t)(static_cast<uint32_t>(tile) & 1) & feedback);
|
||||
}
|
||||
|
||||
_cur_tileloop_tile = tile;
|
||||
|
@ -935,11 +935,11 @@ static void GenerateTerrain(int type, uint flag)
|
|||
|
||||
static void CreateDesertOrRainForest(uint desert_tropic_line)
|
||||
{
|
||||
TileIndex update_freq = Map::Size() / 4;
|
||||
uint update_freq = Map::Size() / 4;
|
||||
const TileIndexDiffC *data;
|
||||
|
||||
for (TileIndex tile = 0; tile != Map::Size(); ++tile) {
|
||||
if ((tile % update_freq) == 0) IncreaseGeneratingWorldProgress(GWP_LANDSCAPE);
|
||||
if ((static_cast<uint32_t>(tile) % update_freq) == 0) IncreaseGeneratingWorldProgress(GWP_LANDSCAPE);
|
||||
|
||||
if (!IsValidTile(tile)) continue;
|
||||
|
||||
|
@ -960,7 +960,7 @@ static void CreateDesertOrRainForest(uint desert_tropic_line)
|
|||
}
|
||||
|
||||
for (TileIndex tile = 0; tile != Map::Size(); ++tile) {
|
||||
if ((tile % update_freq) == 0) IncreaseGeneratingWorldProgress(GWP_LANDSCAPE);
|
||||
if ((static_cast<uint32_t>(tile) % update_freq) == 0) IncreaseGeneratingWorldProgress(GWP_LANDSCAPE);
|
||||
|
||||
if (!IsValidTile(tile)) continue;
|
||||
|
||||
|
|
|
@ -50,9 +50,9 @@ void FlowMapper::Run(LinkGraphJob &job) const
|
|||
/* Scale by time the graph has been running without being compressed. Add 1 to avoid
|
||||
* division by 0 if spawn date == last compression date. This matches
|
||||
* LinkGraph::Monthly(). */
|
||||
uint runtime = job.JoinDate() - job.Settings().recalc_time / SECONDS_PER_DAY - job.LastCompression() + 1;
|
||||
auto runtime = job.JoinDate() - job.Settings().recalc_time / SECONDS_PER_DAY - job.LastCompression() + 1;
|
||||
for (auto &it : flows) {
|
||||
it.second.ScaleToMonthly(runtime);
|
||||
it.second.ScaleToMonthly(static_cast<int32_t>(runtime));
|
||||
}
|
||||
}
|
||||
/* Clear paths. */
|
||||
|
|
|
@ -65,7 +65,7 @@ void LinkGraph::ShiftDates(TimerGameCalendar::Date interval)
|
|||
|
||||
void LinkGraph::Compress()
|
||||
{
|
||||
this->last_compression = (TimerGameCalendar::date + this->last_compression) / 2;
|
||||
this->last_compression = static_cast<int32_t>(TimerGameCalendar::date + this->last_compression) / 2;
|
||||
for (NodeID node1 = 0; node1 < this->Size(); ++node1) {
|
||||
this->nodes[node1].supply /= 2;
|
||||
for (BaseEdge &edge : this->nodes[node1].edges) {
|
||||
|
|
|
@ -186,7 +186,7 @@ public:
|
|||
*/
|
||||
inline static uint Scale(uint val, TimerGameCalendar::Date target_age, TimerGameCalendar::Date orig_age)
|
||||
{
|
||||
return val > 0 ? std::max(1U, val * target_age / orig_age) : 0;
|
||||
return val > 0 ? std::max(1U, val * static_cast<int32_t>(target_age) / static_cast<int32_t>(orig_age)) : 0;
|
||||
}
|
||||
|
||||
/** Bare constructor, only for save/load. */
|
||||
|
@ -249,7 +249,7 @@ public:
|
|||
*/
|
||||
inline uint Monthly(uint base) const
|
||||
{
|
||||
return base * 30 / (TimerGameCalendar::date - this->last_compression + 1);
|
||||
return base * 30 / static_cast<int32_t>(TimerGameCalendar::date - this->last_compression + 1);
|
||||
}
|
||||
|
||||
NodeID AddNode(const Station *st);
|
||||
|
|
|
@ -178,7 +178,7 @@ void StateGameLoop_LinkGraphPauseControl()
|
|||
}
|
||||
} else if (_pause_mode == PM_UNPAUSED &&
|
||||
TimerGameCalendar::date_fract == LinkGraphSchedule::SPAWN_JOIN_TICK - 2 &&
|
||||
TimerGameCalendar::date % (_settings_game.linkgraph.recalc_interval / SECONDS_PER_DAY) == (_settings_game.linkgraph.recalc_interval / SECONDS_PER_DAY) / 2 &&
|
||||
static_cast<int32_t>(TimerGameCalendar::date) % (_settings_game.linkgraph.recalc_interval / SECONDS_PER_DAY) == (_settings_game.linkgraph.recalc_interval / SECONDS_PER_DAY) / 2 &&
|
||||
LinkGraphSchedule::instance.IsJoinWithUnfinishedJobDue()) {
|
||||
/* Perform check two TimerGameCalendar::date_fract ticks before we would join, to make
|
||||
* sure it also works in multiplayer. */
|
||||
|
@ -205,7 +205,7 @@ void AfterLoad_LinkGraphPauseControl()
|
|||
void OnTick_LinkGraph()
|
||||
{
|
||||
if (TimerGameCalendar::date_fract != LinkGraphSchedule::SPAWN_JOIN_TICK) return;
|
||||
TimerGameCalendar::Date offset = TimerGameCalendar::date % (_settings_game.linkgraph.recalc_interval / SECONDS_PER_DAY);
|
||||
TimerGameCalendar::Date offset = static_cast<int32_t>(TimerGameCalendar::date) % (_settings_game.linkgraph.recalc_interval / SECONDS_PER_DAY);
|
||||
if (offset == 0) {
|
||||
LinkGraphSchedule::instance.SpawnNext();
|
||||
} else if (offset == (_settings_game.linkgraph.recalc_interval / SECONDS_PER_DAY) / 2) {
|
||||
|
|
|
@ -53,7 +53,7 @@ public:
|
|||
if constexpr (std::is_enum_v<T>) {
|
||||
this->Write(static_cast<std::underlying_type_t<const T>>(data));
|
||||
} else if constexpr (std::is_base_of_v<StrongTypedefBase, T>) {
|
||||
this->Write(static_cast<typename T::Type>(data));
|
||||
this->Write(static_cast<typename T::BaseType>(data));
|
||||
} else {
|
||||
this->Write(data);
|
||||
}
|
||||
|
@ -146,7 +146,7 @@ public:
|
|||
if constexpr (std::is_enum_v<T>) {
|
||||
data = static_cast<T>(this->Read<std::underlying_type_t<T>>());
|
||||
} else if constexpr (std::is_base_of_v<StrongTypedefBase, T>) {
|
||||
data = this->Read<typename T::Type>();
|
||||
data = this->Read<typename T::BaseType>();
|
||||
} else {
|
||||
data = this->Read<T>();
|
||||
}
|
||||
|
|
|
@ -227,8 +227,8 @@ void SerializeNetworkGameInfo(Packet *p, const NetworkServerGameInfo *info, bool
|
|||
}
|
||||
|
||||
/* NETWORK_GAME_INFO_VERSION = 3 */
|
||||
p->Send_uint32(info->game_date);
|
||||
p->Send_uint32(info->start_date);
|
||||
p->Send_uint32(static_cast<int32_t>(info->game_date));
|
||||
p->Send_uint32(static_cast<int32_t>(info->start_date));
|
||||
|
||||
/* NETWORK_GAME_INFO_VERSION = 2 */
|
||||
p->Send_uint8 (info->companies_max);
|
||||
|
@ -323,8 +323,8 @@ void DeserializeNetworkGameInfo(Packet *p, NetworkGameInfo *info, const GameInfo
|
|||
}
|
||||
|
||||
case 3:
|
||||
info->game_date = Clamp(p->Recv_uint32(), 0, MAX_DATE);
|
||||
info->start_date = Clamp(p->Recv_uint32(), 0, MAX_DATE);
|
||||
info->game_date = Clamp(p->Recv_uint32(), 0, static_cast<int32_t>(MAX_DATE));
|
||||
info->start_date = Clamp(p->Recv_uint32(), 0, static_cast<int32_t>(MAX_DATE));
|
||||
FALLTHROUGH;
|
||||
|
||||
case 2:
|
||||
|
|
|
@ -178,7 +178,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendWelcome()
|
|||
p->Send_string(""); // Used to be map-name.
|
||||
p->Send_uint32(_settings_game.game_creation.generation_seed);
|
||||
p->Send_uint8 (_settings_game.game_creation.landscape);
|
||||
p->Send_uint32(TimerGameCalendar::ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1));
|
||||
p->Send_uint32(static_cast<int32_t>(TimerGameCalendar::ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1)));
|
||||
p->Send_uint16(Map::SizeX());
|
||||
p->Send_uint16(Map::SizeY());
|
||||
|
||||
|
@ -208,7 +208,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendDate()
|
|||
{
|
||||
Packet *p = new Packet(ADMIN_PACKET_SERVER_DATE);
|
||||
|
||||
p->Send_uint32(TimerGameCalendar::date);
|
||||
p->Send_uint32(static_cast<int32_t>(TimerGameCalendar::date));
|
||||
this->SendPacket(p);
|
||||
|
||||
return NETWORK_RECV_STATUS_OKAY;
|
||||
|
@ -244,7 +244,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendClientInfo(const NetworkC
|
|||
p->Send_string(cs == nullptr ? "" : const_cast<NetworkAddress &>(cs->client_address).GetHostname());
|
||||
p->Send_string(ci->client_name);
|
||||
p->Send_uint8 (0); // Used to be language
|
||||
p->Send_uint32(ci->join_date);
|
||||
p->Send_uint32(static_cast<int32_t>(ci->join_date));
|
||||
p->Send_uint8 (ci->client_playas);
|
||||
|
||||
this->SendPacket(p);
|
||||
|
@ -329,7 +329,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCompanyInfo(const Company
|
|||
p->Send_string(GetString(STR_PRESIDENT_NAME));
|
||||
p->Send_uint8 (c->colour);
|
||||
p->Send_bool (NetworkCompanyIsPassworded(c->index));
|
||||
p->Send_uint32(c->inaugurated_year);
|
||||
p->Send_uint32(static_cast<int32_t>(c->inaugurated_year));
|
||||
p->Send_bool (c->is_ai);
|
||||
p->Send_uint8 (CeilDiv(c->months_of_bankruptcy, 3)); // send as quarters_of_bankruptcy
|
||||
|
||||
|
|
|
@ -6512,18 +6512,18 @@ bool GetGlobalVariable(byte param, uint32_t *value, const GRFFile *grffile)
|
|||
{
|
||||
switch (param) {
|
||||
case 0x00: // current date
|
||||
*value = std::max(TimerGameCalendar::date - DAYS_TILL_ORIGINAL_BASE_YEAR, TimerGameCalendar::Date(0));
|
||||
*value = static_cast<int32_t>(std::max(TimerGameCalendar::date - DAYS_TILL_ORIGINAL_BASE_YEAR, TimerGameCalendar::Date(0)));
|
||||
return true;
|
||||
|
||||
case 0x01: // current year
|
||||
*value = Clamp(TimerGameCalendar::year, ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR) - ORIGINAL_BASE_YEAR;
|
||||
*value = static_cast<int32_t>(Clamp(TimerGameCalendar::year, ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR) - ORIGINAL_BASE_YEAR);
|
||||
return true;
|
||||
|
||||
case 0x02: { // detailed date information: month of year (bit 0-7), day of month (bit 8-12), leap year (bit 15), day of year (bit 16-24)
|
||||
TimerGameCalendar::YearMonthDay ymd;
|
||||
TimerGameCalendar::ConvertDateToYMD(TimerGameCalendar::date, &ymd);
|
||||
TimerGameCalendar::Date start_of_year = TimerGameCalendar::ConvertYMDToDate(ymd.year, 0, 1);
|
||||
*value = ymd.month | (ymd.day - 1) << 8 | (TimerGameCalendar::IsLeapYear(ymd.year) ? 1 << 15 : 0) | (TimerGameCalendar::date - start_of_year) << 16;
|
||||
*value = ymd.month | (ymd.day - 1) << 8 | (TimerGameCalendar::IsLeapYear(ymd.year) ? 1 << 15 : 0) | static_cast<int32_t>(TimerGameCalendar::date - start_of_year) << 16;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -6629,11 +6629,11 @@ bool GetGlobalVariable(byte param, uint32_t *value, const GRFFile *grffile)
|
|||
return true;
|
||||
|
||||
case 0x23: // long format date
|
||||
*value = TimerGameCalendar::date;
|
||||
*value = static_cast<int32_t>(TimerGameCalendar::date);
|
||||
return true;
|
||||
|
||||
case 0x24: // long format year
|
||||
*value = TimerGameCalendar::year;
|
||||
*value = static_cast<int32_t>(TimerGameCalendar::year);
|
||||
return true;
|
||||
|
||||
default: return false;
|
||||
|
@ -7228,7 +7228,7 @@ static uint32_t GetPatchVariable(uint8_t param)
|
|||
{
|
||||
switch (param) {
|
||||
/* start year - 1920 */
|
||||
case 0x0B: return std::max(_settings_game.game_creation.starting_year, ORIGINAL_BASE_YEAR) - ORIGINAL_BASE_YEAR;
|
||||
case 0x0B: return static_cast<int32_t>(std::max(_settings_game.game_creation.starting_year, ORIGINAL_BASE_YEAR) - ORIGINAL_BASE_YEAR);
|
||||
|
||||
/* freight trains weight factor */
|
||||
case 0x0E: return _settings_game.vehicle.freight_trains;
|
||||
|
|
|
@ -572,7 +572,7 @@ static uint32_t VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *objec
|
|||
}
|
||||
|
||||
case 0x48: return v->GetEngine()->flags; // Vehicle Type Info
|
||||
case 0x49: return v->build_year;
|
||||
case 0x49: return static_cast<int32_t>(v->build_year);
|
||||
|
||||
case 0x4A:
|
||||
switch (v->type) {
|
||||
|
@ -597,7 +597,7 @@ static uint32_t VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *objec
|
|||
}
|
||||
|
||||
case 0x4B: // Long date of last service
|
||||
return v->date_of_last_service_newgrf;
|
||||
return static_cast<int32_t>(v->date_of_last_service_newgrf);
|
||||
|
||||
case 0x4C: // Current maximum speed in NewGRF units
|
||||
if (!v->IsPrimaryVehicle()) return 0;
|
||||
|
@ -829,7 +829,7 @@ static uint32_t VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *objec
|
|||
case 0x41: return GB(ClampTo<uint16_t>(v->age), 8, 8);
|
||||
case 0x42: return ClampTo<uint16_t>(v->max_age);
|
||||
case 0x43: return GB(ClampTo<uint16_t>(v->max_age), 8, 8);
|
||||
case 0x44: return Clamp(v->build_year, ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR) - ORIGINAL_BASE_YEAR;
|
||||
case 0x44: return static_cast<int32_t>(Clamp(v->build_year, ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR) - ORIGINAL_BASE_YEAR);
|
||||
case 0x45: return v->unitnumber;
|
||||
case 0x46: return v->GetEngine()->grf_prop.local_id;
|
||||
case 0x47: return GB(v->GetEngine()->grf_prop.local_id, 8, 8);
|
||||
|
@ -972,11 +972,11 @@ static uint32_t VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *objec
|
|||
}
|
||||
}
|
||||
case 0x48: return Engine::Get(this->self_type)->flags; // Vehicle Type Info
|
||||
case 0x49: return TimerGameCalendar::year; // 'Long' format build year
|
||||
case 0x4B: return TimerGameCalendar::date; // Long date of last service
|
||||
case 0x49: return static_cast<int32_t>(TimerGameCalendar::year); // 'Long' format build year
|
||||
case 0x4B: return static_cast<int32_t>(TimerGameCalendar::date); // Long date of last service
|
||||
case 0x92: return ClampTo<uint16_t>(TimerGameCalendar::date - DAYS_TILL_ORIGINAL_BASE_YEAR); // Date of last service
|
||||
case 0x93: return GB(ClampTo<uint16_t>(TimerGameCalendar::date - DAYS_TILL_ORIGINAL_BASE_YEAR), 8, 8);
|
||||
case 0xC4: return Clamp(TimerGameCalendar::year, ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR) - ORIGINAL_BASE_YEAR; // Build year
|
||||
case 0xC4: return static_cast<int32_t>(Clamp(TimerGameCalendar::year, ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR) - ORIGINAL_BASE_YEAR); // Build year
|
||||
case 0xC6: return Engine::Get(this->self_type)->grf_prop.local_id;
|
||||
case 0xC7: return GB(Engine::Get(this->self_type)->grf_prop.local_id, 8, 8);
|
||||
case 0xDA: return INVALID_VEHICLE; // Next vehicle
|
||||
|
|
|
@ -296,7 +296,7 @@ static uint32_t GetDistanceFromNearbyHouse(uint8_t parameter, TileIndex tile, Ho
|
|||
case 0x40: return (IsTileType(this->tile, MP_HOUSE) ? GetHouseBuildingStage(this->tile) : 0) | TileHash2Bit(TileX(this->tile), TileY(this->tile)) << 2;
|
||||
|
||||
/* Building age. */
|
||||
case 0x41: return IsTileType(this->tile, MP_HOUSE) ? GetHouseAge(this->tile) : 0;
|
||||
case 0x41: return static_cast<int32_t>(IsTileType(this->tile, MP_HOUSE) ? GetHouseAge(this->tile) : 0);
|
||||
|
||||
/* Town zone */
|
||||
case 0x42: return GetTownRadiusGroup(this->town, this->tile);
|
||||
|
|
|
@ -163,7 +163,7 @@ static uint32_t GetCountAndDistanceOfClosestInstance(byte param_setID, byte layo
|
|||
|
||||
switch (variable) {
|
||||
case 0x80: return this->tile;
|
||||
case 0x81: return GB(this->tile, 8, 8);
|
||||
case 0x81: return GB(static_cast<uint32_t>(this->tile), 8, 8);
|
||||
|
||||
/* Pointer to the town the industry is associated with */
|
||||
case 0x82: return this->industry->town->index;
|
||||
|
@ -247,7 +247,7 @@ static uint32_t GetCountAndDistanceOfClosestInstance(byte param_setID, byte layo
|
|||
return this->industry->founder | (is_ai ? 0x10000 : 0) | (colours << 24);
|
||||
}
|
||||
|
||||
case 0x46: return this->industry->construction_date; // Date when built - long format - (in days)
|
||||
case 0x46: return static_cast<int32_t>(this->industry->construction_date); // Date when built - long format - (in days)
|
||||
|
||||
/* Override flags from GS */
|
||||
case 0x47: return this->industry->ctlflags;
|
||||
|
@ -338,7 +338,7 @@ static uint32_t GetCountAndDistanceOfClosestInstance(byte param_setID, byte layo
|
|||
if (!IsValidCargoID(cargo)) return 0;
|
||||
auto it = this->industry->GetCargoAccepted(cargo);
|
||||
if (it == std::end(this->industry->accepted)) return 0; // invalid cargo
|
||||
if (variable == 0x6E) return it->last_accepted;
|
||||
if (variable == 0x6E) return static_cast<int32_t>(it->last_accepted);
|
||||
if (variable == 0x6F) return it->waiting;
|
||||
NOT_REACHED();
|
||||
}
|
||||
|
@ -348,7 +348,7 @@ static uint32_t GetCountAndDistanceOfClosestInstance(byte param_setID, byte layo
|
|||
|
||||
/* Industry structure access*/
|
||||
case 0x80: return this->industry->location.tile;
|
||||
case 0x81: return GB(this->industry->location.tile, 8, 8);
|
||||
case 0x81: return GB(static_cast<uint32_t>(this->industry->location.tile), 8, 8);
|
||||
/* Pointer to the town the industry is associated with */
|
||||
case 0x82: return this->industry->town->index;
|
||||
case 0x83:
|
||||
|
|
|
@ -277,7 +277,7 @@ static uint32_t GetCountAndDistanceOfClosestInstance(byte local_id, uint32_t grf
|
|||
break;
|
||||
|
||||
/* Construction date */
|
||||
case 0x42: return TimerGameCalendar::date;
|
||||
case 0x42: return static_cast<int32_t>(TimerGameCalendar::date);
|
||||
|
||||
/* Object founder information */
|
||||
case 0x44: return _current_company;
|
||||
|
@ -315,7 +315,7 @@ static uint32_t GetCountAndDistanceOfClosestInstance(byte local_id, uint32_t grf
|
|||
case 0x41: return GetTileSlope(this->tile) << 8 | GetTerrainType(this->tile);
|
||||
|
||||
/* Construction date */
|
||||
case 0x42: return this->obj->build_date;
|
||||
case 0x42: return static_cast<int32_t>(this->obj->build_date);
|
||||
|
||||
/* Animation counter */
|
||||
case 0x43: return GetAnimationFrame(this->tile);
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
case 0x40: return 0;
|
||||
case 0x41: return 0;
|
||||
case 0x42: return 0;
|
||||
case 0x43: return TimerGameCalendar::date;
|
||||
case 0x43: return static_cast<int32_t>(TimerGameCalendar::date);
|
||||
case 0x44: return HZB_TOWN_EDGE;
|
||||
}
|
||||
}
|
||||
|
@ -40,8 +40,8 @@
|
|||
case 0x41: return 0;
|
||||
case 0x42: return IsLevelCrossingTile(this->tile) && IsCrossingBarred(this->tile);
|
||||
case 0x43:
|
||||
if (IsRailDepotTile(this->tile)) return Depot::GetByTile(this->tile)->build_date;
|
||||
return TimerGameCalendar::date;
|
||||
if (IsRailDepotTile(this->tile)) return static_cast<int32_t>(Depot::GetByTile(this->tile)->build_date);
|
||||
return static_cast<int32_t>(TimerGameCalendar::date);
|
||||
case 0x44: {
|
||||
const Town *t = nullptr;
|
||||
if (IsRailDepotTile(this->tile)) {
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
case 0x40: return 0;
|
||||
case 0x41: return 0;
|
||||
case 0x42: return 0;
|
||||
case 0x43: return TimerGameCalendar::date;
|
||||
case 0x43: return static_cast<int32_t>(TimerGameCalendar::date);
|
||||
case 0x44: return HZB_TOWN_EDGE;
|
||||
}
|
||||
}
|
||||
|
@ -40,8 +40,8 @@
|
|||
case 0x41: return 0;
|
||||
case 0x42: return IsLevelCrossingTile(this->tile) && IsCrossingBarred(this->tile);
|
||||
case 0x43:
|
||||
if (IsRoadDepotTile(this->tile)) return Depot::GetByTile(this->tile)->build_date;
|
||||
return TimerGameCalendar::date;
|
||||
if (IsRoadDepotTile(this->tile)) return static_cast<int32_t>(Depot::GetByTile(this->tile)->build_date);
|
||||
return static_cast<int32_t>(TimerGameCalendar::date);
|
||||
case 0x44: {
|
||||
const Town *t = nullptr;
|
||||
if (IsRoadDepotTile(this->tile)) {
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
|
||||
/* Town properties */
|
||||
case 0x80: return this->t->xy;
|
||||
case 0x81: return GB(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 0x83: return GB(ClampTo<uint16_t>(this->t->cache.population), 8, 8);
|
||||
case 0x8A: return this->t->grow_counter / TOWN_GROWTH_TICKS;
|
||||
|
|
|
@ -430,7 +430,7 @@ struct AfterNewGRFScan : NewGRFScanCallback {
|
|||
MusicDriver::GetInstance()->SetVolume(_settings_client.music.music_vol);
|
||||
SetEffectVolume(_settings_client.music.effect_vol);
|
||||
|
||||
if (startyear != INVALID_YEAR) IConsoleSetSetting("game_creation.starting_year", startyear);
|
||||
if (startyear != INVALID_YEAR) IConsoleSetSetting("game_creation.starting_year", static_cast<int32_t>(startyear));
|
||||
if (generation_seed != GENERATE_NEW_SEED) _settings_newgame.game_creation.generation_seed = generation_seed;
|
||||
|
||||
if (!dedicated_host.empty()) {
|
||||
|
@ -1389,7 +1389,7 @@ void StateGameLoop()
|
|||
CallWindowGameTickEvent();
|
||||
NewsLoop();
|
||||
} else {
|
||||
if (_debug_desync_level > 2 && TimerGameCalendar::date_fract == 0 && (TimerGameCalendar::date & 0x1F) == 0) {
|
||||
if (_debug_desync_level > 2 && TimerGameCalendar::date_fract == 0 && (static_cast<int32_t>(TimerGameCalendar::date) & 0x1F) == 0) {
|
||||
/* Save the desync savegame if needed. */
|
||||
std::string name = fmt::format("dmp_cmds_{:08x}_{:08x}.sav", _settings_game.game_creation.generation_seed, TimerGameCalendar::date);
|
||||
SaveOrLoad(name, SLO_SAVE, DFT_GAME_FILE, AUTOSAVE_DIR, false);
|
||||
|
|
|
@ -1922,6 +1922,12 @@ static bool OrderConditionCompare(OrderConditionComparator occ, int variable, in
|
|||
}
|
||||
}
|
||||
|
||||
template <typename T, std::enable_if_t<std::is_base_of<StrongTypedefBase, T>::value, int> = 0>
|
||||
static bool OrderConditionCompare(OrderConditionComparator occ, T variable, int value)
|
||||
{
|
||||
return OrderConditionCompare(occ, static_cast<typename T::BaseType>(variable), value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a conditional order and determine the next order.
|
||||
* @param order the order the vehicle currently has
|
||||
|
|
|
@ -25,7 +25,7 @@ struct CYapfNodeKeyExitDir {
|
|||
|
||||
inline int CalcHash() const
|
||||
{
|
||||
return m_exitdir | (m_tile << 2);
|
||||
return m_exitdir | (static_cast<uint32_t>(m_tile) << 2);
|
||||
}
|
||||
|
||||
inline bool operator==(const CYapfNodeKeyExitDir &other) const
|
||||
|
@ -45,7 +45,7 @@ struct CYapfNodeKeyTrackDir : public CYapfNodeKeyExitDir
|
|||
{
|
||||
inline int CalcHash() const
|
||||
{
|
||||
return m_td | (m_tile << 4);
|
||||
return m_td | (static_cast<uint32_t>(m_tile) << 4);
|
||||
}
|
||||
|
||||
inline bool operator==(const CYapfNodeKeyTrackDir &other) const
|
||||
|
|
|
@ -225,7 +225,7 @@ RailTypes AddDateIntroducedRailTypes(RailTypes current, TimerGameCalendar::Date
|
|||
if (rti->label == 0) continue;
|
||||
|
||||
/* Not date introduced. */
|
||||
if (!IsInsideMM(rti->introduction_date, 0, MAX_DATE)) continue;
|
||||
if (!IsInsideMM(rti->introduction_date, 0, static_cast<int32_t>(MAX_DATE))) continue;
|
||||
|
||||
/* Not yet introduced at this date. */
|
||||
if (rti->introduction_date > date) continue;
|
||||
|
|
|
@ -115,7 +115,7 @@ bool HasRoadTypeAvail(const CompanyID company, RoadType roadtype)
|
|||
if (rti->label == 0) return false;
|
||||
|
||||
/* Not yet introduced at this date. */
|
||||
if (IsInsideMM(rti->introduction_date, 0, MAX_DATE) && rti->introduction_date > TimerGameCalendar::date) return false;
|
||||
if (IsInsideMM(rti->introduction_date, 0, static_cast<int32_t>(MAX_DATE)) && rti->introduction_date > TimerGameCalendar::date) return false;
|
||||
|
||||
/*
|
||||
* Do not allow building hidden road types, except when a town may build it.
|
||||
|
@ -173,7 +173,7 @@ RoadTypes AddDateIntroducedRoadTypes(RoadTypes current, TimerGameCalendar::Date
|
|||
if (rti->label == 0) continue;
|
||||
|
||||
/* Not date introduced. */
|
||||
if (!IsInsideMM(rti->introduction_date, 0, MAX_DATE)) continue;
|
||||
if (!IsInsideMM(rti->introduction_date, 0, static_cast<int32_t>(MAX_DATE))) continue;
|
||||
|
||||
/* Not yet introduced at this date. */
|
||||
if (rti->introduction_date > date) continue;
|
||||
|
|
|
@ -169,7 +169,7 @@ struct MAP2ChunkHandler : ChunkHandler {
|
|||
std::array<uint16_t, MAP_SL_BUF_SIZE> buf;
|
||||
TileIndex size = Map::Size();
|
||||
|
||||
SlSetLength(size * sizeof(uint16_t));
|
||||
SlSetLength(static_cast<uint32_t>(size) * sizeof(uint16_t));
|
||||
for (TileIndex i = 0; i != size;) {
|
||||
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = Tile(i++).m2();
|
||||
SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT16);
|
||||
|
@ -344,7 +344,7 @@ struct MAP8ChunkHandler : ChunkHandler {
|
|||
std::array<uint16_t, MAP_SL_BUF_SIZE> buf;
|
||||
TileIndex size = Map::Size();
|
||||
|
||||
SlSetLength(size * sizeof(uint16_t));
|
||||
SlSetLength(static_cast<uint32_t>(size) * sizeof(uint16_t));
|
||||
for (TileIndex i = 0; i != size;) {
|
||||
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = Tile(i++).m8();
|
||||
SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT16);
|
||||
|
|
|
@ -93,9 +93,6 @@ struct OldChunks {
|
|||
OldChunkProc *proc; ///< Pointer to function that is called with OC_CHUNK
|
||||
};
|
||||
|
||||
/* If it fails, check lines above.. */
|
||||
static_assert(sizeof(TileIndex) == 4);
|
||||
|
||||
extern uint _bump_assert_value;
|
||||
byte ReadByte(LoadgameState *ls);
|
||||
bool LoadChunk(LoadgameState *ls, void *base, const OldChunks *chunks);
|
||||
|
|
|
@ -57,8 +57,8 @@ static void FixTTDMapArray()
|
|||
/* _old_map3 is moved to _m::m3 and _m::m4 */
|
||||
for (TileIndex t = 0; t < OLD_MAP_SIZE; t++) {
|
||||
Tile tile(t);
|
||||
tile.m3() = _old_map3[t * 2];
|
||||
tile.m4() = _old_map3[t * 2 + 1];
|
||||
tile.m3() = _old_map3[static_cast<uint32_t>(t) * 2];
|
||||
tile.m4() = _old_map3[static_cast<uint32_t>(t) * 2 + 1];
|
||||
}
|
||||
|
||||
for (TileIndex t = 0; t < OLD_MAP_SIZE; t++) {
|
||||
|
@ -416,7 +416,7 @@ static bool FixTTOEngines()
|
|||
if (TimerGameCalendar::date >= e->intro_date && HasBit(e->info.climates, 0)) {
|
||||
e->flags |= ENGINE_AVAILABLE;
|
||||
e->company_avail = MAX_UVALUE(CompanyMask);
|
||||
e->age = TimerGameCalendar::date > e->intro_date ? (TimerGameCalendar::date - e->intro_date) / 30 : 0;
|
||||
e->age = TimerGameCalendar::date > e->intro_date ? static_cast<int32_t>(TimerGameCalendar::date - e->intro_date) / 30 : 0;
|
||||
}
|
||||
} else {
|
||||
/* Using data from TTO savegame */
|
||||
|
|
|
@ -63,5 +63,5 @@
|
|||
{
|
||||
if (!IsValidBaseStation(station_id)) return ScriptDate::DATE_INVALID;
|
||||
|
||||
return (ScriptDate::Date)::BaseStation::Get(station_id)->build_date;
|
||||
return (ScriptDate::Date)(int32_t)::BaseStation::Get(station_id)->build_date;
|
||||
}
|
||||
|
|
|
@ -50,5 +50,5 @@ static NetworkClientInfo *FindClientInfo(ScriptClient::ClientID client)
|
|||
{
|
||||
NetworkClientInfo *ci = FindClientInfo(client);
|
||||
if (ci == nullptr) return ScriptDate::DATE_INVALID;
|
||||
return (ScriptDate::Date)ci->join_date;
|
||||
return (ScriptDate::Date)(int32_t)ci->join_date;
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
/* static */ ScriptDate::Date ScriptDate::GetCurrentDate()
|
||||
{
|
||||
return (ScriptDate::Date)TimerGameCalendar::date;
|
||||
return (ScriptDate::Date)(int32_t)TimerGameCalendar::date;
|
||||
}
|
||||
|
||||
/* static */ SQInteger ScriptDate::GetYear(ScriptDate::Date date)
|
||||
|
@ -31,7 +31,7 @@
|
|||
|
||||
::TimerGameCalendar::YearMonthDay ymd;
|
||||
::TimerGameCalendar::ConvertDateToYMD(date, &ymd);
|
||||
return ymd.year;
|
||||
return (int32_t)ymd.year;
|
||||
}
|
||||
|
||||
/* static */ SQInteger ScriptDate::GetMonth(ScriptDate::Date date)
|
||||
|
@ -58,7 +58,7 @@
|
|||
if (day_of_month < 1 || day_of_month > 31) return DATE_INVALID;
|
||||
if (year < 0 || year > MAX_YEAR) return DATE_INVALID;
|
||||
|
||||
return (ScriptDate::Date)::TimerGameCalendar::ConvertYMDToDate(year, month - 1, day_of_month);
|
||||
return (ScriptDate::Date)(int32_t)::TimerGameCalendar::ConvertYMDToDate(year, month - 1, day_of_month);
|
||||
}
|
||||
|
||||
/* static */ SQInteger ScriptDate::GetSystemTime()
|
||||
|
|
|
@ -31,7 +31,7 @@ public:
|
|||
* compose valid date values for a known year, month and day.
|
||||
*/
|
||||
enum Date {
|
||||
DATE_INVALID = ::INVALID_DATE, ///< A value representing an invalid date.
|
||||
DATE_INVALID = (int32_t)::INVALID_DATE, ///< A value representing an invalid date.
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -139,7 +139,7 @@
|
|||
if (!IsValidEngine(engine_id)) return -1;
|
||||
if (GetVehicleType(engine_id) == ScriptVehicle::VT_RAIL && IsWagon(engine_id)) return -1;
|
||||
|
||||
return ::Engine::Get(engine_id)->GetLifeLengthInDays();
|
||||
return (int32_t)::Engine::Get(engine_id)->GetLifeLengthInDays();
|
||||
}
|
||||
|
||||
/* static */ Money ScriptEngine::GetRunningCost(EngineID engine_id)
|
||||
|
@ -179,7 +179,7 @@
|
|||
{
|
||||
if (!IsValidEngine(engine_id)) return ScriptDate::DATE_INVALID;
|
||||
|
||||
return (ScriptDate::Date)::Engine::Get(engine_id)->intro_date;
|
||||
return (ScriptDate::Date)(int32_t)::Engine::Get(engine_id)->intro_date;
|
||||
}
|
||||
|
||||
/* static */ ScriptVehicle::VehicleType ScriptEngine::GetVehicleType(EngineID engine_id)
|
||||
|
|
|
@ -53,7 +53,7 @@
|
|||
{
|
||||
Industry *i = Industry::GetIfValid(industry_id);
|
||||
if (i == nullptr) return ScriptDate::DATE_INVALID;
|
||||
return (ScriptDate::Date)i->construction_date;
|
||||
return (ScriptDate::Date)(int32_t)i->construction_date;
|
||||
}
|
||||
|
||||
/* static */ bool ScriptIndustry::SetText(IndustryID industry_id, Text *text)
|
||||
|
@ -222,7 +222,7 @@
|
|||
{
|
||||
Industry *i = Industry::GetIfValid(industry_id);
|
||||
if (i == nullptr) return 0;
|
||||
return i->last_prod_year;
|
||||
return (int32_t)i->last_prod_year;
|
||||
}
|
||||
|
||||
/* static */ ScriptDate::Date ScriptIndustry::GetCargoLastAcceptedDate(IndustryID industry_id, CargoID cargo_type)
|
||||
|
@ -232,11 +232,11 @@
|
|||
|
||||
if (!::IsValidCargoID(cargo_type)) {
|
||||
auto it = std::max_element(std::begin(i->accepted), std::end(i->accepted), [](const auto &a, const auto &b) { return a.last_accepted < b.last_accepted; });
|
||||
return (ScriptDate::Date)it->last_accepted;
|
||||
return (ScriptDate::Date)(int32_t)it->last_accepted;
|
||||
} else {
|
||||
auto it = i->GetCargoAccepted(cargo_type);
|
||||
if (it == std::end(i->accepted)) return ScriptDate::DATE_INVALID;
|
||||
return (ScriptDate::Date)it->last_accepted;
|
||||
return (ScriptDate::Date)(int32_t)it->last_accepted;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -182,7 +182,7 @@ static inline bool StoryPageElementTypeRequiresText(StoryPageElementType type)
|
|||
EnforcePrecondition(ScriptDate::DATE_INVALID, IsValidStoryPage(story_page_id));
|
||||
EnforceDeityMode(ScriptDate::DATE_INVALID);
|
||||
|
||||
return (ScriptDate::Date)StoryPage::Get(story_page_id)->date;
|
||||
return (ScriptDate::Date)(int32_t)StoryPage::Get(story_page_id)->date;
|
||||
}
|
||||
|
||||
/* static */ bool ScriptStoryPage::SetDate(StoryPageID story_page_id, ScriptDate::Date date)
|
||||
|
|
|
@ -311,7 +311,7 @@
|
|||
{
|
||||
if (!IsValidVehicle(vehicle_id)) return -1;
|
||||
|
||||
return ::Vehicle::Get(vehicle_id)->age;
|
||||
return (int32_t)::Vehicle::Get(vehicle_id)->age;
|
||||
}
|
||||
|
||||
/* static */ SQInteger ScriptVehicle::GetWagonAge(VehicleID vehicle_id, SQInteger wagon)
|
||||
|
@ -323,21 +323,21 @@
|
|||
if (v->type == VEH_TRAIN) {
|
||||
while (wagon-- > 0) v = ::Train::From(v)->GetNextUnit();
|
||||
}
|
||||
return v->age;
|
||||
return (int32_t)v->age;
|
||||
}
|
||||
|
||||
/* static */ SQInteger ScriptVehicle::GetMaxAge(VehicleID vehicle_id)
|
||||
{
|
||||
if (!IsPrimaryVehicle(vehicle_id)) return -1;
|
||||
|
||||
return ::Vehicle::Get(vehicle_id)->max_age;
|
||||
return (int32_t)::Vehicle::Get(vehicle_id)->max_age;
|
||||
}
|
||||
|
||||
/* static */ SQInteger ScriptVehicle::GetAgeLeft(VehicleID vehicle_id)
|
||||
{
|
||||
if (!IsPrimaryVehicle(vehicle_id)) return -1;
|
||||
|
||||
return ::Vehicle::Get(vehicle_id)->max_age - ::Vehicle::Get(vehicle_id)->age;
|
||||
return (int32_t)(::Vehicle::Get(vehicle_id)->max_age - ::Vehicle::Get(vehicle_id)->age);
|
||||
}
|
||||
|
||||
/* static */ SQInteger ScriptVehicle::GetCurrentSpeed(VehicleID vehicle_id)
|
||||
|
|
|
@ -149,12 +149,46 @@ struct IntSettingDesc : SettingDesc {
|
|||
*/
|
||||
typedef void PostChangeCallback(int32_t value);
|
||||
|
||||
IntSettingDesc(const SaveLoad &save, SettingFlag flags, bool startup, int32_t def,
|
||||
int32_t min, uint32_t max, int32_t interval, StringID str, StringID str_help, StringID str_val,
|
||||
template <
|
||||
typename Tdef,
|
||||
typename Tmin,
|
||||
typename Tmax,
|
||||
typename Tinterval,
|
||||
std::enable_if_t<std::disjunction_v<std::is_convertible<Tdef, int32_t>, std::is_base_of<StrongTypedefBase, Tdef>>, int> = 0,
|
||||
std::enable_if_t<std::disjunction_v<std::is_convertible<Tmin, int32_t>, std::is_base_of<StrongTypedefBase, Tmin>>, int> = 0,
|
||||
std::enable_if_t<std::disjunction_v<std::is_convertible<Tmax, uint32_t>, std::is_base_of<StrongTypedefBase, Tmax>>, int> = 0,
|
||||
std::enable_if_t<std::disjunction_v<std::is_convertible<Tinterval, int32_t>, std::is_base_of<StrongTypedefBase, Tinterval>>, int> = 0
|
||||
>
|
||||
IntSettingDesc(const SaveLoad &save, SettingFlag flags, bool startup, Tdef def,
|
||||
Tmin min, Tmax max, Tinterval interval, StringID str, StringID str_help, StringID str_val,
|
||||
SettingCategory cat, PreChangeCheck pre_check, PostChangeCallback post_callback) :
|
||||
SettingDesc(save, flags, startup), def(def), min(min), max(max), interval(interval),
|
||||
SettingDesc(save, flags, startup),
|
||||
str(str), str_help(str_help), str_val(str_val), cat(cat), pre_check(pre_check),
|
||||
post_callback(post_callback) {}
|
||||
post_callback(post_callback) {
|
||||
if constexpr (std::is_base_of_v<StrongTypedefBase, Tdef>) {
|
||||
this->def = static_cast<typename Tdef::BaseType>(def);
|
||||
} else {
|
||||
this->def = def;
|
||||
}
|
||||
|
||||
if constexpr (std::is_base_of_v<StrongTypedefBase, Tmin>) {
|
||||
this->min = static_cast<typename Tmin::BaseType>(min);
|
||||
} else {
|
||||
this->min = min;
|
||||
}
|
||||
|
||||
if constexpr (std::is_base_of_v<StrongTypedefBase, Tmax>) {
|
||||
this->max = static_cast<typename Tmax::BaseType>(max);
|
||||
} else {
|
||||
this->max = max;
|
||||
}
|
||||
|
||||
if constexpr (std::is_base_of_v<StrongTypedefBase, Tinterval>) {
|
||||
this->interval = static_cast<typename Tinterval::BaseType>(interval);
|
||||
} else {
|
||||
this->interval = interval;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t def; ///< default value given when none is present
|
||||
int32_t min; ///< minimum values
|
||||
|
@ -193,7 +227,7 @@ struct BoolSettingDesc : IntSettingDesc {
|
|||
BoolSettingDesc(const SaveLoad &save, SettingFlag flags, bool startup, bool def,
|
||||
StringID str, StringID str_help, StringID str_val, SettingCategory cat,
|
||||
PreChangeCheck pre_check, PostChangeCallback post_callback) :
|
||||
IntSettingDesc(save, flags, startup, def, 0, 1, 0, str, str_help, str_val, cat,
|
||||
IntSettingDesc(save, flags, startup, def ? 1 : 0, 0, 1, 0, str, str_help, str_val, cat,
|
||||
pre_check, post_callback) {}
|
||||
|
||||
static std::optional<bool> ParseSingleValue(const char *str);
|
||||
|
|
|
@ -126,6 +126,13 @@
|
|||
# define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
// See https://learn.microsoft.com/en-us/cpp/cpp/empty-bases?view=msvc-170
|
||||
# define EMPTY_BASES __declspec(empty_bases)
|
||||
#else
|
||||
# define EMPTY_BASES
|
||||
#endif
|
||||
|
||||
/* Stuff for MSVC */
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "gfx_type.h"
|
||||
#include "core/bitmath_func.hpp"
|
||||
#include "core/span_type.hpp"
|
||||
#include "core/strong_typedef_type.hpp"
|
||||
#include "vehicle_type.h"
|
||||
|
||||
/**
|
||||
|
@ -82,6 +83,18 @@ void SetDParam(size_t n, uint64_t v);
|
|||
void SetDParamMaxValue(size_t n, uint64_t max_value, uint min_count = 0, FontSize size = FS_NORMAL);
|
||||
void SetDParamMaxDigits(size_t n, uint count, FontSize size = FS_NORMAL);
|
||||
|
||||
template <typename T, std::enable_if_t<std::is_base_of<StrongTypedefBase, T>::value, int> = 0>
|
||||
void SetDParam(size_t n, T v)
|
||||
{
|
||||
SetDParam(n, static_cast<typename T::BaseType>(v));
|
||||
}
|
||||
|
||||
template <typename T, std::enable_if_t<std::is_base_of<StrongTypedefBase, T>::value, int> = 0>
|
||||
void SetDParamMaxValue(size_t n, T max_value, uint min_count = 0, FontSize size = FS_NORMAL)
|
||||
{
|
||||
SetDParamMaxValue(n, static_cast<typename T::BaseType>(max_value), min_count, size);
|
||||
}
|
||||
|
||||
void SetDParamStr(size_t n, const char *str);
|
||||
void SetDParamStr(size_t n, const std::string &str);
|
||||
void SetDParamStr(size_t n, std::string &&str);
|
||||
|
|
|
@ -153,6 +153,12 @@ public:
|
|||
this->parameters[n].string_view = nullptr;
|
||||
}
|
||||
|
||||
template <typename T, std::enable_if_t<std::is_base_of<StrongTypedefBase, T>::value, int> = 0>
|
||||
void SetParam(size_t n, T v)
|
||||
{
|
||||
SetParam(n, static_cast<typename T::BaseType>(v));
|
||||
}
|
||||
|
||||
void SetParam(size_t n, const char *str)
|
||||
{
|
||||
assert(n < this->parameters.size());
|
||||
|
|
|
@ -82,7 +82,7 @@ static const RoadTypeInfo _original_roadtypes[] = {
|
|||
0x01,
|
||||
|
||||
/* introduction date */
|
||||
MIN_YEAR,
|
||||
static_cast<int32_t>(MIN_YEAR),
|
||||
|
||||
/* roadtypes required for this to be introduced */
|
||||
ROADTYPES_NONE,
|
||||
|
|
|
@ -81,36 +81,13 @@ enum TropicZone {
|
|||
|
||||
/**
|
||||
* The index/ID of a Tile.
|
||||
*
|
||||
* It is compatible with int32 / int64 for easy math throughout the code.
|
||||
*/
|
||||
struct TileIndex : StrongIntegralTypedef<uint32_t, TileIndex> {
|
||||
using StrongIntegralTypedef<uint32_t, TileIndex>::StrongIntegralTypedef;
|
||||
using TileIndex = StrongType::Typedef<uint32_t, struct TileIndexTag, StrongType::Implicit, StrongType::Compare, StrongType::Integer, StrongType::Compatible<int32_t>, StrongType::Compatible<int64_t>>;
|
||||
|
||||
debug_inline constexpr TileIndex() = default;
|
||||
debug_inline constexpr TileIndex(const TileIndex &o) = default;
|
||||
debug_inline constexpr TileIndex(TileIndex &&o) = default;
|
||||
|
||||
debug_inline constexpr TileIndex(const uint32_t &value) : StrongIntegralTypedef<uint32_t, TileIndex>(value) {}
|
||||
|
||||
debug_inline constexpr TileIndex &operator =(const TileIndex &rhs) { this->value = rhs.value; return *this; }
|
||||
debug_inline constexpr TileIndex &operator =(TileIndex &&rhs) { this->value = std::move(rhs.value); return *this; }
|
||||
debug_inline constexpr TileIndex &operator =(const uint32_t &rhs) { this->value = rhs; return *this; }
|
||||
|
||||
/** Implicit conversion to the base type for e.g. array indexing. */
|
||||
debug_inline constexpr operator uint32_t() const { return this->value; }
|
||||
|
||||
/* Import operators from the base class into our overload set. */
|
||||
using StrongIntegralTypedef::operator ==;
|
||||
using StrongIntegralTypedef::operator !=;
|
||||
using StrongIntegralTypedef::operator +;
|
||||
using StrongIntegralTypedef::operator -;
|
||||
|
||||
/* Add comparison and add/sub for signed ints as e.g. 0 is signed and will
|
||||
* match ambiguously when only unsigned overloads are present. */
|
||||
constexpr bool operator ==(int rhs) const { return this->value == (uint32_t)rhs; }
|
||||
constexpr bool operator !=(int rhs) const { return this->value != (uint32_t)rhs; }
|
||||
constexpr TileIndex operator +(int rhs) const { return { (uint32_t)(this->value + rhs) }; }
|
||||
constexpr TileIndex operator -(int rhs) const { return { (uint32_t)(this->value - rhs) }; }
|
||||
};
|
||||
/* Make sure the size is as expected. */
|
||||
static_assert(sizeof(TileIndex) == 4);
|
||||
|
||||
/**
|
||||
* The very nice invalid tile marker
|
||||
|
|
|
@ -75,8 +75,8 @@ static const uint16_t _accum_days_for_month[] = {
|
|||
*/
|
||||
|
||||
/* There are 97 leap years in 400 years */
|
||||
TimerGameCalendar::Year yr = 400 * (date / (DAYS_IN_YEAR * 400 + 97));
|
||||
int rem = date % (DAYS_IN_YEAR * 400 + 97);
|
||||
TimerGameCalendar::Year yr = 400 * (static_cast<int32_t>(date) / (DAYS_IN_YEAR * 400 + 97));
|
||||
int rem = static_cast<int32_t>(date) % (DAYS_IN_YEAR * 400 + 97);
|
||||
uint16_t x;
|
||||
|
||||
if (rem >= DAYS_IN_YEAR * 100 + 25) {
|
||||
|
@ -141,7 +141,7 @@ static const uint16_t _accum_days_for_month[] = {
|
|||
*/
|
||||
/* static */ bool TimerGameCalendar::IsLeapYear(TimerGameCalendar::Year yr)
|
||||
{
|
||||
return yr % 4 == 0 && (yr % 100 != 0 || yr % 400 == 0);
|
||||
return static_cast<int32_t>(yr) % 4 == 0 && (static_cast<int32_t>(yr) % 100 != 0 || static_cast<int32_t>(yr) % 400 == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -215,7 +215,7 @@ void TimerManager<TimerGameCalendar>::Elapsed(TimerGameCalendar::TElapsed delta)
|
|||
timer->Elapsed(TimerGameCalendar::DAY);
|
||||
}
|
||||
|
||||
if ((TimerGameCalendar::date % 7) == 3) {
|
||||
if ((static_cast<int32_t>(TimerGameCalendar::date) % 7) == 3) {
|
||||
for (auto timer : timers) {
|
||||
timer->Elapsed(TimerGameCalendar::WEEK);
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#define TIMER_GAME_CALENDAR_H
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "../core/strong_typedef_type.hpp"
|
||||
|
||||
/**
|
||||
* Timer that is increased every 27ms, and counts towards ticks / days / months / years.
|
||||
|
@ -76,12 +77,18 @@ public:
|
|||
struct TStorage {
|
||||
};
|
||||
|
||||
using Date = int32_t; ///< The type to store our dates in
|
||||
using DateFract = uint16_t; ///< The fraction of a date we're in, i.e. the number of ticks since the last date changeover
|
||||
/** The type to store our dates in. */
|
||||
using Date = StrongType::Typedef<int32_t, struct DateTag, StrongType::Explicit, StrongType::Compare, StrongType::Integer>;
|
||||
|
||||
using Year = int32_t; ///< Type for the year, note: 0 based, i.e. starts at the year 0.
|
||||
using Month = uint8_t; ///< Type for the month, note: 0 based, i.e. 0 = January, 11 = December.
|
||||
using Day = uint8_t; ///< Type for the day of the month, note: 1 based, first day of a month is 1.
|
||||
/** The fraction of a date we're in, i.e. the number of ticks since the last date changeover. */
|
||||
using DateFract = uint16_t;
|
||||
|
||||
/** Type for the year, note: 0 based, i.e. starts at the year 0. */
|
||||
using Year = StrongType::Typedef<int32_t, struct YearTag, StrongType::Explicit, StrongType::Compare, StrongType::Integer>;
|
||||
/** Type for the month, note: 0 based, i.e. 0 = January, 11 = December. */
|
||||
using Month = uint8_t;
|
||||
/** Type for the day of the month, note: 1 based, first day of a month is 1. */
|
||||
using Day = uint8_t;
|
||||
|
||||
/**
|
||||
* Data structure to convert between Date and triplet (year, month, and day).
|
||||
|
|
|
@ -426,7 +426,7 @@ void UpdateVehicleTimetable(Vehicle *v, bool travelling)
|
|||
just_started = !HasBit(v->vehicle_flags, VF_TIMETABLE_STARTED);
|
||||
|
||||
if (v->timetable_start != 0) {
|
||||
v->lateness_counter = (TimerGameCalendar::date - v->timetable_start) * DAY_TICKS + TimerGameCalendar::date_fract;
|
||||
v->lateness_counter = static_cast<int32_t>(TimerGameCalendar::date - v->timetable_start) * DAY_TICKS + TimerGameCalendar::date_fract;
|
||||
v->timetable_start = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -2510,7 +2510,7 @@ struct ScenarioEditorToolbarWindow : Window {
|
|||
value = atoi(str);
|
||||
} else {
|
||||
/* An empty string means revert to the default */
|
||||
value = DEF_START_YEAR;
|
||||
value = static_cast<int32_t>(DEF_START_YEAR);
|
||||
}
|
||||
SetStartingYear(value);
|
||||
|
||||
|
|
|
@ -595,7 +595,7 @@ static void TileLoop_Town(TileIndex tile)
|
|||
/* Binomial distribution per tick, by a series of coin flips */
|
||||
/* Reduce generation rate to a 1/4, using tile bits to spread out distribution.
|
||||
* As tick counter is incremented by 256 between each call, we ignore the lower 8 bits. */
|
||||
if (GB(TimerGameTick::counter, 8, 2) == GB(tile, 0, 2)) {
|
||||
if (GB(TimerGameTick::counter, 8, 2) == GB(static_cast<uint32_t>(tile), 0, 2)) {
|
||||
/* Make a bitmask with up to 32 bits set, one for each potential pax */
|
||||
int genmax = (hs->population + 7) / 8;
|
||||
uint32_t genmask = (genmax >= 32) ? 0xFFFFFFFF : ((1 << genmax) - 1);
|
||||
|
@ -871,7 +871,7 @@ RoadType GetTownRoadType(const Town *t)
|
|||
if (!HasBit(rti->flags, ROTF_TOWN_BUILD)) continue;
|
||||
|
||||
/* Not yet introduced at this date. */
|
||||
if (IsInsideMM(rti->introduction_date, 0, MAX_DATE) && rti->introduction_date > TimerGameCalendar::date) continue;
|
||||
if (IsInsideMM(rti->introduction_date, 0, static_cast<int32_t>(MAX_DATE)) && rti->introduction_date > TimerGameCalendar::date) continue;
|
||||
|
||||
if (best != nullptr) {
|
||||
if ((rti->max_speed == 0 ? assume_max_speed : rti->max_speed) < (best->max_speed == 0 ? assume_max_speed : best->max_speed)) continue;
|
||||
|
|
|
@ -1400,7 +1400,7 @@ void AgeVehicle(Vehicle *v)
|
|||
str = STR_NEWS_VEHICLE_IS_GETTING_OLD;
|
||||
} else if (age == DateAtStartOfYear(0)) {
|
||||
str = STR_NEWS_VEHICLE_IS_GETTING_VERY_OLD;
|
||||
} else if (age > DateAtStartOfYear(0) && (age % DAYS_IN_LEAP_YEAR) == 0) {
|
||||
} else if (age > DateAtStartOfYear(0) && (static_cast<int32_t>(age) % DAYS_IN_LEAP_YEAR) == 0) {
|
||||
str = STR_NEWS_VEHICLE_IS_GETTING_VERY_OLD_AND;
|
||||
} else {
|
||||
return;
|
||||
|
|
Loading…
Reference in New Issue