diff options
author | Michael Lutz <michi@icosahedron.de> | 2021-11-06 23:11:22 +0100 |
---|---|---|
committer | Michael Lutz <michi@icosahedron.de> | 2021-12-16 22:28:32 +0100 |
commit | b0990fcff7358e839468e5cf811ffddc8b9d73e2 (patch) | |
tree | 08da5cbe48d5dcc46e8c539e0da1aa8f6233bad9 | |
parent | 4fc055d6e97e76faf53ff3f29e36a4a4549bf6e7 (diff) | |
download | openttd-b0990fcff7358e839468e5cf811ffddc8b9d73e2.tar.xz |
Codechange: Make TileIndex a "strong" typedef to give it a distinct type.
This is accomplished by changing it to a single member struct with the
appropriate operator overloads to make it all work with not too much
source modifications.
-rw-r--r-- | src/build_vehicle_gui.cpp | 6 | ||||
-rw-r--r-- | src/cargopacket.cpp | 2 | ||||
-rw-r--r-- | src/company_func.h | 2 | ||||
-rw-r--r-- | src/company_gui.cpp | 6 | ||||
-rw-r--r-- | src/core/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/core/strong_typedef_type.hpp | 73 | ||||
-rw-r--r-- | src/disaster_vehicle.cpp | 2 | ||||
-rw-r--r-- | src/group_gui.cpp | 4 | ||||
-rw-r--r-- | src/map.cpp | 2 | ||||
-rw-r--r-- | src/map_func.h | 4 | ||||
-rw-r--r-- | src/newgrf_railtype.cpp | 2 | ||||
-rw-r--r-- | src/newgrf_roadtype.cpp | 2 | ||||
-rw-r--r-- | src/news_gui.cpp | 2 | ||||
-rw-r--r-- | src/saveload/oldloader_sl.cpp | 2 | ||||
-rw-r--r-- | src/script/api/script_company.cpp | 2 | ||||
-rw-r--r-- | src/script/api/script_types.hpp | 2 | ||||
-rw-r--r-- | src/script/squirrel_helper.hpp | 3 | ||||
-rw-r--r-- | src/tile_type.h | 24 | ||||
-rw-r--r-- | src/tilearea_type.h | 30 | ||||
-rw-r--r-- | src/timetable_gui.cpp | 8 | ||||
-rw-r--r-- | src/town_gui.cpp | 4 | ||||
-rw-r--r-- | src/tree_cmd.cpp | 4 | ||||
-rw-r--r-- | src/water_cmd.cpp | 6 |
23 files changed, 160 insertions, 33 deletions
diff --git a/src/build_vehicle_gui.cpp b/src/build_vehicle_gui.cpp index 34d771090..7901b4574 100644 --- a/src/build_vehicle_gui.cpp +++ b/src/build_vehicle_gui.cpp @@ -1081,7 +1081,7 @@ struct BuildVehicleWindow : Window { { this->vehicle_type = type; this->listview_mode = tile == INVALID_TILE; - this->window_number = this->listview_mode ? (int)type : tile; + this->window_number = this->listview_mode ? (int)type : (int)tile; this->sel_engine = INVALID_ENGINE; @@ -1116,7 +1116,7 @@ struct BuildVehicleWindow : Window { this->details_height = ((this->vehicle_type == VEH_TRAIN) ? 10 : 9); - this->FinishInitNested(tile == INVALID_TILE ? (int)type : tile); + this->FinishInitNested(tile == INVALID_TILE ? (int)type : (int)tile); this->owner = (tile != INVALID_TILE) ? GetTileOwner(tile) : _local_company; @@ -1683,7 +1683,7 @@ void ShowBuildVehicleWindow(TileIndex tile, VehicleType type) * so if tile == INVALID_TILE (Available XXX Window), use 'type' as unique number. * As it always is a low value, it won't collide with any real tile * number. */ - uint num = (tile == INVALID_TILE) ? (int)type : tile; + uint num = (tile == INVALID_TILE) ? (int)type : (int)tile; assert(IsCompanyBuildableVehicleType(type)); diff --git a/src/cargopacket.cpp b/src/cargopacket.cpp index 86bba0261..e9c6e1aa7 100644 --- a/src/cargopacket.cpp +++ b/src/cargopacket.cpp @@ -75,7 +75,7 @@ CargoPacket::CargoPacket(uint16 count, byte days_in_transit, StationID source, T source_id(source_id), source(source), source_xy(source_xy), - loaded_at_xy(loaded_at_xy) + loaded_at_xy(loaded_at_xy.value) { assert(count != 0); this->source_type = source_type; diff --git a/src/company_func.h b/src/company_func.h index 01f585910..97e1e6e82 100644 --- a/src/company_func.h +++ b/src/company_func.h @@ -27,7 +27,7 @@ void UpdateLandscapingLimits(); bool CheckCompanyHasMoney(CommandCost &cost); void SubtractMoneyFromCompany(const CommandCost& cost); void SubtractMoneyFromCompanyFract(CompanyID company, const CommandCost& cost); -CommandCost CheckOwnership(Owner owner, TileIndex tile = 0); +CommandCost CheckOwnership(Owner owner, TileIndex tile = 0U); CommandCost CheckTileOwnership(TileIndex tile); extern CompanyID _local_company; diff --git a/src/company_gui.cpp b/src/company_gui.cpp index 6ab3b0aa7..7a6e68dea 100644 --- a/src/company_gui.cpp +++ b/src/company_gui.cpp @@ -2576,11 +2576,11 @@ struct CompanyWindow : Window break; case WID_C_BUY_SHARE: - DoCommandP(CMD_BUY_SHARE_IN_COMPANY, STR_ERROR_CAN_T_BUY_25_SHARE_IN_THIS, 0, this->window_number, 0); + DoCommandP(CMD_BUY_SHARE_IN_COMPANY, STR_ERROR_CAN_T_BUY_25_SHARE_IN_THIS, (TileIndex)0, this->window_number, 0); break; case WID_C_SELL_SHARE: - DoCommandP(CMD_SELL_SHARE_IN_COMPANY, STR_ERROR_CAN_T_SELL_25_SHARE_IN, 0, this->window_number, 0); + DoCommandP(CMD_SELL_SHARE_IN_COMPANY, STR_ERROR_CAN_T_SELL_25_SHARE_IN, (TileIndex)0, this->window_number, 0); break; case WID_C_COMPANY_PASSWORD: @@ -2771,7 +2771,7 @@ struct BuyCompanyWindow : Window { break; case WID_BC_YES: - DoCommandP(CMD_BUY_COMPANY, STR_ERROR_CAN_T_BUY_COMPANY, 0, this->window_number, 0); + DoCommandP(CMD_BUY_COMPANY, STR_ERROR_CAN_T_BUY_COMPANY, (TileIndex)0, this->window_number, 0); break; } } diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index b94ed77e9..1c14067ae 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -28,4 +28,5 @@ add_files( smallvec_type.hpp span_type.hpp string_compare_type.hpp + strong_typedef_type.hpp ) diff --git a/src/core/strong_typedef_type.hpp b/src/core/strong_typedef_type.hpp new file mode 100644 index 000000000..b5df28b2f --- /dev/null +++ b/src/core/strong_typedef_type.hpp @@ -0,0 +1,73 @@ +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>. + */ + +/** @file strong_typedef_type.hpp Type (helpers) for making a strong typedef that is a distinct type. */ + +#ifndef STRONG_TYPEDEF_TYPE_HPP +#define STRONG_TYPEDEF_TYPE_HPP + +/** Non-templated base for #StrongTypedef 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; + + T value{}; ///< Backing storage field. + + constexpr StrongTypedef() = default; + constexpr StrongTypedef(const StrongTypedef &o) = default; + constexpr StrongTypedef(StrongTypedef &&o) = default; + + constexpr StrongTypedef(const T &value) : value(value) {} + + constexpr Tthis &operator =(const StrongTypedef &rhs) { this->value = rhs.value; return static_cast<Tthis &>(*this); } + constexpr Tthis &operator =(StrongTypedef &&rhs) { this->value = std::move(rhs.value); return static_cast<Tthis &>(*this); } + constexpr Tthis &operator =(const T &rhs) { this->value = rhs; return static_cast<Tthis &>(*this); } + + explicit constexpr operator T() const { return this->value; } + + constexpr bool operator ==(const StrongTypedef &rhs) const { return this->value == rhs.value; } + constexpr bool operator !=(const StrongTypedef &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; } +}; + +/** + * 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; + + 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 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 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 }; } +}; + +#endif /* STRONG_TYPEDEF_TYPE_HPP */ diff --git a/src/disaster_vehicle.cpp b/src/disaster_vehicle.cpp index 126e48f5f..63f4188a8 100644 --- a/src/disaster_vehicle.cpp +++ b/src/disaster_vehicle.cpp @@ -941,7 +941,7 @@ void ReleaseDisastersTargetingIndustry(IndustryID i) /* primary disaster vehicles that have chosen target */ if (v->subtype == ST_AIRPLANE || v->subtype == ST_HELICOPTER) { /* if it has chosen target, and it is this industry (yes, dest_tile is IndustryID here), set order to "leaving map peacefully" */ - if (v->current_order.GetDestination() > 0 && v->dest_tile == i) v->current_order.SetDestination(3); + if (v->current_order.GetDestination() > 0 && v->dest_tile == (uint32)i) v->current_order.SetDestination(3); } } } diff --git a/src/group_gui.cpp b/src/group_gui.cpp index e9ded9536..8beab1884 100644 --- a/src/group_gui.cpp +++ b/src/group_gui.cpp @@ -641,7 +641,7 @@ public: if (confirmed) { VehicleGroupWindow *w = (VehicleGroupWindow*)win; w->vli.index = ALL_GROUP; - DoCommandP(CMD_DELETE_GROUP, STR_ERROR_GROUP_CAN_T_DELETE, 0, w->group_confirm, 0); + DoCommandP(CMD_DELETE_GROUP, STR_ERROR_GROUP_CAN_T_DELETE, (TileIndex)0, w->group_confirm, 0); } } @@ -965,7 +965,7 @@ public: case ADI_REMOVE_ALL: // Remove all Vehicles from the selected group assert(Group::IsValidID(this->vli.index)); - DoCommandP(CMD_REMOVE_ALL_VEHICLES_GROUP, STR_ERROR_GROUP_CAN_T_REMOVE_ALL_VEHICLES, 0, this->vli.index, 0); + DoCommandP(CMD_REMOVE_ALL_VEHICLES_GROUP, STR_ERROR_GROUP_CAN_T_REMOVE_ALL_VEHICLES, (TileIndex)0, this->vli.index, 0); break; default: NOT_REACHED(); } diff --git a/src/map.cpp b/src/map.cpp index 308e28e49..2a08d656e 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -84,7 +84,7 @@ TileIndex TileAdd(TileIndex tile, TileIndexDiff add, char buf[512]; seprintf(buf, lastof(buf), "TILE_ADD(%s) when adding 0x%.4X and 0x%.4X failed", - exp, tile, add); + exp, (uint32)tile, add); #if !defined(_MSC_VER) fprintf(stderr, "%s:%d %s\n", file, line, buf); #else diff --git a/src/map_func.h b/src/map_func.h index b02ba5777..34cc5ee0e 100644 --- a/src/map_func.h +++ b/src/map_func.h @@ -204,7 +204,7 @@ static inline TileIndex TileVirtXY(uint x, uint y) */ static inline uint TileX(TileIndex tile) { - return tile & MapMaxX(); + return tile.value & MapMaxX(); } /** @@ -214,7 +214,7 @@ static inline uint TileX(TileIndex tile) */ static inline uint TileY(TileIndex tile) { - return tile >> MapLogX(); + return tile.value >> MapLogX(); } /** diff --git a/src/newgrf_railtype.cpp b/src/newgrf_railtype.cpp index 471978952..c6e2b1c40 100644 --- a/src/newgrf_railtype.cpp +++ b/src/newgrf_railtype.cpp @@ -18,7 +18,7 @@ /* virtual */ uint32 RailTypeScopeResolver::GetRandomBits() const { - uint tmp = CountBits(this->tile + (TileX(this->tile) + TileY(this->tile)) * TILE_SIZE); + uint tmp = CountBits(static_cast<uint32>(this->tile + (TileX(this->tile) + TileY(this->tile)) * TILE_SIZE)); return GB(tmp, 0, 2); } diff --git a/src/newgrf_roadtype.cpp b/src/newgrf_roadtype.cpp index e4d29e4c5..8eb8325c7 100644 --- a/src/newgrf_roadtype.cpp +++ b/src/newgrf_roadtype.cpp @@ -18,7 +18,7 @@ /* virtual */ uint32 RoadTypeScopeResolver::GetRandomBits() const { - uint tmp = CountBits(this->tile + (TileX(this->tile) + TileY(this->tile)) * TILE_SIZE); + uint tmp = CountBits(static_cast<uint32>(this->tile + (TileX(this->tile) + TileY(this->tile)) * TILE_SIZE)); return GB(tmp, 0, 2); } diff --git a/src/news_gui.cpp b/src/news_gui.cpp index 75b84a443..69ab19b3b 100644 --- a/src/news_gui.cpp +++ b/src/news_gui.cpp @@ -311,7 +311,7 @@ struct NewsWindow : Window { /* Initialize viewport if it exists. */ NWidgetViewport *nvp = this->GetWidget<NWidgetViewport>(WID_N_VIEWPORT); if (nvp != nullptr) { - nvp->InitializeViewport(this, ni->reftype1 == NR_VEHICLE ? 0x80000000 | ni->ref1 : GetReferenceTile(ni->reftype1, ni->ref1), ZOOM_LVL_NEWS); + nvp->InitializeViewport(this, ni->reftype1 == NR_VEHICLE ? 0x80000000 | ni->ref1 : (uint32)GetReferenceTile(ni->reftype1, ni->ref1), ZOOM_LVL_NEWS); if (this->ni->flags & NF_NO_TRANSPARENT) nvp->disp_flags |= ND_NO_TRANSPARENCY; if ((this->ni->flags & NF_INCOLOUR) == 0) { nvp->disp_flags |= ND_SHADE_GREY; diff --git a/src/saveload/oldloader_sl.cpp b/src/saveload/oldloader_sl.cpp index 8b33c02db..cfcc6bd37 100644 --- a/src/saveload/oldloader_sl.cpp +++ b/src/saveload/oldloader_sl.cpp @@ -1343,7 +1343,7 @@ bool LoadOldVehicle(LoadgameState *ls, int num) if (_cargo_count != 0 && CargoPacket::CanAllocateItem()) { StationID source = (_cargo_source == 0xFF) ? INVALID_STATION : _cargo_source; - TileIndex source_xy = (source != INVALID_STATION) ? Station::Get(source)->xy : 0; + TileIndex source_xy = (source != INVALID_STATION) ? Station::Get(source)->xy : (TileIndex)0; v->cargo.Append(new CargoPacket(_cargo_count, _cargo_days, source, source_xy, source_xy)); } } diff --git a/src/script/api/script_company.cpp b/src/script/api/script_company.cpp index dddcc950c..876ad84c5 100644 --- a/src/script/api/script_company.cpp +++ b/src/script/api/script_company.cpp @@ -238,7 +238,7 @@ EnforcePrecondition(false, company != COMPANY_INVALID); /* Network commands only allow 0 to indicate invalid tiles, not INVALID_TILE */ - return ScriptObject::DoCommand(tile == INVALID_TILE ? 0 : tile , (uint32)(delta), company | expenses_type << 8 , CMD_CHANGE_BANK_BALANCE); + return ScriptObject::DoCommand(tile == INVALID_TILE ? (TileIndex)0U : tile , (uint32)(delta), company | expenses_type << 8 , CMD_CHANGE_BANK_BALANCE); } /* static */ bool ScriptCompany::BuildCompanyHQ(TileIndex tile) diff --git a/src/script/api/script_types.hpp b/src/script/api/script_types.hpp index 0d652a2d2..a570aabf7 100644 --- a/src/script/api/script_types.hpp +++ b/src/script/api/script_types.hpp @@ -82,6 +82,7 @@ #include "../../core/overflowsafe_type.hpp" #include "../../company_type.h" +#include "../../tile_type.h" #include <squirrel.h> /* Define all types here, so we don't have to include the whole _type.h maze */ @@ -100,7 +101,6 @@ typedef uint32 StringID; ///< The ID of a string. typedef uint16 SubsidyID; ///< The ID of a subsidy. typedef uint16 StoryPageID; ///< The ID of a story page. typedef uint16 StoryPageElementID; ///< The ID of a story page element. -typedef uint32 TileIndex; ///< The ID of a tile (just named differently). typedef uint16 TownID; ///< The ID of a town. typedef uint32 VehicleID; ///< The ID of a vehicle. diff --git a/src/script/squirrel_helper.hpp b/src/script/squirrel_helper.hpp index 6a3ba6125..7308006fa 100644 --- a/src/script/squirrel_helper.hpp +++ b/src/script/squirrel_helper.hpp @@ -14,6 +14,7 @@ #include "../core/smallvec_type.hpp" #include "../economy_type.h" #include "../string_func.h" +#include "../tile_type.h" #include "squirrel_helper_type.hpp" template <class CL, ScriptType ST> const char *GetClassName(); @@ -85,6 +86,7 @@ namespace SQConvert { template <> inline int Return<int32> (HSQUIRRELVM vm, int32 res) { sq_pushinteger(vm, res); return 1; } template <> inline int Return<int64> (HSQUIRRELVM vm, int64 res) { sq_pushinteger(vm, res); return 1; } template <> inline int Return<Money> (HSQUIRRELVM vm, Money res) { sq_pushinteger(vm, res); return 1; } + template <> inline int Return<TileIndex> (HSQUIRRELVM vm, TileIndex res) { sq_pushinteger(vm, (int32)res.value); return 1; } template <> inline int Return<bool> (HSQUIRRELVM vm, bool res) { sq_pushbool (vm, res); return 1; } template <> inline int Return<char *> (HSQUIRRELVM vm, char *res) { if (res == nullptr) sq_pushnull(vm); else { sq_pushstring(vm, res, -1); free(res); } return 1; } template <> inline int Return<const char *>(HSQUIRRELVM vm, const char *res) { if (res == nullptr) sq_pushnull(vm); else { sq_pushstring(vm, res, -1); } return 1; } @@ -103,6 +105,7 @@ namespace SQConvert { template <> inline int16 GetParam(ForceType<int16> , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; } template <> inline int32 GetParam(ForceType<int32> , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; } template <> inline int64 GetParam(ForceType<int64> , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; } + template <> inline TileIndex GetParam(ForceType<TileIndex> , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return TileIndex((uint32)(int32)tmp); } template <> inline Money GetParam(ForceType<Money> , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; } template <> inline bool GetParam(ForceType<bool> , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQBool tmp; sq_getbool (vm, index, &tmp); return tmp != 0; } template <> inline void *GetParam(ForceType<void *> , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer tmp; sq_getuserpointer(vm, index, &tmp); return tmp; } diff --git a/src/tile_type.h b/src/tile_type.h index 73fd0e97e..6b5514d90 100644 --- a/src/tile_type.h +++ b/src/tile_type.h @@ -10,6 +10,8 @@ #ifndef TILE_TYPE_H #define TILE_TYPE_H +#include "core/strong_typedef_type.hpp" + static const uint TILE_SIZE = 16; ///< Tile size in world coordinates. static const uint TILE_UNIT_MASK = TILE_SIZE - 1; ///< For masking in/out the inner-tile world coordinate units. static const uint TILE_PIXELS = 32; ///< Pixel distance between tile columns/rows in #ZOOM_LVL_BASE. @@ -80,11 +82,29 @@ enum TropicZone { /** * The index/ID of a Tile. */ -typedef uint32 TileIndex; +struct TileIndex : StrongIntegralTypedef<uint32, TileIndex> { + using StrongIntegralTypedef<uint32, TileIndex>::StrongIntegralTypedef; + + /** Implicit conversion to the base type for e.g. array indexing. */ + constexpr operator uint32() 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)rhs; } + constexpr bool operator !=(int rhs) const { return this->value != (uint32)rhs; } + constexpr TileIndex operator +(int rhs) const { return { (uint32)(this->value + rhs) }; } + constexpr TileIndex operator -(int rhs) const { return { (uint32)(this->value - rhs) }; } +}; /** * The very nice invalid tile marker */ -static const TileIndex INVALID_TILE = (TileIndex)-1; +static inline constexpr TileIndex INVALID_TILE = TileIndex{ (uint32)-1 }; #endif /* TILE_TYPE_H */ diff --git a/src/tilearea_type.h b/src/tilearea_type.h index e6d9bad60..b6af998a7 100644 --- a/src/tilearea_type.h +++ b/src/tilearea_type.h @@ -147,6 +147,36 @@ public: * Allocate a new iterator that is a copy of this one. */ virtual TileIterator *Clone() const = 0; + + /** + * Equality comparison. + */ + bool operator ==(const TileIterator &rhs) const + { + return this->tile == rhs.tile; + } + /** + * Inequality comparison. + */ + bool operator !=(const TileIterator &rhs) const + { + return this->tile != rhs.tile; + } + + /** + * Equality comparison. + */ + bool operator ==(const TileIndex &rhs) const + { + return this->tile == rhs; + } + /** + * Inequality comparison. + */ + bool operator !=(const TileIndex &rhs) const + { + return this->tile != rhs; + } }; /** Iterator to iterate over a tile area (rectangle) of the map. */ diff --git a/src/timetable_gui.cpp b/src/timetable_gui.cpp index 00ab50115..a205a505e 100644 --- a/src/timetable_gui.cpp +++ b/src/timetable_gui.cpp @@ -578,25 +578,25 @@ struct TimetableWindow : Window { case WID_VT_CLEAR_TIME: { // Clear waiting time. uint32 p1 = PackTimetableArgs(v, this->sel_index, false); - DoCommandP(CMD_CHANGE_TIMETABLE, STR_ERROR_CAN_T_TIMETABLE_VEHICLE, 0, p1, 0); + DoCommandP(CMD_CHANGE_TIMETABLE, STR_ERROR_CAN_T_TIMETABLE_VEHICLE, (TileIndex)0, p1, 0); break; } case WID_VT_CLEAR_SPEED: { // Clear max speed button. uint32 p1 = PackTimetableArgs(v, this->sel_index, true); - DoCommandP(CMD_CHANGE_TIMETABLE, STR_ERROR_CAN_T_TIMETABLE_VEHICLE, 0, p1, UINT16_MAX); + DoCommandP(CMD_CHANGE_TIMETABLE, STR_ERROR_CAN_T_TIMETABLE_VEHICLE, (TileIndex)0, p1, UINT16_MAX); break; } case WID_VT_RESET_LATENESS: // Reset the vehicle's late counter. - DoCommandP(CMD_SET_VEHICLE_ON_TIME, STR_ERROR_CAN_T_TIMETABLE_VEHICLE, 0, v->index, 0); + DoCommandP(CMD_SET_VEHICLE_ON_TIME, STR_ERROR_CAN_T_TIMETABLE_VEHICLE, (TileIndex)0, v->index, 0); break; case WID_VT_AUTOFILL: { // Autofill the timetable. uint32 p2 = 0; if (!HasBit(v->vehicle_flags, VF_AUTOFILL_TIMETABLE)) SetBit(p2, 0); if (_ctrl_pressed) SetBit(p2, 1); - DoCommandP(CMD_AUTOFILL_TIMETABLE, STR_ERROR_CAN_T_TIMETABLE_VEHICLE, 0, v->index, p2); + DoCommandP(CMD_AUTOFILL_TIMETABLE, STR_ERROR_CAN_T_TIMETABLE_VEHICLE, (TileIndex)0, v->index, p2); break; } diff --git a/src/town_gui.cpp b/src/town_gui.cpp index 660b1ac98..cb88c5c00 100644 --- a/src/town_gui.cpp +++ b/src/town_gui.cpp @@ -474,12 +474,12 @@ public: _warn_town_no_roads = true; } - DoCommandP(CMD_EXPAND_TOWN, STR_ERROR_CAN_T_EXPAND_TOWN, 0, this->window_number, 0); + DoCommandP(CMD_EXPAND_TOWN, STR_ERROR_CAN_T_EXPAND_TOWN, (TileIndex)0, this->window_number, 0); break; } case WID_TV_DELETE: // delete town - only available on Scenario editor - DoCommandP(CMD_DELETE_TOWN, STR_ERROR_TOWN_CAN_T_DELETE, 0, this->window_number, 0); + DoCommandP(CMD_DELETE_TOWN, STR_ERROR_TOWN_CAN_T_DELETE, (TileIndex)0, this->window_number, 0); break; } } diff --git a/src/tree_cmd.cpp b/src/tree_cmd.cpp index a16ad7b82..ab439cd58 100644 --- a/src/tree_cmd.cpp +++ b/src/tree_cmd.cpp @@ -399,7 +399,7 @@ CommandCost CmdPlantTree(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 Company *c = (_game_mode != GM_EDITOR) ? Company::GetIfValid(_current_company) : nullptr; int limit = (c == nullptr ? INT32_MAX : GB(c->tree_limit, 16, 16)); - TileArea ta(tile, p2); + TileArea ta(tile, (TileIndex)p2); for (TileIndex current_tile : ta) { switch (GetTileType(current_tile)) { case MP_TREES: @@ -528,7 +528,7 @@ static void DrawTile_Trees(TileInfo *ti) /* Do not draw trees when the invisible trees setting is set */ if (IsInvisibilitySet(TO_TREES)) return; - uint tmp = CountBits(ti->tile + ti->x + ti->y); + uint tmp = CountBits(static_cast<uint32>(ti->tile + ti->x + ti->y)); uint index = GB(tmp, 0, 2) + (GetTreeType(ti->tile) << 2); /* different tree styles above one of the grounds */ diff --git a/src/water_cmd.cpp b/src/water_cmd.cpp index 145b8084d..6e357f9c6 100644 --- a/src/water_cmd.cpp +++ b/src/water_cmd.cpp @@ -454,7 +454,7 @@ CommandCost CmdBuildCanal(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 /* Outside the editor you can only drag canals, and not areas */ if (_game_mode != GM_EDITOR) { - TileArea ta(tile, p1); + TileArea ta(tile, (TileIndex)p1); if (ta.w != 1 && ta.h != 1) return CMD_ERROR; } @@ -462,9 +462,9 @@ CommandCost CmdBuildCanal(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 std::unique_ptr<TileIterator> iter; if (HasBit(p2, 2)) { - iter = std::make_unique<DiagonalTileIterator>(tile, p1); + iter = std::make_unique<DiagonalTileIterator>(tile, (TileIndex)p1); } else { - iter = std::make_unique<OrthogonalTileIterator>(tile, p1); + iter = std::make_unique<OrthogonalTileIterator>(tile, (TileIndex)p1); } for (; *iter != INVALID_TILE; ++(*iter)) { |