Copy land info tool to citymania source

This commit is contained in:
dP
2020-08-16 06:16:24 +03:00
parent d6d61af834
commit d084a4b8a8
6 changed files with 412 additions and 4 deletions

View File

@@ -1235,6 +1235,8 @@ citymania/cm_locations.hpp
citymania/cm_locations.cpp
citymania/cm_minimap.hpp
citymania/cm_minimap.cpp
citymania/cm_misc_gui.hpp
citymania/cm_misc_gui.cpp
citymania/cm_station_gui.hpp
citymania/cm_station_gui.cpp
newgrf_revisions.hpp

View File

@@ -0,0 +1,394 @@
#include "../stdafx.h"
#include "cm_misc_gui.hpp"
#include "../command_func.h"
#include "../company_base.h"
#include "../debug.h"
#include "../newgrf_debug.h"
#include "../string_func.h"
#include "../strings_func.h"
#include "../tile_cmd.h"
#include "../town.h"
#include "../widget_type.h"
#include "../window_func.h"
#include "../window_gui.h"
#include "../zoom_func.h"
#include "../widgets/misc_widget.h"
namespace citymania {
static const NWidgetPart _nested_land_info_widgets[] = {
NWidget(WWT_PANEL, COLOUR_GREY, WID_LI_BACKGROUND), SetMinimalSize(64, 32), EndContainer(),
};
static WindowDesc _land_info_desc(
WDP_MANUAL, "land_info", 0, 0,
WC_LAND_INFO, WC_NONE,
0,
_nested_land_info_widgets, lengthof(_nested_land_info_widgets)
);
class LandInfoWindow : public Window {
enum LandInfoLines {
LAND_INFO_CENTERED_LINES = 32, ///< Up to 32 centered lines (arbitrary limit)
LAND_INFO_MULTICENTER_LINE = LAND_INFO_CENTERED_LINES, ///< One multicenter line
LAND_INFO_LINE_END,
};
static const uint LAND_INFO_LINE_BUFF_SIZE = 512;
public:
char landinfo_data[LAND_INFO_LINE_END][LAND_INFO_LINE_BUFF_SIZE];
TileIndex tile;
TileIndex end_tile; ///< For use in ruler(dragdrop) mode
virtual Point OnInitialPosition(int16 sm_width, int16 sm_height, int window_number)
{
int scr_top = GetMainViewTop() + 2;
int scr_bot = GetMainViewBottom() - 2;
Point pt;
pt.y = Clamp(_cursor.pos.y + _cursor.total_size.y + _cursor.total_offs.y + 5, scr_top, scr_bot);
if (pt.y + sm_height > scr_bot) pt.y = min(_cursor.pos.y + _cursor.total_offs.y - 5, scr_bot) - sm_height;
pt.x = sm_width >= _screen.width ? 0 : Clamp(_cursor.pos.x - (sm_width >> 1), 0, _screen.width - sm_width);
return pt;
}
void DrawWidget(const Rect &r, int widget) const override
{
if (widget != WID_LI_BACKGROUND) return;
GfxDrawLine(r.left, r.top, r.right, r.top, PC_BLACK);
GfxDrawLine(r.left, r.bottom, r.right, r.bottom, PC_BLACK);
GfxDrawLine(r.left, r.top, r.left, r.bottom, PC_BLACK);
GfxDrawLine(r.right, r.top, r.right, r.bottom, PC_BLACK);
uint y = r.top + WD_TEXTPANEL_TOP;
for (uint i = 0; i < LAND_INFO_CENTERED_LINES; i++) {
if (StrEmpty(this->landinfo_data[i])) break;
DrawString(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, y, this->landinfo_data[i], i == 0 ? TC_LIGHT_BLUE : TC_FROMSTRING, SA_HOR_CENTER);
y += FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL;
if (i == 0) y += 4;
}
if (!StrEmpty(this->landinfo_data[LAND_INFO_MULTICENTER_LINE])) {
SetDParamStr(0, this->landinfo_data[LAND_INFO_MULTICENTER_LINE]);
DrawStringMultiLine(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, y, r.bottom - WD_TEXTPANEL_BOTTOM, STR_JUST_RAW_STRING, TC_FROMSTRING, SA_CENTER);
}
}
void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
{
if (widget != WID_LI_BACKGROUND) return;
size->height = WD_TEXTPANEL_TOP + WD_TEXTPANEL_BOTTOM;
for (uint i = 0; i < LAND_INFO_CENTERED_LINES; i++) {
if (StrEmpty(this->landinfo_data[i])) break;
uint width = GetStringBoundingBox(this->landinfo_data[i]).width + WD_FRAMETEXT_LEFT + WD_FRAMETEXT_RIGHT;
size->width = max(size->width, width);
size->height += FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL;
if (i == 0) size->height += 4;
}
if (!StrEmpty(this->landinfo_data[LAND_INFO_MULTICENTER_LINE])) {
uint width = GetStringBoundingBox(this->landinfo_data[LAND_INFO_MULTICENTER_LINE]).width + WD_FRAMETEXT_LEFT + WD_FRAMETEXT_RIGHT;
size->width = max(size->width, min<uint>(ScaleGUITrad(300), width));
SetDParamStr(0, this->landinfo_data[LAND_INFO_MULTICENTER_LINE]);
size->height += GetStringHeight(STR_JUST_RAW_STRING, size->width - WD_FRAMETEXT_LEFT - WD_FRAMETEXT_RIGHT);
}
}
LandInfoWindow(TileIndex tile, TileIndex end_tile=INVALID_TILE) :
Window(&_land_info_desc), tile(tile), end_tile(end_tile)
{
this->InitNested();
CLRBITS(this->flags, WF_WHITE_BORDER);
#if defined(_DEBUG)
# define LANDINFOD_LEVEL 0
#else
# define LANDINFOD_LEVEL 1
#endif
DEBUG(misc, LANDINFOD_LEVEL, "TILE: %#x (%i,%i)", tile, TileX(tile), TileY(tile));
DEBUG(misc, LANDINFOD_LEVEL, "type = %#x", _m[tile].type);
DEBUG(misc, LANDINFOD_LEVEL, "height = %#x", _m[tile].height);
DEBUG(misc, LANDINFOD_LEVEL, "m1 = %#x", _m[tile].m1);
DEBUG(misc, LANDINFOD_LEVEL, "m2 = %#x", _m[tile].m2);
DEBUG(misc, LANDINFOD_LEVEL, "m3 = %#x", _m[tile].m3);
DEBUG(misc, LANDINFOD_LEVEL, "m4 = %#x", _m[tile].m4);
DEBUG(misc, LANDINFOD_LEVEL, "m5 = %#x", _m[tile].m5);
DEBUG(misc, LANDINFOD_LEVEL, "m6 = %#x", _me[tile].m6);
DEBUG(misc, LANDINFOD_LEVEL, "m7 = %#x", _me[tile].m7);
DEBUG(misc, LANDINFOD_LEVEL, "m8 = %#x", _me[tile].m8);
#undef LANDINFOD_LEVEL
}
void OnInit() override
{
Town *t = ClosestTownFromTile(tile, _settings_game.economy.dist_local_authority);
/* Because build_date is not set yet in every TileDesc, we make sure it is empty */
TileDesc td;
td.build_date = INVALID_DATE;
/* Most tiles have only one owner, but
* - drivethrough roadstops can be build on town owned roads (up to 2 owners) and
* - roads can have up to four owners (railroad, road, tram, 3rd-roadtype "highway").
*/
td.owner_type[0] = STR_LAND_AREA_INFORMATION_OWNER; // At least one owner is displayed, though it might be "N/A".
td.owner_type[1] = STR_NULL; // STR_NULL results in skipping the owner
td.owner_type[2] = STR_NULL;
td.owner_type[3] = STR_NULL;
td.owner[0] = OWNER_NONE;
td.owner[1] = OWNER_NONE;
td.owner[2] = OWNER_NONE;
td.owner[3] = OWNER_NONE;
td.station_class = STR_NULL;
td.station_name = STR_NULL;
td.airport_class = STR_NULL;
td.airport_name = STR_NULL;
td.airport_tile_name = STR_NULL;
td.railtype = STR_NULL;
td.rail_speed = 0;
td.roadtype = STR_NULL;
td.road_speed = 0;
td.tramtype = STR_NULL;
td.tram_speed = 0;
td.population = 0;
td.grf = nullptr;
CargoArray acceptance;
AddAcceptedCargo(tile, acceptance, nullptr);
GetTileDesc(tile, &td);
uint line_nr = 0;
/* Tiletype */
SetDParam(0, td.dparam[0]);
GetString(this->landinfo_data[line_nr], td.str, lastof(this->landinfo_data[line_nr]));
line_nr++;
/* Up to four owners */
for (uint i = 0; i < 4; i++) {
if (td.owner_type[i] == STR_NULL) continue;
SetDParam(0, STR_LAND_AREA_INFORMATION_OWNER_N_A);
if (td.owner[i] != OWNER_NONE && td.owner[i] != OWNER_WATER) GetNameOfOwner(td.owner[i], tile);
GetString(this->landinfo_data[line_nr], td.owner_type[i], lastof(this->landinfo_data[line_nr]));
line_nr++;
}
/* Cost to clear/revenue when cleared */
StringID str = STR_LAND_AREA_INFORMATION_COST_TO_CLEAR_N_A;
Company *c = Company::GetIfValid(_local_company);
if (c != nullptr) {
assert(_current_company == _local_company);
CommandCost costclear = DoCommand(tile, 0, 0, DC_QUERY_COST, CMD_LANDSCAPE_CLEAR);
if (costclear.Succeeded()) {
Money cost = costclear.GetCost();
if (cost < 0) {
cost = -cost; // Negate negative cost to a positive revenue
str = STR_LAND_AREA_INFORMATION_REVENUE_WHEN_CLEARED;
} else {
str = STR_LAND_AREA_INFORMATION_COST_TO_CLEAR;
}
SetDParam(0, cost);
}
}
GetString(this->landinfo_data[line_nr], str, lastof(this->landinfo_data[line_nr]));
line_nr++;
/* Location */
char tmp[16];
seprintf(tmp, lastof(tmp), "0x%.4X", tile);
SetDParam(0, TileX(tile));
SetDParam(1, TileY(tile));
SetDParam(2, GetTileZ(tile));
SetDParamStr(3, tmp);
GetString(this->landinfo_data[line_nr], STR_LAND_AREA_INFORMATION_LANDINFO_COORDS, lastof(this->landinfo_data[line_nr]));
line_nr++;
/* Local authority */
SetDParam(0, STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE);
if (t != nullptr) {
SetDParam(0, STR_TOWN_NAME);
SetDParam(1, t->index);
}
GetString(this->landinfo_data[line_nr], STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY, lastof(this->landinfo_data[line_nr]));
line_nr++;
/* Build date */
if (td.build_date != INVALID_DATE) {
SetDParam(0, td.build_date);
GetString(this->landinfo_data[line_nr], STR_LAND_AREA_INFORMATION_BUILD_DATE, lastof(this->landinfo_data[line_nr]));
line_nr++;
}
/* Station class */
if (td.station_class != STR_NULL) {
SetDParam(0, td.station_class);
GetString(this->landinfo_data[line_nr], STR_LAND_AREA_INFORMATION_STATION_CLASS, lastof(this->landinfo_data[line_nr]));
line_nr++;
}
/* Station type name */
if (td.station_name != STR_NULL) {
SetDParam(0, td.station_name);
GetString(this->landinfo_data[line_nr], STR_LAND_AREA_INFORMATION_STATION_TYPE, lastof(this->landinfo_data[line_nr]));
line_nr++;
}
/* Airport class */
if (td.airport_class != STR_NULL) {
SetDParam(0, td.airport_class);
GetString(this->landinfo_data[line_nr], STR_LAND_AREA_INFORMATION_AIRPORT_CLASS, lastof(this->landinfo_data[line_nr]));
line_nr++;
}
/* Airport name */
if (td.airport_name != STR_NULL) {
SetDParam(0, td.airport_name);
GetString(this->landinfo_data[line_nr], STR_LAND_AREA_INFORMATION_AIRPORT_NAME, lastof(this->landinfo_data[line_nr]));
line_nr++;
}
/* Airport tile name */
if (td.airport_tile_name != STR_NULL) {
SetDParam(0, td.airport_tile_name);
GetString(this->landinfo_data[line_nr], STR_LAND_AREA_INFORMATION_AIRPORTTILE_NAME, lastof(this->landinfo_data[line_nr]));
line_nr++;
}
/* Rail type name */
if (td.railtype != STR_NULL) {
SetDParam(0, td.railtype);
GetString(this->landinfo_data[line_nr], STR_LANG_AREA_INFORMATION_RAIL_TYPE, lastof(this->landinfo_data[line_nr]));
line_nr++;
}
/* Rail speed limit */
if (td.rail_speed != 0) {
SetDParam(0, td.rail_speed);
GetString(this->landinfo_data[line_nr], STR_LANG_AREA_INFORMATION_RAIL_SPEED_LIMIT, lastof(this->landinfo_data[line_nr]));
line_nr++;
}
/* Road type name */
if (td.roadtype != STR_NULL) {
SetDParam(0, td.roadtype);
GetString(this->landinfo_data[line_nr], STR_LANG_AREA_INFORMATION_ROAD_TYPE, lastof(this->landinfo_data[line_nr]));
line_nr++;
}
/* Road speed limit */
if (td.road_speed != 0) {
SetDParam(0, td.road_speed);
GetString(this->landinfo_data[line_nr], STR_LANG_AREA_INFORMATION_ROAD_SPEED_LIMIT, lastof(this->landinfo_data[line_nr]));
line_nr++;
}
/* Tram type name */
if (td.tramtype != STR_NULL) {
SetDParam(0, td.tramtype);
GetString(this->landinfo_data[line_nr], STR_LANG_AREA_INFORMATION_TRAM_TYPE, lastof(this->landinfo_data[line_nr]));
line_nr++;
}
/* Tram speed limit */
if (td.tram_speed != 0) {
SetDParam(0, td.tram_speed);
GetString(this->landinfo_data[line_nr], STR_LANG_AREA_INFORMATION_TRAM_SPEED_LIMIT, lastof(this->landinfo_data[line_nr]));
line_nr++;
}
/* NewGRF name */
if (td.grf != nullptr) {
SetDParamStr(0, td.grf);
GetString(this->landinfo_data[line_nr], STR_LAND_AREA_INFORMATION_NEWGRF_NAME, lastof(this->landinfo_data[line_nr]));
line_nr++;
}
/* House pop */
if (td.population != 0) {
SetDParam(0, td.population);
GetString(this->landinfo_data[line_nr], STR_LAND_AREA_INFORMATION_POP, lastof(this->landinfo_data[line_nr]));
line_nr++;
}
assert(line_nr < LAND_INFO_CENTERED_LINES);
/* Mark last line empty */
this->landinfo_data[line_nr][0] = '\0';
/* Cargo acceptance is displayed in a extra multiline */
char *strp = GetString(this->landinfo_data[LAND_INFO_MULTICENTER_LINE], STR_LAND_AREA_INFORMATION_CARGO_ACCEPTED, lastof(this->landinfo_data[LAND_INFO_MULTICENTER_LINE]));
bool found = false;
for (CargoID i = 0; i < NUM_CARGO; ++i) {
if (acceptance[i] > 0) {
/* Add a comma between each item. */
if (found) strp = strecpy(strp, ", ", lastof(this->landinfo_data[LAND_INFO_MULTICENTER_LINE]));
found = true;
/* If the accepted value is less than 8, show it in 1/8:ths */
if (acceptance[i] < 8) {
SetDParam(0, acceptance[i]);
SetDParam(1, CargoSpec::Get(i)->name);
strp = GetString(strp, STR_LAND_AREA_INFORMATION_CARGO_EIGHTS, lastof(this->landinfo_data[LAND_INFO_MULTICENTER_LINE]));
} else {
strp = GetString(strp, CargoSpec::Get(i)->name, lastof(this->landinfo_data[LAND_INFO_MULTICENTER_LINE]));
}
}
}
if (!found) this->landinfo_data[LAND_INFO_MULTICENTER_LINE][0] = '\0';
}
bool IsNewGRFInspectable() const override
{
return ::IsNewGRFInspectable(GetGrfSpecFeature(this->tile), this->tile);
}
void ShowNewGRFInspectWindow() const override
{
::ShowNewGRFInspectWindow(GetGrfSpecFeature(this->tile), this->tile);
}
/**
* Some data on this window has become invalid.
* @param data Information about the changed data.
* @param gui_scope Whether the call is done from GUI scope. You may not do everything when not in GUI scope. See #InvalidateWindowData() for details.
*/
void OnInvalidateData(int data = 0, bool gui_scope = true) override
{
if (!gui_scope) return;
switch (data) {
case 1:
/* ReInit, "debug" sprite might have changed */
this->ReInit();
break;
}
}
};
/**
* Show land information window.
* @param tile The tile to show information about.
*/
void ShowLandInfo(TileIndex tile, TileIndex end_tile)
{
static TileIndex last_tooltip_tile = INVALID_TILE;
if (tile == last_tooltip_tile) return;
last_tooltip_tile = tile;
DeleteWindowById(WC_LAND_INFO, 0);
if (tile == INVALID_TILE) return;
new LandInfoWindow(tile, end_tile);
}
} // namespace citymania

