# terraform_gui.cpp

Go to the documentation of this file.

    00001 /* $Id: terraform_gui.cpp 13689 2008-07-09 19:30:44Z rubidium $ */
    00002
    00005 #include "stdafx.h"
    00006 #include "openttd.h"
    00007 #include "bridge_map.h"
    00008 #include "clear_map.h"
    00009 #include "player_func.h"
    00010 #include "player_base.h"
    00011 #include "gui.h"
    00012 #include "window_gui.h"
    00013 #include "viewport_func.h"
    00014 #include "gfx_func.h"
    00015 #include "command_func.h"
    00016 #include "signs.h"
    00017 #include "variables.h"
    00018 #include "functions.h"
    00019 #include "sound_func.h"
    00020 #include "station.h"
    00021 #include "unmovable_map.h"
    00022 #include "textbuf_gui.h"
    00023 #include "genworld.h"
    00024 #include "settings_type.h"
    00025 #include "tree_map.h"
    00026
    00027 #include "table/sprites.h"
    00028 #include "table/strings.h"
    00029
    00030 void CcTerraform(bool success, TileIndex tile, uint32 p1, uint32 p2)
    00031 {
    00032   if (success) {
    00033     SndPlayTileFx(SND_1F_SPLAT, tile);
    00034   } else {
    00035     extern TileIndex _terraform_err_tile;
    00036     SetRedErrorSquare(_terraform_err_tile);
    00037   }
    00038 }
    00039
    00040
    00042 static void GenerateDesertArea(TileIndex end, TileIndex start)
    00043 {
    00044   int size_x, size_y;
    00045   int sx = TileX(start);
    00046   int sy = TileY(start);
    00047   int ex = TileX(end);
    00048   int ey = TileY(end);
    00049
    00050   if (_game_mode != GM_EDITOR) return;
    00051
    00052   if (ex < sx) Swap(ex, sx);
    00053   if (ey < sy) Swap(ey, sy);
    00054   size_x = (ex - sx) + 1;
    00055   size_y = (ey - sy) + 1;
    00056
    00057   _generating_world = true;
    00058   BEGIN_TILE_LOOP(tile, size_x, size_y, TileXY(sx, sy)) {
    00059     if (GetTileType(tile) != MP_WATER) {
    00060       SetTropicZone(tile, (_ctrl_pressed) ? TROPICZONE_NORMAL : TROPICZONE_DESERT);
    00061       DoCommandP(tile, 0, 0, NULL, CMD_LANDSCAPE_CLEAR);
    00062       MarkTileDirtyByTile(tile);
    00063     }
    00064   } END_TILE_LOOP(tile, size_x, size_y, 0);
    00065   _generating_world = false;
    00066 }
    00067
    00069 static void GenerateRockyArea(TileIndex end, TileIndex start)
    00070 {
    00071   int size_x, size_y;
    00072   bool success = false;
    00073   int sx = TileX(start);
    00074   int sy = TileY(start);
    00075   int ex = TileX(end);
    00076   int ey = TileY(end);
    00077
    00078   if (_game_mode != GM_EDITOR) return;
    00079
    00080   if (ex < sx) Swap(ex, sx);
    00081   if (ey < sy) Swap(ey, sy);
    00082   size_x = (ex - sx) + 1;
    00083   size_y = (ey - sy) + 1;
    00084
    00085   BEGIN_TILE_LOOP(tile, size_x, size_y, TileXY(sx, sy)) {
    00086     switch (GetTileType(tile)) {
    00087       case MP_TREES:
    00088         if (GetTreeGround(tile) == TREE_GROUND_SHORE) continue;
    00089       /* FALL THROUGH */
    00090       case MP_CLEAR:
    00091         MakeClear(tile, CLEAR_ROCKS, 3);
    00092         break;
    00093
    00094       default: continue;
    00095     }
    00096     MarkTileDirtyByTile(tile);
    00097     success = true;
    00098   } END_TILE_LOOP(tile, size_x, size_y, 0);
    00099
    00100   if (success) SndPlayTileFx(SND_1F_SPLAT, end);
    00101 }
    00102
    00111 bool GUIPlaceProcDragXY(const WindowEvent *e)
    00112 {
    00113   TileIndex start_tile = e->we.place.starttile;
    00114   TileIndex end_tile = e->we.place.tile;
    00115
    00116   switch (e->we.place.select_proc) {
    00117     case DDSP_DEMOLISH_AREA:
    00118       DoCommandP(end_tile, start_tile, 0, CcPlaySound10, CMD_CLEAR_AREA | CMD_MSG(STR_00B5_CAN_T_CLEAR_THIS_AREA));
    00119       break;
    00120     case DDSP_RAISE_AND_LEVEL_AREA:
    00121       DoCommandP(end_tile, start_tile, 1, CcTerraform, CMD_LEVEL_LAND | CMD_MSG(STR_0808_CAN_T_RAISE_LAND_HERE));
    00122       break;
    00123     case DDSP_LOWER_AND_LEVEL_AREA:
    00124       DoCommandP(end_tile, start_tile, (uint32)-1, CcTerraform, CMD_LEVEL_LAND | CMD_MSG(STR_0809_CAN_T_LOWER_LAND_HERE));
    00125       break;
    00126     case DDSP_LEVEL_AREA:
    00127       DoCommandP(end_tile, start_tile, 0, CcPlaySound10, CMD_LEVEL_LAND);
    00128       break;
    00129     case DDSP_CREATE_ROCKS:
    00130       GenerateRockyArea(end_tile, start_tile);
    00131       break;
    00132     case DDSP_CREATE_DESERT:
    00133       GenerateDesertArea(end_tile, start_tile);
    00134       break;
    00135     case DDSP_CREATE_WATER:
    00136       DoCommandP(end_tile, start_tile, _ctrl_pressed, CcBuildCanal, CMD_BUILD_CANAL | CMD_MSG(STR_CANT_BUILD_CANALS));
    00137       break;
    00138     case DDSP_CREATE_RIVER:
    00139       DoCommandP(end_tile, start_tile, 2, CcBuildCanal, CMD_BUILD_CANAL | CMD_MSG(STR_CANT_BUILD_CANALS));
    00140       break;
    00141     default:
    00142       return false;
    00143   }
    00144
    00145   return true;
    00146 }
    00147
    00148 typedef void OnButtonClick(Window *w);
    00149
    00150 static const uint16 _terraform_keycodes[] = {
    00151   'Q',
    00152   'W',
    00153   'E',
    00154   'D',
    00155   'U',
    00156   'I',
    00157   'O',
    00158 };
    00159
    00160 void PlaceProc_DemolishArea(TileIndex tile)
    00161 {
    00162   VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_DEMOLISH_AREA);
    00163 }
    00164
    00165 static void PlaceProc_RaiseLand(TileIndex tile)
    00166 {
    00167   VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_RAISE_AND_LEVEL_AREA);
    00168 }
    00169
    00170 static void PlaceProc_LowerLand(TileIndex tile)
    00171 {
    00172   VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_LOWER_AND_LEVEL_AREA);
    00173 }
    00174
    00175 void PlaceProc_LevelLand(TileIndex tile)
    00176 {
    00177   VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_LEVEL_AREA);
    00178 }
    00179
    00180 static void TerraformClick_Lower(Window *w)
    00181 {
    00182   HandlePlacePushButton(w, 4, ANIMCURSOR_LOWERLAND, VHM_POINT, PlaceProc_LowerLand);
    00183 }
    00184
    00185 static void TerraformClick_Raise(Window *w)
    00186 {
    00187   HandlePlacePushButton(w, 5, ANIMCURSOR_RAISELAND, VHM_POINT, PlaceProc_RaiseLand);
    00188 }
    00189
    00190 static void TerraformClick_Level(Window *w)
    00191 {
    00192   HandlePlacePushButton(w, 6, SPR_CURSOR_LEVEL_LAND, VHM_POINT, PlaceProc_LevelLand);
    00193 }
    00194
    00195 static void TerraformClick_Dynamite(Window *w)
    00196 {
    00197   HandlePlacePushButton(w, 7, ANIMCURSOR_DEMOLISH , VHM_RECT, PlaceProc_DemolishArea);
    00198 }
    00199
    00200 static void TerraformClick_BuyLand(Window *w)
    00201 {
    00202   HandlePlacePushButton(w, 8, SPR_CURSOR_BUY_LAND, VHM_RECT, PlaceProc_BuyLand);
    00203 }
    00204
    00205 static void TerraformClick_Trees(Window *w)
    00206 {
    00207   /* This button is NOT a place-push-button, so don't treat it as such */
    00208   ShowBuildTreesToolbar();
    00209 }
    00210
    00211 static void TerraformClick_PlaceSign(Window *w)
    00212 {
    00213   HandlePlacePushButton(w, 10, SPR_CURSOR_SIGN, VHM_RECT, PlaceProc_Sign);
    00214 }
    00215
    00216 static OnButtonClick * const _terraform_button_proc[] = {
    00217   TerraformClick_Lower,
    00218   TerraformClick_Raise,
    00219   TerraformClick_Level,
    00220   TerraformClick_Dynamite,
    00221   TerraformClick_BuyLand,
    00222   TerraformClick_Trees,
    00223   TerraformClick_PlaceSign,
    00224 };
    00225
    00226 static void TerraformToolbWndProc(Window *w, WindowEvent *e)
    00227 {
    00228   switch (e->event) {
    00229   case WE_PAINT:
    00230     DrawWindowWidgets(w);
    00231     break;
    00232
    00233   case WE_CLICK:
    00234     if (e->we.click.widget >= 4) _terraform_button_proc[e->we.click.widget - 4](w);
    00235     break;
    00236
    00237   case WE_KEYPRESS: {
    00238     uint i;
    00239
    00240     for (i = 0; i != lengthof(_terraform_keycodes); i++) {
    00241       if (e->we.keypress.keycode == _terraform_keycodes[i]) {
    00242         e->we.keypress.cont = false;
    00243         _terraform_button_proc[i](w);
    00244         break;
    00245       }
    00246     }
    00247     break;
    00248   }
    00249
    00250   case WE_PLACE_OBJ:
    00251     _place_proc(e->we.place.tile);
    00252     return;
    00253
    00254   case WE_PLACE_DRAG:
    00255     VpSelectTilesWithMethod(e->we.place.pt.x, e->we.place.pt.y, e->we.place.select_method);
    00256     break;
    00257
    00258   case WE_PLACE_MOUSEUP:
    00259     if (e->we.place.pt.x != -1) {
    00260       switch (e->we.place.select_proc) {
    00261         case DDSP_DEMOLISH_AREA:
    00262         case DDSP_RAISE_AND_LEVEL_AREA:
    00263         case DDSP_LOWER_AND_LEVEL_AREA:
    00264         case DDSP_LEVEL_AREA:
    00265           GUIPlaceProcDragXY(e);
    00266           break;
    00267       }
    00268     }
    00269     break;
    00270
    00271   case WE_ABORT_PLACE_OBJ:
    00272     w->RaiseButtons();
    00273     break;
    00274   }
    00275 }
    00276
    00277 static const Widget _terraform_widgets[] = {
    00278 { WWT_CLOSEBOX,   RESIZE_NONE,     7,   0,  10,   0,  13, STR_00C5,                STR_018B_CLOSE_WINDOW},
    00279 {  WWT_CAPTION,   RESIZE_NONE,     7,  11, 145,   0,  13, STR_LANDSCAPING_TOOLBAR, STR_018C_WINDOW_TITLE_DRAG_THIS},
    00280 {WWT_STICKYBOX,   RESIZE_NONE,     7, 146, 157,   0,  13, STR_NULL,                STR_STICKY_BUTTON},
    00281
    00282 {    WWT_PANEL,   RESIZE_NONE,     7,  66,  69,  14,  35, 0x0,                    STR_NULL},
    00283 {   WWT_IMGBTN,   RESIZE_NONE,     7,   0,  21,  14,  35, SPR_IMG_TERRAFORM_DOWN,  STR_018E_LOWER_A_CORNER_OF_LAND},
    00284 {   WWT_IMGBTN,   RESIZE_NONE,     7,  22,  43,  14,  35, SPR_IMG_TERRAFORM_UP,    STR_018F_RAISE_A_CORNER_OF_LAND},
    00285 {   WWT_IMGBTN,   RESIZE_NONE,     7,  44,  65,  14,  35, SPR_IMG_LEVEL_LAND,      STR_LEVEL_LAND_TOOLTIP},
    00286 {   WWT_IMGBTN,   RESIZE_NONE,     7,  70,  91,  14,  35, SPR_IMG_DYNAMITE,        STR_018D_DEMOLISH_BUILDINGS_ETC},
    00287 {   WWT_IMGBTN,   RESIZE_NONE,     7,  92, 113,  14,  35, SPR_IMG_BUY_LAND,        STR_0329_PURCHASE_LAND_FOR_FUTURE},
    00288 {   WWT_IMGBTN,   RESIZE_NONE,     7, 114, 135,  14,  35, SPR_IMG_PLANTTREES,      STR_0185_PLANT_TREES_PLACE_SIGNS},
    00289 {   WWT_IMGBTN,   RESIZE_NONE,     7, 136, 157,  14,  35, SPR_IMG_SIGN,            STR_0289_PLACE_SIGN},
    00290
    00291 {   WIDGETS_END},
    00292 };
    00293
    00294 static const WindowDesc _terraform_desc = {
    00295   WDP_ALIGN_TBR, 22 + 36, 158, 36, 158, 36,
    00296   WC_SCEN_LAND_GEN, WC_NONE,
    00297   WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_STICKY_BUTTON,
    00298   _terraform_widgets,
    00299   TerraformToolbWndProc
    00300 };
    00301
    00302 void ShowTerraformToolbar(Window *link)
    00303 {
    00304   if (!IsValidPlayer(_current_player)) return;
    00305   Window *w = AllocateWindowDescFront(&_terraform_desc, 0);
    00306   if (w != NULL && link != NULL) {
    00307     /* Align the terraform toolbar under the main toolbar and put the linked
    00308      * toolbar to left of it
    00309      */
    00310     w->top = 22;
    00311     link->left = w->left - link->width;
    00312
    00313     SetWindowDirty(link);
    00314   }
    00315 }
    00316
    00317 static byte _terraform_size = 1;
    00318
    00328 static void CommonRaiseLowerBigLand(TileIndex tile, int mode)
    00329 {
    00330   int sizex, sizey;
    00331   uint h;
    00332
    00333   _generating_world = true; // used to create green terraformed land
    00334
    00335   if (_terraform_size == 1) {
    00336     StringID msg =
    00337       mode ? STR_0808_CAN_T_RAISE_LAND_HERE : STR_0809_CAN_T_LOWER_LAND_HERE;
    00338
    00339     DoCommandP(tile, SLOPE_N, (uint32)mode, CcTerraform, CMD_TERRAFORM_LAND | CMD_MSG(msg));
    00340   } else {
    00341     assert(_terraform_size != 0);
    00342     /* check out for map overflows */
    00343     sizex = min(MapSizeX() - TileX(tile) - 1, _terraform_size);
    00344     sizey = min(MapSizeY() - TileY(tile) - 1, _terraform_size);
    00345
    00346     if (sizex == 0 || sizey == 0) return;
    00347
    00348     SndPlayTileFx(SND_1F_SPLAT, tile);
    00349
    00350     if (mode != 0) {
    00351       /* Raise land */
    00352       h = 15; // XXX - max height
    00353       BEGIN_TILE_LOOP(tile2, sizex, sizey, tile) {
    00354         h = min(h, TileHeight(tile2));
    00355       } END_TILE_LOOP(tile2, sizex, sizey, tile)
    00356     } else {
    00357       /* Lower land */
    00358       h = 0;
    00359       BEGIN_TILE_LOOP(tile2, sizex, sizey, tile) {
    00360         h = max(h, TileHeight(tile2));
    00361       } END_TILE_LOOP(tile2, sizex, sizey, tile)
    00362     }
    00363
    00364     BEGIN_TILE_LOOP(tile2, sizex, sizey, tile) {
    00365       if (TileHeight(tile2) == h) {
    00366         DoCommandP(tile2, SLOPE_N, (uint32)mode, NULL, CMD_TERRAFORM_LAND);
    00367       }
    00368     } END_TILE_LOOP(tile2, sizex, sizey, tile)
    00369   }
    00370
    00371   _generating_world = false;
    00372 }
    00373
    00374 static void PlaceProc_RaiseBigLand(TileIndex tile)
    00375 {
    00376   CommonRaiseLowerBigLand(tile, 1);
    00377 }
    00378
    00379 static void PlaceProc_LowerBigLand(TileIndex tile)
    00380 {
    00381   CommonRaiseLowerBigLand(tile, 0);
    00382 }
    00383
    00384 static void PlaceProc_RockyArea(TileIndex tile)
    00385 {
    00386   VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_CREATE_ROCKS);
    00387 }
    00388
    00389 static void PlaceProc_LightHouse(TileIndex tile)
    00390 {
    00391   /* not flat || not(trees || clear without bridge above) */
    00392   if (GetTileSlope(tile, NULL) != SLOPE_FLAT || !(IsTileType(tile, MP_TREES) || (IsTileType(tile, MP_CLEAR) && !IsBridgeAbove(tile)))) {
    00393     return;
    00394   }
    00395
    00396   MakeLighthouse(tile);
    00397   MarkTileDirtyByTile(tile);
    00398   SndPlayTileFx(SND_1F_SPLAT, tile);
    00399 }
    00400
    00401 static void PlaceProc_Transmitter(TileIndex tile)
    00402 {
    00403   /* not flat || not(trees || clear without bridge above) */
    00404   if (GetTileSlope(tile, NULL) != SLOPE_FLAT || !(IsTileType(tile, MP_TREES) || (IsTileType(tile, MP_CLEAR) && !IsBridgeAbove(tile)))) {
    00405     return;
    00406   }
    00407
    00408   MakeTransmitter(tile);
    00409   MarkTileDirtyByTile(tile);
    00410   SndPlayTileFx(SND_1F_SPLAT, tile);
    00411 }
    00412
    00413 static void PlaceProc_DesertArea(TileIndex tile)
    00414 {
    00415   VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_CREATE_DESERT);
    00416 }
    00417
    00418 static void PlaceProc_WaterArea(TileIndex tile)
    00419 {
    00420   VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_CREATE_WATER);
    00421 }
    00422
    00423 static void PlaceProc_RiverArea(TileIndex tile)
    00424 {
    00425   VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_CREATE_RIVER);
    00426 }
    00427
    00428 static const Widget _scen_edit_land_gen_widgets[] = {
    00429 {  WWT_CLOSEBOX,   RESIZE_NONE,     7,     0,    10,     0,    13, STR_00C5,                  STR_018B_CLOSE_WINDOW},
    00430 {   WWT_CAPTION,   RESIZE_NONE,     7,    11,   191,     0,    13, STR_0223_LAND_GENERATION,  STR_018C_WINDOW_TITLE_DRAG_THIS},
    00431 { WWT_STICKYBOX,   RESIZE_NONE,     7,   192,   203,     0,    13, STR_NULL,                  STR_STICKY_BUTTON},
    00432 {     WWT_PANEL,   RESIZE_NONE,     7,     0,   203,    14,   102, 0x0,                       STR_NULL},
    00433 {    WWT_IMGBTN,   RESIZE_NONE,    14,     2,    23,    16,    37, SPR_IMG_DYNAMITE,          STR_018D_DEMOLISH_BUILDINGS_ETC},
    00434 {    WWT_IMGBTN,   RESIZE_NONE,    14,    24,    45,    16,    37, SPR_IMG_TERRAFORM_DOWN,    STR_018E_LOWER_A_CORNER_OF_LAND},
    00435 {    WWT_IMGBTN,   RESIZE_NONE,    14,    46,    67,    16,    37, SPR_IMG_TERRAFORM_UP,      STR_018F_RAISE_A_CORNER_OF_LAND},
    00436 {    WWT_IMGBTN,   RESIZE_NONE,    14,    68,    89,    16,    37, SPR_IMG_LEVEL_LAND,        STR_LEVEL_LAND_TOOLTIP},
    00437 {    WWT_IMGBTN,   RESIZE_NONE,    14,    90,   111,    16,    37, SPR_IMG_BUILD_CANAL,       STR_CREATE_LAKE},
    00438 {    WWT_IMGBTN,   RESIZE_NONE,    14,   112,   133,    16,    37, SPR_IMG_BUILD_RIVER,       STR_CREATE_RIVER},
    00439 {    WWT_IMGBTN,   RESIZE_NONE,    14,   134,   156,    16,    37, SPR_IMG_ROCKS,             STR_028C_PLACE_ROCKY_AREAS_ON_LANDSCAPE},
    00440 {    WWT_IMGBTN,   RESIZE_NONE,    14,   157,   179,    16,    37, SPR_IMG_LIGHTHOUSE_DESERT, STR_NULL}, // XXX - dynamic
    00441 {    WWT_IMGBTN,   RESIZE_NONE,    14,   180,   201,    16,    37, SPR_IMG_TRANSMITTER,       STR_028E_PLACE_TRANSMITTER},
    00442 {    WWT_IMGBTN,   RESIZE_NONE,    14,   150,   161,    45,    56, SPR_ARROW_UP,              STR_0228_INCREASE_SIZE_OF_LAND_AREA},
    00443 {    WWT_IMGBTN,   RESIZE_NONE,    14,   150,   161,    58,    69, SPR_ARROW_DOWN,            STR_0229_DECREASE_SIZE_OF_LAND_AREA},
    00444 {   WWT_TEXTBTN,   RESIZE_NONE,    14,    24,   179,    76,    87, STR_SE_NEW_WORLD,          STR_022A_GENERATE_RANDOM_LAND},
    00445 {   WWT_TEXTBTN,   RESIZE_NONE,    14,    24,   179,    89,   100, STR_022B_RESET_LANDSCAPE,  STR_RESET_LANDSCAPE_TOOLTIP},
    00446 {   WIDGETS_END},
    00447 };
    00448
    00449 static const int8 _multi_terraform_coords[][2] = {
    00450   {  0, -2},
    00451   {  4,  0}, { -4,  0}, {  0,  2},
    00452   { -8,  2}, { -4,  4}, {  0,  6}, {  4,  4}, {  8,  2},
    00453   {-12,  0}, { -8, -2}, { -4, -4}, {  0, -6}, {  4, -4}, {  8, -2}, { 12,  0},
    00454   {-16,  2}, {-12,  4}, { -8,  6}, { -4,  8}, {  0, 10}, {  4,  8}, {  8,  6}, { 12,  4}, { 16,  2},
    00455   {-20,  0}, {-16, -2}, {-12, -4}, { -8, -6}, { -4, -8}, {  0,-10}, {  4, -8}, {  8, -6}, { 12, -4}, { 16, -2}, { 20,  0},
    00456   {-24,  2}, {-20,  4}, {-16,  6}, {-12,  8}, { -8, 10}, { -4, 12}, {  0, 14}, {  4, 12}, {  8, 10}, { 12,  8}, { 16,  6}, { 20,  4}, { 24,  2},
    00457   {-28,  0}, {-24, -2}, {-20, -4}, {-16, -6}, {-12, -8}, { -8,-10}, { -4,-12}, {  0,-14}, {  4,-12}, {  8,-10}, { 12, -8}, { 16, -6}, { 20, -4}, { 24, -2}, { 28,  0},
    00458 };
    00459
    00464 static void EditorTerraformClick_Dynamite(Window *w)
    00465 {
    00466   HandlePlacePushButton(w, 4, ANIMCURSOR_DEMOLISH, VHM_RECT, PlaceProc_DemolishArea);
    00467 }
    00468
    00469 static void EditorTerraformClick_LowerBigLand(Window *w)
    00470 {
    00471   HandlePlacePushButton(w, 5, ANIMCURSOR_LOWERLAND, VHM_POINT, PlaceProc_LowerBigLand);
    00472 }
    00473
    00474 static void EditorTerraformClick_RaiseBigLand(Window *w)
    00475 {
    00476   HandlePlacePushButton(w, 6, ANIMCURSOR_RAISELAND, VHM_POINT, PlaceProc_RaiseBigLand);
    00477 }
    00478
    00479 static void EditorTerraformClick_LevelLand(Window *w)
    00480 {
    00481   HandlePlacePushButton(w, 7, SPR_CURSOR_LEVEL_LAND, VHM_POINT, PlaceProc_LevelLand);
    00482 }
    00483
    00484 static void EditorTerraformClick_WaterArea(Window *w)
    00485 {
    00486   HandlePlacePushButton(w, 8, SPR_CURSOR_CANAL, VHM_RECT, PlaceProc_WaterArea);
    00487 }
    00488
    00489 static void EditorTerraformClick_RiverArea(Window *w)
    00490 {
    00491   HandlePlacePushButton(w, 9, SPR_CURSOR_RIVER, VHM_RECT, PlaceProc_RiverArea);
    00492 }
    00493
    00494 static void EditorTerraformClick_RockyArea(Window *w)
    00495 {
    00496   HandlePlacePushButton(w, 10, SPR_CURSOR_ROCKY_AREA, VHM_RECT, PlaceProc_RockyArea);
    00497 }
    00498
    00499 static void EditorTerraformClick_DesertLightHouse(Window *w)
    00500 {
    00501   HandlePlacePushButton(w, 11, SPR_CURSOR_LIGHTHOUSE, VHM_RECT, (_opt.landscape == LT_TROPIC) ? PlaceProc_DesertArea : PlaceProc_LightHouse);
    00502 }
    00503
    00504 static void EditorTerraformClick_Transmitter(Window *w)
    00505 {
    00506   HandlePlacePushButton(w, 12, SPR_CURSOR_TRANSMITTER, VHM_RECT, PlaceProc_Transmitter);
    00507 }
    00508
    00509 static const uint16 _editor_terraform_keycodes[] = {
    00510   'D',
    00511   'Q',
    00512   'W',
    00513   'E',
    00514   'R',
    00515   'T',
    00516   'Y',
    00517   'U',
    00518   'I'
    00519 };
    00520
    00521 typedef void OnButtonClick(Window *w);
    00522 static OnButtonClick * const _editor_terraform_button_proc[] = {
    00523   EditorTerraformClick_Dynamite,
    00524   EditorTerraformClick_LowerBigLand,
    00525   EditorTerraformClick_RaiseBigLand,
    00526   EditorTerraformClick_LevelLand,
    00527   EditorTerraformClick_WaterArea,
    00528   EditorTerraformClick_RiverArea,
    00529   EditorTerraformClick_RockyArea,
    00530   EditorTerraformClick_DesertLightHouse,
    00531   EditorTerraformClick_Transmitter
    00532 };
    00533
    00534
    00538 static void ResetLandscapeConfirmationCallback(Window *w, bool confirmed)
    00539 {
    00540   if (confirmed) {
    00541     Player *p;
    00542
    00543     /* Set generating_world to true to get instant-green grass after removing
    00544      * player property. */
    00545     _generating_world = true;
    00546     /* Delete all players */
    00547     FOR_ALL_PLAYERS(p) {
    00548       if (p->is_active) {
    00549         ChangeOwnershipOfPlayerItems(p->index, PLAYER_SPECTATOR);
    00550         p->is_active = false;
    00551       }
    00552     }
    00553     _generating_world = false;
    00554
    00555     /* Delete all stations owned by a player */
    00556     Station *st;
    00557     FOR_ALL_STATIONS(st) {
    00558       if (IsValidPlayer(st->owner)) delete st;
    00559     }
    00560   }
    00561 }
    00562
    00563 static void ScenEditLandGenWndProc(Window *w, WindowEvent *e)
    00564 {
    00565   switch (e->event) {
    00566     case WE_CREATE:
    00567       /* XXX - lighthouse button is widget 11!! Don't forget when changing */
    00568       w->widget[11].tooltips = (_opt.landscape == LT_TROPIC) ? STR_028F_DEFINE_DESERT_AREA : STR_028D_PLACE_LIGHTHOUSE;
    00569       break;
    00570
    00571     case WE_PAINT: {
    00572       DrawWindowWidgets(w);
    00573
    00574       int n = _terraform_size * _terraform_size;
    00575       const int8 *coords = &_multi_terraform_coords[0][0];
    00576
    00577       assert(n != 0);
    00578       do {
    00579         DrawSprite(SPR_WHITE_POINT, PAL_NONE, 88 + coords[0], 55 + coords[1]);
    00580         coords += 2;
    00581       } while (--n);
    00582
    00583       if (w->IsWidgetLowered(5) || w->IsWidgetLowered(6)) // change area-size if raise/lower corner is selected
    00584         SetTileSelectSize(_terraform_size, _terraform_size);
    00585
    00586     } break;
    00587
    00588     case WE_KEYPRESS:
    00589       for (uint i = 0; i != lengthof(_editor_terraform_keycodes); i++) {
    00590         if (e->we.keypress.keycode == _editor_terraform_keycodes[i]) {
    00591           e->we.keypress.cont = false;
    00592           _editor_terraform_button_proc[i](w);
    00593           break;
    00594         }
    00595       }
    00596       break;
    00597
    00598     case WE_CLICK:
    00599       switch (e->we.click.widget) {
    00600         case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: case 12:
    00601           _editor_terraform_button_proc[e->we.click.widget - 4](w);
    00602           break;
    00603         case 13: case 14: { // Increase/Decrease terraform size
    00604           int size = (e->we.click.widget == 13) ? 1 : -1;
    00605           w->HandleButtonClick(e->we.click.widget);
    00606           size += _terraform_size;
    00607
    00608           if (!IsInsideMM(size, 1, 8 + 1)) return;
    00609           _terraform_size = size;
    00610
    00611           SndPlayFx(SND_15_BEEP);
    00612           SetWindowDirty(w);
    00613         } break;
    00614         case 15: // gen random land
    00615           w->HandleButtonClick(15);
    00616           ShowCreateScenario();
    00617           break;
    00618         case 16: // Reset landscape
    00619           ShowQuery(
    00620             STR_022C_RESET_LANDSCAPE,
    00621             STR_RESET_LANDSCAPE_CONFIRMATION_TEXT,
    00622             NULL,
    00623             ResetLandscapeConfirmationCallback);
    00624           break;
    00625       }
    00626       break;
    00627
    00628     case WE_TIMEOUT:
    00629       for (uint i = 0; i < w->widget_count; i++) {
    00630         if (w->IsWidgetLowered(i)) {
    00631           w->RaiseWidget(i);
    00632           w->InvalidateWidget(i);
    00633         }
    00634         if (i == 3) i = 12;
    00635       }
    00636       break;
    00637
    00638     case WE_PLACE_OBJ:
    00639       _place_proc(e->we.place.tile);
    00640       break;
    00641
    00642     case WE_PLACE_DRAG:
    00643       VpSelectTilesWithMethod(e->we.place.pt.x, e->we.place.pt.y, e->we.place.select_method);
    00644       break;
    00645
    00646     case WE_PLACE_MOUSEUP:
    00647       if (e->we.place.pt.x != -1) {
    00648         switch (e->we.place.select_proc) {
    00649           case DDSP_CREATE_ROCKS:
    00650           case DDSP_CREATE_DESERT:
    00651           case DDSP_CREATE_WATER:
    00652           case DDSP_CREATE_RIVER:
    00653           case DDSP_RAISE_AND_LEVEL_AREA:
    00654           case DDSP_LOWER_AND_LEVEL_AREA:
    00655           case DDSP_LEVEL_AREA:
    00656           case DDSP_DEMOLISH_AREA:
    00657             GUIPlaceProcDragXY(e);
    00658             break;
    00659         }
    00660       }
    00661       break;
    00662
    00663     case WE_ABORT_PLACE_OBJ:
    00664       w->RaiseButtons();
    00665       SetWindowDirty(w);
    00666       break;
    00667   }
    00668 }
    00669
    00670 static const WindowDesc _scen_edit_land_gen_desc = {
    00671   WDP_AUTO, WDP_AUTO, 204, 103, 204, 103,
    00672   WC_SCEN_LAND_GEN, WC_NONE,
    00673   WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_STICKY_BUTTON,
    00674   _scen_edit_land_gen_widgets,
    00675   ScenEditLandGenWndProc,
    00676 };
    00677
    00678 void ShowEditorTerraformToolbar()
    00679 {
    00680   AllocateWindowDescFront(&_scen_edit_land_gen_desc, 0);
    00681 }