1
0
Fork 0

Codechange: Use enum class for Borders values. (#13290)

This makes water border settings type-safe, and avoids mixing bit numbers with masks.
pull/13297/head
Peter Nelson 2025-01-08 17:55:53 +00:00 committed by GitHub
parent d79ae73c14
commit ce4012b7c7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 54 additions and 35 deletions

View File

@ -60,4 +60,19 @@ debug_inline constexpr bool HasFlag(const T x, const T y)
return (x & y) == y;
}
/**
* Toggle a value in a bitset enum.
* @param x The value to change.
* @param y The flag to toggle.
*/
template <typename T, class = typename std::enable_if_t<std::is_enum_v<T>>>
debug_inline constexpr void ToggleFlag(T &x, const T y)
{
if (HasFlag(x, y)) {
x &= ~y;
} else {
x |= y;
}
}
#endif /* ENUM_TYPE_HPP */

View File

@ -479,11 +479,11 @@ struct GenerateLandscapeWindow : public Window {
case WID_GL_RIVER_PULLDOWN: SetDParam(0, _rivers[_settings_newgame.game_creation.amount_of_rivers]); break;
case WID_GL_SMOOTHNESS_PULLDOWN: SetDParam(0, _smoothness[_settings_newgame.game_creation.tgen_smoothness]); break;
case WID_GL_VARIETY_PULLDOWN: SetDParam(0, _variety[_settings_newgame.game_creation.variety]); break;
case WID_GL_BORDERS_RANDOM: SetDParam(0, (_settings_newgame.game_creation.water_borders == BORDERS_RANDOM) ? STR_MAPGEN_BORDER_RANDOMIZE : STR_MAPGEN_BORDER_MANUAL); break;
case WID_GL_WATER_NE: SetDParam(0, (_settings_newgame.game_creation.water_borders == BORDERS_RANDOM) ? STR_MAPGEN_BORDER_RANDOM : HasBit(_settings_newgame.game_creation.water_borders, BORDER_NE) ? STR_MAPGEN_BORDER_WATER : STR_MAPGEN_BORDER_FREEFORM); break;
case WID_GL_WATER_NW: SetDParam(0, (_settings_newgame.game_creation.water_borders == BORDERS_RANDOM) ? STR_MAPGEN_BORDER_RANDOM : HasBit(_settings_newgame.game_creation.water_borders, BORDER_NW) ? STR_MAPGEN_BORDER_WATER : STR_MAPGEN_BORDER_FREEFORM); break;
case WID_GL_WATER_SE: SetDParam(0, (_settings_newgame.game_creation.water_borders == BORDERS_RANDOM) ? STR_MAPGEN_BORDER_RANDOM : HasBit(_settings_newgame.game_creation.water_borders, BORDER_SE) ? STR_MAPGEN_BORDER_WATER : STR_MAPGEN_BORDER_FREEFORM); break;
case WID_GL_WATER_SW: SetDParam(0, (_settings_newgame.game_creation.water_borders == BORDERS_RANDOM) ? STR_MAPGEN_BORDER_RANDOM : HasBit(_settings_newgame.game_creation.water_borders, BORDER_SW) ? STR_MAPGEN_BORDER_WATER : STR_MAPGEN_BORDER_FREEFORM); break;
case WID_GL_BORDERS_RANDOM: SetDParam(0, (_settings_newgame.game_creation.water_borders == Borders::Random) ? STR_MAPGEN_BORDER_RANDOMIZE : STR_MAPGEN_BORDER_MANUAL); break;
case WID_GL_WATER_NE: SetDParam(0, (_settings_newgame.game_creation.water_borders == Borders::Random) ? STR_MAPGEN_BORDER_RANDOM : HasFlag(_settings_newgame.game_creation.water_borders, Borders::NorthEast) ? STR_MAPGEN_BORDER_WATER : STR_MAPGEN_BORDER_FREEFORM); break;
case WID_GL_WATER_NW: SetDParam(0, (_settings_newgame.game_creation.water_borders == Borders::Random) ? STR_MAPGEN_BORDER_RANDOM : HasFlag(_settings_newgame.game_creation.water_borders, Borders::NorthWest) ? STR_MAPGEN_BORDER_WATER : STR_MAPGEN_BORDER_FREEFORM); break;
case WID_GL_WATER_SE: SetDParam(0, (_settings_newgame.game_creation.water_borders == Borders::Random) ? STR_MAPGEN_BORDER_RANDOM : HasFlag(_settings_newgame.game_creation.water_borders, Borders::SouthEast) ? STR_MAPGEN_BORDER_WATER : STR_MAPGEN_BORDER_FREEFORM); break;
case WID_GL_WATER_SW: SetDParam(0, (_settings_newgame.game_creation.water_borders == Borders::Random) ? STR_MAPGEN_BORDER_RANDOM : HasFlag(_settings_newgame.game_creation.water_borders, Borders::SouthWest) ? STR_MAPGEN_BORDER_WATER : STR_MAPGEN_BORDER_FREEFORM); break;
case WID_GL_HEIGHTMAP_ROTATION_PULLDOWN: SetDParam(0, _rotation[_settings_newgame.game_creation.heightmap_rotation]); break;
case WID_GL_HEIGHTMAP_SIZE_TEXT:
@ -517,15 +517,15 @@ struct GenerateLandscapeWindow : public Window {
this->SetWidgetDisabledState(WID_GL_SMOOTHNESS_PULLDOWN, _settings_newgame.game_creation.land_generator == LG_ORIGINAL);
this->SetWidgetDisabledState(WID_GL_VARIETY_PULLDOWN, _settings_newgame.game_creation.land_generator == LG_ORIGINAL);
this->SetWidgetDisabledState(WID_GL_BORDERS_RANDOM, _settings_newgame.game_creation.land_generator == LG_ORIGINAL || !_settings_newgame.construction.freeform_edges);
this->SetWidgetsDisabledState(_settings_newgame.game_creation.land_generator == LG_ORIGINAL || !_settings_newgame.construction.freeform_edges || _settings_newgame.game_creation.water_borders == BORDERS_RANDOM,
this->SetWidgetsDisabledState(_settings_newgame.game_creation.land_generator == LG_ORIGINAL || !_settings_newgame.construction.freeform_edges || _settings_newgame.game_creation.water_borders == Borders::Random,
WID_GL_WATER_NW, WID_GL_WATER_NE, WID_GL_WATER_SE, WID_GL_WATER_SW);
this->SetWidgetLoweredState(WID_GL_BORDERS_RANDOM, _settings_newgame.game_creation.water_borders == BORDERS_RANDOM);
this->SetWidgetLoweredState(WID_GL_BORDERS_RANDOM, _settings_newgame.game_creation.water_borders == Borders::Random);
this->SetWidgetLoweredState(WID_GL_WATER_NW, HasBit(_settings_newgame.game_creation.water_borders, BORDER_NW));
this->SetWidgetLoweredState(WID_GL_WATER_NE, HasBit(_settings_newgame.game_creation.water_borders, BORDER_NE));
this->SetWidgetLoweredState(WID_GL_WATER_SE, HasBit(_settings_newgame.game_creation.water_borders, BORDER_SE));
this->SetWidgetLoweredState(WID_GL_WATER_SW, HasBit(_settings_newgame.game_creation.water_borders, BORDER_SW));
this->SetWidgetLoweredState(WID_GL_WATER_NW, HasFlag(_settings_newgame.game_creation.water_borders, Borders::NorthWest));
this->SetWidgetLoweredState(WID_GL_WATER_NE, HasFlag(_settings_newgame.game_creation.water_borders, Borders::NorthEast));
this->SetWidgetLoweredState(WID_GL_WATER_SE, HasFlag(_settings_newgame.game_creation.water_borders, Borders::SouthEast));
this->SetWidgetLoweredState(WID_GL_WATER_SW, HasFlag(_settings_newgame.game_creation.water_borders, Borders::SouthWest));
this->SetWidgetsDisabledState(_settings_newgame.game_creation.land_generator == LG_ORIGINAL && (_settings_newgame.game_creation.landscape == LT_ARCTIC || _settings_newgame.game_creation.landscape == LT_TROPIC),
WID_GL_TERRAIN_PULLDOWN, WID_GL_WATER_PULLDOWN);
@ -829,27 +829,27 @@ struct GenerateLandscapeWindow : public Window {
/* Freetype map borders */
case WID_GL_WATER_NW:
_settings_newgame.game_creation.water_borders = ToggleBit(_settings_newgame.game_creation.water_borders, BORDER_NW);
ToggleFlag(_settings_newgame.game_creation.water_borders, Borders::NorthWest);
this->InvalidateData();
break;
case WID_GL_WATER_NE:
_settings_newgame.game_creation.water_borders = ToggleBit(_settings_newgame.game_creation.water_borders, BORDER_NE);
ToggleFlag(_settings_newgame.game_creation.water_borders, Borders::NorthEast);
this->InvalidateData();
break;
case WID_GL_WATER_SE:
_settings_newgame.game_creation.water_borders = ToggleBit(_settings_newgame.game_creation.water_borders, BORDER_SE);
ToggleFlag(_settings_newgame.game_creation.water_borders, Borders::SouthEast);
this->InvalidateData();
break;
case WID_GL_WATER_SW:
_settings_newgame.game_creation.water_borders = ToggleBit(_settings_newgame.game_creation.water_borders, BORDER_SW);
ToggleFlag(_settings_newgame.game_creation.water_borders, Borders::SouthWest);
this->InvalidateData();
break;
case WID_GL_BORDERS_RANDOM:
_settings_newgame.game_creation.water_borders = (_settings_newgame.game_creation.water_borders == BORDERS_RANDOM) ? 0 : BORDERS_RANDOM;
_settings_newgame.game_creation.water_borders = (_settings_newgame.game_creation.water_borders == Borders::Random) ? Borders::None : Borders::Random;
this->InvalidateData();
break;

View File

@ -10,6 +10,7 @@
#ifndef LANDSCAPE_TYPE_H
#define LANDSCAPE_TYPE_H
#include "core/enum_type.hpp"
typedef uint8_t LandscapeID; ///< Landscape type. @see LandscapeType
/** Landscape types */
@ -25,12 +26,15 @@ enum LandscapeType {
/**
* For storing the water borders which shall be retained.
*/
enum Borders {
BORDER_NE = 0,
BORDER_SE = 1,
BORDER_SW = 2,
BORDER_NW = 3,
BORDERS_RANDOM = 16,
enum class Borders : uint8_t {
None = 0,
NorthEast = 1U << 0, ///< Border on North East.
SouthEast = 1U << 1, ///< Border on South East.
SouthWest = 1U << 2, ///< Border on South West.
NorthWest = 1U << 3, ///< Border on North West.
Random = 1U << 4, ///< Randomise borders.
All = NorthEast | SouthEast | SouthWest | NorthWest, ///< Border on all sides.
};
DECLARE_ENUM_AS_BIT_SET(Borders)
#endif /* LANDSCAPE_TYPE_H */

View File

@ -366,7 +366,7 @@ struct GameCreationSettings {
uint8_t se_flat_world_height; ///< land height a flat world gets in SE
uint8_t town_name; ///< the town name generator used for town names
uint8_t landscape; ///< the landscape we're currently in
uint8_t water_borders; ///< bitset of the borders that are water
Borders water_borders; ///< bitset of the borders that are water
uint16_t custom_town_number; ///< manually entered number of towns
uint16_t custom_industry_number; ///< manually entered number of industries
uint8_t variety; ///< variety level applied to TGP

View File

@ -718,7 +718,7 @@ static double perlin_coast_noise_2D(const double x, const double y, const double
* Please note that all the small numbers; 53, 101, 167, etc. are small primes
* to help give the perlin noise a bit more of a random feel.
*/
static void HeightMapCoastLines(uint8_t water_borders)
static void HeightMapCoastLines(Borders water_borders)
{
int smallest_size = std::min(_settings_game.game_creation.map_x, _settings_game.game_creation.map_y);
const int margin = 4;
@ -728,7 +728,7 @@ static void HeightMapCoastLines(uint8_t water_borders)
/* Lower to sea level */
for (y = 0; y <= _height_map.size_y; y++) {
if (HasBit(water_borders, BORDER_NE)) {
if (HasFlag(water_borders, Borders::NorthEast)) {
/* Top right */
max_x = abs((perlin_coast_noise_2D(_height_map.size_y - y, y, 0.9, 53) + 0.25) * 5 + (perlin_coast_noise_2D(y, y, 0.35, 179) + 1) * 12);
max_x = std::max((smallest_size * smallest_size / 64) + max_x, (smallest_size * smallest_size / 64) + margin - max_x);
@ -738,7 +738,7 @@ static void HeightMapCoastLines(uint8_t water_borders)
}
}
if (HasBit(water_borders, BORDER_SW)) {
if (HasFlag(water_borders, Borders::SouthWest)) {
/* Bottom left */
max_x = abs((perlin_coast_noise_2D(_height_map.size_y - y, y, 0.85, 101) + 0.3) * 6 + (perlin_coast_noise_2D(y, y, 0.45, 67) + 0.75) * 8);
max_x = std::max((smallest_size * smallest_size / 64) + max_x, (smallest_size * smallest_size / 64) + margin - max_x);
@ -751,7 +751,7 @@ static void HeightMapCoastLines(uint8_t water_borders)
/* Lower to sea level */
for (x = 0; x <= _height_map.size_x; x++) {
if (HasBit(water_borders, BORDER_NW)) {
if (HasFlag(water_borders, Borders::NorthWest)) {
/* Top left */
max_y = abs((perlin_coast_noise_2D(x, _height_map.size_y / 2, 0.9, 167) + 0.4) * 5 + (perlin_coast_noise_2D(x, _height_map.size_y / 3, 0.4, 211) + 0.7) * 9);
max_y = std::max((smallest_size * smallest_size / 64) + max_y, (smallest_size * smallest_size / 64) + margin - max_y);
@ -761,7 +761,7 @@ static void HeightMapCoastLines(uint8_t water_borders)
}
}
if (HasBit(water_borders, BORDER_SE)) {
if (HasFlag(water_borders, Borders::SouthEast)) {
/* Bottom right */
max_y = abs((perlin_coast_noise_2D(x, _height_map.size_y / 3, 0.85, 71) + 0.25) * 6 + (perlin_coast_noise_2D(x, _height_map.size_y / 3, 0.35, 193) + 0.75) * 12);
max_y = std::max((smallest_size * smallest_size / 64) + max_y, (smallest_size * smallest_size / 64) + margin - max_y);
@ -811,18 +811,18 @@ static void HeightMapSmoothCoastInDirection(int org_x, int org_y, int dir_x, int
}
/** Smooth coasts by modulating height of tiles close to map edges with cosine of distance from edge */
static void HeightMapSmoothCoasts(uint8_t water_borders)
static void HeightMapSmoothCoasts(Borders water_borders)
{
int x, y;
/* First Smooth NW and SE coasts (y close to 0 and y close to size_y) */
for (x = 0; x < _height_map.size_x; x++) {
if (HasBit(water_borders, BORDER_NW)) HeightMapSmoothCoastInDirection(x, 0, 0, 1);
if (HasBit(water_borders, BORDER_SE)) HeightMapSmoothCoastInDirection(x, _height_map.size_y - 1, 0, -1);
if (HasFlag(water_borders, Borders::NorthWest)) HeightMapSmoothCoastInDirection(x, 0, 0, 1);
if (HasFlag(water_borders, Borders::SouthEast)) HeightMapSmoothCoastInDirection(x, _height_map.size_y - 1, 0, -1);
}
/* First Smooth NE and SW coasts (x close to 0 and x close to size_x) */
for (y = 0; y < _height_map.size_y; y++) {
if (HasBit(water_borders, BORDER_NE)) HeightMapSmoothCoastInDirection(0, y, 1, 0);
if (HasBit(water_borders, BORDER_SW)) HeightMapSmoothCoastInDirection(_height_map.size_x - 1, y, -1, 0);
if (HasFlag(water_borders, Borders::NorthEast)) HeightMapSmoothCoastInDirection(0, y, 1, 0);
if (HasFlag(water_borders, Borders::SouthWest)) HeightMapSmoothCoastInDirection(_height_map.size_x - 1, y, -1, 0);
}
}
@ -865,8 +865,8 @@ static void HeightMapNormalize()
HeightMapAdjustWaterLevel(water_percent, h_max_new);
uint8_t water_borders = _settings_game.construction.freeform_edges ? _settings_game.game_creation.water_borders : 0xF;
if (water_borders == BORDERS_RANDOM) water_borders = GB(Random(), 0, 4);
Borders water_borders = _settings_game.construction.freeform_edges ? _settings_game.game_creation.water_borders : Borders::All;
if (water_borders == Borders::Random) water_borders = static_cast<Borders>(GB(Random(), 0, 4));
HeightMapCoastLines(water_borders);
HeightMapSmoothSlopes(roughness);