diff --git a/layer.txt b/layer.txt new file mode 100644 index 0000000000..a5947189b9 --- /dev/null +++ b/layer.txt @@ -0,0 +1,48 @@ +* Card generation (extended card) + +VISUALIZATION + +* arrange a "shift" of the viewport to select a layer +- and restriction on movement ++ each viewport has its own layer + +LOGICS + +dungeon: + unavailability: +* flood +* landscape change +* building +* houses +* trees +* water +* factories +* bridges +* tunnels +* airports +* roads at the intersection of layers +? generator +? rivers, cities +* edges (independent lifting, void) + +activity restriction +synchronization of landscape changes + +GUI + +** construction of a two-level station +- construction of a worm-hole from one layer to a neighbour layer +** work with the station (construction, removal / blocking of parts / cost) +* menu template for management / construction + ++ add selection of number of layers ++ only show layer switches for available layers +? only show tiles of current layer ++ fix the coordinates in the "help area" +- fix the coordinates in the start screen +- signatures, station names (on all layers), effects (on the desired layer) + +BAGI ++ station deletion (departure) +* Expansion of the underground station does not work (when adding cells, a new one is added) +- GF. "jumps" (the non-editable part of the station changes randomly when the station is modified) diff --git a/media/baseset/opntitle.dat b/media/baseset/opntitle.dat index 264aaff60b..9793856b76 100644 Binary files a/media/baseset/opntitle.dat and b/media/baseset/opntitle.dat differ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e0af799994..134d96620b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -210,6 +210,10 @@ add_files( landscape.h landscape_type.h language.h + layer.cpp + layer_func.h + layer_gui.h + layer_type.h livery.h main_gui.cpp map.cpp @@ -447,6 +451,8 @@ add_files( tunnelbridge.h tunnelbridge_cmd.cpp tunnelbridge_map.h + underground_gui.cpp + underground_gui.h vehicle.cpp vehicle_base.h vehicle_cmd.cpp diff --git a/src/base_station_base.h b/src/base_station_base.h index 40543f1b8f..ace01445a9 100644 --- a/src/base_station_base.h +++ b/src/base_station_base.h @@ -26,6 +26,13 @@ struct StationSpecList { /** StationRect - used to track station spread out rectangle - cheaper than scanning whole map */ +/* +** Ïàò÷ "layer" +** Êðèòè÷åñêîå èçìåíåíèå: +** "Rect" ïîäðàçóìåâàåò òîëüêî âåðõíèé ñëîé (ïîâåðõíîñòü) +** (ñòàíöèÿ ìîæåò ðàñïîëàãàòüñÿ íà ëþáîì ñëîå, -- +** Rect îïèñûâàåò ñîîòâåòñòâóþùóþ ÷àñòü âåðõíåãî ñëîÿ) +*/ struct StationRect : public Rect { enum StationRectMode { @@ -36,7 +43,7 @@ struct StationRect : public Rect { StationRect(); void MakeEmpty(); - bool PtInExtendedRect(int x, int y, int distance = 0) const; + bool PtInExtendedRect(int topx, int topy, int distance = 0) const; bool IsEmpty() const; CommandCost BeforeAddTile(TileIndex tile, StationRectMode mode); CommandCost BeforeAddRect(TileIndex tile, int w, int h, StationRectMode mode); diff --git a/src/clear_cmd.cpp b/src/clear_cmd.cpp index 6d3167e5a2..6c022e5e50 100644 --- a/src/clear_cmd.cpp +++ b/src/clear_cmd.cpp @@ -12,6 +12,7 @@ #include "command_func.h" #include "landscape.h" #include "genworld.h" +#include "layer_func.h" #include "viewport_func.h" #include "water.h" #include "core/random_func.hpp" @@ -98,8 +99,28 @@ static void DrawClearLandFence(const TileInfo *ti) EndSpriteCombine(); } +static void DrawUndergroundTile_Clear(TileInfo *ti) +{ + +} + static void DrawTile_Clear(TileInfo *ti) { + uint base_tile = TopTile(ti->tile); + uint underground_tile = DownTile(base_tile); + + bool self_underground = IsUnderground(ti->tile); + + bool have_canalization = IsTileType(base_tile, MP_HOUSE); + bool have_underground = !IsTileType(underground_tile, MP_CLEAR); + + if (self_underground && !have_canalization) + DrawGroundSprite(SPR_FLAT_BARE_LAND + SlopeToSpriteOffset(ti->tileh), PAL_NONE); + + if (self_underground && have_canalization) + DrawGroundSprite(SPR_FLAT_GRASS_TILE + SlopeToSpriteOffset(ti->tileh), PAL_NONE); + + if (!self_underground) switch (GetClearGround(ti->tile)) { case CLEAR_GRASS: DrawClearLandTile(ti, GetClearDensity(ti->tile)); @@ -124,6 +145,9 @@ static void DrawTile_Clear(TileInfo *ti) break; } + if (!self_underground && have_underground) + DrawGroundSprite(SPR_FLAT_BARE_LAND + SlopeToSpriteOffset(ti->tileh), PAL_NONE); + DrawBridgeMiddle(ti); } @@ -321,7 +345,7 @@ void GenerateClearTile() SetGeneratingWorldProgress(GWP_ROUGH_ROCKY, gi + i); do { IncreaseGeneratingWorldProgress(GWP_ROUGH_ROCKY); - tile = RandomTile(); + tile = TopTile(RandomTile()); if (IsTileType(tile, MP_CLEAR) && !IsClearGround(tile, CLEAR_DESERT)) SetClearGroundDensity(tile, CLEAR_ROUGH, 3); } while (--i); @@ -329,7 +353,7 @@ void GenerateClearTile() i = gi; do { uint32 r = Random(); - tile = RandomTileSeed(r); + tile = TopTile(RandomTileSeed(r)); IncreaseGeneratingWorldProgress(GWP_ROUGH_ROCKY); if (IsTileType(tile, MP_CLEAR) && !IsClearGround(tile, CLEAR_DESERT)) { diff --git a/src/console_cmds.cpp b/src/console_cmds.cpp index 905a41c3e7..f19a86f633 100644 --- a/src/console_cmds.cpp +++ b/src/console_cmds.cpp @@ -25,6 +25,7 @@ #include "screenshot.h" #include "genworld.h" #include "strings_func.h" +#include "layer_func.h" #include "viewport_func.h" #include "window_func.h" #include "date_func.h" @@ -1069,6 +1070,7 @@ DEF_CONSOLE_CMD(ConRestart) } /* Don't copy the _newgame pointers to the real pointers, so call SwitchToMode directly */ + _settings_game.game_creation.layers = FindFirstBit(LayerCount()); _settings_game.game_creation.map_x = MapLogX(); _settings_game.game_creation.map_y = FindFirstBit(MapSizeY()); _switch_mode = SM_RESTARTGAME; diff --git a/src/disaster_vehicle.cpp b/src/disaster_vehicle.cpp index c5d76877cc..110eff64f8 100644 --- a/src/disaster_vehicle.cpp +++ b/src/disaster_vehicle.cpp @@ -325,7 +325,7 @@ static bool DisasterTick_Ufo(DisasterVehicle *v) return true; } if (++v->age < 6) { - v->dest_tile = RandomTile(); + v->dest_tile = TopTile(RandomTile()); return true; } v->current_order.SetDestination(1); @@ -572,12 +572,12 @@ static bool DisasterTick_Big_Ufo(DisasterVehicle *v) } if (++v->age < 6) { - v->dest_tile = RandomTile(); + v->dest_tile = TopTile(RandomTile()); return true; } v->current_order.SetDestination(1); - TileIndex tile_org = RandomTile(); + TileIndex tile_org = TopTile(RandomTile()); TileIndex tile = tile_org; do { if (IsPlainRailTile(tile) && @@ -958,7 +958,7 @@ void ReleaseDisastersTargetingVehicle(VehicleID vehicle) if (v->current_order.GetDestination() != 0 && v->dest_tile == vehicle) { /* Revert to target-searching */ v->current_order.SetDestination(0); - v->dest_tile = RandomTile(); + v->dest_tile = TopTile(RandomTile()); GetAircraftFlightLevelBounds(v, &v->z_pos, nullptr); v->age = 0; } diff --git a/src/genworld.cpp b/src/genworld.cpp index c76fe309d9..61cbe2b2ab 100644 --- a/src/genworld.cpp +++ b/src/genworld.cpp @@ -350,6 +350,6 @@ void GenerateWorld(GenWorldMode mode, uint size_x, uint size_y, bool reset_setti /* Centre the view on the map */ if (FindWindowById(WC_MAIN_WINDOW, 0) != nullptr) { - ScrollMainWindowToTile(TileXY(MapSizeX() / 2, MapSizeY() / 2), true); + ScrollMainWindowToTile(TileXY(MapSizeX() / 2, MapSizeY() / LayerCount() / 2), true); } } diff --git a/src/genworld_gui.cpp b/src/genworld_gui.cpp index 8fb0800ac7..bceb64206b 100644 --- a/src/genworld_gui.cpp +++ b/src/genworld_gui.cpp @@ -16,6 +16,8 @@ #include "window_func.h" #include "date_func.h" #include "sound_func.h" +#include "map_type.h" +#include "layer_type.h" #include "fios.h" #include "string_func.h" #include "widgets/dropdown_type.h" @@ -81,6 +83,7 @@ static const NWidgetPart _nested_generate_landscape_widgets[] = { /* Left column with labels. */ NWidget(NWID_VERTICAL, NC_EQUALSIZE), SetPIP(0, 4, 0), NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_MAPSIZE, STR_MAPGEN_MAPSIZE_TOOLTIP), SetFill(1, 1), + NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_UNDERGROUND_LAYER_COUNT, STR_NULL), SetFill(1, 1), NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_LAND_GENERATOR, STR_NULL), SetFill(1, 1), NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_TERRAIN_TYPE, STR_NULL), SetFill(1, 1), NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_VARIETY, STR_NULL), SetFill(1, 1), @@ -97,6 +100,7 @@ static const NWidgetPart _nested_generate_landscape_widgets[] = { NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_BY, STR_NULL), SetPadding(1, 0, 0, 0), SetFill(1, 1), NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_MAPSIZE_Y_PULLDOWN), SetDataTip(STR_JUST_INT, STR_MAPGEN_MAPSIZE_TOOLTIP), SetFill(1, 0), EndContainer(), + NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_LAYER_COUNT_PULLDOWN), SetDataTip(STR_JUST_INT, STR_NULL), SetFill(1, 0), NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_LANDSCAPE_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_TERRAIN_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_VARIETY_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), @@ -202,6 +206,7 @@ static const NWidgetPart _nested_heightmap_load_widgets[] = { NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_HEIGHTMAP_SIZE_LABEL, STR_NULL), SetFill(1, 1), NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_MAPSIZE, STR_NULL), SetFill(1, 1), NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_HEIGHTMAP_ROTATION, STR_NULL), SetFill(1, 1), + NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_UNDERGROUND_LAYER_COUNT, STR_NULL), SetFill(1, 1), NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_NUMBER_OF_TOWNS, STR_NULL), SetFill(1, 1), NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_NUMBER_OF_INDUSTRIES, STR_NULL), SetFill(1, 1), NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_QUANTITY_OF_RIVERS, STR_NULL), SetFill(1, 1), @@ -219,6 +224,7 @@ static const NWidgetPart _nested_heightmap_load_widgets[] = { NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_MAPSIZE_Y_PULLDOWN), SetDataTip(STR_JUST_INT, STR_NULL), SetFill(1, 0), EndContainer(), NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_HEIGHTMAP_ROTATION_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), + NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_LAYER_COUNT_PULLDOWN), SetDataTip(STR_JUST_INT, STR_NULL), SetFill(1, 0), NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_TOWN_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_INDUSTRY_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_RIVER_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), @@ -282,11 +288,11 @@ static void LandscapeGenerationCallback(Window *w, bool confirmed) if (confirmed) StartGeneratingLandscape((GenerateLandscapeWindowMode)w->window_number); } -static DropDownList BuildMapsizeDropDown() +static DropDownList BuildBitListDropDown(uint min_bits, uint max_bits) { DropDownList list; - for (uint i = MIN_MAP_SIZE_BITS; i <= MAX_MAP_SIZE_BITS; i++) { + for (uint i = min_bits; i <= max_bits; i++) { DropDownListParamStringItem *item = new DropDownListParamStringItem(STR_JUST_INT, i, false); item->SetParam(0, 1LL << i); list.emplace_back(item); @@ -322,6 +328,15 @@ static DropDownList BuildTownNameDropDown() return list; } +static DropDownList BuildMapsizeDropDown() +{ + return BuildBitListDropDown(MIN_MAP_SIZE_BITS, MAX_MAP_SIZE_BITS); +} + +static DropDownList BuildLayerDropDown() +{ + return BuildBitListDropDown(MIN_LAYER_COUNT_BITS, MAX_LAYER_COUNT_BITS); +} static const StringID _elevations[] = {STR_TERRAIN_TYPE_VERY_FLAT, STR_TERRAIN_TYPE_FLAT, STR_TERRAIN_TYPE_HILLY, STR_TERRAIN_TYPE_MOUNTAINOUS, STR_TERRAIN_TYPE_ALPINIST, INVALID_STRING_ID}; static const StringID _sea_lakes[] = {STR_SEA_LEVEL_VERY_LOW, STR_SEA_LEVEL_LOW, STR_SEA_LEVEL_MEDIUM, STR_SEA_LEVEL_HIGH, STR_SEA_LEVEL_CUSTOM, INVALID_STRING_ID}; @@ -364,6 +379,7 @@ struct GenerateLandscapeWindow : public Window { case WID_GL_START_DATE_TEXT: SetDParam(0, ConvertYMDToDate(_settings_newgame.game_creation.starting_year, 0, 1)); break; case WID_GL_MAPSIZE_X_PULLDOWN: SetDParam(0, 1LL << _settings_newgame.game_creation.map_x); break; case WID_GL_MAPSIZE_Y_PULLDOWN: SetDParam(0, 1LL << _settings_newgame.game_creation.map_y); break; + case WID_GL_LAYER_COUNT_PULLDOWN: SetDParam(0, 1 << _settings_newgame.game_creation.layers); break; case WID_GL_MAX_HEIGHTLEVEL_TEXT: SetDParam(0, _settings_newgame.construction.max_heightlevel); break; case WID_GL_SNOW_LEVEL_TEXT: SetDParam(0, _settings_newgame.game_creation.snow_line_height); break; @@ -494,6 +510,11 @@ struct GenerateLandscapeWindow : public Window { *size = maxdim(*size, GetStringBoundingBox(STR_JUST_INT)); break; + case WID_GL_LAYER_COUNT_PULLDOWN: + SetDParam(0, MAX_LAYER_COUNT); + *size = GetStringBoundingBox(STR_JUST_INT); + break; + case WID_GL_SNOW_LEVEL_TEXT: SetDParamMaxValue(0, MAX_TILE_HEIGHT); *size = maxdim(*size, GetStringBoundingBox(STR_JUST_INT)); @@ -579,6 +600,10 @@ struct GenerateLandscapeWindow : public Window { ShowDropDownList(this, BuildMapsizeDropDown(), _settings_newgame.game_creation.map_y, WID_GL_MAPSIZE_Y_PULLDOWN); break; + case WID_GL_LAYER_COUNT_PULLDOWN: // Mapsize Z + ShowDropDownList(this, BuildLayerDropDown(), _settings_newgame.game_creation.layers, WID_GL_LAYER_COUNT_PULLDOWN); + break; + case WID_GL_TOWN_PULLDOWN: // Number of towns ShowDropDownMenu(this, _num_towns, _settings_newgame.difficulty.number_towns, WID_GL_TOWN_PULLDOWN, 0, 0); break; @@ -752,6 +777,7 @@ struct GenerateLandscapeWindow : public Window { switch (widget) { case WID_GL_MAPSIZE_X_PULLDOWN: _settings_newgame.game_creation.map_x = index; break; case WID_GL_MAPSIZE_Y_PULLDOWN: _settings_newgame.game_creation.map_y = index; break; + case WID_GL_LAYER_COUNT_PULLDOWN: _settings_newgame.game_creation.layers = index; break; case WID_GL_RIVER_PULLDOWN: _settings_newgame.game_creation.amount_of_rivers = index; break; case WID_GL_SMOOTHNESS_PULLDOWN: _settings_newgame.game_creation.tgen_smoothness = index; break; case WID_GL_VARIETY_PULLDOWN: _settings_newgame.game_creation.variety = index; break; @@ -942,6 +968,10 @@ struct CreateScenarioWindow : public Window SetDParam(0, 1LL << _settings_newgame.game_creation.map_y); break; + case WID_CS_LAYER_COUNT_PULLDOWN: + SetDParam(0, 1 << _settings_newgame.game_creation.layers); + break; + case WID_CS_FLAT_LAND_HEIGHT_TEXT: SetDParam(0, _settings_newgame.game_creation.se_flat_world_height); break; @@ -975,6 +1005,10 @@ struct CreateScenarioWindow : public Window case WID_CS_MAPSIZE_X_PULLDOWN: case WID_CS_MAPSIZE_Y_PULLDOWN: SetDParamMaxValue(0, MAX_MAP_SIZE); + break; + + case WID_CS_LAYER_COUNT_PULLDOWN: + SetDParam(0, MAX_LAYER_COUNT); break; case WID_CS_FLAT_LAND_HEIGHT_TEXT: @@ -1008,6 +1042,10 @@ struct CreateScenarioWindow : public Window ShowDropDownList(this, BuildMapsizeDropDown(), _settings_newgame.game_creation.map_y, WID_CS_MAPSIZE_Y_PULLDOWN); break; + case WID_CS_LAYER_COUNT_PULLDOWN: // Mapsize Y + ShowDropDownList(this, BuildLayerDropDown(), _settings_newgame.game_creation.layers, WID_CS_LAYER_COUNT_PULLDOWN); + break; + case WID_CS_EMPTY_WORLD: // Empty world / flat world StartGeneratingLandscape(GLWM_SCENARIO); break; @@ -1070,6 +1108,7 @@ struct CreateScenarioWindow : public Window switch (widget) { case WID_CS_MAPSIZE_X_PULLDOWN: _settings_newgame.game_creation.map_x = index; break; case WID_CS_MAPSIZE_Y_PULLDOWN: _settings_newgame.game_creation.map_y = index; break; + case WID_CS_LAYER_COUNT_PULLDOWN: _settings_newgame.game_creation.layers = index; break; } this->SetDirty(); } @@ -1125,6 +1164,7 @@ static const NWidgetPart _nested_create_scenario_widgets[] = { NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_CS_MAPSIZE_X_PULLDOWN), SetDataTip(STR_JUST_INT, STR_NULL), SetPadding(0, 4, 0, 0), NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_BY, STR_NULL), SetPadding(1, 2, 0, 0), NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_CS_MAPSIZE_Y_PULLDOWN), SetDataTip(STR_JUST_INT, STR_NULL), + NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_CS_LAYER_COUNT_PULLDOWN), SetDataTip(STR_JUST_INT, STR_NULL), EndContainer(), /* Date. */ NWidget(NWID_HORIZONTAL), diff --git a/src/gfx_type.h b/src/gfx_type.h index 3b9f04d9e8..9f6aee7ea3 100644 --- a/src/gfx_type.h +++ b/src/gfx_type.h @@ -156,6 +156,7 @@ struct DrawPixelInfo { void *dst_ptr; int left, top, width, height; int pitch; + int layer; ZoomLevel zoom; }; diff --git a/src/heightmap.cpp b/src/heightmap.cpp index fab93c9802..f345f5ee6d 100644 --- a/src/heightmap.cpp +++ b/src/heightmap.cpp @@ -14,6 +14,7 @@ #include "error.h" #include "saveload/saveload.h" #include "bmp.h" +#include "layer_func.h" #include "gfx_func.h" #include "fios.h" #include "fileio_func.h" @@ -395,6 +396,9 @@ void FixSlopes() width = MapSizeX(); height = MapSizeY(); + /* Layers height correct */ + FixUndergroundHeights(); + /* Top and left edge */ for (row = 0; (uint)row < height; row++) { for (col = 0; (uint)col < width; col++) { diff --git a/src/industry_cmd.cpp b/src/industry_cmd.cpp index 20c38e5456..b0c620bcb0 100644 --- a/src/industry_cmd.cpp +++ b/src/industry_cmd.cpp @@ -12,6 +12,7 @@ #include "industry.h" #include "station_base.h" #include "landscape.h" +#include "layer_func.h" #include "viewport_func.h" #include "command_func.h" #include "town.h" @@ -1444,7 +1445,7 @@ static CommandCost CheckIfIndustryTilesAreFree(TileIndex tile, const IndustryTil IndustryGfx gfx = GetTranslatedIndustryTileID(it.gfx); TileIndex cur_tile = TileAddWrap(tile, it.ti.x, it.ti.y); - if (!IsValidTile(cur_tile)) { + if (!IsValidTile(cur_tile) || IsUnderground(cur_tile)) { return_cmd_error(STR_ERROR_SITE_UNSUITABLE); } @@ -2023,7 +2024,7 @@ CommandCost CmdBuildIndustry(TileIndex tile, DoCommandFlag flags, uint32 p1, uin /* We should not have more than one Random() in a function call * because parameter evaluation order is not guaranteed in the c++ standard */ - tile = RandomTile(); + tile = TopTile(RandomTile()); /* Start with a random layout */ size_t layout = RandomRange((uint32)num_layouts); /* Check now each layout, starting with the random one */ @@ -2229,7 +2230,7 @@ static Industry *PlaceIndustry(IndustryType type, IndustryAvailabilityCallType c { uint tries = try_hard ? 10000u : 2000u; for (; tries > 0; tries--) { - Industry *ind = CreateNewIndustry(RandomTile(), type, creation_type); + Industry *ind = CreateNewIndustry(TopTile(RandomTile()), type, creation_type); if (ind != nullptr) return ind; } return nullptr; diff --git a/src/landscape.cpp b/src/landscape.cpp index 80ba516ac7..e8f782eece 100644 --- a/src/landscape.cpp +++ b/src/landscape.cpp @@ -33,6 +33,7 @@ #include "framerate_type.h" #include #include +#include "layer_func.h" #include "table/strings.h" #include "table/sprites.h" @@ -812,10 +813,10 @@ void RunTileLoop() 0xD8F, 0x1296, 0x2496, 0x4357, 0x8679, 0x1030E, 0x206CD, 0x403FE, 0x807B8, 0x1004B2, 0x2006A8, 0x4004B2, 0x800B87 }; static_assert(lengthof(feedbacks) == 2 * MAX_MAP_SIZE_BITS - 2 * MIN_MAP_SIZE_BITS + 1); - const uint32 feedback = feedbacks[MapLogX() + MapLogY() - 2 * MIN_MAP_SIZE_BITS]; + const uint32 feedback = feedbacks[MapLogX() + MapLogY() - LayerCountLog() - 2 * MIN_MAP_SIZE_BITS]; /* We update every tile every 256 ticks, so divide the map size by 2^8 = 256 */ - uint count = 1 << (MapLogX() + MapLogY() - 8); + uint count = 1 << (MapLogX() + MapLogY() - LayerCountLog() - 8); TileIndex tile = _cur_tileloop_tile; /* The LFSR cannot have a zeroed state. */ @@ -839,17 +840,23 @@ void RunTileLoop() void InitializeLandscape() { - for (uint y = _settings_game.construction.freeform_edges ? 1 : 0; y < MapMaxY(); y++) { - for (uint x = _settings_game.construction.freeform_edges ? 1 : 0; x < MapMaxX(); x++) { - MakeClear(TileXY(x, y), CLEAR_GRASS, 3); - SetTileHeight(TileXY(x, y), 0); - SetTropicZone(TileXY(x, y), TROPICZONE_NORMAL); - ClearBridgeMiddle(TileXY(x, y)); + uint maxx = LayerMaxX(); + uint maxy = LayerMaxY(); + uint sizex = MapSizeX(); + uint layersize = LayerSize(); + + FOR_ALL_LAYERS(layer) { + for (uint y = _settings_game.construction.freeform_edges ? 1 : 0; y < LayerMaxY(); y++) { + for (uint x = _settings_game.construction.freeform_edges ? 1 : 0; x < LayerMaxX(); x++) { + MakeClear(layer * layersize + TileXY(x, y), CLEAR_GRASS, 3); + SetTileHeight(layer * layersize + TileXY(x, y), 0); + SetTropicZone(layer * layersize + TileXY(x, y), TROPICZONE_NORMAL); + ClearBridgeMiddle(layer * layersize + TileXY(x, y)); + } + MakeVoid(layer * layersize + TileXY(LayerMaxX(), y)); } + for (uint x = 0; x < LayerSizeX(); x++) MakeVoid(TileXY(x, LayerMaxY())); } - - for (uint x = 0; x < MapSizeX(); x++) MakeVoid(TileXY(x, MapMaxY())); - for (uint y = 0; y < MapSizeY(); y++) MakeVoid(TileXY(MapMaxX(), y)); } static const byte _genterrain_tbl_1[5] = { 10, 22, 33, 37, 4 }; @@ -1278,7 +1285,7 @@ static void CreateRivers() for (; wells != 0; wells--) { IncreaseGeneratingWorldProgress(GWP_RIVER); for (int tries = 0; tries < 128; tries++) { - TileIndex t = RandomTile(); + TileIndex t = TopTile(RandomTile()); if (!CircularTileSearch(&t, 8, FindSpring, nullptr)) continue; if (FlowRiver(t, t)) break; } diff --git a/src/lang/afrikaans.txt b/src/lang/afrikaans.txt index bfaea6bf94..213f75e594 100644 --- a/src/lang/afrikaans.txt +++ b/src/lang/afrikaans.txt @@ -2592,7 +2592,7 @@ STR_LAND_AREA_INFORMATION_TRAM_OWNER :{BLACK}Tremweg STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Spoorweg eienaar: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Plaaslike raad: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Geen -STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Koördinate: {LTBLUE}{NUM}x{NUM}x{NUM} ({STRING}) +STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Koördinate: {LTBLUE}{NUM}x{NUM}x{NUM}x-{NUM} ({STRING}) STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Gebou: {LTBLUE}{DATE_LONG} STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Stasie klas: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Stasie tiepe: {LTBLUE}{STRING} diff --git a/src/lang/arabic_egypt.txt b/src/lang/arabic_egypt.txt index 3fdaf5cdd0..9a3055f656 100644 --- a/src/lang/arabic_egypt.txt +++ b/src/lang/arabic_egypt.txt @@ -2201,7 +2201,7 @@ STR_LAND_AREA_INFORMATION_TRAM_OWNER :{BLACK}مالك STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}مالك سكة الحديد: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}السلطة المحلية: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Ùارغ -STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}الأحداثيات: {LTBLUE}{NUM}x{NUM}x{NUM} ({STRING}) +STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}الأحداثيات: {LTBLUE}{NUM}x{NUM}x{NUM}x-{NUM} ({STRING}) STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}بني: {LTBLUE}{DATE_LONG} STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK} Ùئة المحطة: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}نوع المحطة: {LTBLUE}{STRING} diff --git a/src/lang/basque.txt b/src/lang/basque.txt index 1a011dbb3a..01a855b872 100644 --- a/src/lang/basque.txt +++ b/src/lang/basque.txt @@ -2450,7 +2450,7 @@ STR_LAND_AREA_INFORMATION_TRAM_OWNER :{BLACK}Tranbia STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Trenbidearen jabea: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Udaletxea {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Ezer ez -STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Koordenadak: {LTBLUE}{NUM} x {NUM} x {NUM} ({STRING}) +STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Koordenadak: {LTBLUE}{NUM} x {NUM} x {NUM} x -{NUM} ({STRING}) STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Eraikia: {LTBLUE}{DATE_LONG} STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Geltoki mota: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Geltoki mota: {LTBLUE}{STRING} diff --git a/src/lang/belarusian.txt b/src/lang/belarusian.txt index 3aa602c9a9..b4aee3513c 100644 --- a/src/lang/belarusian.txt +++ b/src/lang/belarusian.txt @@ -2918,7 +2918,7 @@ STR_LAND_AREA_INFORMATION_TRAM_OWNER :{BLACK}Улад STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Уладальнiк чыгункi: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}ÐœÑÑÑ†Ð¾Ð²Ð°Ñ Ð°Ð´Ð¼Ñ–Ð½Ñ–ÑтрацыÑ: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :ÐÑма -STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Каардынаты: {LTBLUE}{NUM}x{NUM}x{NUM} ({STRING}) +STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Каардынаты: {LTBLUE}{NUM}x{NUM}x{NUM}x-{NUM} ({STRING}) STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Пабудавана: {LTBLUE}{DATE_LONG} STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}КлÑÑа Ñтанцыі: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Тып Ñтанцыi: {LTBLUE}{STRING} diff --git a/src/lang/brazilian_portuguese.txt b/src/lang/brazilian_portuguese.txt index b86aca3aeb..bf1114cd98 100644 --- a/src/lang/brazilian_portuguese.txt +++ b/src/lang/brazilian_portuguese.txt @@ -2621,7 +2621,7 @@ STR_LAND_AREA_INFORMATION_TRAM_OWNER :{BLACK}Dono da STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Dono da linha ferroviária: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Prefeitura: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Nenhum -STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Coordenadas: {LTBLUE}{NUM} x {NUM} x {NUM} ({STRING}) +STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Coordenadas: {LTBLUE}{NUM} x {NUM} x {NUM} x -{NUM} ({STRING}) STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Construído: {LTBLUE}{DATE_LONG} STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Classe de Estação: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Tipo de Estação: {LTBLUE}{STRING} diff --git a/src/lang/bulgarian.txt b/src/lang/bulgarian.txt index 6b53d93231..ea476af318 100644 --- a/src/lang/bulgarian.txt +++ b/src/lang/bulgarian.txt @@ -2504,7 +2504,7 @@ STR_LAND_AREA_INFORMATION_TRAM_OWNER :{BLACK}Ð¡Ð¾Ð±Ñ STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}СобÑтвеник на железопътната линиÑ: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Община: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Ðищо -STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Координати: {LTBLUE}{NUM} x {NUM} x {NUM} ({STRING}) +STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Координати: {LTBLUE}{NUM} x {NUM} x {NUM} x -{NUM} ({STRING}) STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}ПоÑтроен: {LTBLUE}{DATE_LONG} STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}ÐšÐ»Ð°Ñ Ð½Ð° ÑтанциÑта: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Тип на ÑтанциÑта: {LTBLUE}{STRING} diff --git a/src/lang/catalan.txt b/src/lang/catalan.txt index 711f9df0c4..8c2d616af7 100644 --- a/src/lang/catalan.txt +++ b/src/lang/catalan.txt @@ -2649,7 +2649,7 @@ STR_LAND_AREA_INFORMATION_TRAM_OWNER :{BLACK}Propieta STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Propietari del rail: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Autoritat Local: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Cap -STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Coordenades: {LTBLUE}{NUM} x {NUM} x {NUM} ({STRING}) +STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Coordenades: {LTBLUE}{NUM} x {NUM} x {NUM} x -{NUM} ({STRING}) STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Construït: {LTBLUE}{DATE_LONG} STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Classe d'estació: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Tipus d'estació: {LTBLUE}{STRING} diff --git a/src/lang/croatian.txt b/src/lang/croatian.txt index baa79fff35..6ce7681127 100644 --- a/src/lang/croatian.txt +++ b/src/lang/croatian.txt @@ -2697,7 +2697,7 @@ STR_LAND_AREA_INFORMATION_TRAM_OWNER :{BLACK}Vlasnik STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Vlasnik željeznice: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}PodruÄna nadležnost: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Nijedan/Nitko/NiÅ¡ta -STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Koordinate: {LTBLUE}{NUM} x {NUM} x {NUM} ({STRING}) +STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Koordinate: {LTBLUE}{NUM} x {NUM} x {NUM} x -{NUM} ({STRING}) STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}IzgraÄ‘eno: {LTBLUE}{DATE_LONG} STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Klasa postaje: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Vrsta postaje: {LTBLUE}{STRING} diff --git a/src/lang/czech.txt b/src/lang/czech.txt index 5202ae6e19..4e483b2543 100644 --- a/src/lang/czech.txt +++ b/src/lang/czech.txt @@ -2694,7 +2694,7 @@ STR_LAND_AREA_INFORMATION_TRAM_OWNER :{BLACK}Majitel STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Majitel tratÄ›: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Místní správa: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Nic -STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}SouÅ™adnice: {LTBLUE}{NUM} x {NUM} x {NUM} ({STRING}) +STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}SouÅ™adnice: {LTBLUE}{NUM} x {NUM} x {NUM} x -{NUM} ({STRING}) STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Postaveno: {LTBLUE}{DATE_LONG} STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Třída stanice: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Druh stanice: {LTBLUE}{STRING} diff --git a/src/lang/danish.txt b/src/lang/danish.txt index fa08cdc2d8..672b5906fa 100644 --- a/src/lang/danish.txt +++ b/src/lang/danish.txt @@ -2601,7 +2601,7 @@ STR_LAND_AREA_INFORMATION_TRAM_OWNER :{BLACK}Ejer af STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Ejer af jernbane: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Lokal myndighed: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Ingen -STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Koordinater: {LTBLUE}{NUM}x{NUM}x{NUM} ({STRING}) +STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Koordinater: {LTBLUE}{NUM}x{NUM}x{NUM}x-{NUM} ({STRING}) STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Produceret: {LTBLUE}{DATE_LONG} STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Stationsklasse: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Stationstype: {LTBLUE}{STRING} diff --git a/src/lang/dutch.txt b/src/lang/dutch.txt index 7dec5e4494..8cf0a85355 100644 --- a/src/lang/dutch.txt +++ b/src/lang/dutch.txt @@ -2648,7 +2648,7 @@ STR_LAND_AREA_INFORMATION_TRAM_OWNER :{BLACK}Eigenaar STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Eigenaar van spoorweg: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Gemeente: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Geen -STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Coördinaten: {LTBLUE}{NUM} x {NUM} x {NUM} ({STRING}) +STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Coördinaten: {LTBLUE}{NUM} x {NUM} x {NUM} x -{NUM} ({STRING}) STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Bouwjaar: {LTBLUE}{DATE_LONG} STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Stationsklasse: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Stationstype: {LTBLUE}{STRING} diff --git a/src/lang/english.txt b/src/lang/english.txt index 43fdd0ff71..5fe14383e8 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -470,6 +470,18 @@ STR_LANDSCAPING_MENU_PLANT_TREES :Plant trees STR_LANDSCAPING_MENU_PLACE_SIGN :Place sign ############ range ends here +############ range for underground menu starts +STR_LANDSCAPING_MENU_UNDERGROUND :Special constructions +STR_LANDSCAPING_MENU_LAYER_1 :Surface +STR_LANDSCAPING_MENU_LAYER_2 :Undergroound (-1) +STR_LANDSCAPING_MENU_LAYER_3 :Undergroound (-2) +STR_LANDSCAPING_MENU_LAYER_4 :Undergroound (-3) +STR_LANDSCAPING_MENU_LAYER_5 :Undergroound (-4) +STR_LANDSCAPING_MENU_LAYER_6 :Undergroound (-5) +STR_LANDSCAPING_MENU_LAYER_7 :Undergroound (-6) +STR_LANDSCAPING_MENU_LAYER_8 :Undergroound (-7) +############ range ends here + ############ range for music menu starts STR_TOOLBAR_SOUND_MUSIC :Sound/music ############ range ends here @@ -2648,7 +2660,7 @@ STR_LAND_AREA_INFORMATION_TRAM_OWNER :{BLACK}Tramway STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Railway owner: {LTBLUE}{STRING1} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Local authority: {LTBLUE}{STRING1} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :None -STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Coordinates: {LTBLUE}{NUM} x {NUM} x {NUM} ({RAW_STRING}) +STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Coordinates: {LTBLUE}{NUM} x {NUM} x {NUM} x -{NUM} ({RAW_STRING}) STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Built: {LTBLUE}{DATE_LONG} STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Station class: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Station type: {LTBLUE}{STRING} @@ -5185,3 +5197,35 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) + +# underground + +# error +STR_ERROR_UNDERGROUND_CAN_T_BUILD_UNDER_GROUND :{WHITE}Can't build this underground +STR_ERROR_UNDERGROUND_CAN_T_BUILD_OVER_GROUND :{WHITE}Can't build this on surface +STR_ERROR_UNDERGROUND_CAN_T_TERRAFORM :{WHITE}Can't terraform underground +STR_ERROR_UNDERGROUND_CAN_T_BUILD_PART :{WHITE}Can't build escalator here... +STR_ERROR_UNDERGROUND_CAN_T_BUILD_TOP_PART :{WHITE}Can't build escalator top here... +STR_ERROR_UNDERGROUND_CAN_T_BUILD_BOTTOM_PART :{WHITE}Can't build escalator bottom here... + +# menus +STR_UNDERGROUND_LAYER_COUNT :{BLACK}Layers count +STR_UNDERGROUND_BUILD :{WHITE}Underground + +# underground land types +STR_UNDERGROUND_FLAT :Cave +STR_UNDERGROUND_SOLID :Ground +STR_UNDERGROUND_ROCKS :Rocks +STR_UNDERGROUND_HEAVY_ROCKS :Hard rocks + +# underground special build types +STR_UNDERGROUND_ESCALATOR :Escalator +STR_UNDERGROUND_CONNECT :Connect +STR_UNDERGROUND_PIPE :Pipe + +# underground tool tip +STR_UNDERGROUND_TOOLTIP_ESCALATOR :{BLACK}Build escalator (underground station connect with surface) +STR_UNDERGROUND_TOOLTIP_CONNECT :{BLACK}Build connect (underground track connect with surface) +STR_UNDERGROUND_TOOLTIP_PIPE :{BLACK}Pipe (xm... anything...) + +# end underground string diff --git a/src/lang/english_AU.txt b/src/lang/english_AU.txt index 9ea557a217..957a6564f4 100644 --- a/src/lang/english_AU.txt +++ b/src/lang/english_AU.txt @@ -2513,7 +2513,7 @@ STR_LAND_AREA_INFORMATION_TRAM_OWNER :{BLACK}Tramway STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Railway owner: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Local authority: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :None -STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Coordinates: {LTBLUE}{NUM} x {NUM} x {NUM} ({STRING}) +STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Coordinates: {LTBLUE}{NUM} x {NUM} x {NUM} x -{NUM} ({STRING}) STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Built: {LTBLUE}{DATE_LONG} STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Station class: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Station type: {LTBLUE}{STRING} diff --git a/src/lang/english_US.txt b/src/lang/english_US.txt index a18ee830cf..5f047c49ea 100644 --- a/src/lang/english_US.txt +++ b/src/lang/english_US.txt @@ -2597,7 +2597,7 @@ STR_LAND_AREA_INFORMATION_TRAM_OWNER :{BLACK}Streetca STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Railroad owner: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Local authority: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :None -STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Co-ordinates: {LTBLUE}{NUM} x {NUM} x {NUM} ({STRING}) +STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Co-ordinates: {LTBLUE}{NUM} x {NUM} x {NUM} x -{NUM} ({STRING}) STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Built: {LTBLUE}{DATE_LONG} STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Station class: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Station type: {LTBLUE}{STRING} diff --git a/src/lang/esperanto.txt b/src/lang/esperanto.txt index 2cabb46a15..f6a12f5a33 100644 --- a/src/lang/esperanto.txt +++ b/src/lang/esperanto.txt @@ -2146,7 +2146,7 @@ STR_LAND_AREA_INFORMATION_TRAM_OWNER :{BLACK}Posedant STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Posedanto de fervojo: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Lokaj estroj: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Neniu -STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}TroviÄo: {LTBLUE}{NUM} x {NUM} x {NUM} ({STRING}) +STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}TroviÄo: {LTBLUE}{NUM} x {NUM} x {NUM} x -{NUM} ({STRING}) STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Kreite: {LTBLUE}{DATE_LONG} STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Stacioklaso: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Staciotipo: {LTBLUE}{STRING} diff --git a/src/lang/estonian.txt b/src/lang/estonian.txt index 279a75b76b..4958456cc3 100644 --- a/src/lang/estonian.txt +++ b/src/lang/estonian.txt @@ -2698,7 +2698,7 @@ STR_LAND_AREA_INFORMATION_TRAM_OWNER :{BLACK}Trammite STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Raudtee omanik: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Kohalik omavalitsus: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :puudub -STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Koordinaadid: {LTBLUE}{NUM} x {NUM} x {NUM} ({STRING}) +STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Koordinaadid: {LTBLUE}{NUM} x {NUM} x {NUM} x -{NUM} ({STRING}) STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Ehitatud: {LTBLUE}{DATE_LONG} STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Jaama liik: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Jaama liik: {LTBLUE}{STRING} diff --git a/src/lang/faroese.txt b/src/lang/faroese.txt index 0666e34927..c7a76722c9 100644 --- a/src/lang/faroese.txt +++ b/src/lang/faroese.txt @@ -2284,7 +2284,7 @@ STR_LAND_AREA_INFORMATION_TRAM_OWNER :{BLACK}Sporvogn STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Jarnbreyta eigari: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Mynduleikar á staðnum: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Eingin -STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Koordinatar: {LTBLUE}{NUM} x {NUM} x {NUM} ({STRING}) +STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Koordinatar: {LTBLUE}{NUM} x {NUM} x {NUM} x -{NUM} ({STRING}) STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Bygt: {LTBLUE}{DATE_LONG} STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Støð klassi: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Støð slag: {LTBLUE}{STRING} diff --git a/src/lang/finnish.txt b/src/lang/finnish.txt index 9198ae0111..2b0bd13984 100644 --- a/src/lang/finnish.txt +++ b/src/lang/finnish.txt @@ -2648,7 +2648,7 @@ STR_LAND_AREA_INFORMATION_TRAM_OWNER :{BLACK}Raitioti STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Rautatien omistaja: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Kunta: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Ei mitään -STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Koordinaatit: {LTBLUE}{NUM}×{NUM}×{NUM} ({STRING}) +STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Koordinaatit: {LTBLUE}{NUM}×{NUM}×{NUM}x-{NUM} ({STRING}) STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Rakennettu: {LTBLUE}{DATE_LONG} STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Aseman luokka: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Aseman tyyppi: {LTBLUE}{STRING} diff --git a/src/lang/french.txt b/src/lang/french.txt index 1cc275135c..3efa659840 100644 --- a/src/lang/french.txt +++ b/src/lang/french.txt @@ -2649,7 +2649,7 @@ STR_LAND_AREA_INFORMATION_TRAM_OWNER :{BLACK}Proprié STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Propriétaire des rails{NBSP}: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Municipalité{NBSP}: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Aucune -STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Coordonnées{NBSP}: {LTBLUE}{NUM} × {NUM} × {NUM} ({STRING}) +STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Coordonnées{NBSP}: {LTBLUE}{NUM} × {NUM} × {NUM} × -{NUM} ({STRING}) STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Construit le{NBSP}: {LTBLUE}{DATE_LONG} STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Type de station{NBSP}: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Type de station{NBSP}: {LTBLUE}{STRING} diff --git a/src/lang/gaelic.txt b/src/lang/gaelic.txt index d4f09bd1b9..ce4d5720a6 100644 --- a/src/lang/gaelic.txt +++ b/src/lang/gaelic.txt @@ -2771,7 +2771,7 @@ STR_LAND_AREA_INFORMATION_TRAM_OWNER :{BLACK}Seilbhea STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Seilbheadair na rathaid-iarainn: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Ùghdarras ionadail: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Chan eil gin -STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Ionad: {LTBLUE}{NUM} x {NUM} x {NUM} ({STRING}) +STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Ionad: {LTBLUE}{NUM} x {NUM} x {NUM} x -{NUM} ({STRING}) STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Air a thogail: {LTBLUE}{DATE_LONG} STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Seòrsa an stèisein: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Seòrsa an stèisein: {LTBLUE}{STRING} diff --git a/src/lang/galician.txt b/src/lang/galician.txt index daddb2bf5a..7aced14811 100644 --- a/src/lang/galician.txt +++ b/src/lang/galician.txt @@ -2592,7 +2592,7 @@ STR_LAND_AREA_INFORMATION_TRAM_OWNER :{BLACK}Propieta STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Propietario da vía ferroviaria: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Autoridade local: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Ningunha -STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Coordenadas: {LTBLUE}{NUM} x {NUM} x {NUM} ({STRING}) +STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Coordenadas: {LTBLUE}{NUM} x {NUM} x {NUM} x -{NUM} ({STRING}) STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Construído: {LTBLUE}{DATE_LONG} STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Clase de estación: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Tipo de estación: {LTBLUE}{STRING} diff --git a/src/lang/german.txt b/src/lang/german.txt index aac6f21b47..67f6c3dc43 100644 --- a/src/lang/german.txt +++ b/src/lang/german.txt @@ -2649,7 +2649,7 @@ STR_LAND_AREA_INFORMATION_TRAM_OWNER :{BLACK}Straßen STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Gleiseigentümer: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Gehört zur Gemeinde: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Keine -STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Koordinaten: {LTBLUE}{NUM} x {NUM} x {NUM} ({STRING}) +STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Koordinaten: {LTBLUE}{NUM} x {NUM} x {NUM} x -{NUM} ({STRING}) STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Errichtet am: {LTBLUE}{DATE_LONG} STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Stationsklasse: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Stationstyp: {LTBLUE}{STRING} diff --git a/src/lang/greek.txt b/src/lang/greek.txt index efff2947b1..748a1e65ab 100644 --- a/src/lang/greek.txt +++ b/src/lang/greek.txt @@ -2681,7 +2681,7 @@ STR_LAND_AREA_INFORMATION_TRAM_OWNER :{BLACK}Ιδιο STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Ιδιοκτήτης του σιδηÏοδÏόμου: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Τοπική αÏχή: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Καμιά -STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Συντεταγμένες: {LTBLUE}{NUM} x {NUM} x {NUM} ({STRING}) +STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Συντεταγμένες: {LTBLUE}{NUM} x {NUM} x {NUM} x -{NUM} ({STRING}) STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Κατασκευή: {LTBLUE}{DATE_LONG} STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}ΚατηγοÏία σταθμοÏ: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}ΤÏπος σταθμοÏ: {LTBLUE}{STRING} diff --git a/src/lang/hebrew.txt b/src/lang/hebrew.txt index ceae1679dc..1d213573bc 100644 --- a/src/lang/hebrew.txt +++ b/src/lang/hebrew.txt @@ -2564,7 +2564,7 @@ STR_LAND_AREA_INFORMATION_TRAM_OWNER :{BLACK}:בעל STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}בעלי מסילת הרכבת: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{LTBLUE}{STRING}{BLACK} :רשות מקומית STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :×ין -STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}קו×ורדינטות: {LTBLUE}{NUM} x {NUM} x {NUM} ({STRING}) +STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}קו×ורדינטות: {LTBLUE}{NUM} x {NUM} x {NUM} x -{NUM} ({STRING}) STR_LAND_AREA_INFORMATION_BUILD_DATE :{LTBLUE}{DATE_LONG}{BLACK} : ת×ריך בניה STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}{LTBLUE}{STRING}: ×ופי התחנה STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK} {LTBLUE}{STRING}: סוג התחנה diff --git a/src/lang/hungarian.txt b/src/lang/hungarian.txt index 1ae020bf6d..a69c572545 100644 --- a/src/lang/hungarian.txt +++ b/src/lang/hungarian.txt @@ -2668,7 +2668,7 @@ STR_LAND_AREA_INFORMATION_TRAM_OWNER :{BLACK}A villam STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}A vasúti pálya tulajdonosa: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Helyi önkormányzat: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Nincs -STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Koordináták: {LTBLUE}{NUM} x {NUM} x {NUM} ({STRING}) +STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Koordináták: {LTBLUE}{NUM} x {NUM} x {NUM} x -{NUM} ({STRING}) STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Épült: {LTBLUE}{DATE_LONG} STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Ãllomás osztálya: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Ãllomás típusa: {LTBLUE}{STRING} diff --git a/src/lang/icelandic.txt b/src/lang/icelandic.txt index 99727dffb9..0ae638d4e7 100644 --- a/src/lang/icelandic.txt +++ b/src/lang/icelandic.txt @@ -2390,7 +2390,7 @@ STR_LAND_AREA_INFORMATION_TRAM_OWNER :{BLACK}Eigandi STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Eigandi járnbrautarspors: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Bæjaryfirvöld: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Enginn -STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Hnit: {LTBLUE}{NUM}x{NUM}x{NUM} ({STRING}) +STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Hnit: {LTBLUE}{NUM}x{NUM}x{NUM}x-{NUM} ({STRING}) STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Byggt: {LTBLUE}{DATE_LONG} STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Tegund stöðvar: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Tegund stöðvar: {LTBLUE}{STRING} diff --git a/src/lang/indonesian.txt b/src/lang/indonesian.txt index 0fda7dfdf0..378c745a0c 100644 --- a/src/lang/indonesian.txt +++ b/src/lang/indonesian.txt @@ -2648,7 +2648,7 @@ STR_LAND_AREA_INFORMATION_TRAM_OWNER :{BLACK}Pemilik STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Pemilik Rel Kereta: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Pemkot setempat: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Kosong -STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Koordinat: {LTBLUE}{NUM} x {NUM} x {NUM} ({STRING}) +STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Koordinat: {LTBLUE}{NUM} x {NUM} x {NUM} x -{NUM} ({STRING}) STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Dibuat: {LTBLUE}{DATE_LONG} STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Kelas Stasiun: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Tipe Stasiun: {LTBLUE}{STRING} diff --git a/src/lang/irish.txt b/src/lang/irish.txt index 68db8dd265..0adb2275cc 100644 --- a/src/lang/irish.txt +++ b/src/lang/irish.txt @@ -2538,7 +2538,7 @@ STR_LAND_AREA_INFORMATION_TRAM_OWNER :{BLACK}Úinéir STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Úinéir an iarnróid: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Údarás áitiúil: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Ceann ar bith -STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Comhordanáidí: {LTBLUE}{NUM} x {NUM} x {NUM} ({STRING}) +STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Comhordanáidí: {LTBLUE}{NUM} x {NUM} x {NUM} x -{NUM} ({STRING}) STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Tógtha: {LTBLUE}{DATE_LONG} STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Aicme an stáisiúin: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Cineál stáisiúin: {LTBLUE}{STRING} diff --git a/src/lang/italian.txt b/src/lang/italian.txt index 7db8a24d11..cded68bc47 100644 --- a/src/lang/italian.txt +++ b/src/lang/italian.txt @@ -2631,7 +2631,7 @@ STR_LAND_AREA_INFORMATION_TRAM_OWNER :{BLACK}Propriet STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Proprietario ferrovia: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Autorità locale: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Nessuna -STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Coordinate: {LTBLUE}{NUM} x {NUM} x {NUM} ({STRING}) +STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Coordinate: {LTBLUE}{NUM} x {NUM} x {NUM} x -{NUM} ({STRING}) STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Costruito il: {LTBLUE}{DATE_LONG} STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Tipo stazione: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Tipo stazione: {LTBLUE}{STRING} diff --git a/src/lang/korean.txt b/src/lang/korean.txt index f8e3c6c5b0..4cd6a4d91a 100644 --- a/src/lang/korean.txt +++ b/src/lang/korean.txt @@ -2649,7 +2649,7 @@ STR_LAND_AREA_INFORMATION_TRAM_OWNER :{BLACK}ì „ì°» STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}ì² ë„ ì†Œìœ ì£¼: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}지역 당국: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :ì—†ìŒ -STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}좌표: {LTBLUE}{NUM} x {NUM} x {NUM} ({STRING}) +STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}좌표: {LTBLUE}{NUM} x {NUM} x {NUM} x -{NUM} ({STRING}) STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}건설날짜: {LTBLUE}{DATE_LONG} STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}ì—­ 분류: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}ì—­ 종류: {LTBLUE}{STRING} diff --git a/src/lang/latin.txt b/src/lang/latin.txt index ccbbbe97c9..5efb445cd3 100644 --- a/src/lang/latin.txt +++ b/src/lang/latin.txt @@ -2773,7 +2773,7 @@ STR_LAND_AREA_INFORMATION_TRAM_OWNER :{BLACK}Possesso STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Possessor ferriviae: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Auctoritas vicinalis: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Nulla -STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Coordinatae: {LTBLUE}{NUM} x {NUM} x {NUM} ({STRING}) +STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Coordinatae: {LTBLUE}{NUM} x {NUM} x {NUM} x -{NUM} ({STRING}) STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Dies struendi: {LTBLUE}{DATE_LONG} STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Classis stationis: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Typus stationis: {LTBLUE}{STRING} diff --git a/src/lang/latvian.txt b/src/lang/latvian.txt index 492047bff9..a5be332a62 100644 --- a/src/lang/latvian.txt +++ b/src/lang/latvian.txt @@ -2638,7 +2638,7 @@ STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Dzelzce STR_LAND_AREA_INFORMATION_RAIL_OWNER.kas :{BLACK}Dzelzceļa Ä«paÅ¡niece: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}PaÅ¡valdÄ«ba: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Neviena -STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}KoordinÄtes: {LTBLUE}{NUM} x {NUM} x {NUM} ({STRING}) +STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}KoordinÄtes: {LTBLUE}{NUM} x {NUM} x {NUM} x -{NUM} ({STRING}) STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}UzbÅ«vÄ“ts: {LTBLUE}{DATE_LONG} STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Stacijas klase: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Stacijas tips: {LTBLUE}{STRING} diff --git a/src/lang/lithuanian.txt b/src/lang/lithuanian.txt index af89a3bf52..0592679e6f 100644 --- a/src/lang/lithuanian.txt +++ b/src/lang/lithuanian.txt @@ -2768,7 +2768,7 @@ STR_LAND_AREA_INFORMATION_TRAM_OWNER :{BLACK}Tramvaja STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Geležinkelio savininkas: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Vietos valdžia: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :NÄ—ra -STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}KoordinatÄ—s: {LTBLUE}{NUM} x {NUM} x {NUM} ({STRING}) +STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}KoordinatÄ—s: {LTBLUE}{NUM} x {NUM} x {NUM} x -{NUM} ({STRING}) STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Pastatytas: {LTBLUE}{DATE_LONG} STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}StotelÄ—s rÅ«Å¡is: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}StotelÄ—s tipas: {LTBLUE}{STRING} diff --git a/src/lang/luxembourgish.txt b/src/lang/luxembourgish.txt index 1bac4dfa3c..ea5f066b6f 100644 --- a/src/lang/luxembourgish.txt +++ b/src/lang/luxembourgish.txt @@ -2600,7 +2600,7 @@ STR_LAND_AREA_INFORMATION_TRAM_OWNER :{BLACK}Tramschi STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Schinnebesëtzer: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Gemeng: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Keng -STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Koordinaten: {LTBLUE}{NUM} x {NUM} x {NUM} ({STRING}) +STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Koordinaten: {LTBLUE}{NUM} x {NUM} x {NUM} x -{NUM} ({STRING}) STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Gebaut: {LTBLUE}{DATE_LONG} STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Statiounsklass: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Statiounstyp: {LTBLUE}{STRING} diff --git a/src/lang/malay.txt b/src/lang/malay.txt index 10c417cc80..b427b8a48f 100644 --- a/src/lang/malay.txt +++ b/src/lang/malay.txt @@ -2288,7 +2288,7 @@ STR_LAND_AREA_INFORMATION_TRAM_OWNER :{BLACK}Pemilik STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Pemilik landasan keretapi: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Pihak berkuasa: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Tiada -STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Koordinat: {LTBLUE}{NUM} x {NUM} x {NUM} ({STRING}) +STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Koordinat: {LTBLUE}{NUM} x {NUM} x {NUM} x -{NUM} ({STRING}) STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Dibina: {LTBLUE}{DATE_LONG} STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Kelas stesen: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Jenis stesen: {LTBLUE}{STRING} diff --git a/src/lang/norwegian_bokmal.txt b/src/lang/norwegian_bokmal.txt index 75d3a22a31..9d562c4e74 100644 --- a/src/lang/norwegian_bokmal.txt +++ b/src/lang/norwegian_bokmal.txt @@ -2644,7 +2644,7 @@ STR_LAND_AREA_INFORMATION_TRAM_OWNER :{BLACK}Eier av STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Eier av jernbanespor: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Bystyret: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Ingen -STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Koordinater: {LTBLUE}{NUM} x {NUM} x {NUM} ({STRING}) +STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Koordinater: {LTBLUE}{NUM} x {NUM} x {NUM} x -{NUM} ({STRING}) STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Bygget: {LTBLUE}{DATE_LONG} STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Stasjonstype: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Stasjonstype: {LTBLUE}{STRING} diff --git a/src/lang/norwegian_nynorsk.txt b/src/lang/norwegian_nynorsk.txt index 4f518caaa4..7f4621881c 100644 --- a/src/lang/norwegian_nynorsk.txt +++ b/src/lang/norwegian_nynorsk.txt @@ -2462,7 +2462,7 @@ STR_LAND_AREA_INFORMATION_TRAM_OWNER :{BLACK}Trikkesp STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Jernbaneskjene-eigar: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Bystyret: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Ingen -STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Koordinatar: {LTBLUE}{NUM} x {NUM} x {NUM} ({STRING}) +STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Koordinatar: {LTBLUE}{NUM} x {NUM} x {NUM} x -{NUM} ({STRING}) STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Byggd: {LTBLUE}{DATE_LONG} STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Stasjonsklasse: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Stasjontype: {LTBLUE}{STRING} diff --git a/src/lang/polish.txt b/src/lang/polish.txt index 712f001f7a..13eadd36e7 100644 --- a/src/lang/polish.txt +++ b/src/lang/polish.txt @@ -3028,7 +3028,7 @@ STR_LAND_AREA_INFORMATION_TRAM_OWNER :{BLACK}WÅ‚aÅ›ci STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}WÅ‚aÅ›ciciel linii kolejowej: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Lokalne wÅ‚adze: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Brak -STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}WspółrzÄ™dne: {LTBLUE}{NUM} x {NUM} x {NUM} ({STRING}) +STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}WspółrzÄ™dne: {LTBLUE}{NUM} x {NUM} x {NUM} x -{NUM} ({STRING}) STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Zbudowano: {LTBLUE}{DATE_LONG} STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Rodzaj stacji: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Typ stacji: {LTBLUE}{STRING} diff --git a/src/lang/portuguese.txt b/src/lang/portuguese.txt index 264623f6a8..07e808d5a5 100644 --- a/src/lang/portuguese.txt +++ b/src/lang/portuguese.txt @@ -2603,7 +2603,7 @@ STR_LAND_AREA_INFORMATION_TRAM_OWNER :{BLACK}Dono da STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Dono da linha férrea: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Autoridade local: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Nenhum -STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Coordenadas: {LTBLUE}{NUM} x {NUM} x {NUM} ({STRING}) +STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Coordenadas: {LTBLUE}{NUM} x {NUM} x {NUM} x -{NUM} ({STRING}) STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Construído: {LTBLUE}{DATE_LONG} STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Tipo de estação: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Tipo de estação: {LTBLUE}{STRING} diff --git a/src/lang/romanian.txt b/src/lang/romanian.txt index e97decc4cc..51a92eff6a 100644 --- a/src/lang/romanian.txt +++ b/src/lang/romanian.txt @@ -2531,7 +2531,7 @@ STR_LAND_AREA_INFORMATION_TRAM_OWNER :{BLACK}Propriet STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Proprietar al căii ferate: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Autoritatea locală: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Nici una -STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Coordonate: {LTBLUE}{NUM} x {NUM} x {NUM} ({STRING}) +STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Coordonate: {LTBLUE}{NUM} x {NUM} x {NUM} x -{NUM} ({STRING}) STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Data construcÅ£iei: {LTBLUE}{DATE_LONG} STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Clasa staÅ£iei: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Tip staÅ£ie: {LTBLUE}{STRING} diff --git a/src/lang/russian.txt b/src/lang/russian.txt index 81cec7bb6a..b3d826eb8b 100644 --- a/src/lang/russian.txt +++ b/src/lang/russian.txt @@ -596,6 +596,18 @@ STR_LANDSCAPING_MENU_PLANT_TREES :Ð’Ñ‹Ñадка STR_LANDSCAPING_MENU_PLACE_SIGN :ПоÑтавить метку ############ range ends here +############ range for underground menu starts +STR_LANDSCAPING_MENU_UNDERGROUND :Спец. конÑтрукции +STR_LANDSCAPING_MENU_LAYER_1 :ПоверхноÑÑ‚ÑŒ +STR_LANDSCAPING_MENU_LAYER_2 :Подземелье (-1) +STR_LANDSCAPING_MENU_LAYER_3 :Подземелье (-2) +STR_LANDSCAPING_MENU_LAYER_4 :Подземелье (-3) +STR_LANDSCAPING_MENU_LAYER_5 :Подземелье (-4) +STR_LANDSCAPING_MENU_LAYER_6 :Подземелье (-5) +STR_LANDSCAPING_MENU_LAYER_7 :Подземелье (-6) +STR_LANDSCAPING_MENU_LAYER_8 :Подземелье (-7) +############ range ends here + ############ range for music menu starts STR_TOOLBAR_SOUND_MUSIC :Звук/музыка ############ range ends here @@ -2826,7 +2838,7 @@ STR_LAND_AREA_INFORMATION_TRAM_OWNER :{BLACK}Влад STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Владелец ж/д пути: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}ÐдминиÑтрациÑ: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Ðет -STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Координаты: {LTBLUE}{NUM} × {NUM} × {NUM} ({STRING}) +STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Координаты: {LTBLUE}{NUM} × {NUM} × {NUM} × -{NUM} ({STRING}) STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}ПоÑтроено: {LTBLUE}{DATE_LONG} STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}КлаÑÑ Ñтанции: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Тип Ñтанции: {LTBLUE}{STRING} @@ -5412,3 +5424,35 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) + +# underground + +# error +STR_ERROR_UNDERGROUND_CAN_T_BUILD_UNDER_GROUND :{WHITE}Ðе может ÑтроитьÑÑ Ð¿Ð¾Ð´ землей +STR_ERROR_UNDERGROUND_CAN_T_BUILD_OVER_GROUND :{WHITE}Ðе может ÑтроитьÑÑ Ð½Ð° поверхноÑти +STR_ERROR_UNDERGROUND_CAN_T_TERRAFORM :{WHITE}Изменение ландшафта недоÑтупно +STR_ERROR_UNDERGROUND_CAN_T_BUILD_PART :{WHITE}ÐÐµÐ»ÑŒÐ·Ñ Ð¿Ð¾Ñтроить ÑÑкалатор... +STR_ERROR_UNDERGROUND_CAN_T_BUILD_TOP_PART :{WHITE}ÐÐµÐ»ÑŒÐ·Ñ Ð¿Ð¾Ñтроить верхнюю чаÑÑ‚ÑŒ ÑÑкалатора... +STR_ERROR_UNDERGROUND_CAN_T_BUILD_BOTTOM_PART :{WHITE}ÐÐµÐ»ÑŒÐ·Ñ Ð¿Ð¾Ñтроить нижнюю чаÑÑ‚ÑŒ ÑÑкалатора... + +# menus +STR_UNDERGROUND_LAYER_COUNT :{BLACK}КоличеÑтво Ñлоев +STR_UNDERGROUND_BUILD :{WHITE}Подземелье + +# underground land types +STR_UNDERGROUND_FLAT :Пещера +STR_UNDERGROUND_SOLID :Грунт +STR_UNDERGROUND_ROCKS :Скалы +STR_UNDERGROUND_HEAVY_ROCKS :Твердые породы + +# underground special build types +STR_UNDERGROUND_ESCALATOR :ЭÑкалатор +STR_UNDERGROUND_CONNECT :Соединение +STR_UNDERGROUND_PIPE :Трубы + +# underground tool tip +STR_UNDERGROUND_TOOLTIP_ESCALATOR :{BLACK}ПоÑтройка ÑÑкалатора (ÑвÑзь подземной Ñтанции Ñ Ð¿Ð¾Ð²ÐµÑ€Ñ…Ð½Ð¾Ñтью) +STR_UNDERGROUND_TOOLTIP_CONNECT :{BLACK}ПоÑтройка подъема (подземные рельÑÑ‹ выходÑÑ‚ наружу) +STR_UNDERGROUND_TOOLTIP_PIPE :{BLACK}Трубы (хм... что-то...) + +# end underground string diff --git a/src/lang/serbian.txt b/src/lang/serbian.txt index b673c738d2..b3462afcc6 100644 --- a/src/lang/serbian.txt +++ b/src/lang/serbian.txt @@ -2746,7 +2746,7 @@ STR_LAND_AREA_INFORMATION_TRAM_OWNER :{BLACK}Vlasnik STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Vlasnik železniÄke pruge: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Lokalna vlast: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Nema -STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Koordinate: {LTBLUE}{NUM} x {NUM} x {NUM} ({STRING}) +STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Koordinate: {LTBLUE}{NUM} x {NUM} x {NUM} x -{NUM} ({STRING}) STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}SagraÄ‘eno: {LTBLUE}{DATE_LONG} STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Klasa stanice: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Vrsta stanice: {LTBLUE}{STRING} diff --git a/src/lang/simplified_chinese.txt b/src/lang/simplified_chinese.txt index c3fc02132e..1952d2bc68 100644 --- a/src/lang/simplified_chinese.txt +++ b/src/lang/simplified_chinese.txt @@ -2601,7 +2601,7 @@ STR_LAND_AREA_INFORMATION_TRAM_OWNER :{BLACK}有轨 STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}é“路归属:{LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}地方政府:{LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :没有 -STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}å标: {LTBLUE}{NUM} × {NUM} × {NUM} ({STRING}) +STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}å标: {LTBLUE}{NUM} × {NUM} × {NUM} × -{NUM} ({STRING}) STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}建造时间:{LTBLUE}{DATE_LONG} STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}车站分类: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}车站类型: {LTBLUE}{STRING} diff --git a/src/lang/slovak.txt b/src/lang/slovak.txt index 194e4393c3..9ec26640dd 100644 --- a/src/lang/slovak.txt +++ b/src/lang/slovak.txt @@ -2716,7 +2716,7 @@ STR_LAND_AREA_INFORMATION_TRAM_OWNER :{BLACK}Vlastní STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Vlastník železnice: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Miestna správa: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Neznáme -STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Súradnice: {LTBLUE}{NUM} x {NUM} x {NUM} ({STRING}) +STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Súradnice: {LTBLUE}{NUM} x {NUM} x {NUM} x -{NUM} ({STRING}) STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Postavené: {LTBLUE}{DATE_LONG} STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Trieda stanice: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Typ stanice: {LTBLUE}{STRING} diff --git a/src/lang/slovenian.txt b/src/lang/slovenian.txt index 20d1617249..efe3e040e9 100644 --- a/src/lang/slovenian.txt +++ b/src/lang/slovenian.txt @@ -2694,7 +2694,7 @@ STR_LAND_AREA_INFORMATION_TRAM_OWNER :{BLACK}Lastnik STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Lastnik železnice: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Lokalna oblast: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Brez -STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Koordinate: {LTBLUE}{NUM} x {NUM} x {NUM} ({STRING}) +STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Koordinate: {LTBLUE}{NUM} x {NUM} x {NUM} x -{NUM} ({STRING}) STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Zgrajeno: {LTBLUE}{DATE_LONG} STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Razred postaje: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Vrsta postaje: {LTBLUE}{STRING} diff --git a/src/lang/spanish.txt b/src/lang/spanish.txt index 0e5e61f075..a265d997a9 100644 --- a/src/lang/spanish.txt +++ b/src/lang/spanish.txt @@ -2640,7 +2640,7 @@ STR_LAND_AREA_INFORMATION_TRAM_OWNER :{BLACK}Propieta STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Propietario del ferrocarril: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Autoridad local: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Ninguna -STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Coordenadas: {LTBLUE}{NUM} x {NUM} x {NUM} ({STRING}) +STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Coordenadas: {LTBLUE}{NUM} x {NUM} x {NUM} x -{NUM} ({STRING}) STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Construido: {LTBLUE}{DATE_LONG} STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Clase de estación: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Tipo de estación: {LTBLUE}{STRING} diff --git a/src/lang/spanish_MX.txt b/src/lang/spanish_MX.txt index cdc0837300..a22a1080ca 100644 --- a/src/lang/spanish_MX.txt +++ b/src/lang/spanish_MX.txt @@ -2647,7 +2647,7 @@ STR_LAND_AREA_INFORMATION_TRAM_OWNER :{BLACK}Propieta STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Propietario del ferrocarril: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Ayuntamiento: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Ninguno -STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Coordenadas: {LTBLUE}{NUM}×{NUM}×{NUM} ({STRING}) +STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Coordenadas: {LTBLUE}{NUM}×{NUM}×{NUM}×-{NUM} ({STRING}) STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Construido: {LTBLUE}{DATE_LONG} STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Clase de estación: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Tipo de estación: {LTBLUE}{STRING} diff --git a/src/lang/swedish.txt b/src/lang/swedish.txt index 57211acd6c..837f943573 100644 --- a/src/lang/swedish.txt +++ b/src/lang/swedish.txt @@ -2601,7 +2601,7 @@ STR_LAND_AREA_INFORMATION_TRAM_OWNER :{BLACK}SpÃ¥rvä STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Järnvägens ägare: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Lokala myndigheter: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Ingen -STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Koordinater: {LTBLUE}{NUM} x {NUM} x {NUM} ({STRING}) +STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Koordinater: {LTBLUE}{NUM} x {NUM} x {NUM} x -{NUM} ({STRING}) STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Byggt: {LTBLUE}{DATE_LONG} STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Stationsklass: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Stationstyp: {LTBLUE}{STRING} diff --git a/src/lang/tamil.txt b/src/lang/tamil.txt index a35bf4b36e..a52b25759b 100644 --- a/src/lang/tamil.txt +++ b/src/lang/tamil.txt @@ -2330,7 +2330,7 @@ STR_LAND_AREA_INFORMATION_TRAM_OWNER :{BLACK}ட௠STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}இரயிலà¯à®µà¯‡ உரிமையாளரà¯: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}நகராடà¯à®šà®¿: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :ஒனà¯à®±à¯à®®à®¿à®²à¯à®²à¯ˆ -STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}அசà¯à®šà¯à®¤à¯ தூரஙà¯à®•à®³à¯: {LTBLUE}{NUM} x {NUM} x {NUM} ({STRING}) +STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}அசà¯à®šà¯à®¤à¯ தூரஙà¯à®•à®³à¯: {LTBLUE}{NUM} x {NUM} x {NUM} x -{NUM} ({STRING}) STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}கடà¯à®Ÿà®ªà¯à®ªà®Ÿà¯à®Ÿà®¤à¯: {LTBLUE}{DATE_LONG} STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}நிலையதà¯à®¤à®¿à®©à¯ பிரிவà¯: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}நிலையதà¯à®¤à®¿à®©à¯ வகை: {LTBLUE}{STRING} diff --git a/src/lang/thai.txt b/src/lang/thai.txt index 85779fe779..e1edabff3e 100644 --- a/src/lang/thai.txt +++ b/src/lang/thai.txt @@ -2487,7 +2487,7 @@ STR_LAND_AREA_INFORMATION_TRAM_OWNER :{BLACK}ผู STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}ผู้ครอบครองทางรถไฟ: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}ขึ้นตรงà¸à¸±à¸šà¸œà¸¹à¹‰à¸”ูà¹à¸¥à¹ƒà¸™à¸—้องถิ่น: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :ไม่มี -STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}ตำà¹à¸«à¸™à¹ˆà¸‡: {LTBLUE}{NUM} x {NUM} x {NUM} ({STRING}) +STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}ตำà¹à¸«à¸™à¹ˆà¸‡: {LTBLUE}{NUM} x {NUM} x {NUM} x -{NUM} ({STRING}) STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}สร้างเมื่อ: {LTBLUE}{DATE_LONG} STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}ประเภทของสถานี: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}รูปà¹à¸šà¸šà¸‚องสถานี: {LTBLUE}{STRING} diff --git a/src/lang/traditional_chinese.txt b/src/lang/traditional_chinese.txt index 33243085cd..bdd012e607 100644 --- a/src/lang/traditional_chinese.txt +++ b/src/lang/traditional_chinese.txt @@ -2541,7 +2541,7 @@ STR_LAND_AREA_INFORMATION_TRAM_OWNER :{BLACK}電車 STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}éµè·¯æ‰€æœ‰è€…:{LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}地方政府:{LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :ç„¡ -STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}座標:{LTBLUE}{NUM} x {NUM} x {NUM} ({STRING}) +STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}座標:{LTBLUE}{NUM} x {NUM} x {NUM} x -{NUM} ({STRING}) STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}建於:{LTBLUE}{DATE_LONG} STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}車站風格:{LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}車站種類:{LTBLUE}{STRING} diff --git a/src/lang/turkish.txt b/src/lang/turkish.txt index aef3eb4c56..fd7f23b779 100644 --- a/src/lang/turkish.txt +++ b/src/lang/turkish.txt @@ -2602,7 +2602,7 @@ STR_LAND_AREA_INFORMATION_TRAM_OWNER :{BLACK}Tramvay STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Demiryolu sahibi: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Belediyesi: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Hiçbiri -STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Koordinatlar: {LTBLUE}{NUM} x {NUM} x {NUM} ({STRING}) +STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Koordinatlar: {LTBLUE}{NUM} x {NUM} x {NUM} x -{NUM} ({STRING}) STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Yapım: {LTBLUE}{DATE_LONG} STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Ä°stasyon sınıfı: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Ä°stasyon türü: {LTBLUE}{STRING} diff --git a/src/lang/ukrainian.txt b/src/lang/ukrainian.txt index ea2c76e92e..b8c61b2776 100644 --- a/src/lang/ukrainian.txt +++ b/src/lang/ukrainian.txt @@ -2732,7 +2732,7 @@ STR_LAND_AREA_INFORMATION_TRAM_OWNER :{BLACK}Ð’Ð»Ð°Ñ STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}ВлаÑник залізниці: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}МіÑцева влада: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Ðемає -STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Координати: {LTBLUE}{NUM} x {NUM} x {NUM} ({STRING}) +STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Координати: {LTBLUE}{NUM} x {NUM} x {NUM} x -{NUM} ({STRING}) STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Рік випуÑку: {LTBLUE}{DATE_LONG} STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}ÐšÐ»Ð°Ñ Ñтанції: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Тип Ñтанції: {LTBLUE}{STRING} diff --git a/src/lang/unfinished/persian.txt b/src/lang/unfinished/persian.txt index 02799129f7..dde96c3291 100644 --- a/src/lang/unfinished/persian.txt +++ b/src/lang/unfinished/persian.txt @@ -2248,7 +2248,7 @@ STR_LAND_AREA_INFORMATION_TRAM_OWNER :{BLACK}مالک STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}مالک ریل راه آهن: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Ùرماندار محلی: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :هیچکدام -STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}مختصات: {LTBLUE}{NUM} x {NUM} x {NUM} ({STRING}) +STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}مختصات: {LTBLUE}{NUM} x {NUM} x {NUM} x -{NUM} ({STRING}) STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}ساخته شده در: {LTBLUE}{DATE_LONG} STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}کلاس ایستگاه: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}نوع ایستگاه: {LTBLUE}{STRING} diff --git a/src/lang/vietnamese.txt b/src/lang/vietnamese.txt index d40a497931..649fbd7d83 100644 --- a/src/lang/vietnamese.txt +++ b/src/lang/vietnamese.txt @@ -2603,7 +2603,7 @@ STR_LAND_AREA_INFORMATION_TRAM_OWNER :{BLACK}Chủ Ä‘ STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Chủ Ä‘Æ°á»ng ray: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Thuá»™c vỠđịa phÆ°Æ¡ng: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Không -STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Toạ Ä‘á»™: {LTBLUE}{NUM} x {NUM} x {NUM} ({STRING}) +STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Toạ Ä‘á»™: {LTBLUE}{NUM} x {NUM} x {NUM} x -{NUM} ({STRING}) STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Xây lúc: {LTBLUE}{DATE_LONG} STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Loại ga,bến: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Kiểu ga,bến: {LTBLUE}{STRING} diff --git a/src/lang/welsh.txt b/src/lang/welsh.txt index 5b524cf3f4..4a758f0ca2 100644 --- a/src/lang/welsh.txt +++ b/src/lang/welsh.txt @@ -2546,7 +2546,7 @@ STR_LAND_AREA_INFORMATION_TRAM_OWNER :{BLACK}Perchenn STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Perchennog rheilffordd: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Awdurdod Lleol: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Dim -STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Cyfeirnodau: {LTBLUE}{NUM} x {NUM} x {NUM} ({STRING}) +STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Cyfeirnodau: {LTBLUE}{NUM} x {NUM} x {NUM} x -{NUM} ({STRING}) STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Adeiladwyd: {LTBLUE}{DATE_LONG} STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Dosbarth gorsaf: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Math gorsaf: {LTBLUE}{STRING} diff --git a/src/layer.cpp b/src/layer.cpp new file mode 100644 index 0000000000..aab234e53d --- /dev/null +++ b/src/layer.cpp @@ -0,0 +1,136 @@ +/* $Id: map.cpp 23740 2012-01-03 21:32:51Z $ */ +/* + +Ýòî ìîäóëü, äëÿ âîçìîæíîñòè ïîëíîöåííîé èãðû â òðåõ èçìåðåíèÿõ +(ïîäçåìåëüå, ìåòðî, èòï.) + + +Ïëîñêîå èãðîâîå ïîëå âûãëÿäèò ïðèìåðíî òàê: +*-----------* +| | +| | +| | +*-----------* + +Ìûñëåííî íàðåæåì åãî íà îäèíàêîâûå ÷àñòè: +*---*---*---* +| | | | +| | | | +| | | | +*---*---*---* + +Ìûñëåííî ñîáåðåì ÷àñòè â âåðòèêàëüíóþ ñòîïî÷êó: +*---* +| *---* +| | *---* +| | | | +* | | | + * | | + *---* + +Òàêèì îáðàçîì èìåÿ ïëîñêóþ êàðòó ìû îïèñûâàåì 3ä ïðîñòðàíñòâî. + +Äëÿ ïðîñòîòû âñÿ êàðòà äåëèòñÿ òîëüêî ïî îñè Y (ðàçðåçû ïàðàëëåëüíû îñè X) +Äåëåíèå ïðîèñõîäèò íà 1, 2, 4, èëè 8 êóñî÷êîâ. + +Íàïðèìåð áûëî âûáðàíî ïîëå 64õ64, ñ 4-ìÿ ñëîÿìè: +Ñîçäàåòñÿ êàðòà 64õ256, ïîäðàçóìåâàåòñÿ, ÷òî: + + X Y + âåðõíèé ñëîé 0--63 0--63 + âòîðîé ñëîé 0--63 64--127 + òðåòèé ñëîé 0--63 128--191 + ÷åòâåðòûé ñëîé 0--63 192--255 + + +Îáû÷íàÿ êàðòà + MapSizeX õ (MapSizeY) + +Ïðåäñòàâëåíèå â âèäå ñëîåâ + LayerSizeX x (LayerSizeY x LayerCount) + +Èíûìè ñëîâàìè èãðîâûå êîîðäèíàòû "ïëîñêîãî" ïðîñòðàíñòâà + + MapX, MapY, MapZ + +ïåðåõîäÿò â êîîðäèíàòû íîâîãî "3ä" ïðîñòðàíñòâà + + // Êîíñòàíòû + LayerCount = ÷èñëî êóñî÷êîâ... (1, èëè 2, èëè 4, èòä.) + LayerSizeZ = ñäâèã ñëîÿ ïî âåðòèêàëè (íàïðèìåð 1) + + // Àêñèîìû + MapSizeX == LayerSizeX + MapSizeY == LayerSizeY * LayerCount + + // Ðàñ÷åò êîîðäèíàò + LayerIndex = MapY / LayerSizeY + + WorldX = MapX + WorldY = MapY - LayerIndex*LayerSizeY + WorldZ = MapZ + LayerIndex*LayerSizeZ +*/ + +/** @file map.cpp Base functions related to the map and distances on them. */ + +#include "stdafx.h" +#include "debug.h" +#include "core/alloc_func.hpp" +#include "void_map.h" +#include "layer_func.h" +#include "layer_type.h" +#include "landscape.h" + +#if defined(_MSC_VER) +/* Why the hell is that not in all MSVC headers?? */ +extern "C" _CRTIMP void __cdecl _assert(void *, void *, unsigned); +#endif + +uint _layer_size_x; ///< Size of the map along the X +uint _layer_size_y; ///< Size of the map along the Y +uint _layer_count; ///< The number of tiles on the map +uint _layer_count_log; +uint _layer_size; ///< Layer size (sizeX * sizeY) + +void InstallLayerSystem(uint size_x, uint size_y, uint layer_count) +{ + if (!IsInsideMM(layer_count, MIN_LAYER_COUNT, MAX_LAYER_COUNT+1)) + error("invalid layer count"); + + _layer_size_x = size_x; + _layer_size_y = size_y; + _layer_size = size_x * size_y; + _layer_count = layer_count; + _layer_count_log = FindFirstBit(layer_count); +} + +void FixUndergroundHeights() +{ + uint width = MapSizeX(); + uint height = MapSizeY(); + + /* Layer correct */ + for (uint row = 0; (uint)row < height; row++) { + + /* Ãðàíèöà ìåæäó ñëîÿìè */ + if (!(row % LayerSizeY())) + for (uint x = 0; x < width; x++) MakeVoid(width * row + x); + + for (uint col = 0; (uint)col < width; col++) { + uint tile = TileXY(row, col); + if (IsUnderground(tile)) + SetTileHeight(tile, 0); + } + } +} + +uint8 calculateLayer(const Viewport *vp) +{ + // Ôóíêöèÿ ViewportDoDraw âûçûâàåòñÿ íåñêîëüêî ðàç ñ ðàçíûìè ïàðàìåòðàìè + // Íóæíî æå íàéòè òîëüêî îäèí ñëîé. + // Îïèðàåìñÿ íà âüþïîðò. + + Point pt = InverseRemapCoords(vp->virtual_left+(vp->virtual_width >> 1),vp->virtual_top+(vp->virtual_height >> 1)); + TileIndex center = TileVirtXY(pt.x, pt.y); + return LayerIndex(center); +} diff --git a/src/layer_func.h b/src/layer_func.h new file mode 100644 index 0000000000..05022163a2 --- /dev/null +++ b/src/layer_func.h @@ -0,0 +1,102 @@ +/* $Id: layer_func.h 2012-09-07 18:11:11 constructor $ */ + +/* +* Ïîäðîáîå îïèñàíèå ñì. â layer.cpp +*/ + +/** @file layer_func.h Functions related to layer in maps. */ + +#ifndef LAYER_FUNC_H +#define LAYER_FUNC_H + +#include "map_func.h" +#include "viewport_type.h" + +/* +* +* Èíèöèàëèçàöèÿ "ïîäçåìåëèé" +* Êîëè÷åñòâî ñëîåâ "1" ðàâíîñèëüíî èãðå áåç "ïîäçåìåëèé" +* +*/ +void InstallLayerSystem(uint size_x, uint size_y, uint layer_count); + +/* Êîððåêòèðîâêà "ïîäçåìíûõ" ñëîåâ +* (â áóäóùåì ñëîè ìîãóò ìåíÿòü âûñîòû -- â ïðåäåëàõ ñîñåäåé) */ +void FixUndergroundHeights(); + +#define UNDERGROUND_COST_MULTIPLIER(tile) (1 + 100 * (TileHeight(TopTile(tile))-TileHeight(tile)-LayerIndex(tile))) + +#define FOR_ALL_LAYERS(var) for (uint var = 0; var < LayerCount(); var++) + +/** + * Get the X component of a tile + * @param tile the tile to get the X component of + * @return the X component + */ +static inline uint LayerX(TileIndex tile) +{ + return tile & LayerMaxX(); +} + +/** + * Get the Y component of a tile + * @param tile the tile to get the Y component of + * @return the Y component + */ +static inline uint LayerY(TileIndex tile) +{ + return (tile >> MapLogX()) & LayerMaxY(); +} + +static inline uint LayerIndex(TileIndex tile) +{ + return (tile >> MapLogX()) / LayerSizeY(); +} + +static inline bool IsUnderground(TileIndex tile) +{ + return LayerIndex(tile) != 0; +} + +/** +* Ðàçìåð ñëîÿ. +* Ìîæíî ïðèáàâèòü ê êëåòêå, ÷òîáû ïîëó÷èòü êëåòêó íèæå +*/ +static inline uint LayerSize() +{ + extern uint _layer_size; + return _layer_size; +} + +/** + * Èùåì êëåòêó ïîâåðõíîñòè äëÿ äàííîé (ñàìóþ âåðõíþþ êëåòêó) + * @param tile the tile to get the Y component of + * @return the Y component + */ +static inline uint TopTile(TileIndex tile) +{ + uint layer = LayerIndex(tile); + return (tile - layer * LayerSize()); +} + +/* Îïðåäåëèòü âåðõíÿÿ ëè êëåòî÷êà î÷åíü ïðîñòî */ +static inline bool IsTopTile(TileIndex tile) +{ + return (tile < LayerSize()); +} + +/* Èùåò êëåòêó íàä äàííîé. (Äëÿ ñàìîé âåðõíåé âåðíåò íèæíþþ??) +*/ +static inline uint UpTile(TileIndex tile) +{ + return TILE_MASK(tile - LayerSize()); +} + +/* Èùåò êëåòêó ïîä äàííîé. (Äëÿ ñàìîé íèæíåé âåðíåò âåðõíþþ??) +*/ +static inline uint DownTile(TileIndex tile) +{ + return TILE_MASK(tile + LayerSize()); +} + +#endif /* LAYER_FUNC_H */ diff --git a/src/layer_gui.h b/src/layer_gui.h new file mode 100644 index 0000000000..7b791b7e9f --- /dev/null +++ b/src/layer_gui.h @@ -0,0 +1,17 @@ +/* $Id: layer_func.h 2012-09-07 18:11:11 constructor $ */ + +/* +* Ïîäðîáîå îïèñàíèå ñì. â layer.cpp +*/ + +/** @file layer_gui.h Functions for visualisation map with support layers */ + +#ifndef LAYER_GUI_H +#define LAYER_GUI_H + +#include "layer_func.h" +#include "viewport_type.h" + +uint8 calculateLayer(const Viewport *vp); + +#endif /* LAYER_GUI_H */ diff --git a/src/layer_type.h b/src/layer_type.h new file mode 100644 index 0000000000..53eafdde63 --- /dev/null +++ b/src/layer_type.h @@ -0,0 +1,22 @@ +/* $Id: layer_type.h 21493 2012-09-11 2:21:53Z constructor $ */ + +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file layer_type.h Types related to maps. */ + +#ifndef LAYER_TYPE_H +#define LAYER_TYPE_H + +/** Minimal and maximal layer counts */ +static const uint MIN_LAYER_COUNT_BITS = 0; ///< Minimal size of map is equal to 2 ^ MIN_LAYER_SIZE_BITS +static const uint MAX_LAYER_COUNT_BITS = 3; ///< Maximal size of map is equal to 2 ^ MAX_LAYER_SIZE_BITS +static const uint MIN_LAYER_COUNT = 1 << MIN_LAYER_COUNT_BITS; ///< Minimal layer count = 1 +static const uint MAX_LAYER_COUNT = 1 << MAX_LAYER_COUNT_BITS; ///< Maximal layer count = 8 + + +#endif /* LAYER_TYPE_H */ diff --git a/src/main_gui.cpp b/src/main_gui.cpp index 1e8cfcbfac..83bd31191d 100644 --- a/src/main_gui.cpp +++ b/src/main_gui.cpp @@ -33,6 +33,9 @@ #include "guitimer_func.h" #include "error.h" #include "news_gui.h" +#include "gfx_func.h" +#include "layer_gui.h" +#include "landscape.h" #include "saveload/saveload.h" @@ -65,7 +68,7 @@ bool HandlePlacePushButton(Window *w, int widget, CursorID cursor, HighLightStyl if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); w->SetDirty(); - if (w->IsWidgetLowered(widget)) { + if (w->IsWidgetLowered(widget) && mode == _thd.place_mode) { ResetObjectToPlace(); return false; } @@ -152,6 +155,22 @@ void ZoomInOrOutToCursorWindow(bool in, Window *w) } } +void LayerUpOrDownToCursorWindow(bool in, Window *w) +{ + assert(w != NULL); + + if (_game_mode != GM_MENU) { + int layer = calculateLayer(w->viewport) + (in ? -1 : 1); + if ((layer < 0) || (layer >= LayerCount())) return; + + Point pt = RemapCoords(0, (in ? -1 : 1) * LayerSizeY() * TILE_SIZE, 0); + w->viewport->dest_scrollpos_x += pt.x; + w->viewport->dest_scrollpos_y += pt.y; + w->InvalidateData(); + + } +} + void FixTitleGameZoom() { if (_game_mode != GM_MENU) return; @@ -409,7 +428,11 @@ struct MainWindow : Window void OnMouseWheel(int wheel) override { if (_settings_client.gui.scrollwheel_scrolling != 2) { - ZoomInOrOutToCursorWindow(wheel < 0, this); + if (_ctrl_pressed) { + LayerUpOrDownToCursorWindow(wheel < 0, this); + } else { + ZoomInOrOutToCursorWindow(wheel < 0, this); + } } } diff --git a/src/map.cpp b/src/map.cpp index 47b89983e3..0be65724f3 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -11,6 +11,7 @@ #include "debug.h" #include "core/alloc_func.hpp" #include "water_map.h" +#include "layer_func.h" #include "string_func.h" #include "safeguards.h" @@ -36,7 +37,7 @@ TileExtended *_me = nullptr; ///< Extended Tiles of the map * @param size_x the width of the map along the NE/SW edge * @param size_y the 'height' of the map along the SE/NW edge */ -void AllocateMap(uint size_x, uint size_y) +void AllocateMap(uint size_x, uint size_y, uint layer_count) { /* Make sure that the map size is within the limits and that * size of both axes is a power of 2. */ @@ -47,6 +48,10 @@ void AllocateMap(uint size_x, uint size_y) error("Invalid map size"); } + /* Ïîñêîëüêó ñëîè ÷àñòü êàðòû, âêëþ÷àåì èõ çäåñü */ + InstallLayerSystem(size_x, size_y, layer_count); + size_y *= layer_count; + DEBUG(map, 1, "Allocating map of size %dx%d", size_x, size_y); _map_log_x = FindFirstBit(size_x); @@ -268,6 +273,7 @@ bool CircularTileSearch(TileIndex *tile, uint size, TestTileOnSearchProc proc, v /* If tile test is not successful, get one tile up, * ready for a test in first circle around center tile */ *tile = TileAddByDir(*tile, DIR_N); + if (size / 2 == 0) return false; return CircularTileSearch(tile, size / 2, 1, 1, proc, user_data); } else { return CircularTileSearch(tile, size / 2, 0, 0, proc, user_data); diff --git a/src/map_func.h b/src/map_func.h index b02ba57773..f0c3edc414 100644 --- a/src/map_func.h +++ b/src/map_func.h @@ -41,7 +41,7 @@ extern Tile *_m; */ extern TileExtended *_me; -void AllocateMap(uint size_x, uint size_y); +void AllocateMap(uint size_x, uint size_y, uint layer_count); /** * Logarithm of the map size along the X side. @@ -113,6 +113,64 @@ static inline uint MapMaxY() return MapSizeY() - 1; } +/** + * Get the size of the layer along the X + * @return the number of tiles along the X of the layer + */ +static inline uint LayerSizeX() +{ + extern uint _map_size_x; + return _map_size_x; +} + +/** + * Get the size of the layer along the Y + * @return the number of tiles along the Y of the layer + */ +static inline uint LayerSizeY() +{ + extern uint _layer_size_y; + return _layer_size_y; +} + +/** + * Gets the maximum X coordinate within the map, including MP_VOID + * @return the maximum X coordinate + */ +static inline uint LayerMaxX() +{ + return LayerSizeX() - 1; +} + +/** + * Gets the maximum Y coordinate within the map, including MP_VOID + * @return the maximum Y coordinate + */ +static inline uint LayerMaxY() +{ + return LayerSizeY() - 1; +} + +/** + * Get the layer counts + * @return the number of layers + */ +static inline uint LayerCount() +{ + extern uint _layer_count; + return _layer_count; +} + +/** + * Get the layer counts + * @return the number of layers + */ +static inline uint LayerCountLog() +{ + extern uint _layer_count_log; + return _layer_count_log; +} + /** * Scales the given value by the map size, where the given value is * for a 256 by 256 map. @@ -123,7 +181,7 @@ static inline uint ScaleByMapSize(uint n) { /* Subtract 12 from shift in order to prevent integer overflow * for large values of n. It's safe since the min mapsize is 64x64. */ - return CeilDiv(n << (MapLogX() + MapLogY() - 12), 1 << 4); + return CeilDiv(n << (MapLogX() + MapLogY() - LayerCountLog() - 12), 1 << 4); } diff --git a/src/misc.cpp b/src/misc.cpp index dcb04fa026..0e28216300 100644 --- a/src/misc.cpp +++ b/src/misc.cpp @@ -8,6 +8,7 @@ /** @file misc.cpp Misc functions that shouldn't be here. */ #include "stdafx.h" +#include "layer_func.h" #include "landscape.h" #include "news_func.h" #include "ai/ai.hpp" @@ -61,7 +62,7 @@ void InitializeGame(uint size_x, uint size_y, bool reset_date, bool reset_settin * related to the new game we're about to start/load. */ UnInitWindowSystem(); - AllocateMap(size_x, size_y); + AllocateMap(size_x, size_y, 1 << _settings_game.game_creation.layers); _pause_mode = PM_UNPAUSED; _fast_forward = 0; diff --git a/src/misc_gui.cpp b/src/misc_gui.cpp index 9d0259b3be..9be947cf9e 100644 --- a/src/misc_gui.cpp +++ b/src/misc_gui.cpp @@ -218,10 +218,11 @@ public: /* Location */ char tmp[16]; seprintf(tmp, lastof(tmp), "0x%.4X", tile); - SetDParam(0, TileX(tile)); - SetDParam(1, TileY(tile)); + SetDParam(0, LayerX(tile)); + SetDParam(1, LayerY(tile)); SetDParam(2, GetTileZ(tile)); - SetDParamStr(3, tmp); + SetDParam(3, LayerIndex(tile)); + SetDParamStr(4, tmp); GetString(this->landinfo_data[line_nr], STR_LAND_AREA_INFORMATION_LANDINFO_COORDS, lastof(this->landinfo_data[line_nr])); line_nr++; diff --git a/src/object_cmd.cpp b/src/object_cmd.cpp index 7a2ff26524..169611aca0 100644 --- a/src/object_cmd.cpp +++ b/src/object_cmd.cpp @@ -705,7 +705,7 @@ static bool TryBuildLightHouse() */ static bool TryBuildTransmitter() { - TileIndex tile = RandomTile(); + TileIndex tile = TopTile(RandomTile()); int h; if (IsTileType(tile, MP_CLEAR) && IsTileFlat(tile, &h) && h >= 4 && !IsBridgeAbove(tile)) { TileIndex t = tile; @@ -769,7 +769,7 @@ void GenerateObjects() default: uint8 view = RandomRange(spec->views); - if (CmdBuildObject(RandomTile(), DC_EXEC | DC_AUTO | DC_NO_TEST_TOWN_RATING | DC_NO_MODIFY_TOWN_RATING, i, view, nullptr).Succeeded()) amount--; + if (CmdBuildObject(TopTile(RandomTile()), DC_EXEC | DC_AUTO | DC_NO_TEST_TOWN_RATING | DC_NO_MODIFY_TOWN_RATING, i, view, nullptr).Succeeded()) amount--; break; } } diff --git a/src/rail.h b/src/rail.h index c5775b9467..52c9ea7aed 100644 --- a/src/rail.h +++ b/src/rail.h @@ -158,7 +158,7 @@ public: SpriteID signals[SIGTYPE_END][2][2]; ///< signal GUI sprites (type, variant, state) } gui_sprites; - struct { + struct Cursor { CursorID rail_ns; ///< Cursor for building rail in N-S direction CursorID rail_swne; ///< Cursor for building rail in X direction CursorID rail_ew; ///< Cursor for building rail in E-W direction diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index 133f596437..c575727880 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -541,12 +541,12 @@ CommandCost CmdBuildSingleRail(TileIndex tile, DoCommandFlag flags, uint32 p1, u uint num_new_road_pieces = (road != ROAD_NONE) ? 2 - CountBits(road) : 0; if (num_new_road_pieces > 0) { - cost.AddCost(num_new_road_pieces * RoadBuildCost(roadtype_road)); + cost.AddCost(num_new_road_pieces * RoadBuildCost(roadtype_road) * UNDERGROUND_COST_MULTIPLIER(tile)); } uint num_new_tram_pieces = (tram != ROAD_NONE) ? 2 - CountBits(tram) : 0; if (num_new_tram_pieces > 0) { - cost.AddCost(num_new_tram_pieces * RoadBuildCost(roadtype_tram)); + cost.AddCost(num_new_tram_pieces * RoadBuildCost(roadtype_tram) * UNDERGROUND_COST_MULTIPLIER(tile)); } if (flags & DC_EXEC) { @@ -609,7 +609,7 @@ CommandCost CmdBuildSingleRail(TileIndex tile, DoCommandFlag flags, uint32 p1, u YapfNotifyTrackLayoutChange(tile, track); } - cost.AddCost(RailBuildCost(railtype)); + cost.AddCost(RailBuildCost(railtype) * UNDERGROUND_COST_MULTIPLIER(tile)); return cost; } @@ -653,7 +653,7 @@ CommandCost CmdRemoveSingleRail(TileIndex tile, DoCommandFlag flags, uint32 p1, if (ret.Failed()) return ret; } - cost.AddCost(RailClearCost(GetRailType(tile))); + cost.AddCost(RailClearCost(GetRailType(tile)) * UNDERGROUND_COST_MULTIPLIER(tile)); if (flags & DC_EXEC) { if (HasReservedTracks(tile, trackbit)) { @@ -687,7 +687,7 @@ CommandCost CmdRemoveSingleRail(TileIndex tile, DoCommandFlag flags, uint32 p1, if ((present & trackbit) == 0) return_cmd_error(STR_ERROR_THERE_IS_NO_RAILROAD_TRACK); if (present == (TRACK_BIT_X | TRACK_BIT_Y)) crossing = true; - cost.AddCost(RailClearCost(GetRailType(tile))); + cost.AddCost(RailClearCost(GetRailType(tile)) * UNDERGROUND_COST_MULTIPLIER(tile)); /* Charge extra to remove signals on the track, if they are there */ if (HasSignalOnTrack(tile, track)) { @@ -1004,7 +1004,7 @@ CommandCost CmdBuildTrainDepot(TileIndex tile, DoCommandFlag flags, uint32 p1, u if (!_settings_game.construction.build_on_slopes || !CanBuildDepotByTileh(dir, tileh)) { return_cmd_error(STR_ERROR_FLAT_LAND_REQUIRED); } - cost.AddCost(_price[PR_BUILD_FOUNDATION]); + cost.AddCost(_price[PR_BUILD_FOUNDATION] * UNDERGROUND_COST_MULTIPLIER(tile)); } cost.AddCost(DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR)); @@ -1029,8 +1029,8 @@ CommandCost CmdBuildTrainDepot(TileIndex tile, DoCommandFlag flags, uint32 p1, u YapfNotifyTrackLayoutChange(tile, DiagDirToDiagTrack(dir)); } - cost.AddCost(_price[PR_BUILD_DEPOT_TRAIN]); - cost.AddCost(RailBuildCost(railtype)); + cost.AddCost(_price[PR_BUILD_DEPOT_TRAIN] * UNDERGROUND_COST_MULTIPLIER(tile)); + cost.AddCost(RailBuildCost(railtype) * UNDERGROUND_COST_MULTIPLIER(tile)); return cost; } @@ -1682,7 +1682,7 @@ CommandCost CmdConvertRail(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 InvalidateWindowData(WC_BUILD_VEHICLE, tile); } found_convertible_track = true; - cost.AddCost(RailConvertCost(type, totype)); + cost.AddCost(RailConvertCost(type, totype) * UNDERGROUND_COST_MULTIPLIER(tile)); break; default: // RAIL_TILE_NORMAL, RAIL_TILE_SIGNALS @@ -1694,7 +1694,7 @@ CommandCost CmdConvertRail(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 } } found_convertible_track = true; - cost.AddCost(RailConvertCost(type, totype) * CountBits(GetTrackBits(tile))); + cost.AddCost(RailConvertCost(type, totype) * CountBits(GetTrackBits(tile)) * UNDERGROUND_COST_MULTIPLIER(tile)); break; } break; @@ -1757,7 +1757,7 @@ CommandCost CmdConvertRail(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 } found_convertible_track = true; - cost.AddCost((GetTunnelBridgeLength(tile, endtile) + 2) * RailConvertCost(type, totype)); + cost.AddCost((GetTunnelBridgeLength(tile, endtile) + 2) * RailConvertCost(type, totype) * UNDERGROUND_COST_MULTIPLIER(tile)); break; } @@ -1768,7 +1768,7 @@ CommandCost CmdConvertRail(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 } found_convertible_track = true; - cost.AddCost(RailConvertCost(type, totype)); + cost.AddCost(RailConvertCost(type, totype) * UNDERGROUND_COST_MULTIPLIER(tile)); break; } diff --git a/src/road_cmd.cpp b/src/road_cmd.cpp index b476416899..a8d200fde8 100644 --- a/src/road_cmd.cpp +++ b/src/road_cmd.cpp @@ -402,7 +402,7 @@ static CommandCost RemoveRoad(TileIndex tile, DoCommandFlag flags, RoadBits piec } } else { assert(IsDriveThroughStopTile(tile)); - cost.AddCost(RoadClearCost(existing_rt) * 2); + cost.AddCost(RoadClearCost(existing_rt) * 2 * UNDERGROUND_COST_MULTIPLIER(tile)); if (flags & DC_EXEC) { /* A full diagonal road tile has two road bits. */ UpdateCompanyRoadInfrastructure(existing_rt, GetRoadOwner(tile, rtt), -2); @@ -883,7 +883,7 @@ do_clear:; /* Count pieces */ CountBits(pieces); - cost.AddCost(num_pieces * RoadBuildCost(rt)); + cost.AddCost(num_pieces * RoadBuildCost(rt) * UNDERGROUND_COST_MULTIPLIER(tile)); if (flags & DC_EXEC) { switch (GetTileType(tile)) { @@ -1198,7 +1198,7 @@ CommandCost CmdBuildRoadDepot(TileIndex tile, DoCommandFlag flags, uint32 p1, ui MarkTileDirtyByTile(tile); MakeDefaultName(dep); } - cost.AddCost(_price[PR_BUILD_DEPOT_ROAD]); + cost.AddCost(_price[PR_BUILD_DEPOT_ROAD] * UNDERGROUND_COST_MULTIPLIER(tile)); return cost; } diff --git a/src/saveload/map_sl.cpp b/src/saveload/map_sl.cpp index 51c56684a9..1841263671 100644 --- a/src/saveload/map_sl.cpp +++ b/src/saveload/map_sl.cpp @@ -9,6 +9,7 @@ #include "../stdafx.h" #include "../map_func.h" +#include "../layer_func.h" #include "../core/bitmath_func.hpp" #include "../fios.h" #include @@ -19,10 +20,12 @@ static uint32 _map_dim_x; static uint32 _map_dim_y; +static uint32 _layer_count; static const SaveLoadGlobVarList _map_dimensions[] = { SLEG_CONDVAR(_map_dim_x, SLE_UINT32, SLV_6, SL_MAX_VERSION), SLEG_CONDVAR(_map_dim_y, SLE_UINT32, SLV_6, SL_MAX_VERSION), + SLEG_CONDVAR(_layer_count, SLE_UINT32, SLV_UNDERGROUND, SL_MAX_VERSION), SLEG_END() }; @@ -30,13 +33,16 @@ static void Save_MAPS() { _map_dim_x = MapSizeX(); _map_dim_y = MapSizeY(); + _layer_count = LayerCount(); SlGlobList(_map_dimensions); } static void Load_MAPS() { SlGlobList(_map_dimensions); - AllocateMap(_map_dim_x, _map_dim_y); + if (IsSavegameVersionBefore(SLV_UNDERGROUND)) + _layer_count = 1; + AllocateMap(_map_dim_x, _map_dim_y/_layer_count, _layer_count); } static void Check_MAPS() diff --git a/src/saveload/saveload.h b/src/saveload/saveload.h index 7f4f0d287c..b0e2099cd3 100644 --- a/src/saveload/saveload.h +++ b/src/saveload/saveload.h @@ -303,7 +303,8 @@ enum SaveLoadVersion : uint16 { SLV_MULTITILE_DOCKS, ///< 216 PR#7380 Multiple docks per station. SLV_TRADING_AGE, ///< 217 PR#7780 Configurable company trading age. SLV_ENDING_YEAR, ///< 218 PR#7747 v1.10 Configurable ending year. - SLV_REMOVE_TOWN_CARGO_CACHE, ///< 219 PR#8258 Remove town cargo acceptance and production caches. + SLV_UNDERGROUND, ///< 219 Underground levels. + SLV_REMOVE_TOWN_CARGO_CACHE, ///< 220 PR#8258 Remove town cargo acceptance and production caches. /* Patchpacks for a while considered it a good idea to jump a few versions * above our version for their savegames. But as time continued, this gap diff --git a/src/script/api/script_window.hpp.in b/src/script/api/script_window.hpp.in index a1dbb65670..b0c3656dc6 100644 --- a/src/script/api/script_window.hpp.in +++ b/src/script/api/script_window.hpp.in @@ -65,6 +65,7 @@ #include "../../widgets/town_widget.h" #include "../../widgets/transparency_widget.h" #include "../../widgets/tree_widget.h" +#include "../../widgets/underground_widget.h" #include "../../widgets/vehicle_widget.h" #include "../../widgets/viewport_widget.h" #include "../../widgets/waypoint_widget.h" diff --git a/src/settings.cpp b/src/settings.cpp index a69162708b..ee9fb2e317 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -31,6 +31,7 @@ #include "command_func.h" #include "console_func.h" #include "pathfinder/pathfinder_type.h" +#include "layer_type.h" #include "genworld.h" #include "train.h" #include "news_func.h" diff --git a/src/settings_type.h b/src/settings_type.h index 3c325a0cc0..57d5177f66 100644 --- a/src/settings_type.h +++ b/src/settings_type.h @@ -148,6 +148,8 @@ struct GUISettings { bool show_newgrf_name; ///< Show the name of the NewGRF in the build vehicle window bool auto_remove_signals; ///< automatically remove signals when in the way during rail construction + uint32 layer_view_type; ///< çàðåçåðâèðîâàíî (òèï îòîáðàæåíèÿ) + uint16 console_backlog_timeout; ///< the minimum amount of time items should be in the console backlog before they will be removed in ~3 seconds granularity. uint16 console_backlog_length; ///< the minimum amount of items in the console backlog before items will be removed. @@ -282,6 +284,7 @@ struct GameCreationSettings { Year ending_year; ///< scoring end date uint8 map_x; ///< X size of map uint8 map_y; ///< Y size of map + uint8 layers; ///< map layer count byte land_generator; ///< the landscape generator byte oil_refinery_limit; ///< distance oil refineries allowed from map edge byte snow_line_height; ///< the configured snow line height diff --git a/src/station.cpp b/src/station.cpp index f859495d19..5465df3192 100644 --- a/src/station.cpp +++ b/src/station.cpp @@ -11,6 +11,7 @@ #include "company_func.h" #include "company_base.h" #include "roadveh.h" +#include "layer_func.h" #include "viewport_func.h" #include "viewport_kdtree.h" #include "date_func.h" @@ -493,7 +494,7 @@ void StationRect::MakeEmpty() /** * Determines whether a given point (x, y) is within a certain distance of * the station rectangle. - * @note x and y are in Tile coordinates + * @note x and y are in Tile coordinates (in top layer) * @param x X coordinate * @param y Y coordinate * @param distance The maximum distance a point may have (L1 norm) @@ -512,8 +513,10 @@ bool StationRect::IsEmpty() const CommandCost StationRect::BeforeAddTile(TileIndex tile, StationRectMode mode) { - int x = TileX(tile); - int y = TileY(tile); + /* Ñòàíöèÿ ìîæåò íàõîäèòñÿ íà ëþáîì óðîâíå. + * Íî îõâàòûâàåò òîëüêî ïîâåðõíîñòü */ + int x = LayerX(tile); + int y = LayerY(tile); if (this->IsEmpty()) { /* we are adding the first station tile */ if (mode != ADD_TEST) { @@ -566,28 +569,35 @@ CommandCost StationRect::BeforeAddRect(TileIndex tile, int w, int h, StationRect */ /* static */ bool StationRect::ScanForStationTiles(StationID st_id, int left_a, int top_a, int right_a, int bottom_a) { - TileArea ta(TileXY(left_a, top_a), TileXY(right_a, bottom_a)); - TILE_AREA_LOOP(tile, ta) { - if (IsTileType(tile, MP_STATION) && GetStationIndex(tile) == st_id) return true; + /* Ñòàíöèÿ ìîæåò íàõîäèòñÿ íà ëþáîì óðîâíå. + * Çíà÷èò íàäî îáîéòè âñå ñëîè */ + TileArea ta(TopTile(TileXY(left_a, top_a)), TopTile(TileXY(right_a, bottom_a))); + + FOR_ALL_LAYERS(layer) { + ta.tile = TopTile(ta.tile) + layer * LayerSize(); + TILE_AREA_LOOP(tile, ta) { + if (IsTileType(tile, MP_STATION) && GetStationIndex(tile) == st_id) return true; + } } - return false; } bool StationRect::AfterRemoveTile(BaseStation *st, TileIndex tile) { - int x = TileX(tile); - int y = TileY(tile); + /* Ñòàíöèÿ ìîæåò íàõîäèòñÿ íà ëþáîì óðîâíå. + * Íî îõâàòûâàåò òîëüêî ïîâåðõíîñòü */ + int x = LayerX(tile); + int y = LayerY(tile); /* look if removed tile was on the bounding rect edge * and try to reduce the rect by this edge * do it until we have empty rect or nothing to do */ for (;;) { /* check if removed tile is on rect edge */ - bool left_edge = (x == this->left); - bool right_edge = (x == this->right); - bool top_edge = (y == this->top); - bool bottom_edge = (y == this->bottom); + bool left_edge = (x == TopTile(this->left)); + bool right_edge = (x == TopTile(this->right)); + bool top_edge = (y == TopTile(this->top)); + bool bottom_edge = (y == TopTile(this->bottom)); /* can we reduce the rect in either direction? */ bool reduce_x = ((left_edge || right_edge) && !ScanForStationTiles(st->index, x, this->top, x, this->bottom)); @@ -626,8 +636,13 @@ bool StationRect::AfterRemoveTile(BaseStation *st, TileIndex tile) bool StationRect::AfterRemoveRect(BaseStation *st, TileArea ta) { - assert(this->PtInExtendedRect(TileX(ta.tile), TileY(ta.tile))); - assert(this->PtInExtendedRect(TileX(ta.tile) + ta.w - 1, TileY(ta.tile) + ta.h - 1)); + /* Ñòàíöèÿ ìîæåò íàõîäèòñÿ íà ëþáîì óðîâíå. + * Íî îõâàòûâàåò òîëüêî ïîâåðõíîñòü */ + int topx = LayerX(ta.tile); + int topy = LayerY(ta.tile); + + assert(this->PtInExtendedRect(topx, topy)); + assert(this->PtInExtendedRect(topx + ta.w - 1, topy + ta.h - 1)); bool empty = this->AfterRemoveTile(st, ta.tile); if (ta.w != 1 || ta.h != 1) empty = empty || this->AfterRemoveTile(st, TILE_ADDXY(ta.tile, ta.w - 1, ta.h - 1)); diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index 4077a7b8c6..19afc68daa 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -11,6 +11,7 @@ #include "aircraft.h" #include "bridge_map.h" #include "cmd_helper.h" +#include "layer_func.h" #include "viewport_func.h" #include "viewport_kdtree.h" #include "command_func.h" @@ -100,21 +101,24 @@ bool IsHangar(TileIndex t) * @return Succeeded command (if zero or one station found) or failed command (for two or more stations found). */ template -CommandCost GetStationAround(TileArea ta, StationID closest_station, CompanyID company, T **st) +CommandCost GetStationAround(TileArea ta, StationID closest_station, CompanyID company, T **st, bool layers=false) { ta.Expand(1); /* check around to see if there are any stations there owned by the company */ - TILE_AREA_LOOP(tile_cur, ta) { - if (IsTileType(tile_cur, MP_STATION)) { - StationID t = GetStationIndex(tile_cur); - if (!T::IsValidID(t) || Station::Get(t)->owner != company) continue; - if (closest_station == INVALID_STATION) { - closest_station = t; - } else if (closest_station != t) { - return_cmd_error(STR_ERROR_ADJOINS_MORE_THAN_ONE_EXISTING); + FOR_ALL_LAYERS(layer) { + TILE_AREA_LOOP(tile_cur, ta) { + if (IsTileType(tile_cur, MP_STATION)) { + StationID t = GetStationIndex(tile_cur); + if (!T::IsValidID(t) || Station::Get(t)->owner != company) continue; + if (closest_station == INVALID_STATION) { + closest_station = t; + } else if (closest_station != t) { + return_cmd_error(STR_ERROR_ADJOINS_MORE_THAN_ONE_EXISTING); + } } } + if (!layers) break; } *st = (closest_station == INVALID_STATION) ? nullptr : T::Get(closest_station); return CommandCost(); @@ -811,7 +815,7 @@ CommandCost CheckBuildableTile(TileIndex tile, uint invalid_dirs, int &allowed_z return_cmd_error(STR_ERROR_FLAT_LAND_REQUIRED); } } - cost.AddCost(_price[PR_BUILD_FOUNDATION]); + cost.AddCost(_price[PR_BUILD_FOUNDATION] * UNDERGROUND_COST_MULTIPLIER(tile)); } /* The level of this tile must be equal to allowed_z. */ @@ -1049,7 +1053,7 @@ static CommandCost CheckFlatLandRoadStop(TileArea tile_area, DoCommandFlag flags ret = DoCommand(cur_tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); if (ret.Failed()) return ret; cost.AddCost(ret); - cost.AddCost(RoadBuildCost(rt) * 2); + cost.AddCost(RoadBuildCost(rt) * 2 * UNDERGROUND_COST_MULTIPLIER(cur_tile)); } } } @@ -1069,11 +1073,13 @@ CommandCost CanExpandRailStation(const BaseStation *st, TileArea &new_ta, Axis a TileArea cur_ta = st->train_station; /* determine new size of train station region.. */ - int x = std::min(TileX(cur_ta.tile), TileX(new_ta.tile)); - int y = std::min(TileY(cur_ta.tile), TileY(new_ta.tile)); - new_ta.w = std::max(TileX(cur_ta.tile) + cur_ta.w, TileX(new_ta.tile) + new_ta.w) - x; - new_ta.h = std::max(TileY(cur_ta.tile) + cur_ta.h, TileY(new_ta.tile) + new_ta.h) - y; - new_ta.tile = TileXY(x, y); + /* Ôàêòè÷åñêè, ïîäçåìíàÿ ñòàíöèÿ ("ýñêàëàòîð") áîëüøå øèðèíû êàðòû. + * Ïîýòîìó ïðîâåðÿì ðàçìåð â ïðåäåëàõ îäíîãî ñëîÿ */ + int topx = std::min(LayerX(cur_ta.tile), LayerX(new_ta.tile)); + int topy = std::min(LayerY(cur_ta.tile), LayerY(new_ta.tile)); + new_ta.w = std::max(LayerX(cur_ta.tile) + cur_ta.w, LayerX(new_ta.tile) + new_ta.w) - topx; + new_ta.h = std::max(LayerY(cur_ta.tile) + cur_ta.h, LayerY(new_ta.tile) + new_ta.h) - topy; + new_ta.tile = TileXY(topx, topy); /* make sure the final size is not too big. */ if (new_ta.w > _settings_game.station.station_spread || new_ta.h > _settings_game.station.station_spread) { @@ -1145,7 +1151,7 @@ void GetStationLayout(byte *layout, int numtracks, int plat_len, const StationSp * @return command cost with the error or 'okay' */ template -CommandCost FindJoiningBaseStation(StationID existing_station, StationID station_to_join, bool adjacent, TileArea ta, T **st) +CommandCost FindJoiningBaseStation(StationID existing_station, StationID station_to_join, bool adjacent, TileArea ta, T **st, bool layers=false) { assert(*st == nullptr); bool check_surrounding = true; @@ -1171,7 +1177,7 @@ CommandCost FindJoiningBaseStation(StationID existing_station, StationID station if (check_surrounding) { /* Make sure there is no more than one other station around us that is owned by us. */ - CommandCost ret = GetStationAround(ta, existing_station, _current_company, st); + CommandCost ret = GetStationAround(ta, existing_station, _current_company, st, layers); if (ret.Failed()) return ret; } @@ -1190,9 +1196,9 @@ CommandCost FindJoiningBaseStation(StationID existing_station, StationID station * @param st 'return' pointer for the found station * @return command cost with the error or 'okay' */ -static CommandCost FindJoiningStation(StationID existing_station, StationID station_to_join, bool adjacent, TileArea ta, Station **st) +static CommandCost FindJoiningStation(StationID existing_station, StationID station_to_join, bool adjacent, TileArea ta, Station **st, bool layers=false) { - return FindJoiningBaseStation(existing_station, station_to_join, adjacent, ta, st); + return FindJoiningBaseStation(existing_station, station_to_join, adjacent, ta, st, layers); } /** @@ -1301,8 +1307,8 @@ CommandCost CmdBuildRailStation(TileIndex tile_org, DoCommandFlag flags, uint32 CommandCost cost = CheckFlatLandRailStation(new_location, flags, axis, &est, rt, affected_vehicles, spec_class, spec_index, plat_len, numtracks); if (cost.Failed()) return cost; /* Add construction expenses. */ - cost.AddCost((numtracks * _price[PR_BUILD_STATION_RAIL] + _price[PR_BUILD_STATION_RAIL_LENGTH]) * plat_len); - cost.AddCost(numtracks * plat_len * RailBuildCost(rt)); + cost.AddCost((numtracks * _price[PR_BUILD_STATION_RAIL] + _price[PR_BUILD_STATION_RAIL_LENGTH]) * plat_len * UNDERGROUND_COST_MULTIPLIER(tile_org)); + cost.AddCost(numtracks * plat_len * RailBuildCost(rt) * UNDERGROUND_COST_MULTIPLIER(tile_org)); Station *st = nullptr; ret = FindJoiningStation(est, station_to_join, adjacent, new_location, &st); @@ -1342,8 +1348,10 @@ CommandCost CmdBuildRailStation(TileIndex tile_org, DoCommandFlag flags, uint32 byte numtracks_orig; Track track; + TileIndex top_tile = TopTile(new_location.tile); st->train_station = new_location; - st->AddFacility(FACIL_TRAIN, new_location.tile); + st->train_station.tile = top_tile; + st->AddFacility(FACIL_TRAIN, tile_org); st->rect.BeforeAddRect(tile_org, w_org, h_org, StationRect::ADD_TRY); @@ -1583,7 +1591,7 @@ CommandCost RemoveFromRailBaseStation(TileArea ta, std::vector &affected_st } /* If we reached here, the tile is valid so increase the quantity of tiles we will remove */ - quantity++; + quantity += UNDERGROUND_COST_MULTIPLIER(tile); if (keep_rail || IsStationTileBlocked(tile)) { /* Don't refund the 'steel' of the track when we keep the @@ -1662,7 +1670,7 @@ CommandCost RemoveFromRailBaseStation(TileArea ta, std::vector &affected_st CommandCost CmdRemoveFromRailStation(TileIndex start, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { TileIndex end = p1 == 0 ? start : p1; - if (start >= MapSize() || end >= MapSize()) return CMD_ERROR; + if (start >= MapSize() || end >= MapSize() || (LayerIndex(start) != LayerIndex(end))) return CMD_ERROR; TileArea ta(start, end); std::vector affected_stations; @@ -1725,11 +1733,16 @@ CommandCost RemoveRailStation(T *st, DoCommandFlag flags, Money removal_cost) /* determine width and height of platforms */ TileArea ta = st->train_station; - assert(ta.w != 0 && ta.h != 0); + /* TileArea is top finite area */ + assert(IsTopTile(ta.tile)); + assert(ta.IsFinite()); CommandCost cost(EXPENSES_CONSTRUCTION); + /* Check all layers */ + FOR_ALL_LAYERS(layer) /* clear all areas of the station */ - TILE_AREA_LOOP(tile, ta) { + TILE_AREA_LOOP(top_tile, ta) { + TileIndex tile = top_tile + layer * LayerSize(); /* only remove tiles that are actually train station tiles */ if (st->TileBelongsToRailStation(tile)) { std::vector affected_stations; // dummy @@ -2095,13 +2108,21 @@ CommandCost CmdRemoveRoadStop(TileIndex tile, DoCommandFlag flags, uint32 p1, ui /* Bankrupting company is not supposed to remove roads, there may be road vehicles. */ if (!keep_drive_through_roads && (flags & DC_BANKRUPT)) return CMD_ERROR; - TileArea roadstop_area(tile, width, height); + /* Ýòî òåððèòîðèÿ óäàëåíèÿ îñòàíîâîê (ÍÅ ñàìèõ îñòàíîâîê) */ + TileArea roadstop_area(TopTile(tile), width, height); + + /* TileArea is top finite area */ + assert(IsTopTile(roadstop_area.tile)); + assert(roadstop_area.IsFinite()); CommandCost cost(EXPENSES_CONSTRUCTION); CommandCost last_error(STR_ERROR_THERE_IS_NO_STATION); bool had_success = false; - TILE_AREA_LOOP(cur_tile, roadstop_area) { + /* Check all layers */ + FOR_ALL_LAYERS(layer) + TILE_AREA_LOOP(top_tile, roadstop_area) { + TileIndex cur_tile = top_tile + layer * LayerSize(); /* Make sure the specified tile is a road stop of the correct type */ if (!IsTileType(cur_tile, MP_STATION) || !IsRoadStop(cur_tile) || (uint32)GetRoadStopType(cur_tile) != GB(p2, 0, 1)) continue; @@ -2271,6 +2292,10 @@ CommandCost CmdBuildAirport(TileIndex tile, DoCommandFlag flags, uint32 p1, uint if (w > _settings_game.station.station_spread || h > _settings_game.station.station_spread) { return_cmd_error(STR_ERROR_STATION_TOO_SPREAD_OUT); } + /* can't make underground airport */ + if (IsUnderground(tile)) { + return_cmd_error(STR_ERROR_UNDERGROUND_CAN_T_BUILD_UNDER_GROUND); + } AirportTileTableIterator iter(as->table[layout], tile); CommandCost cost = CheckFlatLandAirport(iter, flags); diff --git a/src/station_gui.cpp b/src/station_gui.cpp index b4156261bc..daba045cb7 100644 --- a/src/station_gui.cpp +++ b/src/station_gui.cpp @@ -19,6 +19,7 @@ #include "strings_func.h" #include "string_func.h" #include "window_func.h" +#include "layer_func.h" #include "viewport_func.h" #include "widgets/dropdown_func.h" #include "station_base.h" @@ -2207,20 +2208,27 @@ static const T *FindStationsNearby(TileArea ta, bool distant_join) _deleted_stations_nearby.clear(); /* Check the inside, to return, if we sit on another station */ - TILE_AREA_LOOP(t, ta) { - if (t < MapSize() && IsTileType(t, MP_STATION) && T::IsValidID(GetStationIndex(t))) return T::GetByTile(t); + FOR_ALL_LAYERS(layer) { + TILE_AREA_LOOP(tile, ta) { + TileIndex t = TopTile(tile) + layer * LayerSize(); + if (t < MapSize() && IsTileType(t, MP_STATION) && T::IsValidID(GetStationIndex(t))) + { + if (t == tile) return T::GetByTile(t); + AddNearbyStation(t, &ctx); + } + } } /* Look for deleted stations */ for (const BaseStation *st : BaseStation::Iterate()) { if (T::IsExpected(st) && !st->IsInUse() && st->owner == _local_company) { /* Include only within station spread (yes, it is strictly less than) */ - if (std::max(DistanceMax(ta.tile, st->xy), DistanceMax(TILE_ADDXY(ta.tile, ta.w - 1, ta.h - 1), st->xy)) < _settings_game.station.station_spread) { + if (std::max(DistanceMax(TopTile(ta.tile), TopTile(st->xy)), DistanceMax(TILE_ADDXY(TopTile(ta.tile), ta.w - 1, ta.h - 1), TopTile(st->xy))) < _settings_game.station.station_spread) { _deleted_stations_nearby.push_back({st->xy, st->index}); /* Add the station when it's within where we're going to build */ - if (IsInsideBS(TileX(st->xy), TileX(ctx.tile), ctx.w) && - IsInsideBS(TileY(st->xy), TileY(ctx.tile), ctx.h)) { + if (IsInsideBS(LayerX(st->xy), LayerX(ctx.tile), ctx.w) && + IsInsideBS(LayerY(st->xy), LayerY(ctx.tile), ctx.h)) { AddNearbyStation(st->xy, &ctx); } } @@ -2233,8 +2241,11 @@ static const T *FindStationsNearby(TileArea ta, bool distant_join) if (distant_join && std::min(ta.w, ta.h) >= _settings_game.station.station_spread) return nullptr; uint max_dist = distant_join ? _settings_game.station.station_spread - std::min(ta.w, ta.h) : 1; - TileIndex tile = TileAddByDir(ctx.tile, DIR_N); - CircularTileSearch(&tile, max_dist, ta.w, ta.h, AddNearbyStation, &ctx); + FOR_ALL_LAYERS(layer) { + ctx.tile = TopTile(ctx.tile) + layer * LayerSize(); + TileIndex tile = TileAddByDir(ctx.tile, DIR_N); + CircularTileSearch(&tile, max_dist, ta.w, ta.h, AddNearbyStation, &ctx); + } return nullptr; } diff --git a/src/table/settings.ini b/src/table/settings.ini index 1c68e6b731..35e1c9feb8 100644 --- a/src/table/settings.ini +++ b/src/table/settings.ini @@ -1932,6 +1932,15 @@ min = 500 max = 1000000 cat = SC_EXPERT +[SDT_VAR] +base = GameSettings +var = game_creation.layers +type = SLE_UINT8 +flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC +def = 1 +min = MIN_LAYER_COUNT_BITS +max = MAX_LAYER_COUNT_BITS + [SDT_BOOL] base = GameSettings var = pf.yapf.rail_firstred_twoway_eol @@ -3262,6 +3271,15 @@ strhelp = STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS_HELPTEXT strval = STR_JUST_COMMA proc = RedrawScreen +[SDTC_VAR] +var = gui.layer_view_type +type = SLE_UINT32 +flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC +def = 0 +min = 0 +max = UINT32_MAX +proc = RedrawScreen + [SDTC_BOOL] var = gui.show_newgrf_name flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC diff --git a/src/terraform_cmd.cpp b/src/terraform_cmd.cpp index 1bc4cb1e2e..5c624ceed1 100644 --- a/src/terraform_cmd.cpp +++ b/src/terraform_cmd.cpp @@ -8,6 +8,7 @@ /** @file terraform_cmd.cpp Commands related to terraforming. */ #include "stdafx.h" +#include "layer_func.h" #include "command_func.h" #include "tunnel_map.h" #include "bridge_map.h" @@ -251,6 +252,10 @@ CommandCost CmdTerraformLand(TileIndex tile, DoCommandFlag flags, uint32 p1, uin if (z_N > z_min) tileh |= SLOPE_N; if (pass == 0) { + /* Terrafrom enable only top layer */ + if (IsUnderground(tile)) { + return_cmd_error(STR_ERROR_UNDERGROUND_CAN_T_TERRAFORM); + } /* Check if bridge would take damage */ if (IsBridgeAbove(tile)) { int bridge_height = GetBridgeHeight(GetSouthernBridgeEnd(tile)); diff --git a/src/tgp.cpp b/src/tgp.cpp index 190499cbc1..3343a7dc80 100644 --- a/src/tgp.cpp +++ b/src/tgp.cpp @@ -12,6 +12,7 @@ #include "clear_map.h" #include "void_map.h" #include "genworld.h" +#include "layer_func.h" #include "core/random_func.hpp" #include "landscape_type.h" @@ -168,6 +169,8 @@ struct HeightMap int total_size; //< height map total size int size_x; //< MapSizeX() int size_y; //< MapSizeY() + int map_x; //< MapSizeX() + int map_y; //< MapSizeY() /** * Height map accessor @@ -325,8 +328,11 @@ static inline bool AllocHeightMap() { height_t *h; - _height_map.size_x = MapSizeX(); - _height_map.size_y = MapSizeY(); + _height_map.map_x = MapSizeX(); + _height_map.map_y = MapSizeY(); + + _height_map.size_x = LayerSizeX(); + _height_map.size_y = LayerSizeY(); /* Allocate memory block for height map row pointers */ _height_map.total_size = (_height_map.size_x + 1) * (_height_map.size_y + 1); @@ -1013,8 +1019,8 @@ void GenerateTerrainPerlin() /* First make sure the tiles at the north border are void tiles if needed. */ if (_settings_game.construction.freeform_edges) { - for (uint x = 0; x < MapSizeX(); x++) MakeVoid(TileXY(x, 0)); - for (uint y = 0; y < MapSizeY(); y++) MakeVoid(TileXY(0, y)); + for (uint x = 0; x < _height_map.map_x; x++) MakeVoid(x); + for (uint y = 0; y < _height_map.map_y - 1; y++) MakeVoid(_height_map.size_x * y); } int max_height = H2I(TGPGetMaxHeight()); diff --git a/src/tile_map.h b/src/tile_map.h index b6c715e8a8..c191ab9042 100644 --- a/src/tile_map.h +++ b/src/tile_map.h @@ -14,6 +14,7 @@ #include "map_func.h" #include "core/bitmath_func.hpp" #include "settings_type.h" +#include "layer_func.h" /** * Returns the height of a tile @@ -110,10 +111,10 @@ static inline bool IsInnerTile(TileIndex tile) { assert(tile < MapSize()); - uint x = TileX(tile); - uint y = TileY(tile); + uint x = LayerX(tile); + uint y = LayerY(tile); - return x < MapMaxX() && y < MapMaxY() && ((x > 0 && y > 0) || !_settings_game.construction.freeform_edges); + return x < LayerMaxX() && y < LayerMaxY() && ((x > 0 && y > 0) || !_settings_game.construction.freeform_edges); } /** @@ -134,7 +135,7 @@ static inline void SetTileType(TileIndex tile, TileType type) /* VOID tiles (and no others) are exactly allowed at the lower left and right * edges of the map. If _settings_game.construction.freeform_edges is true, * the upper edges of the map are also VOID tiles. */ - assert(IsInnerTile(tile) == (type != MP_VOID)); + assert(IsInnerTile(tile) == (type != MP_VOID)); // was commented in SB(_m[tile].type, 4, 4, type); } diff --git a/src/tilearea_type.h b/src/tilearea_type.h index 2648219853..76971ae48a 100644 --- a/src/tilearea_type.h +++ b/src/tilearea_type.h @@ -42,6 +42,16 @@ struct OrthogonalTileArea { this->h = 0; } + inline bool IsEmpty() const + { + return (w==0 && h==0); + } + + inline bool IsFinite() const + { + return (w!=0 && h!=0); + } + bool Intersects(const OrthogonalTileArea &ta) const; bool Contains(TileIndex tile) const; diff --git a/src/toolbar_gui.cpp b/src/toolbar_gui.cpp index 6a851d2b5d..5dbbaf1114 100644 --- a/src/toolbar_gui.cpp +++ b/src/toolbar_gui.cpp @@ -11,7 +11,10 @@ #include "gui.h" #include "window_gui.h" #include "window_func.h" +#include "layer_gui.h" +#include "layer_func.h" #include "viewport_func.h" +#include "landscape.h" #include "command_func.h" #include "vehicle_gui.h" #include "rail_gui.h" @@ -21,6 +24,7 @@ #include "vehicle_func.h" #include "sound_func.h" #include "terraform_gui.h" +#include "underground_gui.h" #include "strings_func.h" #include "company_func.h" #include "company_gui.h" @@ -1006,6 +1010,39 @@ static CallBackFunction MenuClickForest(int index) return CBF_NONE; } +/* --- Underground button menu --- */ + +/** + * Handle click on the entry in the underground menu. + * + * @param index Menu entry clicked. + * @return #CBF_NONE + */ +static CallBackFunction MenuClickUnderground(int index) +{ + if (index==0) { + ShowUndergroundToolbar(); + return CBF_NONE; + } + index -= 1; + if ((index<0) || (uint(index) >= LayerCount())) + return CBF_NONE; + Window *w = FindWindowById(WC_MAIN_WINDOW, 0); + int delta_layer = calculateLayer(w->viewport) - index; + Point pt = RemapCoords(0, -delta_layer * LayerSizeY() * TILE_SIZE, 0); + w->viewport->dest_scrollpos_x += pt.x; + w->viewport->dest_scrollpos_y += pt.y; + w->InvalidateData(); + return CBF_NONE; +} + +static CallBackFunction ToolbarUndergroundClick(Window *w) +{ + PopupMainToolbMenu(w, WID_TN_UNDERGROUND, STR_LANDSCAPING_MENU_UNDERGROUND, 1+LayerCount()); + if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); + return CBF_NONE; +} + /* --- Music button menu --- */ static CallBackFunction ToolbarMusicClick(Window *w) @@ -1316,9 +1353,10 @@ static MenuClickedProc * const _menu_clicked_procs[] = { MenuClickBuildWater, // 24 MenuClickBuildAir, // 25 MenuClickForest, // 26 - MenuClickMusicWindow, // 27 - MenuClickNewspaper, // 28 - MenuClickHelp, // 29 + MenuClickUnderground, // 27 + MenuClickMusicWindow, // 28 + MenuClickNewspaper, // 29 + MenuClickHelp, // 30 }; /** Full blown container to make it behave exactly as we want :) */ @@ -1483,7 +1521,7 @@ class NWidgetMainToolbarContainer : public NWidgetToolbarContainer { const byte *GetButtonArrangement(uint &width, uint &arrangable_count, uint &button_count, uint &spacer_count) const override { static const uint SMALLEST_ARRANGEMENT = 14; - static const uint BIGGEST_ARRANGEMENT = 20; + static const uint BIGGEST_ARRANGEMENT = 21; /* The number of buttons of each row of the toolbar should match the number of items which we want to be visible. * The total number of buttons should be equal to arrangable_count * 2. @@ -1750,6 +1788,67 @@ class NWidgetMainToolbarContainer : public NWidgetToolbarContainer { WID_TN_ZOOM_OUT, WID_TN_SWITCH_BAR, }; + static const byte arrange21[] = { + WID_TN_PAUSE, + WID_TN_FAST_FORWARD, + WID_TN_SETTINGS, + WID_TN_SMALL_MAP, + WID_TN_TOWNS, + WID_TN_SUBSIDIES, + WID_TN_STATIONS, + WID_TN_FINANCES, + WID_TN_COMPANIES, + WID_TN_STORY, + WID_TN_GOAL, + WID_TN_GRAPHS, + WID_TN_LEAGUE, + WID_TN_INDUSTRIES, + WID_TN_TRAINS, + WID_TN_ROADVEHS, + WID_TN_SHIPS, + WID_TN_AIRCRAFT, + WID_TN_ZOOM_IN, + WID_TN_ZOOM_OUT, + WID_TN_RAILS, + WID_TN_ROADS, + WID_TN_WATER, + WID_TN_AIR, + WID_TN_LANDSCAPE, + WID_TN_UNDERGROUND, + WID_TN_MUSIC_SOUND, + WID_TN_MESSAGES, + WID_TN_HELP, + // lower toolbar + WID_TN_PAUSE, + WID_TN_FAST_FORWARD, + WID_TN_SAVE, + WID_TN_SMALL_MAP, + WID_TN_TOWNS, + WID_TN_SUBSIDIES, + WID_TN_STATIONS, + WID_TN_FINANCES, + WID_TN_COMPANIES, + WID_TN_STORY, + WID_TN_GOAL, + WID_TN_GRAPHS, + WID_TN_LEAGUE, + WID_TN_INDUSTRIES, + WID_TN_TRAINS, + WID_TN_ROADVEHS, + WID_TN_SHIPS, + WID_TN_AIRCRAFT, + WID_TN_ZOOM_IN, + WID_TN_ZOOM_OUT, + WID_TN_RAILS, + WID_TN_ROADS, + WID_TN_WATER, + WID_TN_AIR, + WID_TN_LANDSCAPE, + WID_TN_UNDERGROUND, + WID_TN_MUSIC_SOUND, + WID_TN_MESSAGES, + WID_TN_HELP, + }; static const byte arrange_all[] = { WID_TN_PAUSE, WID_TN_FAST_FORWARD, @@ -1778,6 +1877,7 @@ class NWidgetMainToolbarContainer : public NWidgetToolbarContainer { WID_TN_WATER, WID_TN_AIR, WID_TN_LANDSCAPE, + WID_TN_UNDERGROUND, WID_TN_MUSIC_SOUND, WID_TN_MESSAGES, WID_TN_HELP @@ -1792,7 +1892,7 @@ class NWidgetMainToolbarContainer : public NWidgetToolbarContainer { } /* Introduce the split toolbar */ - static const byte * const arrangements[] = { arrange14, arrange15, arrange16, arrange17, arrange18, arrange19, arrange20 }; + static const byte * const arrangements[] = { arrange14, arrange15, arrange16, arrange17, arrange18, arrange19, arrange20, arrange21 }; button_count = arrangable_count = full_buttons; spacer_count = this->spacers; @@ -1949,6 +2049,7 @@ static ToolbarButtonProc * const _toolbar_button_procs[] = { ToolbarBuildWaterClick, ToolbarBuildAirClick, ToolbarForestClick, + ToolbarUndergroundClick, ToolbarMusicClick, ToolbarNewspaperClick, ToolbarHelpClick, @@ -2240,6 +2341,7 @@ static NWidgetBase *MakeMainToolbar(int *biggest_index) SPR_IMG_BUILDWATER, // WID_TN_WATER SPR_IMG_BUILDAIR, // WID_TN_AIR SPR_IMG_LANDSCAPING, // WID_TN_LANDSCAPE + SPR_IMG_LANDSCAPING, // WID_TN_UNDERGROUND SPR_IMG_MUSIC, // WID_TN_MUSIC_SOUND SPR_IMG_MESSAGES, // WID_TN_MESSAGES SPR_IMG_QUERY, // WID_TN_HELP diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index a37c36ed7e..ea9e281c06 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -12,6 +12,7 @@ #include "road_internal.h" /* Cleaning up road bits */ #include "road_cmd.h" #include "landscape.h" +#include "layer_func.h" #include "viewport_func.h" #include "viewport_kdtree.h" #include "cmd_helper.h" @@ -2153,7 +2154,7 @@ static Town *CreateRandomTown(uint attempts, uint32 townnameparts, TownSize size do { /* Generate a tile index not too close from the edge */ - TileIndex tile = AlignTileToGrid(RandomTile(), layout); + TileIndex tile = AlignTileToGrid(TopTile(RandomTile()), layout); /* if we tried to place the town on water, slide it over onto * the nearest likely-looking spot */ @@ -2329,6 +2330,9 @@ static inline bool CanBuildHouseHere(TileIndex tile, bool noslope) Slope slope = GetTileSlope(tile); if ((noslope && slope != SLOPE_FLAT) || IsSteepSlope(slope)) return false; + /* Íåäîïóñòèìî ñòðîèòåëüñòâî îáúåêòà ïîä çåìëåé */ + if (IsUnderground(tile)) return false; + /* at least one RoadTypes allow building the house here? */ if (!RoadTypesAllowHouseHere(tile)) return false; @@ -2764,6 +2768,8 @@ CommandCost CmdRenameTown(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 InvalidateWindowData(WC_TOWN_DIRECTORY, 0, TDIWD_FORCE_RESORT); ClearAllStationCachedNames(); ClearAllIndustryCachedNames(); + InvalidateWindowClassesData(WC_TOWN_VIEW); + InvalidateWindowClassesData(WC_INDUSTRY_VIEW); UpdateAllStationVirtCoords(); } return CommandCost(); diff --git a/src/tree_cmd.cpp b/src/tree_cmd.cpp index dee79e1b72..310868d15e 100644 --- a/src/tree_cmd.cpp +++ b/src/tree_cmd.cpp @@ -11,6 +11,7 @@ #include "clear_map.h" #include "landscape.h" #include "tree_map.h" +#include "layer_func.h" #include "viewport_func.h" #include "command_func.h" #include "town.h" @@ -71,7 +72,8 @@ static bool CanPlantTreesOnTile(TileIndex tile, bool allow_desert) case MP_CLEAR: return !IsBridgeAbove(tile) && !IsClearGround(tile, CLEAR_FIELDS) && GetRawClearGround(tile) != CLEAR_ROCKS && - (allow_desert || !IsClearGround(tile, CLEAR_DESERT)); + (allow_desert || !IsClearGround(tile, CLEAR_DESERT)) + && !IsUnderground(tile); default: return false; } @@ -185,7 +187,7 @@ static void PlaceTree(TileIndex tile, uint32 r) static void PlaceTreeGroups(uint num_groups) { do { - TileIndex center_tile = RandomTile(); + TileIndex center_tile = TopTile(RandomTile()); for (uint i = 0; i < DEFAULT_TREE_STEPS; i++) { uint32 r = Random(); @@ -250,7 +252,7 @@ void PlaceTreesRandomly() if (_game_mode == GM_EDITOR) i /= EDITOR_TREE_DIV; do { uint32 r = Random(); - TileIndex tile = RandomTileSeed(r); + TileIndex tile = TopTile(RandomTileSeed(r)); IncreaseGeneratingWorldProgress(GWP_TREE); @@ -279,7 +281,7 @@ void PlaceTreesRandomly() do { uint32 r = Random(); - TileIndex tile = RandomTileSeed(r); + TileIndex tile = TopTile(RandomTileSeed(r)); IncreaseGeneratingWorldProgress(GWP_TREE); @@ -383,6 +385,10 @@ CommandCost CmdPlantTree(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 const byte tree_to_plant = GB(p1, 0, 8); // We cannot use Extract as min and max are climate specific. if (p2 >= MapSize()) return CMD_ERROR; + + /* tree only top layer */ + if (IsUnderground(p2)) return CMD_ERROR; + /* Check the tree type within the current climate */ if (tree_to_plant != TREE_INVALID && !IsInsideBS(tree_to_plant, _tree_base_by_landscape[_settings_game.game_creation.landscape], _tree_count_by_landscape[_settings_game.game_creation.landscape])) return CMD_ERROR; @@ -813,7 +819,7 @@ void OnTick_Trees() /* place a tree at a random rainforest spot */ if (_settings_game.game_creation.landscape == LT_TROPIC && - (r = Random(), tile = RandomTileSeed(r), GetTropicZone(tile) == TROPICZONE_RAINFOREST) && + (r = Random(), tile = TopTile(RandomTileSeed(r)), GetTropicZone(tile) == TROPICZONE_RAINFOREST) && CanPlantTreesOnTile(tile, false) && (tree = GetRandomTreeType(tile, GB(r, 24, 8))) != TREE_INVALID) { PlantTreesOnTile(tile, tree, 0, 0); @@ -824,7 +830,7 @@ void OnTick_Trees() /* place a tree at a random spot */ r = Random(); - tile = RandomTileSeed(r); + tile = TopTile(RandomTileSeed(r)); if (CanPlantTreesOnTile(tile, false) && (tree = GetRandomTreeType(tile, GB(r, 24, 8))) != TREE_INVALID) { PlantTreesOnTile(tile, tree, 0, 0); } diff --git a/src/tunnelbridge_cmd.cpp b/src/tunnelbridge_cmd.cpp index e71440fc2e..23accf2730 100644 --- a/src/tunnelbridge_cmd.cpp +++ b/src/tunnelbridge_cmd.cpp @@ -13,6 +13,7 @@ #include "stdafx.h" #include "newgrf_object.h" +#include "layer_func.h" #include "viewport_func.h" #include "cmd_helper.h" #include "command_func.h" @@ -309,6 +310,10 @@ CommandCost CmdBuildBridge(TileIndex end_tile, DoCommandFlag flags, uint32 p1, u return_cmd_error(STR_ERROR_CAN_T_START_AND_END_ON); } + if (IsUnderground(tile_start) || IsUnderground(tile_end)) { + return_cmd_error(STR_ERROR_UNDERGROUND_CAN_T_BUILD_UNDER_GROUND); + } + Axis direction; if (TileX(tile_start) == TileX(tile_end)) { direction = AXIS_Y; @@ -702,6 +707,12 @@ CommandCost CmdBuildTunnel(TileIndex start_tile, DoCommandFlag flags, uint32 p1, for (;;) { end_tile += delta; if (!IsValidTile(end_tile)) return_cmd_error(STR_ERROR_TUNNEL_THROUGH_MAP_BORDER); + + + if (IsUnderground(start_tile) || IsUnderground(end_tile)) { + return_cmd_error(STR_ERROR_UNDERGROUND_CAN_T_BUILD_UNDER_GROUND); + } + end_tileh = GetTileSlope(end_tile, &end_z); if (start_z == end_z) break; diff --git a/src/underground_gui.cpp b/src/underground_gui.cpp new file mode 100644 index 0000000000..406bd8cb7d --- /dev/null +++ b/src/underground_gui.cpp @@ -0,0 +1,321 @@ +/* $Id: terraform_gui.cpp 23547 2011-12-16 18:21:13Z truebrain $ */ + +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file terraform_gui.cpp GUI related to terraforming the map. */ + +#include "stdafx.h" +#include "clear_map.h" +#include "company_func.h" +#include "company_base.h" +#include "gui.h" +#include "window_gui.h" +#include "window_func.h" +#include "layer_func.h" +#include "viewport_func.h" +#include "command_func.h" +#include "signs_func.h" +#include "sound_func.h" +#include "base_station_base.h" +#include "textbuf_gui.h" +#include "genworld.h" +#include "tree_map.h" +#include "landscape_type.h" +#include "tilehighlight_func.h" +#include "strings_func.h" +#include "newgrf_object.h" +#include "newgrf_station.h" +#include "object.h" +#include "hotkeys.h" +#include "engine_base.h" + +#include "widgets/underground_widget.h" + +#include "table/strings.h" +#include "error.h" + +void ShowError(TileIndex tile, CommandCost res, uint32 cmd) +{ + int x = TileX(tile) * TILE_SIZE; + int y = TileY(tile) * TILE_SIZE; + StringID error_part1 = GB(cmd, 16, 16); + + if (IsLocalCompany() && error_part1 != 0) { + ShowErrorMessage(error_part1, res.GetErrorMessage(), WL_INFO, x, y, res.GetTextRefStackGRF(), res.GetTextRefStackSize(), res.GetTextRefStack()); + } +} + + +/** + * Place a escalator. + * @param tile Position to place or start dragging a station. + */ +static void PlaceUnderground_Escalator(TileIndex tile) +{ + RailType railtype = RAILTYPE_RAIL; + Axis orientation = AXIS_X; + StationClassID station_class = STAT_CLASS_DFLT; + byte station_type = 0; + + uint32 p1 = railtype | orientation << 4 | 1 << 8 | 1 << 16 | _ctrl_pressed << 24; + uint32 p2 = station_class | station_type << 8 | INVALID_STATION << 16; + + int w = 1; + int h = 1; + + uint top_tile = TopTile(tile); + uint base_tile = tile; + bool from_top = false; // Ñòðîèì îò âåðõíåãî ñëîÿ + + if (top_tile == base_tile) + { + from_top = true; + base_tile += LayerSize(); + }; + + uint32 cmdS = CMD_BUILD_RAIL_STATION | CMD_MSG(STR_ERROR_UNDERGROUND_CAN_T_BUILD_PART); + uint32 cmdT = CMD_BUILD_RAIL_STATION | CMD_MSG(STR_ERROR_UNDERGROUND_CAN_T_BUILD_TOP_PART); + uint32 cmdB = CMD_BUILD_RAIL_STATION | CMD_MSG(STR_ERROR_UNDERGROUND_CAN_T_BUILD_BOTTOM_PART); + CommandContainer cmdTop = { top_tile, p1, p2, cmdT, CcStation, "" }; + CommandContainer cmdBase = { base_tile, p1, p2, cmdB, CcStation, "" }; + + DoCommandFlag flags = DC_AUTO | DC_NO_WATER; + CommandCost resTop; + CommandCost res; + + // Ïðîâåðÿåì âîçìîæíîñòü ïîñòðîéêè âåðõà è íèçà: + resTop=DoCommand(&cmdTop, flags | DC_QUERY_COST); + if (resTop.Failed()) + { + ShowError(tile, resTop, cmdT); + return; + } + + res=DoCommand(&cmdBase, flags | DC_QUERY_COST); + if (res.Failed()) + { + ShowError(tile, res, cmdB); + return; + } + + res.AddCost(resTop.GetCost()); + if (_shift_pressed || !CheckCompanyHasMoney(res)) + { + if (res.Failed()) ShowError(tile, res, cmdS); + else ShowEstimatedCostOrIncome(res.GetCost(), TileX(tile) * TILE_SIZE, TileY(tile) * TILE_SIZE); + return; + } + + // Ñòàíöèè ìîãóò áûòü ñâåðõó è ñíèçó. + // ×òîáû íå áûëî êîíôëèêòà, íóæíî ñòðîèòü îò àêòèâíîãî ñëîÿ + CommandContainer *cmd1 = from_top ? &cmdTop : &cmdBase; + CommandContainer *cmd2 = from_top ? &cmdBase : &cmdTop; + + // Ñòðîèì óðîâåíü (â àêòèâíîì ñëîå) + res=DoCommand(cmd1, flags | DC_EXEC); + assert(!res.Failed()); + + // Óòî÷íÿåì ïàðàìåòðû + StationID station = GetStationIndex(cmd1->tile); + cmd2->p2 = station_class | station_type << 8 | station << 16; + + // Ñòðîèì óðîâåíü (â äðóãîì ñëîå) + res=DoCommand(cmd2, flags | DC_EXEC); + assert(!res.Failed()); +} + +/** Underground toolbar managing class. */ +struct UndergroundToolbarWindow : Window { + int last_user_action; ///< Last started user action. + + UndergroundToolbarWindow(WindowDesc *desc, WindowNumber window_number) : Window(desc) + { + /* This is needed as we like to have the tree available on OnInit. */ + this->CreateNestedTree(desc); + this->FinishInitNested(window_number); + this->last_user_action = WIDGET_LIST_END; + } + + ~UndergroundToolbarWindow() + { + } + + virtual void OnInit() + { + } + + virtual void OnClick(Point pt, int widget, int click_count) + { + switch (widget) { + case WID_UT_BUILD_ESCALATOR: // WID_TT_BUILD_ESCALATOR + HandlePlacePushButton(this, WID_UT_BUILD_ESCALATOR, SPR_CURSOR_RAIL_STATION, HT_RECT); + this->last_user_action = widget; + break; + + case WID_UT_DEMOLISH: // Demolish aka dynamite button + HandlePlacePushButton(this, WID_UT_DEMOLISH, ANIMCURSOR_DEMOLISH, HT_RECT | HT_DIAGONAL); + this->last_user_action = widget; + break; + + default: NOT_REACHED(); + } + } + + virtual void OnTimeout() + { + } + + virtual void OnPlaceObject(Point pt, TileIndex tile) + { + switch (this->last_user_action) { + case WID_UT_BUILD_ESCALATOR: + PlaceUnderground_Escalator(tile); + break; + + case WID_UT_DEMOLISH: // Demolish aka dynamite button + PlaceProc_DemolishArea(tile); + break; + + default: NOT_REACHED(); + } + } + + virtual void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt) + { + VpSelectTilesWithMethod(pt.x, pt.y, select_method); + } + + virtual Point OnInitialPosition(const WindowDesc *desc, int16 sm_width, int16 sm_height, int window_number) + { + Point pt = GetToolbarAlignedWindowPosition(sm_width); + pt.y += sm_height; + return pt; + } + + virtual void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile) + { + if (pt.x != -1) { + switch (select_proc) { + default: NOT_REACHED(); + case DDSP_DEMOLISH_AREA: + GUIPlaceProcDragXY(select_proc, start_tile, end_tile); + break; + } + } + } + + virtual void OnPlaceObjectAbort() + { + DeleteWindowById(WC_BUILD_OBJECT, 0); + this->RaiseButtons(); + } + + static HotkeyList hotkeys; +}; + +/** + * Handler for global hotkeys of the UndergroundToolbarWindow. + * @param hotkey Hotkey + * @return ES_HANDLED if hotkey was accepted. + */ +static EventState UndergroundToolbarGlobalHotkeys(int hotkey) +{ + if (_game_mode != GM_NORMAL) return ES_NOT_HANDLED; +/* TODO Window *w = ShowAIDebugWindow(INVALID_COMPANY); + if (w == NULL) return ES_NOT_HANDLED; + return w->OnHotkey(hotkey); */ +} + +EventState UndergroundToolbarGlobalHotkeys(uint16 key, uint16 keycode) +{ +/* int num = CheckHotkeyMatch(_underground_hotkeys, keycode, NULL, true); + if (num == -1) return ES_NOT_HANDLED; + Window *w = ShowUndergroundToolbar(NULL); TODO + if (w == NULL) return ES_NOT_HANDLED; + return w->OnKeyPress(key, keycode); +} + int num = CheckHotkeyMatch(underground_hotkeys, keycode, this); + if (num == -1) return ES_NOT_HANDLED; + this->OnClick(Point(), num, 1); + return ES_HANDLED; ++static EventState AIDebugGlobalHotkeys(int hotkey) ++{ ++ if (_game_mode != GM_NORMAL) return ES_NOT_HANDLED; ++ Window *w = ShowAIDebugWindow(INVALID_COMPANY); ++ if (w == NULL) return ES_NOT_HANDLED; ++ return w->OnHotkey(hotkey); ++} +-EventState AIDebugGlobalHotkeys(uint16 key, uint16 keycode) +-{ +- int num = CheckHotkeyMatch(_aidebug_hotkeys, keycode, NULL, true); +- if (num == -1) return ES_NOT_HANDLED; +- Window *w = ShowAIDebugWindow(INVALID_COMPANY); +- if (w == NULL) return ES_NOT_HANDLED; +- return w->OnKeyPress(key, keycode); +-} +- */ + return ES_NOT_HANDLED; +} + +static Hotkey underground_hotkeys[] = { + Hotkey('D' | WKC_GLOBAL_HOTKEY, "dynamite", WID_UT_DEMOLISH), + Hotkey('0', "placeescalator", WID_UT_BUILD_ESCALATOR), + HOTKEY_LIST_END +}; +HotkeyList UndergroundToolbarWindow::hotkeys("undergroundtoolbar", underground_hotkeys, UndergroundToolbarGlobalHotkeys); + +static const NWidgetPart _nested_underground_widgets[] = { + NWidget(NWID_HORIZONTAL), + NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN), + NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetDataTip(STR_UNDERGROUND_BUILD, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), + NWidget(WWT_STICKYBOX, COLOUR_DARK_GREEN), + EndContainer(), + NWidget(NWID_HORIZONTAL), + NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_UT_BUILD_ESCALATOR), + SetFill(0, 1), SetMinimalSize(42, 22), SetDataTip(SPR_IMG_RAIL_STATION, STR_UNDERGROUND_TOOLTIP_ESCALATOR), + NWidget(WWT_PANEL, COLOUR_DARK_GREEN), SetMinimalSize(64, 22), EndContainer(), + NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_UT_DEMOLISH), SetMinimalSize(22, 22), + SetFill(0, 1), SetDataTip(SPR_IMG_DYNAMITE, STR_TOOLTIP_DEMOLISH_BUILDINGS_ETC), + EndContainer(), +}; + +static WindowDesc _underground_desc( + WDP_MANUAL, "undergroundtoolbar", 0, 0, + WC_UNDERGROUND, WC_NONE, + WDF_CONSTRUCTION, + _nested_underground_widgets, lengthof(_nested_underground_widgets) +); + +/** + * Show the toolbar for terraforming in the game. + * @param link The toolbar we might want to link to. + * @return The allocated toolbar. + */ +Window *ShowUndergroundToolbar(Window *link) +{ + if (!Company::IsValidID(_local_company)) return NULL; + + Window *w; + if (link == NULL) { + w = AllocateWindowDescFront(&_underground_desc, 0); + return w; + } + + /* Delete the terraform toolbar to place it again. */ + DeleteWindowById(WC_UNDERGROUND, 0, true); + w = AllocateWindowDescFront(&_underground_desc, 0); + /* Align the terraform toolbar under the main toolbar. */ + w->top -= w->height; + w->SetDirty(); + /* Put the linked toolbar to the left / right of it. */ + link->left = w->left + (_current_text_dir == TD_RTL ? w->width : -link->width); + link->top = w->top; + link->SetDirty(); + + return w; +} diff --git a/src/underground_gui.h b/src/underground_gui.h new file mode 100644 index 0000000000..81b119545e --- /dev/null +++ b/src/underground_gui.h @@ -0,0 +1,19 @@ +/* $Id: underground_gui.h 21608 2012-09-08 1:13:14 constructor $ */ + +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file underground_gui.h GUI stuff related to terraforming. */ + +#ifndef UNDERGROUND_GUI_H +#define UNDERGROUND_GUI_H + +#include "window_type.h" + +Window *ShowUndergroundToolbar(Window *link = NULL); + +#endif /* UNDERGROUND_GUI_H */ diff --git a/src/vehicle.cpp b/src/vehicle.cpp index 3bec190804..87005d6099 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -13,6 +13,7 @@ #include "ship.h" #include "spritecache.h" #include "timetable.h" +#include "layer_func.h" #include "viewport_func.h" #include "news_func.h" #include "command_func.h" @@ -1143,6 +1144,7 @@ void ViewportAddVehicles(DrawPixelInfo *dpi) while (v != nullptr) { + if (LayerIndex(v->tile) == dpi->layer) if (!(v->vehstatus & VS_HIDDEN) && l <= v->coord.right + xb && t <= v->coord.bottom + yb && diff --git a/src/viewport.cpp b/src/viewport.cpp index 2a3f9b32de..2868e41c5f 100644 --- a/src/viewport.cpp +++ b/src/viewport.cpp @@ -62,6 +62,8 @@ #include "stdafx.h" #include "landscape.h" +#include "layer_gui.h" +#include "layer_func.h" #include "viewport_func.h" #include "station_base.h" #include "waypoint_base.h" @@ -1241,24 +1243,27 @@ static void ViewportAddLandscape() int min_visible_height = viewport_y - (_vd.dpi.top + _vd.dpi.height); bool tile_visible = min_visible_height <= 0; - if (tile_type != MP_VOID) { - /* Is tile with buildings visible? */ - if (min_visible_height < MAX_TILE_EXTENT_TOP) tile_visible = true; - - if (IsBridgeAbove(tile_info.tile)) { - /* Is the bridge visible? */ - TileIndex bridge_tile = GetNorthernBridgeEnd(tile_info.tile); - int bridge_height = ZOOM_LVL_BASE * (GetBridgePixelHeight(bridge_tile) - TilePixelHeight(tile_info.tile)); - if (min_visible_height < bridge_height + MAX_TILE_EXTENT_TOP) tile_visible = true; - } + /* Âàëèäíû òîëüêî êëåòêè òåêóùåãî ñëîÿ */ + if (LayerIndex(tile_info.tile) == _vd.dpi.layer) { + if (tile_type != MP_VOID) { + /* Is tile with buildings visible? */ + if (min_visible_height < MAX_TILE_EXTENT_TOP) tile_visible = true; + + if (IsBridgeAbove(tile_info.tile)) { + /* Is the bridge visible? */ + TileIndex bridge_tile = GetNorthernBridgeEnd(tile_info.tile); + int bridge_height = ZOOM_LVL_BASE * (GetBridgePixelHeight(bridge_tile) - TilePixelHeight(tile_info.tile)); + if (min_visible_height < bridge_height + MAX_TILE_EXTENT_TOP) tile_visible = true; + } - /* Would a higher bridge on a more southern tile be visible? - * If yes, we need to loop over more rows to possibly find one. */ - if (min_visible_height < potential_bridge_height + MAX_TILE_EXTENT_TOP) last_row = false; - } else { - /* Outside of map. If we are on the north border of the map, there may still be a bridge visible, - * so we need to loop over more rows to possibly find one. */ - if ((tilecoord.x <= 0 || tilecoord.y <= 0) && min_visible_height < potential_bridge_height + MAX_TILE_EXTENT_TOP) last_row = false; + /* Would a higher bridge on a more southern tile be visible? + * If yes, we need to loop over more rows to possibly find one. */ + if (min_visible_height < potential_bridge_height + MAX_TILE_EXTENT_TOP) last_row = false; + } else { + /* Outside of map. If we are on the north border of the map, there may still be a bridge visible, + * so we need to loop over more rows to possibly find one. */ + if ((tilecoord.x <= 0 || tilecoord.y <= 0) && min_visible_height < potential_bridge_height + MAX_TILE_EXTENT_TOP) last_row = false; + } } if (tile_visible) { @@ -1733,6 +1738,9 @@ void ViewportDoDraw(const Viewport *vp, int left, int top, int right, int bottom _vd.dpi.dst_ptr = BlitterFactory::GetCurrentBlitter()->MoveTo(old_dpi->dst_ptr, x - old_dpi->left, y - old_dpi->top); + /* Îïðåäåëåíèå ñëîÿ (êîòîðûé áóäåì ðèñîâàòü) */ + _vd.dpi.layer = calculateLayer(vp); + ViewportAddLandscape(); ViewportAddVehicles(&_vd.dpi); diff --git a/src/viewport_func.h b/src/viewport_func.h index 9461f3df5e..beeb29aaf0 100644 --- a/src/viewport_func.h +++ b/src/viewport_func.h @@ -31,6 +31,7 @@ bool MarkAllViewportsDirty(int left, int top, int right, int bottom); bool DoZoomInOutWindow(ZoomStateChange how, Window *w); void ZoomInOrOutToCursorWindow(bool in, Window * w); +void LayerUpOrDownToCursorWindow(bool in, Window * w); Point GetTileZoomCenterWindow(bool in, Window * w); void FixTitleGameZoom(); void HandleZoomMessage(Window *w, const Viewport *vp, byte widget_zoom_in, byte widget_zoom_out); diff --git a/src/viewport_gui.cpp b/src/viewport_gui.cpp index 5047f04f3f..3c02f9ab8b 100644 --- a/src/viewport_gui.cpp +++ b/src/viewport_gui.cpp @@ -14,6 +14,7 @@ #include "strings_func.h" #include "zoom_func.h" #include "window_func.h" +#include "gfx_func.h" #include "widgets/viewport_widget.h" @@ -137,7 +138,11 @@ public: void OnMouseWheel(int wheel) override { if (_settings_client.gui.scrollwheel_scrolling != 2) { - ZoomInOrOutToCursorWindow(wheel < 0, this); + if (_ctrl_pressed) { + LayerUpOrDownToCursorWindow(wheel < 0, this); + } else { + ZoomInOrOutToCursorWindow(wheel < 0, this); + } } } diff --git a/src/water_cmd.cpp b/src/water_cmd.cpp index 6a3b730657..02a4d45156 100644 --- a/src/water_cmd.cpp +++ b/src/water_cmd.cpp @@ -10,6 +10,7 @@ #include "stdafx.h" #include "cmd_helper.h" #include "landscape.h" +#include "layer_func.h" #include "viewport_func.h" #include "command_func.h" #include "town.h" @@ -466,6 +467,11 @@ CommandCost CmdBuildCanal(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 /* can't make water of water! */ if (IsTileType(tile, MP_WATER) && (!IsTileOwner(tile, OWNER_WATER) || wc == WATER_CLASS_SEA)) continue; + /* can't make underground water */ + if (IsUnderground(tile)) { + return_cmd_error(STR_ERROR_UNDERGROUND_CAN_T_BUILD_UNDER_GROUND); + } + bool water = IsWaterTile(tile); ret = DoCommand(tile, 0, 0, flags | DC_FORCE_CLEAR_TILE, CMD_LANDSCAPE_CLEAR); if (ret.Failed()) return ret; @@ -1097,6 +1103,9 @@ void DoFloodTile(TileIndex target) { assert(!IsTileType(target, MP_WATER)); + /* Ïîäçåìíàÿ ÷àñòü êàðòû íå çàëèâàåòñÿ */ + if (IsUnderground(target)) return; + bool flooded = false; // Will be set to true if something is changed. Backup cur_company(_current_company, OWNER_WATER, FILE_LINE); @@ -1256,7 +1265,7 @@ void ConvertGroundTilesIntoWaterTiles() for (TileIndex tile = 0; tile < MapSize(); ++tile) { Slope slope = GetTileSlope(tile, &z); - if (IsTileType(tile, MP_CLEAR) && z == 0) { + if (IsTileType(tile, MP_CLEAR) && z == 0 && !IsUnderground(tile)) { /* Make both water for tiles at level 0 * and make shore, as that looks much better * during the generation. */ diff --git a/src/widgets/CMakeLists.txt b/src/widgets/CMakeLists.txt index 18ecd529e8..509adda581 100644 --- a/src/widgets/CMakeLists.txt +++ b/src/widgets/CMakeLists.txt @@ -55,6 +55,7 @@ add_files( town_widget.h transparency_widget.h tree_widget.h + underground_widget.h vehicle_widget.h viewport_widget.h waypoint_widget.h diff --git a/src/widgets/genworld_widget.h b/src/widgets/genworld_widget.h index 11226b5fa1..0a90bdfbcf 100644 --- a/src/widgets/genworld_widget.h +++ b/src/widgets/genworld_widget.h @@ -19,6 +19,7 @@ enum GenerateLandscapeWidgets { WID_GL_MAPSIZE_X_PULLDOWN, ///< Dropdown 'map X size'. WID_GL_MAPSIZE_Y_PULLDOWN, ///< Dropdown 'map Y size'. + WID_GL_LAYER_COUNT_PULLDOWN, ///< Dropdown 'map layer count'. WID_GL_TOWN_PULLDOWN, ///< Dropdown 'No. of towns'. WID_GL_TOWNNAME_DROPDOWN, ///< Dropdown 'Townnames'. @@ -67,6 +68,7 @@ enum CreateScenarioWidgets { WID_CS_RANDOM_WORLD, ///< Generate random land button WID_CS_MAPSIZE_X_PULLDOWN, ///< Pull-down arrow for x map size. WID_CS_MAPSIZE_Y_PULLDOWN, ///< Pull-down arrow for y map size. + WID_CS_LAYER_COUNT_PULLDOWN, ///< Pull-down arrow for map layer count. WID_CS_START_DATE_DOWN, ///< Decrease start year (start earlier). WID_CS_START_DATE_TEXT, ///< Clickable start date value. WID_CS_START_DATE_UP, ///< Increase start year (start later). diff --git a/src/widgets/toolbar_widget.h b/src/widgets/toolbar_widget.h index d68de49700..0b4e53227f 100644 --- a/src/widgets/toolbar_widget.h +++ b/src/widgets/toolbar_widget.h @@ -41,6 +41,7 @@ enum ToolbarNormalWidgets { WID_TN_WATER, ///< Water building toolbar. WID_TN_AIR, ///< Airport building toolbar. WID_TN_LANDSCAPE, ///< Landscaping toolbar. + WID_TN_UNDERGROUND, ///< Landscaping toolbar. WID_TN_MUSIC_SOUND, ///< Music/sound configuration menu. WID_TN_MESSAGES, ///< Messages menu. WID_TN_HELP, ///< Help menu. diff --git a/src/widgets/underground_widget.h b/src/widgets/underground_widget.h new file mode 100644 index 0000000000..522c9db8bf --- /dev/null +++ b/src/widgets/underground_widget.h @@ -0,0 +1,21 @@ +/* $Id: terraform_widget.h 23600 2011-12-19 20:46:17Z truebrain $ */ + +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file terraform_widget.h Types related to the terraform widgets. */ + +#ifndef WIDGETS_UNDERGROUND_WIDGET_H +#define WIDGETS_UNDERGROUND_WIDGET_H + +/** Widgets of the #TerraformToolbarWindow class. */ +enum UndergroundToolbarWidgets { + WID_UT_BUILD_ESCALATOR, ///< Build escalator + WID_UT_DEMOLISH, ///< Demolish aka dynamite button. +}; + +#endif /* WIDGETS_UNDERGROUND_WIDGET_H */ diff --git a/src/window_type.h b/src/window_type.h index 86dcc6fb33..02533dd030 100644 --- a/src/window_type.h +++ b/src/window_type.h @@ -441,6 +441,12 @@ enum WindowClass { */ WC_SCEN_LAND_GEN, + /** + * Underground (in game); %Window numbers: + * - 0 = #UndergroundToolbarWidgets + */ + WC_UNDERGROUND, + /** * Generate landscape (newgame); %Window numbers: * - GLWM_SCENARIO = #CreateScenarioWidgets