From 6a0d1c7c1934f5f98ba7c2bc7956c2e6590c94df Mon Sep 17 00:00:00 2001 From: PeterN Date: Fri, 13 Jan 2023 19:22:31 +0000 Subject: [PATCH 1/7] Fix: Link variants to parents when finalising engines. (#10346) This ensures that definition-order of engines within the NewGRF does not matter. --- src/newgrf.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/newgrf.cpp b/src/newgrf.cpp index 62e72f8e8e..bbf29750a0 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -1329,7 +1329,7 @@ static ChangeInfoResult RailVehicleChangeInfo(uint engine, int numinfo, int prop break; case 0x2F: // Engine variant - ei->variant_id = GetNewEngineID(_cur.grffile, VEH_TRAIN, buf->ReadWord()); + ei->variant_id = buf->ReadWord(); break; case 0x30: // Extra miscellaneous flags @@ -1531,7 +1531,7 @@ static ChangeInfoResult RoadVehicleChangeInfo(uint engine, int numinfo, int prop } case 0x26: // Engine variant - ei->variant_id = GetNewEngineID(_cur.grffile, VEH_ROAD, buf->ReadWord()); + ei->variant_id = buf->ReadWord(); break; case 0x27: // Extra miscellaneous flags @@ -1711,7 +1711,7 @@ static ChangeInfoResult ShipVehicleChangeInfo(uint engine, int numinfo, int prop } case 0x20: // Engine variant - ei->variant_id = GetNewEngineID(_cur.grffile, VEH_SHIP, buf->ReadWord()); + ei->variant_id = buf->ReadWord(); break; case 0x21: // Extra miscellaneous flags @@ -1873,7 +1873,7 @@ static ChangeInfoResult AircraftVehicleChangeInfo(uint engine, int numinfo, int break; case 0x20: // Engine variant - ei->variant_id = GetNewEngineID(_cur.grffile, VEH_AIRCRAFT, buf->ReadWord()); + ei->variant_id = buf->ReadWord(); break; case 0x21: // Extra miscellaneous flags @@ -9001,13 +9001,16 @@ static void FinaliseEngineArray() } } - if (!HasBit(e->info.climates, _settings_game.game_creation.landscape)) continue; - - /* Set appropriate flags on variant engine */ + /* Do final mapping on variant engine ID and set appropriate flags on variant engine */ if (e->info.variant_id != INVALID_ENGINE) { - Engine::Get(e->info.variant_id)->display_flags |= EngineDisplayFlags::HasVariants | EngineDisplayFlags::IsFolded; + e->info.variant_id = GetNewEngineID(e->grf_prop.grffile, e->type, e->info.variant_id); + if (e->info.variant_id != INVALID_ENGINE) { + Engine::Get(e->info.variant_id)->display_flags |= EngineDisplayFlags::HasVariants | EngineDisplayFlags::IsFolded; + } } + if (!HasBit(e->info.climates, _settings_game.game_creation.landscape)) continue; + /* Skip wagons, there livery is defined via the engine */ if (e->type != VEH_TRAIN || e->u.rail.railveh_type != RAILVEH_WAGON) { LiveryScheme ls = GetEngineLiveryScheme(e->index, INVALID_ENGINE, nullptr); From f667a831a5a1045e041e5b03328ef3b2b6803ddf Mon Sep 17 00:00:00 2001 From: Rubidium Date: Fri, 13 Jan 2023 17:19:25 +0100 Subject: [PATCH 2/7] Codechange: unify creation of diagonal/orthogonal iterator using smart pointers --- src/landscape.cpp | 4 +--- src/object_cmd.cpp | 3 +-- src/rail_cmd.cpp | 3 +-- src/terraform_cmd.cpp | 4 +--- src/tilearea.cpp | 15 +++++++++++++++ src/tilearea_type.h | 2 ++ src/water_cmd.cpp | 8 +------- 7 files changed, 22 insertions(+), 17 deletions(-) diff --git a/src/landscape.cpp b/src/landscape.cpp index a0707108a4..90737de745 100644 --- a/src/landscape.cpp +++ b/src/landscape.cpp @@ -758,7 +758,7 @@ std::tuple CmdClearArea(DoCommandFlag flags, TileIndex tile, const Company *c = (flags & (DC_AUTO | DC_BANKRUPT)) ? nullptr : Company::GetIfValid(_current_company); int limit = (c == nullptr ? INT32_MAX : GB(c->clear_limit, 16, 16)); - TileIterator *iter = diagonal ? (TileIterator *)new DiagonalTileIterator(tile, start_tile) : new OrthogonalTileIterator(tile, start_tile); + std::unique_ptr iter = TileIterator::Create(tile, start_tile, diagonal); for (; *iter != INVALID_TILE; ++(*iter)) { TileIndex t = *iter; CommandCost ret = Command::Do(flags & ~DC_EXEC, t); @@ -774,7 +774,6 @@ std::tuple CmdClearArea(DoCommandFlag flags, TileIndex tile, if (flags & DC_EXEC) { money -= ret.GetCost(); if (ret.GetCost() > 0 && money < 0) { - delete iter; return { cost, ret.GetCost() }; } Command::Do(flags, t); @@ -794,7 +793,6 @@ std::tuple CmdClearArea(DoCommandFlag flags, TileIndex tile, cost.AddCost(ret); } - delete iter; return { had_success ? cost : last_error, 0 }; } diff --git a/src/object_cmd.cpp b/src/object_cmd.cpp index 3eced27ef6..4c9b95809f 100644 --- a/src/object_cmd.cpp +++ b/src/object_cmd.cpp @@ -402,7 +402,7 @@ CommandCost CmdBuildObjectArea(DoCommandFlag flags, TileIndex tile, TileIndex st const Company *c = Company::GetIfValid(_current_company); int limit = (c == nullptr ? INT32_MAX : GB(c->build_object_limit, 16, 16)); - TileIterator *iter = diagonal ? (TileIterator *)new DiagonalTileIterator(tile, start_tile) : new OrthogonalTileIterator(tile, start_tile); + std::unique_ptr iter = TileIterator::Create(tile, start_tile, diagonal); for (; *iter != INVALID_TILE; ++(*iter)) { TileIndex t = *iter; CommandCost ret = Command::Do(flags & ~DC_EXEC, t, type, view); @@ -426,7 +426,6 @@ CommandCost CmdBuildObjectArea(DoCommandFlag flags, TileIndex tile, TileIndex st cost.AddCost(ret); } - delete iter; return had_success ? cost : last_error; } diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index 7ee5813606..eda42d1620 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -1548,7 +1548,7 @@ CommandCost CmdConvertRail(DoCommandFlag flags, TileIndex tile, TileIndex area_s CommandCost error = CommandCost(STR_ERROR_NO_SUITABLE_RAILROAD_TRACK); // by default, there is no track to convert. bool found_convertible_track = false; // whether we actually did convert some track (see bug #7633) - TileIterator *iter = diagonal ? (TileIterator *)new DiagonalTileIterator(area_start, area_end) : new OrthogonalTileIterator(area_start, area_end); + std::unique_ptr iter = TileIterator::Create(area_start, area_end, diagonal); for (; (tile = *iter) != INVALID_TILE; ++(*iter)) { TileType tt = GetTileType(tile); @@ -1745,7 +1745,6 @@ CommandCost CmdConvertRail(DoCommandFlag flags, TileIndex tile, TileIndex area_s } } - delete iter; return found_convertible_track ? cost : error; } diff --git a/src/terraform_cmd.cpp b/src/terraform_cmd.cpp index 21df5ccbe3..8ec602a4f0 100644 --- a/src/terraform_cmd.cpp +++ b/src/terraform_cmd.cpp @@ -361,7 +361,7 @@ std::tuple CmdLevelLand(DoCommandFlag flags, Tile if (limit == 0) return { CommandCost(STR_ERROR_TERRAFORM_LIMIT_REACHED), 0, INVALID_TILE }; TileIndex error_tile = INVALID_TILE; - TileIterator *iter = diagonal ? (TileIterator *)new DiagonalTileIterator(tile, start_tile) : new OrthogonalTileIterator(tile, start_tile); + std::unique_ptr iter = TileIterator::Create(tile, start_tile, diagonal); for (; *iter != INVALID_TILE; ++(*iter)) { TileIndex t = *iter; uint curh = TileHeight(t); @@ -379,7 +379,6 @@ std::tuple CmdLevelLand(DoCommandFlag flags, Tile if (flags & DC_EXEC) { money -= ret.GetCost(); if (money < 0) { - delete iter; return { cost, ret.GetCost(), error_tile }; } Command::Do(flags, t, SLOPE_N, curh <= h); @@ -403,7 +402,6 @@ std::tuple CmdLevelLand(DoCommandFlag flags, Tile if (limit <= 0) break; } - delete iter; CommandCost cc_ret = had_success ? cost : last_error; return { cc_ret, 0, cc_ret.Succeeded() ? tile : error_tile }; } diff --git a/src/tilearea.cpp b/src/tilearea.cpp index 21271f94f1..6c943e8c87 100644 --- a/src/tilearea.cpp +++ b/src/tilearea.cpp @@ -280,3 +280,18 @@ TileIterator &DiagonalTileIterator::operator++() if (this->b_max == this->b_cur) this->tile = INVALID_TILE; return *this; } + +/** + * Create either an OrthogonalTileIterator or DiagonalTileIterator given the diagonal parameter. + * @param corner1 Tile from where to begin iterating. + * @param corner2 Tile where to end the iterating. + * @param diagonal Whether to create a DiagonalTileIterator or OrthogonalTileIterator. + * @return unique_ptr to the allocated TileIterator. + */ +/* static */ std::unique_ptr TileIterator::Create(TileIndex corner1, TileIndex corner2, bool diagonal) +{ + if (diagonal) { + return std::make_unique(corner1, corner2); + } + return std::make_unique(corner1, corner2); +} diff --git a/src/tilearea_type.h b/src/tilearea_type.h index b6af998a76..2484aac2c6 100644 --- a/src/tilearea_type.h +++ b/src/tilearea_type.h @@ -177,6 +177,8 @@ public: { return this->tile != rhs; } + + static std::unique_ptr Create(TileIndex corner1, TileIndex corner2, bool diagonal); }; /** Iterator to iterate over a tile area (rectangle) of the map. */ diff --git a/src/water_cmd.cpp b/src/water_cmd.cpp index 44be4dc367..68b2cef3e7 100644 --- a/src/water_cmd.cpp +++ b/src/water_cmd.cpp @@ -445,13 +445,7 @@ CommandCost CmdBuildCanal(DoCommandFlag flags, TileIndex tile, TileIndex start_t CommandCost cost(EXPENSES_CONSTRUCTION); - std::unique_ptr iter; - if (diagonal) { - iter = std::make_unique(tile, start_tile); - } else { - iter = std::make_unique(tile, start_tile); - } - + std::unique_ptr iter = TileIterator::Create(tile, start_tile, diagonal); for (; *iter != INVALID_TILE; ++(*iter)) { TileIndex current_tile = *iter; CommandCost ret; From b35c791d05f7d2eb337eca419d120adf513fa779 Mon Sep 17 00:00:00 2001 From: Rubidium Date: Fri, 13 Jan 2023 17:54:53 +0100 Subject: [PATCH 3/7] Codechange: use smart pointers when cloning iterators --- src/bitmap_type.h | 4 ++-- src/newgrf_airport.h | 4 ++-- src/road_cmd.cpp | 3 +-- src/station_base.h | 4 ++-- src/tilearea_type.h | 10 +++++----- 5 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/bitmap_type.h b/src/bitmap_type.h index 75f9ab6642..3aff869724 100644 --- a/src/bitmap_type.h +++ b/src/bitmap_type.h @@ -126,9 +126,9 @@ public: return *this; } - virtual TileIterator *Clone() const + virtual std::unique_ptr Clone() const { - return new BitmapTileIterator(*this); + return std::make_unique(*this); } }; diff --git a/src/newgrf_airport.h b/src/newgrf_airport.h index 264da05ebb..2774fbc645 100644 --- a/src/newgrf_airport.h +++ b/src/newgrf_airport.h @@ -58,9 +58,9 @@ public: return this->att->gfx; } - virtual AirportTileTableIterator *Clone() const + virtual std::unique_ptr Clone() const { - return new AirportTileTableIterator(*this); + return std::make_unique(*this); } }; diff --git a/src/road_cmd.cpp b/src/road_cmd.cpp index 94b4423a15..dbfc00494a 100644 --- a/src/road_cmd.cpp +++ b/src/road_cmd.cpp @@ -2400,7 +2400,7 @@ CommandCost CmdConvertRoad(DoCommandFlag flags, TileIndex tile, TileIndex area_s CommandCost error = CommandCost((rtt == RTT_TRAM) ? STR_ERROR_NO_SUITABLE_TRAMWAY : STR_ERROR_NO_SUITABLE_ROAD); // by default, there is no road to convert. bool found_convertible_road = false; // whether we actually did convert any road/tram (see bug #7633) - TileIterator *iter = new OrthogonalTileIterator(area_start, area_end); + std::unique_ptr iter = std::make_unique(area_start, area_end); for (; (tile = *iter) != INVALID_TILE; ++(*iter)) { /* Is road present on tile? */ if (!MayHaveRoad(tile)) continue; @@ -2556,7 +2556,6 @@ CommandCost CmdConvertRoad(DoCommandFlag flags, TileIndex tile, TileIndex area_s } } - delete iter; return found_convertible_road ? cost : error; } diff --git a/src/station_base.h b/src/station_base.h index ebb29026a9..e8eb40d4b8 100644 --- a/src/station_base.h +++ b/src/station_base.h @@ -555,9 +555,9 @@ public: return *this; } - virtual TileIterator *Clone() const + virtual std::unique_ptr Clone() const { - return new AirportTileIterator(*this); + return std::make_unique(*this); } }; diff --git a/src/tilearea_type.h b/src/tilearea_type.h index 2484aac2c6..412f7c3752 100644 --- a/src/tilearea_type.h +++ b/src/tilearea_type.h @@ -146,7 +146,7 @@ public: /** * Allocate a new iterator that is a copy of this one. */ - virtual TileIterator *Clone() const = 0; + virtual std::unique_ptr Clone() const = 0; /** * Equality comparison. @@ -225,9 +225,9 @@ public: return *this; } - virtual TileIterator *Clone() const + virtual std::unique_ptr Clone() const { - return new OrthogonalTileIterator(*this); + return std::make_unique(*this); } }; @@ -264,9 +264,9 @@ public: TileIterator& operator ++(); - virtual TileIterator *Clone() const + virtual std::unique_ptr Clone() const { - return new DiagonalTileIterator(*this); + return std::make_unique(*this); } }; From b951332def2cb43c8b38ea833ffcaccf233742d6 Mon Sep 17 00:00:00 2001 From: Rubidium Date: Fri, 13 Jan 2023 17:55:43 +0100 Subject: [PATCH 4/7] Codechange: use smart pointers when creating StringIterators --- src/os/macosx/string_osx.cpp | 4 ++-- src/os/macosx/string_osx.h | 2 +- src/string.cpp | 18 +++++++++--------- src/string_base.h | 2 +- src/textbuf.cpp | 5 +---- src/textbuf_type.h | 2 +- 6 files changed, 15 insertions(+), 18 deletions(-) diff --git a/src/os/macosx/string_osx.cpp b/src/os/macosx/string_osx.cpp index c79ca88894..f263db3753 100644 --- a/src/os/macosx/string_osx.cpp +++ b/src/os/macosx/string_osx.cpp @@ -443,9 +443,9 @@ int MacOSStringCompare(const char *s1, const char *s2) return this->utf16_to_utf8[this->cur_pos]; } -/* static */ StringIterator *OSXStringIterator::Create() +/* static */ std::unique_ptr OSXStringIterator::Create() { if (!MacOSVersionIsAtLeast(10, 5, 0)) return nullptr; - return new OSXStringIterator(); + return std::make_unique(); } diff --git a/src/os/macosx/string_osx.h b/src/os/macosx/string_osx.h index 88e5924e8c..fc737b1639 100644 --- a/src/os/macosx/string_osx.h +++ b/src/os/macosx/string_osx.h @@ -33,7 +33,7 @@ public: size_t Next(IterType what) override; size_t Prev(IterType what) override; - static StringIterator *Create(); + static std::unique_ptr Create(); }; /** diff --git a/src/string.cpp b/src/string.cpp index 2e14b4208e..9bdbafa46a 100644 --- a/src/string.cpp +++ b/src/string.cpp @@ -765,9 +765,9 @@ int strnatcmp(const char *s1, const char *s2, bool ignore_garbage_at_front) #ifdef WITH_UNISCRIBE -/* static */ StringIterator *StringIterator::Create() +/* static */ std::unique_ptr StringIterator::Create() { - return new UniscribeStringIterator(); + return std::make_unique(); } #elif defined(WITH_ICU_I18N) @@ -921,9 +921,9 @@ public: } }; -/* static */ StringIterator *StringIterator::Create() +/* static */ std::unique_ptr StringIterator::Create() { - return new IcuStringIterator(); + return std::make_unique(); } #else @@ -1032,17 +1032,17 @@ public: }; #if defined(WITH_COCOA) && !defined(STRGEN) && !defined(SETTINGSGEN) -/* static */ StringIterator *StringIterator::Create() +/* static */ std::unique_ptr StringIterator::Create() { - StringIterator *i = OSXStringIterator::Create(); + std::unique_ptr i = OSXStringIterator::Create(); if (i != nullptr) return i; - return new DefaultStringIterator(); + return std::make_unique(); } #else -/* static */ StringIterator *StringIterator::Create() +/* static */ std::unique_ptr StringIterator::Create() { - return new DefaultStringIterator(); + return std::make_unique(); } #endif /* defined(WITH_COCOA) && !defined(STRGEN) && !defined(SETTINGSGEN) */ diff --git a/src/string_base.h b/src/string_base.h index a22be65713..d7414c9156 100644 --- a/src/string_base.h +++ b/src/string_base.h @@ -26,7 +26,7 @@ public: * Create a new iterator instance. * @return New iterator instance. */ - static StringIterator *Create(); + static std::unique_ptr Create(); virtual ~StringIterator() {} diff --git a/src/textbuf.cpp b/src/textbuf.cpp index 75e1f44848..30cef7b0ce 100644 --- a/src/textbuf.cpp +++ b/src/textbuf.cpp @@ -369,13 +369,11 @@ bool Textbuf::MovePos(uint16 keycode) * @param max_chars maximum size in chars, including terminating '\0' */ Textbuf::Textbuf(uint16 max_bytes, uint16 max_chars) - : buf(MallocT(max_bytes)) + : buf(MallocT(max_bytes)), char_iter(StringIterator::Create()) { assert(max_bytes != 0); assert(max_chars != 0); - this->char_iter = StringIterator::Create(); - this->afilter = CS_ALPHANUMERAL; this->max_bytes = max_bytes; this->max_chars = max_chars == UINT16_MAX ? max_bytes : max_chars; @@ -385,7 +383,6 @@ Textbuf::Textbuf(uint16 max_bytes, uint16 max_chars) Textbuf::~Textbuf() { - delete this->char_iter; free(this->buf); } diff --git a/src/textbuf_type.h b/src/textbuf_type.h index b4f234f737..14e92cbb3d 100644 --- a/src/textbuf_type.h +++ b/src/textbuf_type.h @@ -67,7 +67,7 @@ struct Textbuf { void DiscardMarkedText(bool update = true); private: - StringIterator *char_iter; + std::unique_ptr char_iter; bool CanDelChar(bool backspace); From 5c64cdcb795f79be85ca99784b4fd5172382f6f1 Mon Sep 17 00:00:00 2001 From: Tyler Trahan Date: Fri, 13 Jan 2023 18:04:30 -0500 Subject: [PATCH 5/7] Feature: Press Ctrl to build a diagonal area of trees (#10342) --- src/lang/english.txt | 4 ++-- src/script/api/script_tile.cpp | 4 ++-- src/tree_cmd.cpp | 8 +++++--- src/tree_cmd.h | 2 +- src/tree_gui.cpp | 6 +++--- 5 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/lang/english.txt b/src/lang/english.txt index 184af016b0..382d52b3c6 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -386,7 +386,7 @@ STR_SCENEDIT_TOOLBAR_TOWN_GENERATION :{BLACK}Town gen STR_SCENEDIT_TOOLBAR_INDUSTRY_GENERATION :{BLACK}Industry generation STR_SCENEDIT_TOOLBAR_ROAD_CONSTRUCTION :{BLACK}Road construction STR_SCENEDIT_TOOLBAR_TRAM_CONSTRUCTION :{BLACK}Tramway construction -STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Plant trees. Shift toggles building/showing cost estimate +STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Plant trees. Ctrl selects the area diagonally. Shift toggles building/showing cost estimate STR_SCENEDIT_TOOLBAR_PLACE_SIGN :{BLACK}Place sign STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Place object. Ctrl selects the area diagonally. Shift toggles building/showing cost estimate @@ -2819,7 +2819,7 @@ STR_OBJECT_CLASS_TRNS :Transmitters STR_PLANT_TREE_CAPTION :{WHITE}Trees STR_PLANT_TREE_TOOLTIP :{BLACK}Select tree type to plant. If the tile already has a tree, this will add more trees of mixed types independent of the selected type STR_TREES_RANDOM_TYPE :{BLACK}Trees of random type -STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Place trees of random type. Shift toggles building/showing cost estimate +STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Place trees of random type. Ctrl selects the area diagonally. Shift toggles building/showing cost estimate STR_TREES_RANDOM_TREES_BUTTON :{BLACK}Random Trees STR_TREES_RANDOM_TREES_TOOLTIP :{BLACK}Plant trees randomly throughout the landscape STR_TREES_MODE_NORMAL_BUTTON :{BLACK}Normal diff --git a/src/script/api/script_tile.cpp b/src/script/api/script_tile.cpp index d8bcc399fa..ed7b1300cd 100644 --- a/src/script/api/script_tile.cpp +++ b/src/script/api/script_tile.cpp @@ -287,7 +287,7 @@ EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); EnforcePrecondition(false, ::IsValidTile(tile)); - return ScriptObject::Command::Do(tile, tile, TREE_INVALID); + return ScriptObject::Command::Do(tile, tile, TREE_INVALID, false); } /* static */ bool ScriptTile::PlantTreeRectangle(TileIndex tile, uint width, uint height) @@ -298,7 +298,7 @@ EnforcePrecondition(false, height >= 1 && height <= 20); TileIndex end_tile = tile + ::TileDiffXY(width - 1, height - 1); - return ScriptObject::Command::Do(tile, end_tile, TREE_INVALID); + return ScriptObject::Command::Do(tile, end_tile, TREE_INVALID, false); } /* static */ bool ScriptTile::IsWithinTownInfluence(TileIndex tile, TownID town_id) diff --git a/src/tree_cmd.cpp b/src/tree_cmd.cpp index c98758062f..505d5bb7af 100644 --- a/src/tree_cmd.cpp +++ b/src/tree_cmd.cpp @@ -384,9 +384,10 @@ void GenerateTrees() * @param tile end tile of area-drag * @param start_tile start tile of area-drag of tree plantation * @param tree_to_plant tree type, TREE_INVALID means random. + * @param diagonal Whether to use the Orthogonal (false) or Diagonal (true) iterator. * @return the cost of this operation or an error */ -CommandCost CmdPlantTree(DoCommandFlag flags, TileIndex tile, TileIndex start_tile, byte tree_to_plant) +CommandCost CmdPlantTree(DoCommandFlag flags, TileIndex tile, TileIndex start_tile, byte tree_to_plant, bool diagonal) { StringID msg = INVALID_STRING_ID; CommandCost cost(EXPENSES_OTHER); @@ -398,8 +399,9 @@ CommandCost CmdPlantTree(DoCommandFlag flags, TileIndex tile, TileIndex start_ti 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, start_tile); - for (TileIndex current_tile : ta) { + std::unique_ptr iter = TileIterator::Create(tile, start_tile, diagonal); + for (; *iter != INVALID_TILE; ++(*iter)) { + TileIndex current_tile = *iter; switch (GetTileType(current_tile)) { case MP_TREES: /* no more space for trees? */ diff --git a/src/tree_cmd.h b/src/tree_cmd.h index 8f2199e3e8..d730cf74ae 100644 --- a/src/tree_cmd.h +++ b/src/tree_cmd.h @@ -12,7 +12,7 @@ #include "command_type.h" -CommandCost CmdPlantTree(DoCommandFlag flags, TileIndex tile, TileIndex start_tile, byte tree_to_plant); +CommandCost CmdPlantTree(DoCommandFlag flags, TileIndex tile, TileIndex start_tile, byte tree_to_plant, bool diagonal); DEF_CMD_TRAIT(CMD_PLANT_TREE, CmdPlantTree, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION) diff --git a/src/tree_gui.cpp b/src/tree_gui.cpp index f3d3603fbd..5292ba1e64 100644 --- a/src/tree_gui.cpp +++ b/src/tree_gui.cpp @@ -103,7 +103,7 @@ class BuildTreesWindow : public Window if (this->tree_to_plant >= 0) { /* Activate placement */ if (_settings_client.sound.confirm) SndPlayFx(SND_15_BEEP); - SetObjectToPlace(SPR_CURSOR_TREE, PAL_NONE, HT_RECT, this->window_class, this->window_number); + SetObjectToPlace(SPR_CURSOR_TREE, PAL_NONE, HT_RECT | HT_DIAGONAL, this->window_class, this->window_number); this->tree_to_plant = current_tree; // SetObjectToPlace may call ResetObjectToPlace which may reset tree_to_plant to -1 } else { /* Deactivate placement */ @@ -231,7 +231,7 @@ public: TileIndex tile = TileVirtXY(pt.x, pt.y); if (this->mode == PM_NORMAL) { - Command::Post(tile, tile, this->tree_to_plant); + Command::Post(tile, tile, this->tree_to_plant, false); } else { this->DoPlantForest(tile); } @@ -241,7 +241,7 @@ public: void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile) override { if (_game_mode != GM_EDITOR && this->mode == PM_NORMAL && pt.x != -1 && select_proc == DDSP_PLANT_TREES) { - Command::Post(STR_ERROR_CAN_T_PLANT_TREE_HERE, end_tile, start_tile, this->tree_to_plant); + Command::Post(STR_ERROR_CAN_T_PLANT_TREE_HERE, end_tile, start_tile, this->tree_to_plant, _ctrl_pressed); } } From 2206c73156742fd671348ba86a26c25d874abd7c Mon Sep 17 00:00:00 2001 From: Tyler Trahan Date: Sat, 14 Jan 2023 05:12:29 -0500 Subject: [PATCH 6/7] Feature: Set a custom number of industries in map generation window (#10340) --- src/genworld_gui.cpp | 36 +++++++++++++++++++--- src/industry_cmd.cpp | 4 +++ src/settings_type.h | 3 ++ src/table/settings/difficulty_settings.ini | 2 +- src/table/settings/world_settings.ini | 7 +++++ 5 files changed, 47 insertions(+), 5 deletions(-) diff --git a/src/genworld_gui.cpp b/src/genworld_gui.cpp index 26c0965a50..6bb11658b7 100644 --- a/src/genworld_gui.cpp +++ b/src/genworld_gui.cpp @@ -32,6 +32,7 @@ #include "video/video_driver.hpp" #include "ai/ai_gui.hpp" #include "game/game_gui.hpp" +#include "industry.h" #include "widgets/genworld_widget.h" @@ -396,7 +397,7 @@ static const StringID _rivers[] = {STR_RIVERS_NONE, STR_RIVERS_FEW, STR_RIV static const StringID _smoothness[] = {STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN_VERY_SMOOTH, STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN_SMOOTH, STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN_ROUGH, STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN_VERY_ROUGH, INVALID_STRING_ID}; static const StringID _rotation[] = {STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE, STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_CLOCKWISE, INVALID_STRING_ID}; static const StringID _num_towns[] = {STR_NUM_VERY_LOW, STR_NUM_LOW, STR_NUM_NORMAL, STR_NUM_HIGH, STR_NUM_CUSTOM, INVALID_STRING_ID}; -static const StringID _num_inds[] = {STR_FUNDING_ONLY, STR_MINIMAL, STR_NUM_VERY_LOW, STR_NUM_LOW, STR_NUM_NORMAL, STR_NUM_HIGH, INVALID_STRING_ID}; +static const StringID _num_inds[] = {STR_FUNDING_ONLY, STR_MINIMAL, STR_NUM_VERY_LOW, STR_NUM_LOW, STR_NUM_NORMAL, STR_NUM_HIGH, STR_NUM_CUSTOM, INVALID_STRING_ID}; static const StringID _variety[] = {STR_VARIETY_NONE, STR_VARIETY_VERY_LOW, STR_VARIETY_LOW, STR_VARIETY_MEDIUM, STR_VARIETY_HIGH, STR_VARIETY_VERY_HIGH, INVALID_STRING_ID}; static_assert(lengthof(_num_inds) == ID_END + 1); @@ -463,7 +464,17 @@ struct GenerateLandscapeWindow : public Window { break; } - case WID_GL_INDUSTRY_PULLDOWN: SetDParam(0, _game_mode == GM_EDITOR ? STR_CONFIG_SETTING_OFF : _num_inds[_settings_newgame.difficulty.industry_density]); break; + case WID_GL_INDUSTRY_PULLDOWN: + if (_game_mode == GM_EDITOR) { + SetDParam(0, STR_CONFIG_SETTING_OFF); + } else if (_settings_newgame.difficulty.industry_density == ID_CUSTOM) { + SetDParam(0, STR_NUM_CUSTOM_NUMBER); + SetDParam(1, _settings_newgame.game_creation.custom_industry_number); + } else { + SetDParam(0, _num_inds[_settings_newgame.difficulty.industry_density]); + } + break; + case WID_GL_TERRAIN_PULLDOWN: if (_settings_newgame.difficulty.terrain_type == CUSTOM_TERRAIN_TYPE_NUMBER_DIFFICULTY) { SetDParam(0, STR_TERRAIN_TYPE_CUSTOM_VALUE); @@ -620,7 +631,11 @@ struct GenerateLandscapeWindow : public Window { *size = maxdim(*size, GetStringBoundingBox(STR_NUM_CUSTOM_NUMBER)); break; - case WID_GL_INDUSTRY_PULLDOWN: strs = _num_inds; break; + case WID_GL_INDUSTRY_PULLDOWN: + strs = _num_inds; + SetDParamMaxValue(0, IndustryPool::MAX_SIZE); + *size = maxdim(*size, GetStringBoundingBox(STR_NUM_CUSTOM_NUMBER)); + break; case WID_GL_TERRAIN_PULLDOWN: strs = _elevations; @@ -908,7 +923,15 @@ struct GenerateLandscapeWindow : public Window { } break; - case WID_GL_INDUSTRY_PULLDOWN: _settings_newgame.difficulty.industry_density = index; break; + case WID_GL_INDUSTRY_PULLDOWN: + if ((uint)index == ID_CUSTOM) { + this->widget_id = widget; + SetDParam(0, _settings_newgame.game_creation.custom_industry_number); + ShowQueryString(STR_JUST_INT, STR_MAPGEN_NUMBER_OF_INDUSTRIES, 5, this, CS_NUMERAL, QSF_NONE); + } + _settings_newgame.difficulty.industry_density = index; + break; + case WID_GL_TERRAIN_PULLDOWN: { if ((uint)index == CUSTOM_TERRAIN_TYPE_NUMBER_DIFFICULTY) { this->widget_id = widget; @@ -948,6 +971,7 @@ struct GenerateLandscapeWindow : public Window { 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; + case WID_GL_INDUSTRY_PULLDOWN: value = 1; break; case WID_GL_TERRAIN_PULLDOWN: value = MIN_MAP_HEIGHT_LIMIT; break; case WID_GL_WATER_PULLDOWN: value = CUSTOM_SEA_LEVEL_MIN_PERCENTAGE; break; default: NOT_REACHED(); @@ -979,6 +1003,10 @@ struct GenerateLandscapeWindow : public Window { _settings_newgame.game_creation.custom_town_number = Clamp(value, 1, CUSTOM_TOWN_MAX_NUMBER); break; + case WID_GL_INDUSTRY_PULLDOWN: + _settings_newgame.game_creation.custom_industry_number = Clamp(value, 1, IndustryPool::MAX_SIZE); + break; + case WID_GL_TERRAIN_PULLDOWN: _settings_newgame.game_creation.custom_terrain_type = Clamp(value, MIN_CUSTOM_TERRAIN_TYPE, GetMapHeightLimit()); break; diff --git a/src/industry_cmd.cpp b/src/industry_cmd.cpp index 78a0966a45..cdf1f9d430 100644 --- a/src/industry_cmd.cpp +++ b/src/industry_cmd.cpp @@ -2236,10 +2236,14 @@ static uint GetNumberOfIndustries() 25, // low 55, // normal 80, // high + 0, // custom }; assert(lengthof(numof_industry_table) == ID_END); uint difficulty = (_game_mode != GM_EDITOR) ? _settings_game.difficulty.industry_density : (uint)ID_VERY_LOW; + + if (difficulty == ID_CUSTOM) return std::min(IndustryPool::MAX_SIZE, _settings_game.game_creation.custom_industry_number); + return std::min(IndustryPool::MAX_SIZE, ScaleByMapSize(numof_industry_table[difficulty])); } diff --git a/src/settings_type.h b/src/settings_type.h index a83384cdb3..2a33d3be0e 100644 --- a/src/settings_type.h +++ b/src/settings_type.h @@ -58,6 +58,8 @@ enum IndustryDensity { ID_NORMAL, ///< Normal amount of industries at game start. ID_HIGH, ///< Many industries at game start. + ID_CUSTOM, ///< Custom number of industries. + ID_END, ///< Number of industry density settings. }; @@ -326,6 +328,7 @@ struct GameCreationSettings { byte landscape; ///< the landscape we're currently in byte water_borders; ///< bitset of the borders that are water uint16 custom_town_number; ///< manually entered number of towns + uint16 custom_industry_number; ///< manually entered number of industries byte variety; ///< variety level applied to TGP byte custom_terrain_type; ///< manually entered height for TGP to aim for byte custom_sea_level; ///< manually entered percentage of water in the map diff --git a/src/table/settings/difficulty_settings.ini b/src/table/settings/difficulty_settings.ini index de1b54955c..d47da817d6 100644 --- a/src/table/settings/difficulty_settings.ini +++ b/src/table/settings/difficulty_settings.ini @@ -83,7 +83,7 @@ var = difficulty.industry_density type = SLE_UINT8 from = SLV_97 flags = SF_GUI_DROPDOWN -def = ID_END - 1 +def = ID_NORMAL min = 0 max = ID_END - 1 interval = 1 diff --git a/src/table/settings/world_settings.ini b/src/table/settings/world_settings.ini index 479f1e7442..d5fafd9d83 100644 --- a/src/table/settings/world_settings.ini +++ b/src/table/settings/world_settings.ini @@ -271,6 +271,13 @@ min = 1 max = 5000 cat = SC_BASIC +[SDT_VAR] +var = game_creation.custom_industry_number +type = SLE_UINT16 +def = 1 +min = 1 +max = 64000 + [SDT_VAR] var = game_creation.custom_terrain_type type = SLE_UINT8 From 07fba75238871fd64e1b3ad3ca9fc71583f04db0 Mon Sep 17 00:00:00 2001 From: Tyler Trahan Date: Sat, 14 Jan 2023 08:20:19 -0500 Subject: [PATCH 7/7] Fix: Various Wide River issues (#10348) --- src/landscape.cpp | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/landscape.cpp b/src/landscape.cpp index 90737de745..66912ee3fc 100644 --- a/src/landscape.cpp +++ b/src/landscape.cpp @@ -1093,7 +1093,7 @@ static bool RiverMakeWider(TileIndex tile, void *data) /* If the tile is at height 0 after terraforming but the ocean hasn't flooded yet, don't build river. */ if (GetTileMaxZ(tile) == 0) return false; - TileIndex origin_tile = *(TileIndex *)data;; + TileIndex origin_tile = *(TileIndex *)data; Slope cur_slope = GetTileSlope(tile); Slope desired_slope = GetTileSlope(origin_tile); // Initialize matching the origin tile as a shortcut if no terraforming is needed. @@ -1131,7 +1131,7 @@ static bool RiverMakeWider(TileIndex tile, void *data) } } /* If we find an adjacent river tile, remember it. We'll terraform to match it later if we don't find a slope. */ - if (IsTileFlat(tile)) flat_river_found = true; + if (IsTileFlat(other_tile)) flat_river_found = true; } } /* We didn't find either an inclined or flat river, so we're climbing the wrong slope. Bail out. */ @@ -1203,6 +1203,11 @@ static bool RiverMakeWider(TileIndex tile, void *data) if (GetTileSlope(downstream_tile) != SLOPE_FLAT) return false; MakeRiver(downstream_tile, Random()); + MarkTileDirtyByTile(downstream_tile); + + /* Remove desert directly around the river tile. */ + TileIndex cur_tile = downstream_tile; + CircularTileSearch(&cur_tile, RIVER_OFFSET_DESERT_DISTANCE, RiverModifyDesertZone, nullptr); } /* If upstream is dry and flat, try making it a river tile. */ @@ -1211,16 +1216,21 @@ static bool RiverMakeWider(TileIndex tile, void *data) if (GetTileSlope(upstream_tile) != SLOPE_FLAT) return false; MakeRiver(upstream_tile, Random()); + MarkTileDirtyByTile(upstream_tile); + + /* Remove desert directly around the river tile. */ + TileIndex cur_tile = upstream_tile; + CircularTileSearch(&cur_tile, RIVER_OFFSET_DESERT_DISTANCE, RiverModifyDesertZone, nullptr); } } /* If the tile slope matches the desired slope, add a river tile. */ if (cur_slope == desired_slope) { MakeRiver(tile, Random()); + MarkTileDirtyByTile(tile); /* Remove desert directly around the river tile. */ TileIndex cur_tile = tile; - MarkTileDirtyByTile(cur_tile); CircularTileSearch(&cur_tile, RIVER_OFFSET_DESERT_DISTANCE, RiverModifyDesertZone, nullptr); } @@ -1494,6 +1504,9 @@ static void CreateRivers() } } + /* Widening rivers may have left some tiles requiring to be watered. */ + ConvertGroundTilesIntoWaterTiles(); + /* Run tile loop to update the ground density. */ for (uint i = 0; i != 256; i++) { if (i % 64 == 0) IncreaseGeneratingWorldProgress(GWP_RIVER);