diff --git a/src/clear_cmd.cpp b/src/clear_cmd.cpp index ff972db1fa..fde9a3136a 100644 --- a/src/clear_cmd.cpp +++ b/src/clear_cmd.cpp @@ -336,7 +336,7 @@ static void GetTileDesc_Clear(TileIndex tile, TileDesc *td) } else { td->str = _clear_land_str[GetClearGround(tile)]; } - td->owner = GetTileOwner(tile); + td->owner[0] = GetTileOwner(tile); } static void ChangeTileOwner_Clear(TileIndex tile, PlayerID old_player, PlayerID new_player) diff --git a/src/dummy_land.cpp b/src/dummy_land.cpp index f426fed826..423d7db41a 100644 --- a/src/dummy_land.cpp +++ b/src/dummy_land.cpp @@ -41,7 +41,7 @@ static void GetAcceptedCargo_Dummy(TileIndex tile, AcceptedCargo ac) static void GetTileDesc_Dummy(TileIndex tile, TileDesc *td) { td->str = STR_EMPTY; - td->owner = OWNER_NONE; + td->owner[0] = OWNER_NONE; } static void AnimateTile_Dummy(TileIndex tile) diff --git a/src/gfx.cpp b/src/gfx.cpp index a59bf568bc..e85caaab81 100644 --- a/src/gfx.cpp +++ b/src/gfx.cpp @@ -427,9 +427,9 @@ end_of_inner_loop: } } -/** Draw a given string with the centre around the given x coordinates +/** Draw a given string with the centre around the given (x,y) coordinates * @param x Centre the string around this pixel width - * @param y Draw the string at this pixel height (first line's bottom) + * @param y Centre the string around this pixel height * @param str String to draw * @param maxw Maximum width the string can have before it is wrapped */ void DrawStringMultiCenter(int x, int y, StringID str, int maxw) diff --git a/src/industry_cmd.cpp b/src/industry_cmd.cpp index a889d08edb..e758b2fec5 100644 --- a/src/industry_cmd.cpp +++ b/src/industry_cmd.cpp @@ -377,7 +377,7 @@ static void GetTileDesc_Industry(TileIndex tile, TileDesc *td) { const Industry *i = GetIndustryByTile(tile); - td->owner = i->owner; + td->owner[0] = i->owner; td->str = GetIndustrySpec(i->type)->name; if (!IsIndustryCompleted(tile)) { SetDParamX(td->dparam, 0, td->str); diff --git a/src/lang/english.txt b/src/lang/english.txt index df43978e55..50e5416b15 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -486,6 +486,9 @@ STR_01A4_COST_TO_CLEAR_N_A :{BLACK}Cost to STR_01A5_COST_TO_CLEAR :{BLACK}Cost to clear: {LTBLUE}{CURRENCY} STR_01A6_N_A :N/A STR_01A7_OWNER :{BLACK}Owner: {LTBLUE}{STRING1} +STR_ROAD_OWNER :{BLACK}Road owner: {LTBLUE}{STRING1} +STR_TRAM_OWNER :{BLACK}Tramway owner: {LTBLUE}{STRING1} +STR_RAIL_OWNER :{BLACK}Railroad owner: {LTBLUE}{STRING1} STR_01A8_LOCAL_AUTHORITY :{BLACK}Local authority: {LTBLUE}{STRING1} STR_01A9_NONE :None STR_01AA_NAME :{BLACK}Name @@ -1714,6 +1717,7 @@ STR_1815_ROAD_WITH_STREETLIGHTS :Road with stree STR_1816_TREE_LINED_ROAD :Tree-lined road STR_1817_ROAD_VEHICLE_DEPOT :Road vehicle depot STR_1818_ROAD_RAIL_LEVEL_CROSSING :Road/rail level crossing +STR_TRAMWAY :Tramway STR_CAN_T_REMOVE_BUS_STATION :{WHITE}Can't remove bus station... STR_CAN_T_REMOVE_TRUCK_STATION :{WHITE}Can't remove lorry station... STR_CAN_T_REMOVE_PASSENGER_TRAM_STATION :{WHITE}Can't remove passenger tram station... diff --git a/src/misc_gui.cpp b/src/misc_gui.cpp index d1baabe947..86f6500620 100644 --- a/src/misc_gui.cpp +++ b/src/misc_gui.cpp @@ -73,24 +73,31 @@ static const WindowDesc _land_info_desc = { class LandInfoWindow : public Window { enum { - LAND_INFO_LINES = 7, + LAND_INFO_CENTERED_LINES = 9, ///< Up to 9 centered lines + LAND_INFO_MULTICENTER_LINE = LAND_INFO_CENTERED_LINES, ///< One multicenter line + LAND_INFO_LINE_END, + LAND_INFO_LINE_BUFF_SIZE = 512, }; public: - char landinfo_data[LAND_INFO_LINES][LAND_INFO_LINE_BUFF_SIZE]; + char landinfo_data[LAND_INFO_LINE_END][LAND_INFO_LINE_BUFF_SIZE]; virtual void OnPaint() { this->DrawWidgets(); - DoDrawStringCentered(140, 16, this->landinfo_data[0], TC_LIGHT_BLUE); - DoDrawStringCentered(140, 27, this->landinfo_data[1], TC_FROMSTRING); - DoDrawStringCentered(140, 38, this->landinfo_data[2], TC_FROMSTRING); - DoDrawStringCentered(140, 49, this->landinfo_data[3], TC_FROMSTRING); - DoDrawStringCentered(140, 60, this->landinfo_data[4], TC_FROMSTRING); - if (!StrEmpty(this->landinfo_data[5])) DrawStringMultiCenter(140, 76, BindCString(this->landinfo_data[5]), this->width - 4); - if (!StrEmpty(this->landinfo_data[6])) DoDrawStringCentered(140, 71, this->landinfo_data[6], TC_FROMSTRING); + uint y = 16; + for (uint i = 0; i < LAND_INFO_CENTERED_LINES; i++) { + if (StrEmpty(this->landinfo_data[i])) continue; + + DoDrawStringCentered(140, y, this->landinfo_data[i], i == 0 ? TC_LIGHT_BLUE : TC_FROMSTRING); + y += 11; + } + + y += 5; + + if (!StrEmpty(this->landinfo_data[LAND_INFO_MULTICENTER_LINE])) DrawStringMultiCenter(140, y, BindCString(this->landinfo_data[LAND_INFO_MULTICENTER_LINE]), this->width - 4); } LandInfoWindow(TileIndex tile) : Window(&_land_info_desc) { @@ -107,38 +114,81 @@ public: AcceptedCargo ac; td.build_date = 0; + + /* 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_01A7_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; + GetAcceptedCargo(tile, ac); GetTileDesc(tile, &td); + uint line_nr = 0; + + /* Tiletype */ SetDParam(0, td.dparam[0]); - GetString(this->landinfo_data[0], td.str, lastof(this->landinfo_data[0])); + GetString(this->landinfo_data[line_nr], td.str, lastof(this->landinfo_data[line_nr])); + line_nr++; - SetDParam(0, STR_01A6_N_A); - if (td.owner != OWNER_NONE && td.owner != OWNER_WATER) GetNameOfOwner(td.owner, tile); - GetString(this->landinfo_data[1], STR_01A7_OWNER, lastof(this->landinfo_data[1])); + /* Up to four owners */ + for (uint i = 0; i < 4; i++) { + if (td.owner_type[i] == STR_NULL) continue; + SetDParam(0, STR_01A6_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 */ StringID str = STR_01A4_COST_TO_CLEAR_N_A; if (CmdSucceeded(costclear)) { SetDParam(0, costclear.GetCost()); str = STR_01A5_COST_TO_CLEAR; } - GetString(this->landinfo_data[2], str, lastof(this->landinfo_data[2])); + GetString(this->landinfo_data[line_nr], str, lastof(this->landinfo_data[line_nr])); + line_nr++; + /* Location */ snprintf(_userstring, lengthof(_userstring), "0x%.4X", tile); SetDParam(0, TileX(tile)); SetDParam(1, TileY(tile)); SetDParam(2, TileHeight(tile)); SetDParam(3, STR_SPEC_USERSTRING); - GetString(this->landinfo_data[3], STR_LANDINFO_COORDS, lastof(this->landinfo_data[3])); + GetString(this->landinfo_data[line_nr], STR_LANDINFO_COORDS, lastof(this->landinfo_data[line_nr])); + line_nr++; + /* Local authority */ SetDParam(0, STR_01A9_NONE); if (t != NULL && t->IsValid()) { SetDParam(0, STR_TOWN); SetDParam(1, t->index); } - GetString(this->landinfo_data[4], STR_01A8_LOCAL_AUTHORITY, lastof(this->landinfo_data[4])); + GetString(this->landinfo_data[line_nr], STR_01A8_LOCAL_AUTHORITY, lastof(this->landinfo_data[line_nr])); + line_nr++; - char *strp = GetString(this->landinfo_data[5], STR_01CE_CARGO_ACCEPTED, lastof(this->landinfo_data[5])); + /* Build date */ + if (td.build_date != 0) { + SetDParam(0, td.build_date); + GetString(this->landinfo_data[line_nr], STR_BUILD_DATE, lastof(this->landinfo_data[line_nr])); + line_nr++; + } + + /* Remaining lines stay empty */ + for (; line_nr < LAND_INFO_CENTERED_LINES; line_nr++) { + 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_01CE_CARGO_ACCEPTED, lastof(this->landinfo_data[LAND_INFO_MULTICENTER_LINE])); bool found = false; for (CargoID i = 0; i < NUM_CARGO; ++i) { @@ -154,20 +204,13 @@ public: if (ac[i] < 8) { SetDParam(0, ac[i]); SetDParam(1, GetCargo(i)->name); - strp = GetString(strp, STR_01D1_8, lastof(this->landinfo_data[5])); + strp = GetString(strp, STR_01D1_8, lastof(this->landinfo_data[LAND_INFO_MULTICENTER_LINE])); } else { - strp = GetString(strp, GetCargo(i)->name, lastof(this->landinfo_data[5])); + strp = GetString(strp, GetCargo(i)->name, lastof(this->landinfo_data[LAND_INFO_MULTICENTER_LINE])); } } } - if (!found) this->landinfo_data[5][0] = '\0'; - - if (td.build_date != 0) { - SetDParam(0, td.build_date); - GetString(this->landinfo_data[6], STR_BUILD_DATE, lastof(this->landinfo_data[6])); - } else { - this->landinfo_data[6][0] = '\0'; - } + if (!found) this->landinfo_data[LAND_INFO_MULTICENTER_LINE][0] = '\0'; #if defined(_DEBUG) # define LANDINFOD_LEVEL 0 diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index 05803936bd..7a42aa74b5 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -2173,7 +2173,7 @@ static void ClickTile_Track(TileIndex tile) static void GetTileDesc_Track(TileIndex tile, TileDesc *td) { - td->owner = GetTileOwner(tile); + td->owner[0] = GetTileOwner(tile); switch (GetRailTileType(tile)) { case RAIL_TILE_NORMAL: td->str = STR_1021_RAILROAD_TRACK; diff --git a/src/road_cmd.cpp b/src/road_cmd.cpp index 3624a69313..edcff7cf5b 100644 --- a/src/road_cmd.cpp +++ b/src/road_cmd.cpp @@ -1446,11 +1446,53 @@ static const StringID _road_tile_strings[] = { static void GetTileDesc_Road(TileIndex tile, TileDesc *td) { - td->owner = GetTileOwner(tile); + Owner rail_owner = INVALID_OWNER; + Owner road_owner = INVALID_OWNER; + Owner tram_owner = INVALID_OWNER; + switch (GetRoadTileType(tile)) { - case ROAD_TILE_CROSSING: td->str = STR_1818_ROAD_RAIL_LEVEL_CROSSING; break; - case ROAD_TILE_DEPOT: td->str = STR_1817_ROAD_VEHICLE_DEPOT; break; - default: td->str = _road_tile_strings[GetRoadside(tile)]; break; + case ROAD_TILE_CROSSING: { + td->str = STR_1818_ROAD_RAIL_LEVEL_CROSSING; + RoadTypes rts = GetRoadTypes(tile); + rail_owner = GetTileOwner(tile); + if (HasBit(rts, ROADTYPE_ROAD)) road_owner = GetRoadOwner(tile, ROADTYPE_ROAD); + if (HasBit(rts, ROADTYPE_TRAM)) tram_owner = GetRoadOwner(tile, ROADTYPE_TRAM); + break; + } + + case ROAD_TILE_DEPOT: + td->str = STR_1817_ROAD_VEHICLE_DEPOT; + road_owner = GetTileOwner(tile); // Tile has only one owner, roadtype does not matter + break; + + default: { + RoadTypes rts = GetRoadTypes(tile); + td->str = (HasBit(rts, ROADTYPE_ROAD) ? _road_tile_strings[GetRoadside(tile)] : STR_TRAMWAY); + if (HasBit(rts, ROADTYPE_ROAD)) road_owner = GetRoadOwner(tile, ROADTYPE_ROAD); + if (HasBit(rts, ROADTYPE_TRAM)) tram_owner = GetRoadOwner(tile, ROADTYPE_TRAM); + break; + } + } + + /* Now we have to discover, if the tile has only one owner or many: + * - Find a first_owner of the tile. (Currently road or tram must be present, but this will break when the third type becomes available) + * - Compare the found owner with the other owners, and test if they differ. + * Note: If road exists it will be the first_owner. + */ + Owner first_owner = (road_owner == INVALID_OWNER ? tram_owner : road_owner); + bool mixed_owners = (tram_owner != INVALID_OWNER && tram_owner != first_owner) || (rail_owner != INVALID_OWNER && rail_owner != first_owner); + + if (mixed_owners) { + /* Multiple owners */ + td->owner_type[0] = (rail_owner == INVALID_OWNER ? STR_NULL : STR_RAIL_OWNER); + td->owner[0] = rail_owner; + td->owner_type[1] = (road_owner == INVALID_OWNER ? STR_NULL : STR_ROAD_OWNER); + td->owner[1] = road_owner; + td->owner_type[2] = (tram_owner == INVALID_OWNER ? STR_NULL : STR_TRAM_OWNER); + td->owner[2] = tram_owner; + } else { + /* One to rule them all */ + td->owner[0] = first_owner; } } diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index 463f977f2d..2cc60b4efc 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -2188,7 +2188,12 @@ static void GetAcceptedCargo_Station(TileIndex tile, AcceptedCargo ac) static void GetTileDesc_Station(TileIndex tile, TileDesc *td) { - td->owner = GetTileOwner(tile); + td->owner[0] = GetTileOwner(tile); + if (IsDriveThroughStopTile(tile) && HasTileRoadType(tile, ROADTYPE_ROAD) && GetStopBuiltOnTownRoad(tile)) { + /* Display a second owner */ + td->owner_type[1] = STR_ROAD_OWNER; + td->owner[1] = OWNER_TOWN; + } td->build_date = GetStationByTile(tile)->build_date; StringID str; diff --git a/src/tile_cmd.h b/src/tile_cmd.h index ce68f987c0..e25f210ccf 100644 --- a/src/tile_cmd.h +++ b/src/tile_cmd.h @@ -49,7 +49,8 @@ struct TileInfo { struct TileDesc { StringID str; - Owner owner; + Owner owner[4]; + StringID owner_type[4]; Date build_date; uint64 dparam[2]; }; diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index c0e5885d96..efe12043e3 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -620,7 +620,7 @@ static void GetTileDesc_Town(TileIndex tile, TileDesc *td) td->str = STR_2058_UNDER_CONSTRUCTION; } - td->owner = OWNER_TOWN; + td->owner[0] = OWNER_TOWN; } static TrackStatus GetTileTrackStatus_Town(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side) diff --git a/src/tree_cmd.cpp b/src/tree_cmd.cpp index f2cd302b5d..1942c48b8f 100644 --- a/src/tree_cmd.cpp +++ b/src/tree_cmd.cpp @@ -560,7 +560,7 @@ static void GetTileDesc_Trees(TileIndex tile, TileDesc *td) td->str = tt == TREE_CACTUS ? STR_2810_CACTUS_PLANTS : STR_280E_TREES; } - td->owner = GetTileOwner(tile); + td->owner[0] = GetTileOwner(tile); } static void AnimateTile_Trees(TileIndex tile) diff --git a/src/tunnelbridge_cmd.cpp b/src/tunnelbridge_cmd.cpp index c53a52a100..ab2be07411 100644 --- a/src/tunnelbridge_cmd.cpp +++ b/src/tunnelbridge_cmd.cpp @@ -1188,7 +1188,7 @@ static void GetTileDesc_TunnelBridge(TileIndex tile, TileDesc *td) } else { //so it must be a bridge td->str = GetBridgeSpec(GetBridgeType(tile))->transport_name[GetTunnelBridgeTransportType(tile)]; } - td->owner = GetTileOwner(tile); + td->owner[0] = GetTileOwner(tile); } diff --git a/src/unmovable_cmd.cpp b/src/unmovable_cmd.cpp index b949736f38..61ab5fe9bf 100644 --- a/src/unmovable_cmd.cpp +++ b/src/unmovable_cmd.cpp @@ -312,7 +312,7 @@ static void GetTileDesc_Unmovable(TileIndex tile, TileDesc *td) case UNMOVABLE_OWNED_LAND: td->str = STR_5805_COMPANY_OWNED_LAND; break; default: td->str = STR_5803_COMPANY_HEADQUARTERS; break; } - td->owner = GetTileOwner(tile); + td->owner[0] = GetTileOwner(tile); } static void AnimateTile_Unmovable(TileIndex tile) diff --git a/src/water_cmd.cpp b/src/water_cmd.cpp index fa6a654b49..d2afac4f44 100644 --- a/src/water_cmd.cpp +++ b/src/water_cmd.cpp @@ -738,7 +738,7 @@ static void GetTileDesc_Water(TileIndex tile, TileDesc *td) default: assert(0); break; } - td->owner = GetTileOwner(tile); + td->owner[0] = GetTileOwner(tile); } static void AnimateTile_Water(TileIndex tile)