View File

@@ -0,0 +1,12 @@
#ifndef CM_MISC_GUI_HPP
#define CM_MISC_GUI_HPP
#include "../tile_type.h"
namespace citymania {
void ShowLandInfo(TileIndex tile, TileIndex end_tile = INVALID_TILE);
} // namespace citymania
#endif

View File

@@ -354,7 +354,6 @@ static void DrawTile_Industry(TileInfo *ti)
DrawWaterClassGround(ti);
} else {
DrawGroundSprite(image, GroundSpritePaletteTransform(image, dits->ground.pal, GENERAL_SPRITE_COLOUR(ind->random_colour)));
// DrawGroundSprite(image, GroundSpritePaletteTransform(image, dits->ground.pal, GENERAL_SPRITE_COLOUR(ind->random_colour)));
}
/* If industries are transparent and invisible, do not draw the upper part */

View File

@@ -39,6 +39,7 @@
#include "industry.h"
#include "citymania/cm_tooltips.hpp"
#include "citymania/cm_misc_gui.hpp"
#include "safeguards.h"
@@ -1322,10 +1323,10 @@ void GuiPrepareTooltipsExtra(Window *parent){
if (_cursor.sprite_seq[0].sprite == SPR_CURSOR_QUERY) {
// Land info tool active
ShowLandInfo(tile);
citymania::ShowLandInfo(tile);
return;
}
ShowLandInfo(INVALID_TILE);
citymania::ShowLandInfo(INVALID_TILE);
if (tile >= MapSize()) tile = INVALID_TILE;
citymania::ShowLandTooltips(tile, parent);