Mercurial > hg > openttd
changeset 8360:bf5f533a604f draft
(svn r11926) -Feature: Rivers. Graphics must be provided by NewGRF else rivers are drawn as canals. Rivers can currently only be placed with-in the scenario editor.
author | peter1138 <peter1138@openttd.org> |
---|---|
date | Sat, 19 Jan 2008 17:00:54 +0000 |
parents | 59a8ddb2ed88 |
children | e3b4302ca836 |
files | src/gui.h src/lang/english.txt src/newgrf_canal.h src/terraform_gui.cpp src/tunnelbridge_cmd.cpp src/water_cmd.cpp src/water_map.h |
diffstat | 7 files changed, 130 insertions(+), 48 deletions(-) [+] |
line wrap: on
line diff
--- a/src/gui.h +++ b/src/gui.h @@ -60,6 +60,7 @@ DDSP_CREATE_DESERT, DDSP_CREATE_ROCKS, DDSP_CREATE_WATER, + DDSP_CREATE_RIVER, DDSP_PLANT_TREES, DDSP_BUILD_BRIDGE,
--- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -726,6 +726,7 @@ STR_028E_PLACE_TRANSMITTER :{BLACK}Place transmitter STR_028F_DEFINE_DESERT_AREA :{BLACK}Define desert area.{}Press and hold CTRL to remove it STR_CREATE_LAKE :{BLACK}Define water area.{}Make a canal, unless CTRL is held down at sea level, when it will flood the surroundings instead +STR_CREATE_RIVER :{BLACK}Place rivers. STR_0290_DELETE :{BLACK}Delete STR_0291_DELETE_THIS_TOWN_COMPLETELY :{BLACK}Delete this town completely STR_0292_SAVE_SCENARIO :Save scenario
--- a/src/newgrf_canal.h +++ b/src/newgrf_canal.h @@ -11,6 +11,8 @@ CF_DIKES, CF_ICON, CF_DOCKS, + CF_RIVER_SLOPE, + CF_RIVER_EDGE, CF_END, };
--- a/src/terraform_gui.cpp +++ b/src/terraform_gui.cpp @@ -132,6 +132,9 @@ case DDSP_CREATE_WATER: DoCommandP(end_tile, start_tile, _ctrl_pressed, CcBuildCanal, CMD_BUILD_CANAL | CMD_MSG(STR_CANT_BUILD_CANALS)); break; + case DDSP_CREATE_RIVER: + DoCommandP(end_tile, start_tile, 2, CcBuildCanal, CMD_BUILD_CANAL | CMD_MSG(STR_CANT_BUILD_CANALS)); + break; default: return false; } @@ -412,23 +415,29 @@ VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_CREATE_WATER); } +static void PlaceProc_RiverArea(TileIndex tile) +{ + VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_CREATE_RIVER); +} + static const Widget _scen_edit_land_gen_widgets[] = { { WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, -{ WWT_CAPTION, RESIZE_NONE, 7, 11, 169, 0, 13, STR_0223_LAND_GENERATION, STR_018C_WINDOW_TITLE_DRAG_THIS}, -{ WWT_STICKYBOX, RESIZE_NONE, 7, 170, 181, 0, 13, STR_NULL, STR_STICKY_BUTTON}, -{ WWT_PANEL, RESIZE_NONE, 7, 0, 181, 14, 102, 0x0, STR_NULL}, +{ WWT_CAPTION, RESIZE_NONE, 7, 11, 191, 0, 13, STR_0223_LAND_GENERATION, STR_018C_WINDOW_TITLE_DRAG_THIS}, +{ WWT_STICKYBOX, RESIZE_NONE, 7, 192, 203, 0, 13, STR_NULL, STR_STICKY_BUTTON}, +{ WWT_PANEL, RESIZE_NONE, 7, 0, 203, 14, 102, 0x0, STR_NULL}, { WWT_IMGBTN, RESIZE_NONE, 14, 2, 23, 16, 37, SPR_IMG_DYNAMITE, STR_018D_DEMOLISH_BUILDINGS_ETC}, { WWT_IMGBTN, RESIZE_NONE, 14, 24, 45, 16, 37, SPR_IMG_TERRAFORM_DOWN, STR_018E_LOWER_A_CORNER_OF_LAND}, { WWT_IMGBTN, RESIZE_NONE, 14, 46, 67, 16, 37, SPR_IMG_TERRAFORM_UP, STR_018F_RAISE_A_CORNER_OF_LAND}, { WWT_IMGBTN, RESIZE_NONE, 14, 68, 89, 16, 37, SPR_IMG_LEVEL_LAND, STR_LEVEL_LAND_TOOLTIP}, { WWT_IMGBTN, RESIZE_NONE, 14, 90, 111, 16, 37, SPR_IMG_BUILD_CANAL, STR_CREATE_LAKE}, -{ WWT_IMGBTN, RESIZE_NONE, 14, 112, 134, 16, 37, SPR_IMG_ROCKS, STR_028C_PLACE_ROCKY_AREAS_ON_LANDSCAPE}, -{ WWT_IMGBTN, RESIZE_NONE, 14, 135, 157, 16, 37, SPR_IMG_LIGHTHOUSE_DESERT, STR_NULL}, // XXX - dynamic -{ WWT_IMGBTN, RESIZE_NONE, 14, 158, 179, 16, 37, SPR_IMG_TRANSMITTER, STR_028E_PLACE_TRANSMITTER}, -{ WWT_IMGBTN, RESIZE_NONE, 14, 139, 150, 45, 56, SPR_ARROW_UP, STR_0228_INCREASE_SIZE_OF_LAND_AREA}, -{ WWT_IMGBTN, RESIZE_NONE, 14, 139, 150, 58, 69, SPR_ARROW_DOWN, STR_0229_DECREASE_SIZE_OF_LAND_AREA}, -{ WWT_TEXTBTN, RESIZE_NONE, 14, 24, 157, 76, 87, STR_SE_NEW_WORLD, STR_022A_GENERATE_RANDOM_LAND}, -{ WWT_TEXTBTN, RESIZE_NONE, 14, 24, 157, 89, 100, STR_022B_RESET_LANDSCAPE, STR_RESET_LANDSCAPE_TOOLTIP}, +{ WWT_IMGBTN, RESIZE_NONE, 14, 112, 133, 16, 37, SPR_IMG_BUILD_CANAL, STR_CREATE_RIVER}, +{ WWT_IMGBTN, RESIZE_NONE, 14, 134, 156, 16, 37, SPR_IMG_ROCKS, STR_028C_PLACE_ROCKY_AREAS_ON_LANDSCAPE}, +{ WWT_IMGBTN, RESIZE_NONE, 14, 157, 179, 16, 37, SPR_IMG_LIGHTHOUSE_DESERT, STR_NULL}, // XXX - dynamic +{ WWT_IMGBTN, RESIZE_NONE, 14, 180, 201, 16, 37, SPR_IMG_TRANSMITTER, STR_028E_PLACE_TRANSMITTER}, +{ WWT_IMGBTN, RESIZE_NONE, 14, 150, 161, 45, 56, SPR_ARROW_UP, STR_0228_INCREASE_SIZE_OF_LAND_AREA}, +{ WWT_IMGBTN, RESIZE_NONE, 14, 150, 161, 58, 69, SPR_ARROW_DOWN, STR_0229_DECREASE_SIZE_OF_LAND_AREA}, +{ WWT_TEXTBTN, RESIZE_NONE, 14, 24, 179, 76, 87, STR_SE_NEW_WORLD, STR_022A_GENERATE_RANDOM_LAND}, +{ WWT_TEXTBTN, RESIZE_NONE, 14, 24, 179, 89, 100, STR_022B_RESET_LANDSCAPE, STR_RESET_LANDSCAPE_TOOLTIP}, { WIDGETS_END}, }; @@ -472,19 +481,24 @@ HandlePlacePushButton(w, 8, SPR_CURSOR_CANAL, VHM_RECT, PlaceProc_WaterArea); } +static void EditorTerraformClick_RiverArea(Window *w) +{ + HandlePlacePushButton(w, 9, SPR_CURSOR_CANAL, VHM_RECT, PlaceProc_RiverArea); +} + static void EditorTerraformClick_RockyArea(Window *w) { - HandlePlacePushButton(w, 9, SPR_CURSOR_ROCKY_AREA, VHM_RECT, PlaceProc_RockyArea); + HandlePlacePushButton(w, 10, SPR_CURSOR_ROCKY_AREA, VHM_RECT, PlaceProc_RockyArea); } static void EditorTerraformClick_DesertLightHouse(Window *w) { - HandlePlacePushButton(w, 10, SPR_CURSOR_LIGHTHOUSE, VHM_RECT, (_opt.landscape == LT_TROPIC) ? PlaceProc_DesertArea : PlaceProc_LightHouse); + HandlePlacePushButton(w, 11, SPR_CURSOR_LIGHTHOUSE, VHM_RECT, (_opt.landscape == LT_TROPIC) ? PlaceProc_DesertArea : PlaceProc_LightHouse); } static void EditorTerraformClick_Transmitter(Window *w) { - HandlePlacePushButton(w, 11, SPR_CURSOR_TRANSMITTER, VHM_RECT, PlaceProc_Transmitter); + HandlePlacePushButton(w, 12, SPR_CURSOR_TRANSMITTER, VHM_RECT, PlaceProc_Transmitter); } static const uint16 _editor_terraform_keycodes[] = { @@ -495,7 +509,8 @@ 'R', 'T', 'Y', - 'U' + 'U', + 'I' }; typedef void OnButtonClick(Window *w); @@ -505,6 +520,7 @@ EditorTerraformClick_RaiseBigLand, EditorTerraformClick_LevelLand, EditorTerraformClick_WaterArea, + EditorTerraformClick_RiverArea, EditorTerraformClick_RockyArea, EditorTerraformClick_DesertLightHouse, EditorTerraformClick_Transmitter @@ -543,8 +559,8 @@ { switch (e->event) { case WE_CREATE: - /* XXX - lighthouse button is widget 10!! Don't forget when changing */ - w->widget[10].tooltips = (_opt.landscape == LT_TROPIC) ? STR_028F_DEFINE_DESERT_AREA : STR_028D_PLACE_LIGHTHOUSE; + /* XXX - lighthouse button is widget 11!! Don't forget when changing */ + w->widget[11].tooltips = (_opt.landscape == LT_TROPIC) ? STR_028F_DEFINE_DESERT_AREA : STR_028D_PLACE_LIGHTHOUSE; break; case WE_PAINT: { @@ -555,7 +571,7 @@ assert(n != 0); do { - DrawSprite(SPR_WHITE_POINT, PAL_NONE, 77 + coords[0], 55 + coords[1]); + DrawSprite(SPR_WHITE_POINT, PAL_NONE, 88 + coords[0], 55 + coords[1]); coords += 2; } while (--n); @@ -576,11 +592,11 @@ case WE_CLICK: switch (e->we.click.widget) { - case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: + case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: case 12: _editor_terraform_button_proc[e->we.click.widget - 4](w); break; - case 12: case 13: { // Increase/Decrease terraform size - int size = (e->we.click.widget == 12) ? 1 : -1; + case 13: case 14: { // Increase/Decrease terraform size + int size = (e->we.click.widget == 13) ? 1 : -1; w->HandleButtonClick(e->we.click.widget); size += _terraform_size; @@ -590,11 +606,11 @@ SndPlayFx(SND_15_BEEP); SetWindowDirty(w); } break; - case 14: // gen random land - w->HandleButtonClick(14); + case 15: // gen random land + w->HandleButtonClick(15); ShowCreateScenario(); break; - case 15: // Reset landscape + case 16: // Reset landscape ShowQuery( STR_022C_RESET_LANDSCAPE, STR_RESET_LANDSCAPE_CONFIRMATION_TEXT, @@ -610,7 +626,7 @@ w->RaiseWidget(i); w->InvalidateWidget(i); } - if (i == 3) i = 11; + if (i == 3) i = 12; } break; @@ -628,6 +644,7 @@ case DDSP_CREATE_ROCKS: case DDSP_CREATE_DESERT: case DDSP_CREATE_WATER: + case DDSP_CREATE_RIVER: case DDSP_RAISE_AND_LEVEL_AREA: case DDSP_LOWER_AND_LEVEL_AREA: case DDSP_LEVEL_AREA: @@ -646,7 +663,7 @@ } static const WindowDesc _scen_edit_land_gen_desc = { - WDP_AUTO, WDP_AUTO, 182, 103, 182, 103, + WDP_AUTO, WDP_AUTO, 204, 103, 204, 103, WC_SCEN_LAND_GEN, WC_NONE, WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_STICKY_BUTTON, _scen_edit_land_gen_widgets,
--- a/src/tunnelbridge_cmd.cpp +++ b/src/tunnelbridge_cmd.cpp @@ -376,7 +376,7 @@ switch (GetTileType(tile)) { case MP_WATER: if (!EnsureNoVehicleOnGround(tile)) return_cmd_error(STR_980E_SHIP_IN_THE_WAY); - if (!IsWater(tile) && !IsCoast(tile)) goto not_valid_below; + if (!IsWater(tile) && !IsCoast(tile) && !IsRiver(tile)) goto not_valid_below; break; case MP_RAILWAY:
--- a/src/water_cmd.cpp +++ b/src/water_cmd.cpp @@ -269,8 +269,9 @@ int sx, sy; if (p1 >= MapSize()) return CMD_ERROR; + /* Outside of the editor you can only build canals, not oceans */ - if (HasBit(p2, 0) && _game_mode != GM_EDITOR) return CMD_ERROR; + if (p2 == 0 && _game_mode != GM_EDITOR) return CMD_ERROR; x = TileX(tile); y = TileY(tile); @@ -288,20 +289,23 @@ BEGIN_TILE_LOOP(tile, size_x, size_y, TileXY(sx, sy)) { CommandCost ret; - if (GetTileSlope(tile, NULL) != SLOPE_FLAT) { + Slope slope = GetTileSlope(tile, NULL); + if (slope != SLOPE_FLAT && (p2 != 2 || (slope != SLOPE_NW && slope != SLOPE_NE && slope != SLOPE_SW && slope != SLOPE_SE))) { return_cmd_error(STR_0007_FLAT_LAND_REQUIRED); } /* can't make water of water! */ - if (IsTileType(tile, MP_WATER) && (!IsTileOwner(tile, OWNER_WATER) || HasBit(p2, 0))) continue; + if (IsTileType(tile, MP_WATER) && (!IsTileOwner(tile, OWNER_WATER) || p2 == 1)) continue; ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); if (CmdFailed(ret)) return ret; cost.AddCost(ret); if (flags & DC_EXEC) { - if (TileHeight(tile) == 0 && HasBit(p2, 0)) { + if (TileHeight(tile) == 0 && p2 == 1) { MakeWater(tile); + } else if (p2 == 2) { + MakeRiver(tile); } else { MakeCanal(tile, _current_player); } @@ -323,6 +327,7 @@ { switch (GetWaterTileType(tile)) { case WATER_TILE_CLEAR: + case WATER_TILE_RIVER: if (flags & DC_NO_WATER) return_cmd_error(STR_3807_CAN_T_BUILD_ON_WATER); /* Make sure it's not an edge tile. */ @@ -400,51 +405,56 @@ } } -/** draw a canal styled water tile with dikes around */ -void DrawCanalWater(TileIndex tile) +static void DrawWaterEdges(SpriteID base, TileIndex tile) { uint wa; - /* Test for custom graphics, else use the default */ - SpriteID dikes_base = GetCanalSprite(CF_DIKES, tile); - if (dikes_base == 0) dikes_base = SPR_CANAL_DIKES_BASE; - /* determine the edges around with water. */ wa = IsWateredTile(TILE_ADDXY(tile, -1, 0)) << 0; wa += IsWateredTile(TILE_ADDXY(tile, 0, 1)) << 1; wa += IsWateredTile(TILE_ADDXY(tile, 1, 0)) << 2; wa += IsWateredTile(TILE_ADDXY(tile, 0, -1)) << 3; - if (!(wa & 1)) DrawGroundSprite(dikes_base, PAL_NONE); - if (!(wa & 2)) DrawGroundSprite(dikes_base + 1, PAL_NONE); - if (!(wa & 4)) DrawGroundSprite(dikes_base + 2, PAL_NONE); - if (!(wa & 8)) DrawGroundSprite(dikes_base + 3, PAL_NONE); + if (!(wa & 1)) DrawGroundSprite(base, PAL_NONE); + if (!(wa & 2)) DrawGroundSprite(base + 1, PAL_NONE); + if (!(wa & 4)) DrawGroundSprite(base + 2, PAL_NONE); + if (!(wa & 8)) DrawGroundSprite(base + 3, PAL_NONE); /* right corner */ switch (wa & 0x03) { - case 0: DrawGroundSprite(dikes_base + 4, PAL_NONE); break; - case 3: if (!IsWateredTile(TILE_ADDXY(tile, -1, 1))) DrawGroundSprite(dikes_base + 8, PAL_NONE); break; + case 0: DrawGroundSprite(base + 4, PAL_NONE); break; + case 3: if (!IsWateredTile(TILE_ADDXY(tile, -1, 1))) DrawGroundSprite(base + 8, PAL_NONE); break; } /* bottom corner */ switch (wa & 0x06) { - case 0: DrawGroundSprite(dikes_base + 5, PAL_NONE); break; - case 6: if (!IsWateredTile(TILE_ADDXY(tile, 1, 1))) DrawGroundSprite(dikes_base + 9, PAL_NONE); break; + case 0: DrawGroundSprite(base + 5, PAL_NONE); break; + case 6: if (!IsWateredTile(TILE_ADDXY(tile, 1, 1))) DrawGroundSprite(base + 9, PAL_NONE); break; } /* left corner */ switch (wa & 0x0C) { - case 0: DrawGroundSprite(dikes_base + 6, PAL_NONE); break; - case 12: if (!IsWateredTile(TILE_ADDXY(tile, 1, -1))) DrawGroundSprite(dikes_base + 10, PAL_NONE); break; + case 0: DrawGroundSprite(base + 6, PAL_NONE); break; + case 12: if (!IsWateredTile(TILE_ADDXY(tile, 1, -1))) DrawGroundSprite(base + 10, PAL_NONE); break; } /* upper corner */ switch (wa & 0x09) { - case 0: DrawGroundSprite(dikes_base + 7, PAL_NONE); break; - case 9: if (!IsWateredTile(TILE_ADDXY(tile, -1, -1))) DrawGroundSprite(dikes_base + 11, PAL_NONE); break; + case 0: DrawGroundSprite(base + 7, PAL_NONE); break; + case 9: if (!IsWateredTile(TILE_ADDXY(tile, -1, -1))) DrawGroundSprite(base + 11, PAL_NONE); break; } } +/** draw a canal styled water tile with dikes around */ +void DrawCanalWater(TileIndex tile) +{ + /* Test for custom graphics, else use the default */ + SpriteID dikes_base = GetCanalSprite(CF_DIKES, tile); + if (dikes_base == 0) dikes_base = SPR_CANAL_DIKES_BASE; + + DrawWaterEdges(dikes_base, tile); +} + struct LocksDrawTileStruct { int8 delta_x, delta_y, delta_z; byte width, height, depth; @@ -483,6 +493,33 @@ } } +static void DrawRiverWater(const TileInfo *ti) +{ + SpriteID image = SPR_FLAT_WATER_TILE; + SpriteID edges_base = GetCanalSprite(CF_RIVER_EDGE, ti->tile); + + if (ti->tileh != SLOPE_FLAT) { + image = GetCanalSprite(CF_RIVER_SLOPE, ti->tile); + if (image == 0) { + image = SPR_FLAT_WATER_TILE; + } else { + switch (ti->tileh) { + default: NOT_REACHED(); + case SLOPE_SE: edges_base += 12; break; + case SLOPE_NE: image += 1; edges_base += 24; break; + case SLOPE_SW: image += 2; edges_base += 36; break; + case SLOPE_NW: image += 3; edges_base += 48; break; + } + } + } + + DrawGroundSprite(image, PAL_NONE); + + /* Draw canal dikes if there are no river edges to draw. */ + if (edges_base <= 48) edges_base = SPR_CANAL_DIKES_BASE; + DrawWaterEdges(edges_base, ti->tile); +} + static void DrawTile_Water(TileInfo *ti) { switch (GetWaterTileType(ti->tile)) { @@ -513,6 +550,11 @@ case WATER_TILE_DEPOT: DrawWaterStuff(ti, _shipdepot_display_seq[GetSection(ti->tile)], PLAYER_SPRITE_COLOR(GetTileOwner(ti->tile)), 0); break; + + case WATER_TILE_RIVER: + DrawRiverWater(ti); + DrawBridgeMiddle(ti); + break; } } @@ -551,6 +593,7 @@ { switch (GetWaterTileType(tile)) { case WATER_TILE_CLEAR: + case WATER_TILE_RIVER: if (!IsCanal(tile)) { td->str = STR_3804_WATER; } else { @@ -848,6 +891,7 @@ case WATER_TILE_COAST: ts = (TrackBits)coast_tracks[GetTileSlope(tile, NULL) & 0xF]; break; case WATER_TILE_LOCK: ts = AxisToTrackBits(DiagDirToAxis(GetLockDirection(tile))); break; case WATER_TILE_DEPOT: ts = AxisToTrackBits(GetShipDepotAxis(tile)); break; + case WATER_TILE_RIVER: ts = (GetTileSlope(tile, NULL) == SLOPE_FLAT) ? TRACK_BIT_ALL : TRACK_BIT_NONE; break; default: return 0; } if (TileX(tile) == 0) {
--- a/src/water_map.h +++ b/src/water_map.h @@ -10,6 +10,7 @@ WATER_TILE_COAST, WATER_TILE_LOCK, WATER_TILE_DEPOT, + WATER_TILE_RIVER, }; enum DepotPart { @@ -31,6 +32,7 @@ if (_m[t].m5 == 0) return WATER_TILE_CLEAR; if (_m[t].m5 == 1) return WATER_TILE_COAST; + if (_m[t].m5 == 2) return WATER_TILE_RIVER; if (IsInsideMM(_m[t].m5, LOCK_MIDDLE, LOCK_END)) return WATER_TILE_LOCK; assert(IsInsideMM(_m[t].m5, DEPOT_NORTH, DEPOT_END)); @@ -60,6 +62,11 @@ return GetWaterTileType(t) == WATER_TILE_CLEAR && GetTileOwner(t) != OWNER_WATER; } +static inline bool IsRiver(TileIndex t) +{ + return GetWaterTileType(t) == WATER_TILE_RIVER; +} + static inline bool IsWaterTile(TileIndex t) { return IsTileType(t, MP_WATER) && IsWater(t); @@ -122,6 +129,16 @@ _m[t].m5 = 1; } +static inline void MakeRiver(TileIndex t) +{ + SetTileType(t, MP_WATER); + SetTileOwner(t, OWNER_WATER); + _m[t].m2 = 0; + _m[t].m3 = 0; + _m[t].m4 = 0; + _m[t].m5 = 2; +} + static inline void MakeCanal(TileIndex t, Owner o) { assert(o != OWNER_WATER);