diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -87,7 +87,6 @@ add_files(
clear_cmd.cpp
clear_func.h
clear_map.h
- cmd_helper.h
command.cpp
command_func.h
command_type.h
diff --git a/src/bridge_gui.cpp b/src/bridge_gui.cpp
--- a/src/bridge_gui.cpp
+++ b/src/bridge_gui.cpp
@@ -20,7 +20,6 @@
#include "sortlist_type.h"
#include "widgets/dropdown_func.h"
#include "core/geometry_func.hpp"
-#include "cmd_helper.h"
#include "tunnelbridge_map.h"
#include "road_gui.h"
#include "tunnelbridge_cmd.h"
diff --git a/src/cmd_helper.h b/src/cmd_helper.h
deleted file mode 100644
--- a/src/cmd_helper.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * 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 .
- */
-
-/** @file cmd_helper.h Helper functions to extract data from command parameters. */
-
-#ifndef CMD_HELPER_H
-#define CMD_HELPER_H
-
-#include "core/enum_type.hpp"
-#include "core/bitmath_func.hpp"
-
-/**
- * Extracts a given type from a value.
- * @tparam T The type of data we're looking for.
- * @tparam S The offset in the data.
- * @tparam N The amount of bits to read.
- * @tparam U The type of data passed to us.
- * @param v The data to extract the value from.
- */
-template static inline T Extract(U v)
-{
- /* Check if there are enough bits in v */
- static_assert(N == EnumPropsT::num_bits);
- static_assert(S + N <= sizeof(U) * 8);
- static_assert(EnumPropsT::end <= (1 << N));
- U masked = GB(v, S, N);
- return IsInsideMM(masked, EnumPropsT::begin, EnumPropsT::end) ? (T)masked : EnumPropsT::invalid;
-}
-
-/**
- * Check if an enum value is inside it's valid values.
- * @tparam T Type of enum.
- * @param v The value to validate
- * @return True if enum is valid.
- */
-template static constexpr inline bool IsEnumValid(T v) noexcept
-{
- return IsInsideMM(v, EnumPropsT::begin, EnumPropsT::end);
-}
-
-#endif /* CMD_HELPER_H */
diff --git a/src/company_cmd.cpp b/src/company_cmd.cpp
--- a/src/company_cmd.cpp
+++ b/src/company_cmd.cpp
@@ -14,7 +14,6 @@
#include "core/backup_type.hpp"
#include "town.h"
#include "news_func.h"
-#include "cmd_helper.h"
#include "command_func.h"
#include "network/network.h"
#include "network/network_func.h"
diff --git a/src/gfx_func.h b/src/gfx_func.h
--- a/src/gfx_func.h
+++ b/src/gfx_func.h
@@ -174,6 +174,17 @@ int GetCharacterHeight(FontSize size);
extern DrawPixelInfo *_cur_dpi;
+/**
+ * Checks if a Colours value is valid.
+ *
+ * @param colours The value to check
+ * @return true if the given value is a valid Colours.
+ */
+static inline bool IsValidColours(Colours colours)
+{
+ return colours < COLOUR_END;
+}
+
TextColour GetContrastColour(uint8 background, uint8 threshold = 128);
/**
diff --git a/src/group_cmd.cpp b/src/group_cmd.cpp
--- a/src/group_cmd.cpp
+++ b/src/group_cmd.cpp
@@ -8,7 +8,6 @@
/** @file group_cmd.cpp Handling of the engine groups */
#include "stdafx.h"
-#include "cmd_helper.h"
#include "command_func.h"
#include "train.h"
#include "vehiclelist.h"
diff --git a/src/industry_cmd.cpp b/src/industry_cmd.cpp
--- a/src/industry_cmd.cpp
+++ b/src/industry_cmd.cpp
@@ -40,7 +40,6 @@
#include "object_base.h"
#include "game/game.hpp"
#include "error.h"
-#include "cmd_helper.h"
#include "string_func.h"
#include "industry_cmd.h"
#include "landscape_cmd.h"
diff --git a/src/misc_cmd.cpp b/src/misc_cmd.cpp
--- a/src/misc_cmd.cpp
+++ b/src/misc_cmd.cpp
@@ -10,7 +10,6 @@
#include "stdafx.h"
#include "command_func.h"
#include "economy_func.h"
-#include "cmd_helper.h"
#include "window_func.h"
#include "textbuf_gui.h"
#include "network/network.h"
diff --git a/src/order_cmd.cpp b/src/order_cmd.cpp
--- a/src/order_cmd.cpp
+++ b/src/order_cmd.cpp
@@ -9,7 +9,6 @@
#include "stdafx.h"
#include "debug.h"
-#include "cmd_helper.h"
#include "command_func.h"
#include "company_func.h"
#include "news_func.h"
diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp
--- a/src/rail_cmd.cpp
+++ b/src/rail_cmd.cpp
@@ -8,7 +8,6 @@
/** @file rail_cmd.cpp Handling of rail tiles. */
#include "stdafx.h"
-#include "cmd_helper.h"
#include "viewport_func.h"
#include "command_func.h"
#include "depot_base.h"
@@ -966,7 +965,7 @@ CommandCost CmdRemoveRailroadTrack(DoCom
CommandCost CmdBuildTrainDepot(DoCommandFlag flags, TileIndex tile, RailType railtype, DiagDirection dir)
{
/* check railtype and valid direction for depot (0 through 3), 4 in total */
- if (!ValParamRailtype(railtype) || !IsEnumValid(dir)) return CMD_ERROR;
+ if (!ValParamRailtype(railtype) || !IsValidDiagDirection(dir)) return CMD_ERROR;
Slope tileh = GetTileSlope(tile);
diff --git a/src/road_cmd.cpp b/src/road_cmd.cpp
--- a/src/road_cmd.cpp
+++ b/src/road_cmd.cpp
@@ -8,7 +8,6 @@
/** @file road_cmd.cpp Commands related to road tiles. */
#include "stdafx.h"
-#include "cmd_helper.h"
#include "road.h"
#include "road_internal.h"
#include "viewport_func.h"
@@ -638,7 +637,7 @@ CommandCost CmdBuildRoad(DoCommandFlag f
}
/* do not allow building 'zero' road bits, code wouldn't handle it */
- if (pieces == ROAD_NONE || !IsEnumValid(pieces) || !IsEnumValid(toggle_drd)) return CMD_ERROR;
+ if (pieces == ROAD_NONE || !IsValidRoadBits(pieces) || !IsValidDisallowedRoadDirections(toggle_drd)) return CMD_ERROR;
if (!ValParamRoadType(rt)) return CMD_ERROR;
Slope tileh = GetTileSlope(tile);
@@ -979,7 +978,7 @@ CommandCost CmdBuildLongRoad(DoCommandFl
{
if (end_tile >= MapSize()) return CMD_ERROR;
- if (!ValParamRoadType(rt) || !IsEnumValid(axis) || !IsEnumValid(drd)) return CMD_ERROR;
+ if (!ValParamRoadType(rt) || !IsValidAxis(axis) || !IsValidDisallowedRoadDirections(drd)) return CMD_ERROR;
/* Only drag in X or Y direction dictated by the direction variable */
if (axis == AXIS_X && TileY(start_tile) != TileY(end_tile)) return CMD_ERROR; // x-axis
@@ -1075,7 +1074,7 @@ std::tuple CmdRemove
CommandCost cost(EXPENSES_CONSTRUCTION);
if (end_tile >= MapSize()) return { CMD_ERROR, 0 };
- if (!ValParamRoadType(rt) || !IsEnumValid(axis)) return { CMD_ERROR, 0 };
+ if (!ValParamRoadType(rt) || !IsValidAxis(axis)) return { CMD_ERROR, 0 };
/* Only drag in X or Y direction dictated by the direction variable */
if (axis == AXIS_X && TileY(start_tile) != TileY(end_tile)) return { CMD_ERROR, 0 }; // x-axis
@@ -1140,7 +1139,7 @@ std::tuple CmdRemove
*/
CommandCost CmdBuildRoadDepot(DoCommandFlag flags, TileIndex tile, RoadType rt, DiagDirection dir)
{
- if (!ValParamRoadType(rt) || !IsEnumValid(dir)) return CMD_ERROR;
+ if (!ValParamRoadType(rt) || !IsValidDiagDirection(dir)) return CMD_ERROR;
CommandCost cost(EXPENSES_CONSTRUCTION);
diff --git a/src/road_map.h b/src/road_map.h
--- a/src/road_map.h
+++ b/src/road_map.h
@@ -283,6 +283,17 @@ static inline bool HasTownOwnedRoad(Tile
}
/**
+ * Checks if a DisallowedRoadDirections is valid.
+ *
+ * @param wc The value to check
+ * @return true if the given value is a valid DisallowedRoadDirections.
+ */
+static inline bool IsValidDisallowedRoadDirections(DisallowedRoadDirections drt)
+{
+ return drt < DRD_END;
+}
+
+/**
* Gets the disallowed directions
* @param t the tile to get the directions from
* @return the disallowed directions
diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp
--- a/src/station_cmd.cpp
+++ b/src/station_cmd.cpp
@@ -10,7 +10,6 @@
#include "stdafx.h"
#include "aircraft.h"
#include "bridge_map.h"
-#include "cmd_helper.h"
#include "viewport_func.h"
#include "viewport_kdtree.h"
#include "command_func.h"
@@ -1257,7 +1256,7 @@ CommandCost CmdBuildRailStation(DoComman
CommandCost ret = CheckIfAuthorityAllowsNewStation(tile_org, flags);
if (ret.Failed()) return ret;
- if (!ValParamRailtype(rt) || !IsEnumValid(axis)) return CMD_ERROR;
+ if (!ValParamRailtype(rt) || !IsValidAxis(axis)) return CMD_ERROR;
/* Check if the given station class is valid */
if ((uint)spec_class >= StationClass::GetClassCount() || spec_class == STAT_CLASS_WAYP) return CMD_ERROR;
@@ -1818,7 +1817,7 @@ static CommandCost FindJoiningRoadStop(S
*/
CommandCost CmdBuildRoadStop(DoCommandFlag flags, TileIndex tile, uint8 width, uint8 length, RoadStopType stop_type, bool is_drive_through, DiagDirection ddir, RoadType rt, StationID station_to_join, bool adjacent)
{
- if (!ValParamRoadType(rt) || !IsEnumValid(ddir) || stop_type >= ROADSTOP_END) return CMD_ERROR;
+ if (!ValParamRoadType(rt) || !IsValidDiagDirection(ddir) || stop_type >= ROADSTOP_END) return CMD_ERROR;
bool reuse = (station_to_join != NEW_STATION);
if (!reuse) station_to_join = INVALID_STATION;
bool distant_join = (station_to_join != INVALID_STATION);
diff --git a/src/story.cpp b/src/story.cpp
--- a/src/story.cpp
+++ b/src/story.cpp
@@ -10,7 +10,6 @@
#include "stdafx.h"
#include "story_base.h"
#include "core/pool_func.hpp"
-#include "cmd_helper.h"
#include "command_func.h"
#include "company_base.h"
#include "company_func.h"
@@ -144,7 +143,9 @@ void StoryPageButtonData::SetVehicleType
/** Get the button background colour. */
Colours StoryPageButtonData::GetColour() const
{
- return Extract(this->referenced_id);
+ Colours colour = (Colours)GB(this->referenced_id, 0, 8);
+ if (!IsValidColours(colour)) return INVALID_COLOUR;
+ return colour;
}
StoryPageButtonFlags StoryPageButtonData::GetFlags() const
@@ -155,7 +156,9 @@ StoryPageButtonFlags StoryPageButtonData
/** Get the mouse cursor used while waiting for input for the button. */
StoryPageButtonCursor StoryPageButtonData::GetCursor() const
{
- return Extract(this->referenced_id);
+ StoryPageButtonCursor cursor = (StoryPageButtonCursor)GB(this->referenced_id, 8, 8);
+ if (!IsValidStoryPageButtonCursor(cursor)) return INVALID_SPBC;
+ return cursor;
}
/** Get the type of vehicles that are accepted by the button */
diff --git a/src/story_base.h b/src/story_base.h
--- a/src/story_base.h
+++ b/src/story_base.h
@@ -113,6 +113,17 @@ enum StoryPageButtonCursor : byte {
/** Define basic enum properties */
template <> struct EnumPropsT : MakeEnumPropsT {};
+/**
+ * Checks if a StoryPageButtonCursor value is valid.
+ *
+ * @param wc The value to check
+ * @return true if the given value is a valid StoryPageButtonCursor.
+ */
+static inline bool IsValidStoryPageButtonCursor(StoryPageButtonCursor cursor)
+{
+ return cursor < SPBC_END;
+}
+
/** Helper to construct packed "id" values for button-type StoryPageElement */
struct StoryPageButtonData {
uint32 referenced_id;
diff --git a/src/timetable_cmd.cpp b/src/timetable_cmd.cpp
--- a/src/timetable_cmd.cpp
+++ b/src/timetable_cmd.cpp
@@ -13,7 +13,6 @@
#include "date_func.h"
#include "window_func.h"
#include "vehicle_base.h"
-#include "cmd_helper.h"
#include "timetable_cmd.h"
#include "table/strings.h"
diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp
--- a/src/town_cmd.cpp
+++ b/src/town_cmd.cpp
@@ -14,7 +14,6 @@
#include "landscape.h"
#include "viewport_func.h"
#include "viewport_kdtree.h"
-#include "cmd_helper.h"
#include "command_func.h"
#include "industry.h"
#include "station_base.h"
diff --git a/src/tunnelbridge_cmd.cpp b/src/tunnelbridge_cmd.cpp
--- a/src/tunnelbridge_cmd.cpp
+++ b/src/tunnelbridge_cmd.cpp
@@ -14,7 +14,6 @@
#include "stdafx.h"
#include "newgrf_object.h"
#include "viewport_func.h"
-#include "cmd_helper.h"
#include "command_func.h"
#include "town.h"
#include "train.h"
diff --git a/src/vehicle_cmd.cpp b/src/vehicle_cmd.cpp
--- a/src/vehicle_cmd.cpp
+++ b/src/vehicle_cmd.cpp
@@ -11,7 +11,6 @@
#include "roadveh.h"
#include "news_func.h"
#include "airport.h"
-#include "cmd_helper.h"
#include "command_func.h"
#include "company_func.h"
#include "train.h"
diff --git a/src/water_cmd.cpp b/src/water_cmd.cpp
--- a/src/water_cmd.cpp
+++ b/src/water_cmd.cpp
@@ -8,7 +8,6 @@
/** @file water_cmd.cpp Handling of water tiles. */
#include "stdafx.h"
-#include "cmd_helper.h"
#include "landscape.h"
#include "viewport_func.h"
#include "command_func.h"
@@ -100,7 +99,7 @@ static void MarkCanalsAndRiversAroundDir
*/
CommandCost CmdBuildShipDepot(DoCommandFlag flags, TileIndex tile, Axis axis)
{
- if (!IsEnumValid(axis)) return CMD_ERROR;
+ if (!IsValidAxis(axis)) return CMD_ERROR;
TileIndex tile2 = tile + (axis == AXIS_X ? TileDiffXY(1, 0) : TileDiffXY(0, 1));
if (!HasTileWaterGround(tile) || !HasTileWaterGround(tile2)) {
@@ -439,7 +438,7 @@ bool RiverModifyDesertZone(TileIndex til
*/
CommandCost CmdBuildCanal(DoCommandFlag flags, TileIndex tile, TileIndex start_tile, WaterClass wc, bool diagonal)
{
- if (start_tile >= MapSize() || !IsEnumValid(wc)) return CMD_ERROR;
+ if (start_tile >= MapSize() || !IsValidWaterClass(wc)) return CMD_ERROR;
/* Outside of the editor you can only build canals, not oceans */
if (wc != WATER_CLASS_CANAL && _game_mode != GM_EDITOR) return CMD_ERROR;
diff --git a/src/water_map.h b/src/water_map.h
--- a/src/water_map.h
+++ b/src/water_map.h
@@ -53,6 +53,17 @@ enum WaterClass : byte {
/** Helper information for extract tool. */
template <> struct EnumPropsT : MakeEnumPropsT {};
+/**
+ * Checks if a water class is valid.
+ *
+ * @param wc The value to check
+ * @return true if the given value is a valid water class.
+ */
+static inline bool IsValidWaterClass(WaterClass wc)
+{
+ return wc < WATER_CLASS_INVALID;
+}
+
/** Sections of the water depot. */
enum DepotPart {
DEPOT_PART_NORTH = 0, ///< Northern part of a depot.
diff --git a/src/waypoint_cmd.cpp b/src/waypoint_cmd.cpp
--- a/src/waypoint_cmd.cpp
+++ b/src/waypoint_cmd.cpp
@@ -9,7 +9,6 @@
#include "stdafx.h"
-#include "cmd_helper.h"
#include "command_func.h"
#include "landscape.h"
#include "bridge_map.h"
@@ -175,7 +174,7 @@ extern CommandCost CanExpandRailStation(
*/
CommandCost CmdBuildRailWaypoint(DoCommandFlag flags, TileIndex start_tile, Axis axis, byte width, byte height, StationClassID spec_class, byte spec_index, StationID station_to_join, bool adjacent)
{
- if (!IsEnumValid(axis)) return CMD_ERROR;
+ if (!IsValidAxis(axis)) return CMD_ERROR;
/* Check if the given station class is valid */
if (spec_class != STAT_CLASS_WAYP) return CMD_ERROR;
if (spec_index >= StationClass::Get(spec_class)->GetSpecCount()) return CMD_ERROR;