terraform_gui.cpp

Go to the documentation of this file.
00001 /* $Id: terraform_gui.cpp 15723 2009-03-15 15:12:06Z rubidium $ */
00002 
00005 #include "stdafx.h"
00006 #include "openttd.h"
00007 #include "clear_map.h"
00008 #include "company_func.h"
00009 #include "company_base.h"
00010 #include "gui.h"
00011 #include "window_gui.h"
00012 #include "window_func.h"
00013 #include "viewport_func.h"
00014 #include "gfx_func.h"
00015 #include "command_func.h"
00016 #include "signs_func.h"
00017 #include "variables.h"
00018 #include "functions.h"
00019 #include "sound_func.h"
00020 #include "station_base.h"
00021 #include "unmovable_map.h"
00022 #include "textbuf_gui.h"
00023 #include "genworld.h"
00024 #include "tree_map.h"
00025 #include "landscape_type.h"
00026 #include "tilehighlight_func.h"
00027 #include "settings_type.h"
00028 
00029 #include "table/sprites.h"
00030 #include "table/strings.h"
00031 
00032 void CcTerraform(bool success, TileIndex tile, uint32 p1, uint32 p2)
00033 {
00034   if (success) {
00035     SndPlayTileFx(SND_1F_SPLAT, tile);
00036   } else {
00037     extern TileIndex _terraform_err_tile;
00038     SetRedErrorSquare(_terraform_err_tile);
00039   }
00040 }
00041 
00042 
00044 static void GenerateDesertArea(TileIndex end, TileIndex start)
00045 {
00046   int size_x, size_y;
00047   int sx = TileX(start);
00048   int sy = TileY(start);
00049   int ex = TileX(end);
00050   int ey = TileY(end);
00051 
00052   if (_game_mode != GM_EDITOR) return;
00053 
00054   if (ex < sx) Swap(ex, sx);
00055   if (ey < sy) Swap(ey, sy);
00056   size_x = (ex - sx) + 1;
00057   size_y = (ey - sy) + 1;
00058 
00059   _generating_world = true;
00060   BEGIN_TILE_LOOP(tile, size_x, size_y, TileXY(sx, sy)) {
00061     if (GetTileType(tile) != MP_WATER) {
00062       SetTropicZone(tile, (_ctrl_pressed) ? TROPICZONE_NORMAL : TROPICZONE_DESERT);
00063       DoCommandP(tile, 0, 0, CMD_LANDSCAPE_CLEAR);
00064       MarkTileDirtyByTile(tile);
00065     }
00066   } END_TILE_LOOP(tile, size_x, size_y, 0);
00067   _generating_world = false;
00068 }
00069 
00071 static void GenerateRockyArea(TileIndex end, TileIndex start)
00072 {
00073   int size_x, size_y;
00074   bool success = false;
00075   int sx = TileX(start);
00076   int sy = TileY(start);
00077   int ex = TileX(end);
00078   int ey = TileY(end);
00079 
00080   if (_game_mode != GM_EDITOR) return;
00081 
00082   if (ex < sx) Swap(ex, sx);
00083   if (ey < sy) Swap(ey, sy);
00084   size_x = (ex - sx) + 1;
00085   size_y = (ey - sy) + 1;
00086 
00087   BEGIN_TILE_LOOP(tile, size_x, size_y, TileXY(sx, sy)) {
00088     switch (GetTileType(tile)) {
00089       case MP_TREES:
00090         if (GetTreeGround(tile) == TREE_GROUND_SHORE) continue;
00091       /* FALL THROUGH */
00092       case MP_CLEAR:
00093         MakeClear(tile, CLEAR_ROCKS, 3);
00094         break;
00095 
00096       default: continue;
00097     }
00098     MarkTileDirtyByTile(tile);
00099     success = true;
00100   } END_TILE_LOOP(tile, size_x, size_y, 0);
00101 
00102   if (success) SndPlayTileFx(SND_1F_SPLAT, end);
00103 }
00104 
00113 bool GUIPlaceProcDragXY(ViewportDragDropSelectionProcess proc, TileIndex start_tile, TileIndex end_tile)
00114 {
00115   if (!_settings_game.construction.freeform_edges) {
00116     /* When end_tile is MP_VOID, the error tile will not be visible to the
00117      * user. This happens when terraforming at the southern border. */
00118     if (TileX(end_tile) == MapMaxX()) end_tile += TileDiffXY(-1, 0);
00119     if (TileY(end_tile) == MapMaxY()) end_tile += TileDiffXY(0, -1);
00120   }
00121 
00122   switch (proc) {
00123     case DDSP_DEMOLISH_AREA:
00124       DoCommandP(end_tile, start_tile, 0, CMD_CLEAR_AREA | CMD_MSG(STR_00B5_CAN_T_CLEAR_THIS_AREA), CcPlaySound10);
00125       break;
00126     case DDSP_RAISE_AND_LEVEL_AREA:
00127       DoCommandP(end_tile, start_tile, 1, CMD_LEVEL_LAND | CMD_MSG(STR_0808_CAN_T_RAISE_LAND_HERE), CcTerraform);
00128       break;
00129     case DDSP_LOWER_AND_LEVEL_AREA:
00130       DoCommandP(end_tile, start_tile, (uint32)-1, CMD_LEVEL_LAND | CMD_MSG(STR_0809_CAN_T_LOWER_LAND_HERE), CcTerraform);
00131       break;
00132     case DDSP_LEVEL_AREA:
00133       DoCommandP(end_tile, start_tile, 0, CMD_LEVEL_LAND | CMD_MSG(STR_CAN_T_LEVEL_LAND_HERE), CcTerraform);
00134       break;
00135     case DDSP_CREATE_ROCKS:
00136       GenerateRockyArea(end_tile, start_tile);
00137       break;
00138     case DDSP_CREATE_DESERT:
00139       GenerateDesertArea(end_tile, start_tile);
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 CcPlaySound1E(bool success, TileIndex tile, uint32 p1, uint32 p2);
00161 
00162 static void PlaceProc_BuyLand(TileIndex tile)
00163 {
00164   DoCommandP(tile, 0, 0, CMD_PURCHASE_LAND_AREA | CMD_MSG(STR_5806_CAN_T_PURCHASE_THIS_LAND), CcPlaySound1E);
00165 }
00166 
00167 void PlaceProc_DemolishArea(TileIndex tile)
00168 {
00169   VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_DEMOLISH_AREA);
00170 }
00171 
00172 static void PlaceProc_RaiseLand(TileIndex tile)
00173 {
00174   VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_RAISE_AND_LEVEL_AREA);
00175 }
00176 
00177 static void PlaceProc_LowerLand(TileIndex tile)
00178 {
00179   VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_LOWER_AND_LEVEL_AREA);
00180 }
00181 
00182 static void PlaceProc_LevelLand(TileIndex tile)
00183 {
00184   VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_LEVEL_AREA);
00185 }
00186 
00188 enum TerraformToolbarWidgets {
00189   TTW_CLOSEBOX = 0,                     
00190   TTW_CAPTION,                          
00191   TTW_STICKY,                           
00192   TTW_SEPERATOR,                        
00193   TTW_BUTTONS_START,                    
00194   TTW_LOWER_LAND = TTW_BUTTONS_START,   
00195   TTW_RAISE_LAND,                       
00196   TTW_LEVEL_LAND,                       
00197   TTW_DEMOLISH,                         
00198   TTW_BUY_LAND,                         
00199   TTW_PLANT_TREES,                      
00200   TTW_PLACE_SIGN,                       
00201 };
00202 
00203 static void TerraformClick_Lower(Window *w)
00204 {
00205   HandlePlacePushButton(w, TTW_LOWER_LAND, ANIMCURSOR_LOWERLAND, VHM_POINT, PlaceProc_LowerLand);
00206 }
00207 
00208 static void TerraformClick_Raise(Window *w)
00209 {
00210   HandlePlacePushButton(w, TTW_RAISE_LAND, ANIMCURSOR_RAISELAND, VHM_POINT, PlaceProc_RaiseLand);
00211 }
00212 
00213 static void TerraformClick_Level(Window *w)
00214 {
00215   HandlePlacePushButton(w, TTW_LEVEL_LAND, SPR_CURSOR_LEVEL_LAND, VHM_POINT, PlaceProc_LevelLand);
00216 }
00217 
00218 static void TerraformClick_Dynamite(Window *w)
00219 {
00220   HandlePlacePushButton(w, TTW_DEMOLISH, ANIMCURSOR_DEMOLISH , VHM_RECT, PlaceProc_DemolishArea);
00221 }
00222 
00223 static void TerraformClick_BuyLand(Window *w)
00224 {
00225   HandlePlacePushButton(w, TTW_BUY_LAND, SPR_CURSOR_BUY_LAND, VHM_RECT, PlaceProc_BuyLand);
00226 }
00227 
00228 static void TerraformClick_Trees(Window *w)
00229 {
00230   /* This button is NOT a place-push-button, so don't treat it as such */
00231   ShowBuildTreesToolbar();
00232 }
00233 
00234 static void TerraformClick_PlaceSign(Window *w)
00235 {
00236   HandlePlacePushButton(w, TTW_PLACE_SIGN, SPR_CURSOR_SIGN, VHM_RECT, PlaceProc_Sign);
00237 }
00238 
00239 static OnButtonClick * const _terraform_button_proc[] = {
00240   TerraformClick_Lower,
00241   TerraformClick_Raise,
00242   TerraformClick_Level,
00243   TerraformClick_Dynamite,
00244   TerraformClick_BuyLand,
00245   TerraformClick_Trees,
00246   TerraformClick_PlaceSign,
00247 };
00248 
00249 struct TerraformToolbarWindow : Window {
00250   TerraformToolbarWindow(const WindowDesc *desc, WindowNumber window_number) : Window(desc, window_number)
00251   {
00252     this->FindWindowPlacementAndResize(desc);
00253   }
00254 
00255   ~TerraformToolbarWindow()
00256   {
00257   }
00258 
00259   virtual void OnPaint()
00260   {
00261     this->DrawWidgets();
00262   }
00263 
00264   virtual void OnClick(Point pt, int widget)
00265   {
00266     if (widget >= TTW_BUTTONS_START) _terraform_button_proc[widget - TTW_BUTTONS_START](this);
00267   }
00268 
00269   virtual EventState OnKeyPress(uint16 key, uint16 keycode)
00270   {
00271     for (uint i = 0; i != lengthof(_terraform_keycodes); i++) {
00272       if (keycode == _terraform_keycodes[i]) {
00273         _terraform_button_proc[i](this);
00274         return ES_HANDLED;
00275       }
00276     }
00277     return ES_NOT_HANDLED;
00278   }
00279 
00280   virtual void OnPlaceObject(Point pt, TileIndex tile)
00281   {
00282     _place_proc(tile);
00283   }
00284 
00285   virtual void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt)
00286   {
00287     VpSelectTilesWithMethod(pt.x, pt.y, select_method);
00288   }
00289 
00290   virtual void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile)
00291   {
00292     if (pt.x != -1) {
00293       switch (select_proc) {
00294         default: NOT_REACHED();
00295         case DDSP_DEMOLISH_AREA:
00296         case DDSP_RAISE_AND_LEVEL_AREA:
00297         case DDSP_LOWER_AND_LEVEL_AREA:
00298         case DDSP_LEVEL_AREA:
00299           GUIPlaceProcDragXY(select_proc, start_tile, end_tile);
00300           break;
00301       }
00302     }
00303   }
00304 
00305   virtual void OnPlaceObjectAbort()
00306   {
00307     this->RaiseButtons();
00308   }
00309 };
00310 
00311 static const Widget _terraform_widgets[] = {
00312 { WWT_CLOSEBOX,   RESIZE_NONE,  COLOUR_DARK_GREEN,   0,  10,   0,  13, STR_00C5,                STR_018B_CLOSE_WINDOW},             // TTW_CLOSEBOX
00313 {  WWT_CAPTION,   RESIZE_NONE,  COLOUR_DARK_GREEN,  11, 145,   0,  13, STR_LANDSCAPING_TOOLBAR, STR_018C_WINDOW_TITLE_DRAG_THIS},   // TTW_CAPTION
00314 {WWT_STICKYBOX,   RESIZE_NONE,  COLOUR_DARK_GREEN, 146, 157,   0,  13, STR_NULL,                STR_STICKY_BUTTON},                 // TTW_STICKY
00315 
00316 {    WWT_PANEL,   RESIZE_NONE,  COLOUR_DARK_GREEN,  66,  69,  14,  35, 0x0,                    STR_NULL},                           // TTW_SEPERATOR
00317 {   WWT_IMGBTN,   RESIZE_NONE,  COLOUR_DARK_GREEN,   0,  21,  14,  35, SPR_IMG_TERRAFORM_DOWN,  STR_018E_LOWER_A_CORNER_OF_LAND},   // TTW_LOWER_LAND
00318 {   WWT_IMGBTN,   RESIZE_NONE,  COLOUR_DARK_GREEN,  22,  43,  14,  35, SPR_IMG_TERRAFORM_UP,    STR_018F_RAISE_A_CORNER_OF_LAND},   // TTW_RAISE_LAND
00319 {   WWT_IMGBTN,   RESIZE_NONE,  COLOUR_DARK_GREEN,  44,  65,  14,  35, SPR_IMG_LEVEL_LAND,      STR_LEVEL_LAND_TOOLTIP},            // TTW_LEVEL_LAND
00320 {   WWT_IMGBTN,   RESIZE_NONE,  COLOUR_DARK_GREEN,  70,  91,  14,  35, SPR_IMG_DYNAMITE,        STR_018D_DEMOLISH_BUILDINGS_ETC},   // TTW_DEMOLISH
00321 {   WWT_IMGBTN,   RESIZE_NONE,  COLOUR_DARK_GREEN,  92, 113,  14,  35, SPR_IMG_BUY_LAND,        STR_0329_PURCHASE_LAND_FOR_FUTURE}, // TTW_BUY_LAND
00322 {   WWT_IMGBTN,   RESIZE_NONE,  COLOUR_DARK_GREEN, 114, 135,  14,  35, SPR_IMG_PLANTTREES,      STR_0185_PLANT_TREES_PLACE_SIGNS},  // TTW_PLANT_TREES
00323 {   WWT_IMGBTN,   RESIZE_NONE,  COLOUR_DARK_GREEN, 136, 157,  14,  35, SPR_IMG_SIGN,            STR_0289_PLACE_SIGN},               // TTW_PLACE_SIGN
00324 
00325 {   WIDGETS_END},
00326 };
00327 
00328 static const WindowDesc _terraform_desc(
00329   WDP_ALIGN_TBR, 22 + 36, 158, 36, 158, 36,
00330   WC_SCEN_LAND_GEN, WC_NONE,
00331   WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_STICKY_BUTTON | WDF_CONSTRUCTION,
00332   _terraform_widgets
00333 );
00334 
00335 void ShowTerraformToolbar(Window *link)
00336 {
00337   if (!IsValidCompanyID(_local_company)) return;
00338 
00339   Window *w = AllocateWindowDescFront<TerraformToolbarWindow>(&_terraform_desc, 0);
00340   if (link == NULL) return;
00341 
00342   if (w == NULL) {
00343     w = FindWindowById(WC_SCEN_LAND_GEN, 0);
00344   } else {
00345     w->top = 22;
00346     w->SetDirty();
00347   }
00348   if (w == NULL) return;
00349 
00350   /* Align the terraform toolbar under the main toolbar and put the linked
00351    * toolbar to left of it
00352    */
00353   link->top  = w->top;
00354   link->left = w->left - link->width;
00355   link->SetDirty();
00356 }
00357 
00358 static byte _terraform_size = 1;
00359 
00369 static void CommonRaiseLowerBigLand(TileIndex tile, int mode)
00370 {
00371   int sizex, sizey;
00372   uint h;
00373 
00374   if (_terraform_size == 1) {
00375     StringID msg =
00376       mode ? STR_0808_CAN_T_RAISE_LAND_HERE : STR_0809_CAN_T_LOWER_LAND_HERE;
00377 
00378     DoCommandP(tile, SLOPE_N, (uint32)mode, CMD_TERRAFORM_LAND | CMD_MSG(msg), CcTerraform);
00379   } else {
00380     assert(_terraform_size != 0);
00381     /* check out for map overflows */
00382     sizex = min(MapSizeX() - TileX(tile), _terraform_size);
00383     sizey = min(MapSizeY() - TileY(tile), _terraform_size);
00384 
00385     if (sizex == 0 || sizey == 0) return;
00386 
00387     SndPlayTileFx(SND_1F_SPLAT, tile);
00388 
00389     if (mode != 0) {
00390       /* Raise land */
00391       h = 15; // XXX - max height
00392       BEGIN_TILE_LOOP(tile2, sizex, sizey, tile) {
00393         h = min(h, TileHeight(tile2));
00394       } END_TILE_LOOP(tile2, sizex, sizey, tile)
00395     } else {
00396       /* Lower land */
00397       h = 0;
00398       BEGIN_TILE_LOOP(tile2, sizex, sizey, tile) {
00399         h = max(h, TileHeight(tile2));
00400       } END_TILE_LOOP(tile2, sizex, sizey, tile)
00401     }
00402 
00403     BEGIN_TILE_LOOP(tile2, sizex, sizey, tile) {
00404       if (TileHeight(tile2) == h) {
00405         DoCommandP(tile2, SLOPE_N, (uint32)mode, CMD_TERRAFORM_LAND);
00406       }
00407     } END_TILE_LOOP(tile2, sizex, sizey, tile)
00408   }
00409 }
00410 
00411 static void PlaceProc_RaiseBigLand(TileIndex tile)
00412 {
00413   CommonRaiseLowerBigLand(tile, 1);
00414 }
00415 
00416 static void PlaceProc_LowerBigLand(TileIndex tile)
00417 {
00418   CommonRaiseLowerBigLand(tile, 0);
00419 }
00420 
00421 static void PlaceProc_RockyArea(TileIndex tile)
00422 {
00423   VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_CREATE_ROCKS);
00424 }
00425 
00426 static void PlaceProc_LightHouse(TileIndex tile)
00427 {
00428   /* not flat || not(trees || clear without bridge above) */
00429   if (GetTileSlope(tile, NULL) != SLOPE_FLAT || !(IsTileType(tile, MP_TREES) || (IsTileType(tile, MP_CLEAR) && !IsBridgeAbove(tile)))) {
00430     return;
00431   }
00432 
00433   MakeLighthouse(tile);
00434   MarkTileDirtyByTile(tile);
00435   SndPlayTileFx(SND_1F_SPLAT, tile);
00436 }
00437 
00438 static void PlaceProc_Transmitter(TileIndex tile)
00439 {
00440   /* not flat || not(trees || clear without bridge above) */
00441   if (GetTileSlope(tile, NULL) != SLOPE_FLAT || !(IsTileType(tile, MP_TREES) || (IsTileType(tile, MP_CLEAR) && !IsBridgeAbove(tile)))) {
00442     return;
00443   }
00444 
00445   MakeTransmitter(tile);
00446   MarkTileDirtyByTile(tile);
00447   SndPlayTileFx(SND_1F_SPLAT, tile);
00448 }
00449 
00450 static void PlaceProc_DesertArea(TileIndex tile)
00451 {
00452   VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_CREATE_DESERT);
00453 }
00454 
00455 
00456 static const Widget _scen_edit_land_gen_widgets[] = {
00457 {  WWT_CLOSEBOX,   RESIZE_NONE,  COLOUR_DARK_GREEN,    0,    10,     0,    13, STR_00C5,                  STR_018B_CLOSE_WINDOW},                   // ETTW_CLOSEBOX
00458 {   WWT_CAPTION,   RESIZE_NONE,  COLOUR_DARK_GREEN,   11,   150,     0,    13, STR_0223_LAND_GENERATION,  STR_018C_WINDOW_TITLE_DRAG_THIS},         // ETTW_CAPTION
00459 { WWT_STICKYBOX,   RESIZE_NONE,  COLOUR_DARK_GREEN,  151,   162,     0,    13, STR_NULL,                  STR_STICKY_BUTTON},                       // ETTW_STICKY
00460 {     WWT_PANEL,   RESIZE_NONE,  COLOUR_DARK_GREEN,    0,   162,    14,   102, 0x0,                       STR_NULL},                                // ETTW_BACKGROUND
00461 {    WWT_IMGBTN,   RESIZE_NONE,  COLOUR_GREY,          2,    23,    16,    37, SPR_IMG_DYNAMITE,          STR_018D_DEMOLISH_BUILDINGS_ETC},         // ETTW_DEMOLISH
00462 {    WWT_IMGBTN,   RESIZE_NONE,  COLOUR_GREY,         24,    45,    16,    37, SPR_IMG_TERRAFORM_DOWN,    STR_018E_LOWER_A_CORNER_OF_LAND},         // ETTW_LOWER_LAND
00463 {    WWT_IMGBTN,   RESIZE_NONE,  COLOUR_GREY,         46,    67,    16,    37, SPR_IMG_TERRAFORM_UP,      STR_018F_RAISE_A_CORNER_OF_LAND},         // ETTW_RAISE_LAND
00464 {    WWT_IMGBTN,   RESIZE_NONE,  COLOUR_GREY,         68,    89,    16,    37, SPR_IMG_LEVEL_LAND,        STR_LEVEL_LAND_TOOLTIP},                  // ETTW_LEVEL_LAND
00465 {    WWT_IMGBTN,   RESIZE_NONE,  COLOUR_GREY,         90,   111,    16,    37, SPR_IMG_ROCKS,             STR_028C_PLACE_ROCKY_AREAS_ON_LANDSCAPE}, // ETTW_PLACE_ROCKS
00466 {    WWT_IMGBTN,   RESIZE_NONE,  COLOUR_GREY,        112,   133,    16,    37, SPR_IMG_LIGHTHOUSE_DESERT, STR_NULL},                                // ETTW_PLACE_DESERT_LIGHTHOUSE XXX - dynamic
00467 {    WWT_IMGBTN,   RESIZE_NONE,  COLOUR_GREY,        134,   156,    16,    37, SPR_IMG_TRANSMITTER,       STR_028E_PLACE_TRANSMITTER},              // ETTW_PLACE_TRANSMITTER
00468 {    WWT_IMGBTN,   RESIZE_NONE,  COLOUR_GREY,        150,   161,    45,    56, SPR_ARROW_UP,              STR_0228_INCREASE_SIZE_OF_LAND_AREA},     // ETTW_INCREASE_SIZE
00469 {    WWT_IMGBTN,   RESIZE_NONE,  COLOUR_GREY,        150,   161,    58,    69, SPR_ARROW_DOWN,            STR_0229_DECREASE_SIZE_OF_LAND_AREA},     // ETTW_DECREASE_SIZE
00470 {   WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,          2,   161,    76,    87, STR_SE_NEW_WORLD,          STR_022A_GENERATE_RANDOM_LAND},           // ETTW_NEW_SCENARIO
00471 {   WWT_TEXTBTN,   RESIZE_NONE,  COLOUR_GREY,          2,   161,    89,   100, STR_022B_RESET_LANDSCAPE,  STR_RESET_LANDSCAPE_TOOLTIP},             // ETTW_RESET_LANDSCAPE
00472 {   WIDGETS_END},
00473 };
00474 
00475 static const int8 _multi_terraform_coords[][2] = {
00476   {  0, -2},
00477   {  4,  0}, { -4,  0}, {  0,  2},
00478   { -8,  2}, { -4,  4}, {  0,  6}, {  4,  4}, {  8,  2},
00479   {-12,  0}, { -8, -2}, { -4, -4}, {  0, -6}, {  4, -4}, {  8, -2}, { 12,  0},
00480   {-16,  2}, {-12,  4}, { -8,  6}, { -4,  8}, {  0, 10}, {  4,  8}, {  8,  6}, { 12,  4}, { 16,  2},
00481   {-20,  0}, {-16, -2}, {-12, -4}, { -8, -6}, { -4, -8}, {  0,-10}, {  4, -8}, {  8, -6}, { 12, -4}, { 16, -2}, { 20,  0},
00482   {-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},
00483   {-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},
00484 };
00485 
00487 enum EditorTerraformToolbarWidgets {
00488   ETTW_START = 0,                        
00489   ETTW_CLOSEBOX = ETTW_START,            
00490   ETTW_CAPTION,                          
00491   ETTW_STICKY,                           
00492   ETTW_BACKGROUND,                       
00493   ETTW_BUTTONS_START,                    
00494   ETTW_DEMOLISH = ETTW_BUTTONS_START,    
00495   ETTW_LOWER_LAND,                       
00496   ETTW_RAISE_LAND,                       
00497   ETTW_LEVEL_LAND,                       
00498   ETTW_PLACE_ROCKS,                      
00499   ETTW_PLACE_DESERT_LIGHTHOUSE,          
00500   ETTW_PLACE_TRANSMITTER,                
00501   ETTW_BUTTONS_END,                      
00502   ETTW_INCREASE_SIZE = ETTW_BUTTONS_END, 
00503   ETTW_DECREASE_SIZE,                    
00504   ETTW_NEW_SCENARIO,                     
00505   ETTW_RESET_LANDSCAPE,                  
00506 };
00507 
00512 static void EditorTerraformClick_Dynamite(Window *w)
00513 {
00514   HandlePlacePushButton(w, ETTW_DEMOLISH, ANIMCURSOR_DEMOLISH, VHM_RECT, PlaceProc_DemolishArea);
00515 }
00516 
00517 static void EditorTerraformClick_LowerBigLand(Window *w)
00518 {
00519   HandlePlacePushButton(w, ETTW_LOWER_LAND, ANIMCURSOR_LOWERLAND, VHM_POINT, PlaceProc_LowerBigLand);
00520 }
00521 
00522 static void EditorTerraformClick_RaiseBigLand(Window *w)
00523 {
00524   HandlePlacePushButton(w, ETTW_RAISE_LAND, ANIMCURSOR_RAISELAND, VHM_POINT, PlaceProc_RaiseBigLand);
00525 }
00526 
00527 static void EditorTerraformClick_LevelLand(Window *w)
00528 {
00529   HandlePlacePushButton(w, ETTW_LEVEL_LAND, SPR_CURSOR_LEVEL_LAND, VHM_POINT, PlaceProc_LevelLand);
00530 }
00531 
00532 static void EditorTerraformClick_RockyArea(Window *w)
00533 {
00534   HandlePlacePushButton(w, ETTW_PLACE_ROCKS, SPR_CURSOR_ROCKY_AREA, VHM_RECT, PlaceProc_RockyArea);
00535 }
00536 
00537 static void EditorTerraformClick_DesertLightHouse(Window *w)
00538 {
00539   HandlePlacePushButton(w, ETTW_PLACE_DESERT_LIGHTHOUSE, SPR_CURSOR_LIGHTHOUSE, VHM_RECT, (_settings_game.game_creation.landscape == LT_TROPIC) ? PlaceProc_DesertArea : PlaceProc_LightHouse);
00540 }
00541 
00542 static void EditorTerraformClick_Transmitter(Window *w)
00543 {
00544   HandlePlacePushButton(w, ETTW_PLACE_TRANSMITTER, SPR_CURSOR_TRANSMITTER, VHM_RECT, PlaceProc_Transmitter);
00545 }
00546 
00547 static const uint16 _editor_terraform_keycodes[] = {
00548   'D',
00549   'Q',
00550   'W',
00551   'E',
00552   'R',
00553   'T',
00554   'Y'
00555 };
00556 
00557 typedef void OnButtonClick(Window *w);
00558 static OnButtonClick * const _editor_terraform_button_proc[] = {
00559   EditorTerraformClick_Dynamite,
00560   EditorTerraformClick_LowerBigLand,
00561   EditorTerraformClick_RaiseBigLand,
00562   EditorTerraformClick_LevelLand,
00563   EditorTerraformClick_RockyArea,
00564   EditorTerraformClick_DesertLightHouse,
00565   EditorTerraformClick_Transmitter
00566 };
00567 
00568 
00572 static void ResetLandscapeConfirmationCallback(Window *w, bool confirmed)
00573 {
00574   if (confirmed) {
00575     Company *c;
00576 
00577     /* Set generating_world to true to get instant-green grass after removing
00578      * company property. */
00579     _generating_world = true;
00580 
00581     /* Delete all stations owned by a company */
00582     Station *st;
00583     FOR_ALL_STATIONS(st) {
00584       if (IsValidCompanyID(st->owner)) delete st;
00585     }
00586 
00587     /* Delete all companies */
00588     FOR_ALL_COMPANIES(c) {
00589       ChangeOwnershipOfCompanyItems(c->index, INVALID_OWNER);
00590       delete c;
00591     }
00592     _generating_world = false;
00593   }
00594 }
00595 
00596 struct ScenarioEditorLandscapeGenerationWindow : Window {
00597   ScenarioEditorLandscapeGenerationWindow(const WindowDesc *desc, WindowNumber window_number) : Window(desc, window_number)
00598   {
00599     this->widget[ETTW_PLACE_DESERT_LIGHTHOUSE].tooltips = (_settings_game.game_creation.landscape == LT_TROPIC) ? STR_028F_DEFINE_DESERT_AREA : STR_028D_PLACE_LIGHTHOUSE;
00600     this->FindWindowPlacementAndResize(desc);
00601   }
00602 
00603   virtual void OnPaint() {
00604     this->DrawWidgets();
00605 
00606     int n = _terraform_size * _terraform_size;
00607     const int8 *coords = &_multi_terraform_coords[0][0];
00608 
00609     assert(n != 0);
00610     do {
00611       DrawSprite(SPR_WHITE_POINT, PAL_NONE, 88 + coords[0], 55 + coords[1]);
00612       coords += 2;
00613     } while (--n);
00614 
00615     if (this->IsWidgetLowered(ETTW_LOWER_LAND) || this->IsWidgetLowered(ETTW_RAISE_LAND)) { // change area-size if raise/lower corner is selected
00616       SetTileSelectSize(_terraform_size, _terraform_size);
00617     }
00618   }
00619 
00620   virtual EventState OnKeyPress(uint16 key, uint16 keycode)
00621   {
00622     for (uint i = 0; i != lengthof(_editor_terraform_keycodes); i++) {
00623       if (keycode == _editor_terraform_keycodes[i]) {
00624         _editor_terraform_button_proc[i](this);
00625         return ES_HANDLED;
00626       }
00627     }
00628     return ES_NOT_HANDLED;
00629   }
00630 
00631   virtual void OnClick(Point pt, int widget)
00632   {
00633     if (IsInsideMM(widget, ETTW_BUTTONS_START, ETTW_BUTTONS_END)) {
00634       _editor_terraform_button_proc[widget - ETTW_BUTTONS_START](this);
00635     } else {
00636       switch (widget) {
00637         case ETTW_INCREASE_SIZE:
00638         case ETTW_DECREASE_SIZE: { // Increase/Decrease terraform size
00639           int size = (widget == ETTW_INCREASE_SIZE) ? 1 : -1;
00640           this->HandleButtonClick(widget);
00641           size += _terraform_size;
00642 
00643           if (!IsInsideMM(size, 1, 8 + 1)) return;
00644           _terraform_size = size;
00645 
00646           SndPlayFx(SND_15_BEEP);
00647           this->SetDirty();
00648         } break;
00649         case ETTW_NEW_SCENARIO: // gen random land
00650           this->HandleButtonClick(widget);
00651           ShowCreateScenario();
00652           break;
00653         case ETTW_RESET_LANDSCAPE: // Reset landscape
00654           ShowQuery(
00655             STR_022C_RESET_LANDSCAPE,
00656             STR_RESET_LANDSCAPE_CONFIRMATION_TEXT,
00657             NULL,
00658             ResetLandscapeConfirmationCallback);
00659           break;
00660       }
00661     }
00662   }
00663 
00664   virtual void OnTimeout()
00665   {
00666     for (uint i = ETTW_START; i < this->widget_count; i++) {
00667       if (i == ETTW_BUTTONS_START) i = ETTW_BUTTONS_END; // skip the buttons
00668       if (this->IsWidgetLowered(i)) {
00669         this->RaiseWidget(i);
00670         this->InvalidateWidget(i);
00671       }
00672     }
00673   }
00674 
00675   virtual void OnPlaceObject(Point pt, TileIndex tile)
00676   {
00677     _place_proc(tile);
00678   }
00679 
00680   virtual void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt)
00681   {
00682     VpSelectTilesWithMethod(pt.x, pt.y, select_method);
00683   }
00684 
00685   virtual void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile)
00686   {
00687     if (pt.x != -1) {
00688       switch (select_proc) {
00689         default: NOT_REACHED();
00690         case DDSP_CREATE_ROCKS:
00691         case DDSP_CREATE_DESERT:
00692         case DDSP_RAISE_AND_LEVEL_AREA:
00693         case DDSP_LOWER_AND_LEVEL_AREA:
00694         case DDSP_LEVEL_AREA:
00695         case DDSP_DEMOLISH_AREA:
00696           GUIPlaceProcDragXY(select_proc, start_tile, end_tile);
00697           break;
00698       }
00699     }
00700   }
00701 
00702   virtual void OnPlaceObjectAbort()
00703   {
00704     this->RaiseButtons();
00705     this->SetDirty();
00706   }
00707 };
00708 
00709 static const WindowDesc _scen_edit_land_gen_desc(
00710   WDP_AUTO, WDP_AUTO, 163, 103, 163, 103,
00711   WC_SCEN_LAND_GEN, WC_NONE,
00712   WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_STICKY_BUTTON | WDF_CONSTRUCTION,
00713   _scen_edit_land_gen_widgets
00714 );
00715 
00716 void ShowEditorTerraformToolbar()
00717 {
00718   AllocateWindowDescFront<ScenarioEditorLandscapeGenerationWindow>(&_scen_edit_land_gen_desc, 0);
00719 }

Generated on Mon May 11 15:48:08 2009 for OpenTTD by  doxygen 1.5.6