diff --git a/cm_changelog.txt b/cm_changelog.txt index 48226ba180..f1e2e2d9e6 100644 --- a/cm_changelog.txt +++ b/cm_changelog.txt @@ -74,8 +74,8 @@ This is usable for any OpenTTD servers == CHANGELOG == -*** 12.0 (4 Oct 2021) *** -- Added rail copy-paste tool. +*** 12.0-RC1 (5 Oct 2021) *** +- Added experimental rail copy-paste tool. - Added client list overlay (toggleable with a button in the regular client list window title). - Added back "New company" option to the company toolbar dropdown menu. - Fixed crash when closing order window with a hotkey. diff --git a/src/citymania/cm_minimap.cpp b/src/citymania/cm_minimap.cpp index 60caab118d..dbe3e5f1b2 100644 --- a/src/citymania/cm_minimap.cpp +++ b/src/citymania/cm_minimap.cpp @@ -915,20 +915,24 @@ void SmallMapWindow::DrawVehicles(const DrawPixelInfo *dpi, Blitter *blitter) co */ void SmallMapWindow::DrawTowns(const DrawPixelInfo *dpi) const { - for (const Town *t : Town::Iterate()) { - /* Remap the town coordinate */ + for (auto &[t, population, width] : this->town_cache.towns) { Point pt = this->TileToPixel(TileX(t->xy) * TILE_SIZE, TileY(t->xy) * TILE_SIZE); - int x = pt.x - (t->cache.sign.width_small >> 1); - int y = pt.y; + int x = pt.x - width / 2; + int y = pt.y - FONT_HEIGHT_SMALL / 2; /* Check if the town sign is within bounds */ - if (x + t->cache.sign.width_small > dpi->left && + if ((int)(x + width) > dpi->left && x < dpi->left + dpi->width && y + FONT_HEIGHT_SMALL > dpi->top && y < dpi->top + dpi->height) { - /* And draw it. */ - SetDParam(0, t->index); - DrawString(x, x + t->cache.sign.width_small, y, t->larger_town ? STR_SMALLMAP_TOWN_LARGE : STR_SMALLMAP_TOWN); + if (this->map_type == CM_SMT_IMBA) { + /* And draw it. */ + SetDParam(0, population); + DrawString(x, x + width, y, t->larger_town ? CM_STR_SMALLMAP_POPULATION_LARGE : CM_STR_SMALLMAP_POPULATION); + } else { + SetDParam(0, t->index); + DrawString(x, x + t->cache.sign.width_small, y, t->larger_town ? CM_STR_SMALLMAP_TOWN_LARGE : STR_SMALLMAP_TOWN); + } } } } @@ -1187,6 +1191,9 @@ void SmallMapWindow::RebuildColourIndexIfNecessary() /* The width of a column is the minimum width of all texts + the size of the blob + some spacing */ this->column_width = min_width + LEGEND_BLOB_WIDTH + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT; + + SetDParam(0, 9999999); // max reasonable population + this->town_cache.max_sign = GetStringBoundingBox(CM_STR_SMALLMAP_POPULATION); } /* virtual */ void SmallMapWindow::OnPaint() @@ -1202,6 +1209,7 @@ void SmallMapWindow::RebuildColourIndexIfNecessary() } } + this->UpdateTownCache(false); this->DrawWidgets(); } @@ -1440,7 +1448,6 @@ int SmallMapWindow::GetPositionOnLegend(Point pt) Window *w = FindWindowById(WC_MAIN_WINDOW, 0); pt = this->PixelToTile(pt.x - wid->pos_x, pt.y - wid->pos_y); ScrollWindowTo(pt.x, pt.y, -1, w); - this->SetDirty(); break; } @@ -1615,6 +1622,14 @@ int SmallMapWindow::GetPositionOnLegend(Point pt) this->SetDirty(); } +/* virtual */ void SmallMapWindow::OnHundredthTick() +{ + if (this->show_towns) { + this->UpdateTownCache(true); + this->SetDirty(); + } +} + /* virtual */ void SmallMapWindow::OnScroll(Point delta) { if (_settings_client.gui.scroll_mode == VSM_VIEWPORT_RMB_FIXED || _settings_client.gui.scroll_mode == VSM_MAP_RMB_FIXED) _cursor.fix_at = true; @@ -1659,6 +1674,62 @@ Point SmallMapWindow::GetStationMiddle(const Station *st) const return ret; } +static bool IsSignVisible(const Rect &rect, Point pt, int sign_width, int sign_height) { + auto x = pt.x - sign_width / 2; + auto y = pt.y - sign_height / 2; + return ( + x < rect.right && + x + sign_width > rect.left && + y < rect.bottom && + y + sign_height > rect.top + ); +} + +void SmallMapWindow::UpdateTownCache(bool force) { + const NWidgetBase *widget = this->GetWidget(WID_SM_MAP); + + if (!this->show_towns) { + this->town_cache.width = 0; + return; + } + + if (!force && + this->town_cache.zoom == this->zoom && + this->town_cache.scroll_x == this->scroll_x && + this->town_cache.scroll_y == this->scroll_y && + this->town_cache.width == widget->current_x && + this->town_cache.height == widget->current_y) + return; + + this->town_cache.zoom = this->zoom; + this->town_cache.scroll_x = this->scroll_x; + this->town_cache.scroll_y = this->scroll_y; + this->town_cache.width = widget->current_x; + this->town_cache.height = widget->current_y; + + auto rect = widget->GetCurrentRect(); + + this->town_cache.towns.clear(); + for (const Town *t : Town::Iterate()) { + /* Remap the town coordinate */ + Point pt = this->TileToPixel(TileX(t->xy) * TILE_SIZE, TileY(t->xy) * TILE_SIZE); + + + if (this->map_type == CM_SMT_IMBA) { + if (!IsSignVisible(rect, pt, this->town_cache.max_sign.width, this->town_cache.max_sign.height)) continue; + SetDParam(0, t->cache.population); + auto dim = GetStringBoundingBox(CM_STR_SMALLMAP_POPULATION); + + if (!IsSignVisible(rect, pt, dim.width, dim.height)) continue; + + this->town_cache.towns.push_back(std::make_tuple(t, t->cache.population, dim.width)); + } else { + if (!IsSignVisible(rect, pt, t->cache.sign.width_small, FONT_HEIGHT_SMALL)) continue; + this->town_cache.towns.push_back(std::make_tuple(t, t->cache.population, t->cache.sign.width_small)); + } + } +} + SmallMapWindow::SmallMapType SmallMapWindow::map_type = CM_SMT_IMBA; bool SmallMapWindow::show_towns = true; int SmallMapWindow::map_height_limit = -1; diff --git a/src/citymania/cm_minimap.hpp b/src/citymania/cm_minimap.hpp index ce9aa4f847..25e723cf96 100644 --- a/src/citymania/cm_minimap.hpp +++ b/src/citymania/cm_minimap.hpp @@ -87,11 +87,21 @@ protected: int32 subscroll; ///< Number of pixels (0..3) between the right end of the base tile and the pixel at the top-left corner of the smallmap display. int tile_zoom; ///< Zoom level. Bigger number means more zoom-out (further away). int ui_zoom; ///< Zoom level. Bigger number means more zoom-out (further away). - int zoom; ///< Zoom level. Bigger number means more zoom-out (further away). + int zoom = 1; ///< Zoom level. Bigger number means more zoom-out (further away). GUITimer refresh; ///< Refresh timer. LinkGraphOverlay *overlay; + struct { + int32 scroll_x; + int32 scroll_y; + uint width = 0; + uint height = 0; + int zoom; + Dimension max_sign; + std::vector> towns; + } town_cache; + static void BreakIndustryChainLink(); Point SmallmapRemapCoords(int x, int y) const; @@ -179,6 +189,8 @@ protected: int GetPositionOnLegend(Point pt); + void UpdateTownCache(bool force); + public: friend class citymania::NWidgetSmallmapDisplay; @@ -197,6 +209,7 @@ public: bool OnRightClick(Point pt, int widget) override; void OnMouseWheel(int wheel) override; void OnRealtimeTick(uint delta_ms) override; + void OnHundredthTick() override; void OnScroll(Point delta) override; void OnMouseOver(Point pt, int widget) override; }; diff --git a/src/lang/english.txt b/src/lang/english.txt index 27a3efd32f..705c45fb08 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -5737,7 +5737,6 @@ STR_TOOLBAR_CARGOS_NAME :{BLACK}{STRING} #towns STR_TOWN_DIRECTORY_TOWN_COLOUR :{ORANGE}{TOWN}{BLACK} ({COMMA}->{COMMA}) {YELLOW}{COMMA} {P "house" "houses"} STR_TOWN_DIRECTORY_CITY_COLOUR :{YELLOW}{TOWN}{BLACK} ({COMMA}->{COMMA}) {YELLOW}{COMMA} {P "house" "houses"} -STR_SMALLMAP_TOWN_LARGE :{TINY_FONT}{YELLOW}{TOWN} STR_SORT_BY_HOUSES :Houses STR_SORT_BY_REAL_POPULATION :Real population @@ -5967,3 +5966,7 @@ STR_CM_CONFIG_SETTING_IMPROVED_STATION_JOIN :Use improved st STR_CM_CONFIG_SETTING_IMPROVED_STATION_JOIN_HELPTEXT :Use Ctrl-click on station tile to select or deselect station to join. If station has no tiles Ctrl-click its sign. Ctrl-click empty tile for a new station. Also recently built station is automatically selected as a station to join. {RED}Doesn't work if joining stations not directly adjacent(distant join) is not allowed in settings. CM_STR_TOGGLE_CLIENTS_OVERLAY :Toggle client list overlay. + +CM_STR_SMALLMAP_TOWN_LARGE :{TINY_FONT}{YELLOW}{TOWN} +CM_STR_SMALLMAP_POPULATION_LARGE :{TINY_FONT}{YELLOW}({NUM}) +CM_STR_SMALLMAP_POPULATION :{TINY_FONT}{WHITE}({NUM}) diff --git a/src/smallmap_gui.cpp b/src/smallmap_gui.cpp index 93ec2ff47e..63fdc0d198 100644 --- a/src/smallmap_gui.cpp +++ b/src/smallmap_gui.cpp @@ -971,7 +971,7 @@ void SmallMapWindow::DrawTowns(const DrawPixelInfo *dpi) const y < dpi->top + dpi->height) { /* And draw it. */ SetDParam(0, t->index); - DrawString(x, x + t->cache.sign.width_small, y, t->larger_town ? STR_SMALLMAP_TOWN_LARGE : STR_SMALLMAP_TOWN); + DrawString(x, x + t->cache.sign.width_small, y, STR_SMALLMAP_TOWN); } } }