00001
00002
00003
00004
00005
00006
00007
00008
00009
00012 #include "stdafx.h"
00013 #include "clear_map.h"
00014 #include "company_func.h"
00015 #include "company_base.h"
00016 #include "gui.h"
00017 #include "window_gui.h"
00018 #include "window_func.h"
00019 #include "viewport_func.h"
00020 #include "command_func.h"
00021 #include "signs_func.h"
00022 #include "sound_func.h"
00023 #include "base_station_base.h"
00024 #include "textbuf_gui.h"
00025 #include "genworld.h"
00026 #include "tree_map.h"
00027 #include "landscape_type.h"
00028 #include "tilehighlight_func.h"
00029 #include "strings_func.h"
00030 #include "newgrf_object.h"
00031 #include "object.h"
00032 #include "hotkeys.h"
00033 #include "engine_base.h"
00034 #include "tile_map.h"
00035
00036 #include "table/strings.h"
00037
00038 void CcTerraform(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2)
00039 {
00040 if (result.Succeeded()) {
00041 SndPlayTileFx(SND_1F_SPLAT, tile);
00042 } else {
00043 extern TileIndex _terraform_err_tile;
00044 SetRedErrorSquare(_terraform_err_tile);
00045 }
00046 }
00047
00048
00050 static void GenerateDesertArea(TileIndex end, TileIndex start)
00051 {
00052 if (_game_mode != GM_EDITOR) return;
00053
00054 _generating_world = true;
00055
00056 TileArea ta(start, end);
00057 TILE_AREA_LOOP(tile, ta) {
00058 SetTropicZone(tile, (_ctrl_pressed) ? TROPICZONE_NORMAL : TROPICZONE_DESERT);
00059 DoCommandP(tile, 0, 0, CMD_LANDSCAPE_CLEAR);
00060 MarkTileDirtyByTile(tile);
00061 }
00062 _generating_world = false;
00063 InvalidateWindowClassesData(WC_TOWN_VIEW, 0);
00064 }
00065
00067 static void GenerateRockyArea(TileIndex end, TileIndex start)
00068 {
00069 if (_game_mode != GM_EDITOR) return;
00070
00071 bool success = false;
00072 TileArea ta(start, end);
00073
00074 TILE_AREA_LOOP(tile, ta) {
00075 switch (GetTileType(tile)) {
00076 case MP_TREES:
00077 if (GetTreeGround(tile) == TREE_GROUND_SHORE) continue;
00078
00079 case MP_CLEAR:
00080 MakeClear(tile, CLEAR_ROCKS, 3);
00081 break;
00082
00083 default: continue;
00084 }
00085 MarkTileDirtyByTile(tile);
00086 success = true;
00087 }
00088
00089 if (success) SndPlayTileFx(SND_1F_SPLAT, end);
00090 }
00091
00101 bool GUIPlaceProcDragXY(ViewportDragDropSelectionProcess proc, TileIndex start_tile, TileIndex end_tile)
00102 {
00103 if (!_settings_game.construction.freeform_edges) {
00104
00105
00106 if (TileX(end_tile) == MapMaxX()) end_tile += TileDiffXY(-1, 0);
00107 if (TileY(end_tile) == MapMaxY()) end_tile += TileDiffXY(0, -1);
00108 }
00109
00110 switch (proc) {
00111 case DDSP_DEMOLISH_AREA:
00112 DoCommandP(end_tile, start_tile, _ctrl_pressed ? 1 : 0, CMD_CLEAR_AREA | CMD_MSG(STR_ERROR_CAN_T_CLEAR_THIS_AREA), CcPlaySound10);
00113 break;
00114 case DDSP_RAISE_AND_LEVEL_AREA:
00115 DoCommandP(end_tile, start_tile, LM_RAISE << 1 | (_ctrl_pressed ? 1 : 0), CMD_LEVEL_LAND | CMD_MSG(STR_ERROR_CAN_T_RAISE_LAND_HERE), CcTerraform);
00116 break;
00117 case DDSP_LOWER_AND_LEVEL_AREA:
00118 DoCommandP(end_tile, start_tile, LM_LOWER << 1 | (_ctrl_pressed ? 1 : 0), CMD_LEVEL_LAND | CMD_MSG(STR_ERROR_CAN_T_LOWER_LAND_HERE), CcTerraform);
00119 break;
00120 case DDSP_LEVEL_AREA:
00121 DoCommandP(end_tile, start_tile, LM_LEVEL << 1 | (_ctrl_pressed ? 1 : 0), CMD_LEVEL_LAND | CMD_MSG(STR_ERROR_CAN_T_LEVEL_LAND_HERE), CcTerraform);
00122 break;
00123 case DDSP_CREATE_ROCKS:
00124 GenerateRockyArea(end_tile, start_tile);
00125 break;
00126 case DDSP_CREATE_DESERT:
00127 GenerateDesertArea(end_tile, start_tile);
00128 break;
00129 default:
00130 return false;
00131 }
00132
00133 return true;
00134 }
00135
00140 void PlaceProc_DemolishArea(TileIndex tile)
00141 {
00142 VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_DEMOLISH_AREA);
00143 }
00144
00146 enum TerraformToolbarWidgets {
00147 TTW_SHOW_PLACE_OBJECT,
00148 TTW_BUTTONS_START,
00149 TTW_LOWER_LAND = TTW_BUTTONS_START,
00150 TTW_RAISE_LAND,
00151 TTW_LEVEL_LAND,
00152 TTW_DEMOLISH,
00153 TTW_BUY_LAND,
00154 TTW_PLANT_TREES,
00155 TTW_PLACE_SIGN,
00156 TTW_PLACE_OBJECT,
00157 TTW_MEASUREMENT_TOOL,
00158 TTW_COPY_PASTE,
00159 };
00160
00162 struct TerraformToolbarWindow : Window {
00163 int last_user_action;
00164
00165 TerraformToolbarWindow(const WindowDesc *desc, WindowNumber window_number) : Window()
00166 {
00167
00168 this->CreateNestedTree(desc);
00169 this->FinishInitNested(desc, window_number);
00170 this->last_user_action = WIDGET_LIST_END;
00171 }
00172
00173 ~TerraformToolbarWindow()
00174 {
00175 }
00176
00177 virtual void OnInit()
00178 {
00179
00180 NWidgetStacked *show_object = this->GetWidget<NWidgetStacked>(TTW_SHOW_PLACE_OBJECT);
00181 show_object->SetDisplayedPlane(ObjectClass::GetCount() != 0 ? 0 : SZSP_NONE);
00182 }
00183
00184 virtual void OnClick(Point pt, int widget, int click_count)
00185 {
00186 if (widget < TTW_BUTTONS_START) return;
00187
00188 switch (widget) {
00189 case TTW_LOWER_LAND:
00190 HandlePlacePushButton(this, TTW_LOWER_LAND, ANIMCURSOR_LOWERLAND, HT_POINT | HT_DIAGONAL);
00191 this->last_user_action = widget;
00192 break;
00193
00194 case TTW_RAISE_LAND:
00195 HandlePlacePushButton(this, TTW_RAISE_LAND, ANIMCURSOR_RAISELAND, HT_POINT | HT_DIAGONAL);
00196 this->last_user_action = widget;
00197 break;
00198
00199 case TTW_LEVEL_LAND:
00200 HandlePlacePushButton(this, TTW_LEVEL_LAND, SPR_CURSOR_LEVEL_LAND, HT_POINT | HT_DIAGONAL);
00201 this->last_user_action = widget;
00202 break;
00203
00204 case TTW_DEMOLISH:
00205 HandlePlacePushButton(this, TTW_DEMOLISH, ANIMCURSOR_DEMOLISH, HT_RECT | HT_DIAGONAL);
00206 this->last_user_action = widget;
00207 break;
00208
00209 case TTW_BUY_LAND:
00210 HandlePlacePushButton(this, TTW_BUY_LAND, SPR_CURSOR_BUY_LAND, HT_RECT);
00211 this->last_user_action = widget;
00212 break;
00213
00214 case TTW_PLANT_TREES:
00215
00216 this->HandleButtonClick(TTW_PLANT_TREES);
00217 ShowBuildTreesToolbar();
00218 break;
00219
00220 case TTW_PLACE_SIGN:
00221 HandlePlacePushButton(this, TTW_PLACE_SIGN, SPR_CURSOR_SIGN, HT_RECT);
00222 this->last_user_action = widget;
00223 break;
00224
00225 case TTW_PLACE_OBJECT:
00226
00227 if (ObjectClass::GetCount() == 0) return;
00228 if (HandlePlacePushButton(this, TTW_PLACE_OBJECT, SPR_CURSOR_TRANSMITTER, HT_RECT)) {
00229 ShowBuildObjectPicker(this);
00230 this->last_user_action = widget;
00231 }
00232 break;
00233
00234 case TTW_MEASUREMENT_TOOL:
00235 HandlePlacePushButton(this, TTW_MEASUREMENT_TOOL, SPR_CURSOR_QUERY, HT_RECT);
00236 this->last_user_action = widget;
00237 break;
00238
00239 case TTW_COPY_PASTE:
00240
00241 this->HandleButtonClick(TTW_COPY_PASTE);
00242 ShowCopyPasteToolbarGui();
00243 break;
00244
00245 default: NOT_REACHED();
00246 }
00247 }
00248
00249 virtual void OnTimeout()
00250 {
00251 this->RaiseWidget(TTW_PLANT_TREES);
00252 this->SetWidgetDirty(TTW_PLANT_TREES);
00253 }
00254
00255 virtual EventState OnKeyPress(uint16 key, uint16 keycode)
00256 {
00257 int num = CheckHotkeyMatch(terraform_hotkeys, keycode, this);
00258 if (num == -1) return ES_NOT_HANDLED;
00259 this->OnClick(Point(), num, 1);
00260 return ES_HANDLED;
00261 }
00262
00263 virtual void OnPlaceObject(Point pt, TileIndex tile)
00264 {
00265 switch (this->last_user_action) {
00266 case TTW_LOWER_LAND:
00267 VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_LOWER_AND_LEVEL_AREA);
00268 break;
00269
00270 case TTW_RAISE_LAND:
00271 VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_RAISE_AND_LEVEL_AREA);
00272 break;
00273
00274 case TTW_LEVEL_LAND:
00275 VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_LEVEL_AREA);
00276 break;
00277
00278 case TTW_DEMOLISH:
00279 PlaceProc_DemolishArea(tile);
00280 break;
00281
00282 case TTW_BUY_LAND:
00283 DoCommandP(tile, OBJECT_OWNED_LAND, 0, CMD_BUILD_OBJECT | CMD_MSG(STR_ERROR_CAN_T_PURCHASE_THIS_LAND), CcPlaySound1E);
00284 break;
00285
00286 case TTW_PLACE_SIGN:
00287 PlaceProc_Sign(tile);
00288 break;
00289
00290 case TTW_PLACE_OBJECT:
00291 PlaceProc_Object(tile);
00292 break;
00293
00294 case TTW_MEASUREMENT_TOOL:
00295 VpStartPlaceSizing(tile, VPM_A_B_LINE, DDSP_MEASURE);
00296 break;
00297
00298 default: NOT_REACHED();
00299 }
00300 }
00301
00302 virtual void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt)
00303 {
00304 VpSelectTilesWithMethod(pt.x, pt.y, select_method);
00305 }
00306
00307 virtual Point OnInitialPosition(const WindowDesc *desc, int16 sm_width, int16 sm_height, int window_number)
00308 {
00309 Point pt = GetToolbarAlignedWindowPosition(sm_width);
00310 pt.y += sm_height;
00311 return pt;
00312 }
00313
00314 virtual void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile)
00315 {
00316 if (pt.x != -1) {
00317 switch (select_proc) {
00318 default: NOT_REACHED();
00319 case DDSP_DEMOLISH_AREA:
00320 case DDSP_RAISE_AND_LEVEL_AREA:
00321 case DDSP_LOWER_AND_LEVEL_AREA:
00322 case DDSP_LEVEL_AREA:
00323 GUIPlaceProcDragXY(select_proc, start_tile, end_tile);
00324 break;
00325 case DDSP_MEASURE:
00326
00327 break;
00328 }
00329 }
00330 }
00331
00332 virtual void OnPlaceObjectAbort()
00333 {
00334 DeleteWindowById(WC_BUILD_OBJECT, 0);
00335 this->RaiseButtons();
00336 }
00337
00338 static Hotkey<TerraformToolbarWindow> terraform_hotkeys[];
00339 };
00340
00341 Hotkey<TerraformToolbarWindow> TerraformToolbarWindow::terraform_hotkeys[] = {
00342 Hotkey<TerraformToolbarWindow>('Q' | WKC_GLOBAL_HOTKEY, "lower", TTW_LOWER_LAND),
00343 Hotkey<TerraformToolbarWindow>('W' | WKC_GLOBAL_HOTKEY, "raise", TTW_RAISE_LAND),
00344 Hotkey<TerraformToolbarWindow>('E' | WKC_GLOBAL_HOTKEY, "level", TTW_LEVEL_LAND),
00345 Hotkey<TerraformToolbarWindow>('D' | WKC_GLOBAL_HOTKEY, "dynamite", TTW_DEMOLISH),
00346 Hotkey<TerraformToolbarWindow>('U', "buyland", TTW_BUY_LAND),
00347 Hotkey<TerraformToolbarWindow>('I', "trees", TTW_PLANT_TREES),
00348 Hotkey<TerraformToolbarWindow>('O', "placesign", TTW_PLACE_SIGN),
00349 Hotkey<TerraformToolbarWindow>('P', "placeobject", TTW_PLACE_OBJECT),
00350 Hotkey<TerraformToolbarWindow>('R' | WKC_SHIFT, "ruler", TTW_MEASUREMENT_TOOL),
00351 HOTKEY_LIST_END(TerraformToolbarWindow)
00352 };
00353 Hotkey<TerraformToolbarWindow> *_terraform_hotkeys = TerraformToolbarWindow::terraform_hotkeys;
00354
00355 static const NWidgetPart _nested_terraform_widgets[] = {
00356 NWidget(NWID_HORIZONTAL),
00357 NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
00358 NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetDataTip(STR_LANDSCAPING_TOOLBAR, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
00359 NWidget(WWT_STICKYBOX, COLOUR_DARK_GREEN),
00360 EndContainer(),
00361 NWidget(NWID_HORIZONTAL),
00362 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, TTW_LOWER_LAND), SetMinimalSize(22, 22),
00363 SetFill(0, 1), SetDataTip(SPR_IMG_TERRAFORM_DOWN, STR_LANDSCAPING_TOOLTIP_LOWER_A_CORNER_OF_LAND),
00364 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, TTW_RAISE_LAND), SetMinimalSize(22, 22),
00365 SetFill(0, 1), SetDataTip(SPR_IMG_TERRAFORM_UP, STR_LANDSCAPING_TOOLTIP_RAISE_A_CORNER_OF_LAND),
00366 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, TTW_LEVEL_LAND), SetMinimalSize(22, 22),
00367 SetFill(0, 1), SetDataTip(SPR_IMG_LEVEL_LAND, STR_LANDSCAPING_LEVEL_LAND_TOOLTIP),
00368
00369 NWidget(WWT_PANEL, COLOUR_DARK_GREEN), SetMinimalSize(4, 22), EndContainer(),
00370
00371 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, TTW_DEMOLISH), SetMinimalSize(22, 22),
00372 SetFill(0, 1), SetDataTip(SPR_IMG_DYNAMITE, STR_TOOLTIP_DEMOLISH_BUILDINGS_ETC),
00373 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, TTW_BUY_LAND), SetMinimalSize(22, 22),
00374 SetFill(0, 1), SetDataTip(SPR_IMG_BUY_LAND, STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND),
00375 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, TTW_PLANT_TREES), SetMinimalSize(22, 22),
00376 SetFill(0, 1), SetDataTip(SPR_IMG_PLANTTREES, STR_SCENEDIT_TOOLBAR_PLANT_TREES),
00377 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, TTW_PLACE_SIGN), SetMinimalSize(22, 22),
00378 SetFill(0, 1), SetDataTip(SPR_IMG_SIGN, STR_SCENEDIT_TOOLBAR_PLACE_SIGN),
00379 NWidget(NWID_SELECTION, INVALID_COLOUR, TTW_SHOW_PLACE_OBJECT),
00380 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, TTW_PLACE_OBJECT), SetMinimalSize(22, 22),
00381 SetFill(0, 1), SetDataTip(SPR_IMG_TRANSMITTER, STR_SCENEDIT_TOOLBAR_PLACE_OBJECT),
00382 EndContainer(),
00383 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, TTW_MEASUREMENT_TOOL), SetMinimalSize(22,22),
00384 SetFill(0, 1), SetDataTip(SPR_IMG_QUERY, STR_LANDSCAPING_TOOLTIP_RULER_TOOL),
00385 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, TTW_COPY_PASTE), SetMinimalSize(22,22),
00386 SetFill(0, 1), SetDataTip(SPR_IMG_COPY, STR_COPY_PASTE_TOOLTIP),
00387 EndContainer(),
00388 };
00389
00390 static const WindowDesc _terraform_desc(
00391 WDP_MANUAL, 0, 0,
00392 WC_SCEN_LAND_GEN, WC_NONE,
00393 WDF_CONSTRUCTION,
00394 _nested_terraform_widgets, lengthof(_nested_terraform_widgets)
00395 );
00396
00402 Window *ShowTerraformToolbar(Window *link)
00403 {
00404 if (!Company::IsValidID(_local_company)) return NULL;
00405
00406 Window *w;
00407 if (link == NULL) {
00408 w = AllocateWindowDescFront<TerraformToolbarWindow>(&_terraform_desc, 0);
00409 return w;
00410 }
00411
00412
00413 DeleteWindowById(WC_SCEN_LAND_GEN, 0, true);
00414 w = AllocateWindowDescFront<TerraformToolbarWindow>(&_terraform_desc, 0);
00415
00416 w->top -= w->height;
00417 w->SetDirty();
00418
00419 link->left = w->left + (_current_text_dir == TD_RTL ? w->width : -link->width);
00420 link->top = w->top;
00421 link->SetDirty();
00422
00423 return w;
00424 }
00425
00426 EventState TerraformToolbarGlobalHotkeys(uint16 key, uint16 keycode)
00427 {
00428 int num = CheckHotkeyMatch<TerraformToolbarWindow>(_terraform_hotkeys, keycode, NULL, true);
00429 if (num == -1) return ES_NOT_HANDLED;
00430 Window *w = ShowTerraformToolbar(NULL);
00431 if (w == NULL) return ES_NOT_HANDLED;
00432 return w->OnKeyPress(key, keycode);
00433 }
00434
00435 static byte _terraform_size = 1;
00436
00446 static void CommonRaiseLowerBigLand(TileIndex tile, int mode)
00447 {
00448 if (_terraform_size == 1) {
00449 StringID msg =
00450 mode ? STR_ERROR_CAN_T_RAISE_LAND_HERE : STR_ERROR_CAN_T_LOWER_LAND_HERE;
00451
00452 DoCommandP(tile, SLOPE_N, (uint32)mode, CMD_TERRAFORM_LAND | CMD_MSG(msg), CcTerraform);
00453 } else {
00454 assert(_terraform_size != 0);
00455 TileArea ta(tile, _terraform_size, _terraform_size);
00456 ta.ClampToMap();
00457
00458 if (ta.w == 0 || ta.h == 0) return;
00459
00460 SndPlayTileFx(SND_1F_SPLAT, tile);
00461
00462 uint h;
00463 if (mode != 0) {
00464
00465 h = GetMaxTileHeight();
00466 TILE_AREA_LOOP(tile2, ta) {
00467 h = min(h, TileHeight(tile2));
00468 }
00469 } else {
00470
00471 h = 0;
00472 TILE_AREA_LOOP(tile2, ta) {
00473 h = max(h, TileHeight(tile2));
00474 }
00475 }
00476
00477 TILE_AREA_LOOP(tile2, ta) {
00478 if (TileHeight(tile2) == h) {
00479 DoCommandP(tile2, SLOPE_N, (uint32)mode, CMD_TERRAFORM_LAND);
00480 }
00481 }
00482 }
00483 }
00484
00485 static const int8 _multi_terraform_coords[][2] = {
00486 { 0, -2},
00487 { 4, 0}, { -4, 0}, { 0, 2},
00488 { -8, 2}, { -4, 4}, { 0, 6}, { 4, 4}, { 8, 2},
00489 {-12, 0}, { -8, -2}, { -4, -4}, { 0, -6}, { 4, -4}, { 8, -2}, { 12, 0},
00490 {-16, 2}, {-12, 4}, { -8, 6}, { -4, 8}, { 0, 10}, { 4, 8}, { 8, 6}, { 12, 4}, { 16, 2},
00491 {-20, 0}, {-16, -2}, {-12, -4}, { -8, -6}, { -4, -8}, { 0,-10}, { 4, -8}, { 8, -6}, { 12, -4}, { 16, -2}, { 20, 0},
00492 {-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},
00493 {-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},
00494 };
00495
00497 enum EditorTerraformToolbarWidgets {
00498 ETTW_SHOW_PLACE_DESERT,
00499 ETTW_START,
00500 ETTW_DOTS = ETTW_START,
00501 ETTW_BUTTONS_START,
00502 ETTW_DEMOLISH = ETTW_BUTTONS_START,
00503 ETTW_LOWER_LAND,
00504 ETTW_RAISE_LAND,
00505 ETTW_LEVEL_LAND,
00506 ETTW_PLACE_ROCKS,
00507 ETTW_PLACE_DESERT,
00508 ETTW_PLACE_OBJECT,
00509 ETTW_MEASUREMENT_TOOL,
00510 ETTW_BUTTONS_END,
00511 ETTW_INCREASE_SIZE = ETTW_BUTTONS_END,
00512 ETTW_DECREASE_SIZE,
00513 ETTW_NEW_SCENARIO,
00514 ETTW_RESET_LANDSCAPE,
00515 };
00516
00517 static const NWidgetPart _nested_scen_edit_land_gen_widgets[] = {
00518 NWidget(NWID_HORIZONTAL),
00519 NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
00520 NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetDataTip(STR_TERRAFORM_TOOLBAR_LAND_GENERATION_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
00521 NWidget(WWT_SHADEBOX, COLOUR_DARK_GREEN),
00522 NWidget(WWT_STICKYBOX, COLOUR_DARK_GREEN),
00523 EndContainer(),
00524 NWidget(WWT_PANEL, COLOUR_DARK_GREEN),
00525 NWidget(NWID_HORIZONTAL), SetPadding(2, 2, 7, 2),
00526 NWidget(NWID_SPACER), SetFill(1, 0),
00527 NWidget(WWT_IMGBTN, COLOUR_GREY, ETTW_DEMOLISH), SetMinimalSize(22, 22),
00528 SetFill(0, 1), SetDataTip(SPR_IMG_DYNAMITE, STR_TOOLTIP_DEMOLISH_BUILDINGS_ETC),
00529 NWidget(WWT_IMGBTN, COLOUR_GREY, ETTW_LOWER_LAND), SetMinimalSize(22, 22),
00530 SetFill(0, 1), SetDataTip(SPR_IMG_TERRAFORM_DOWN, STR_LANDSCAPING_TOOLTIP_LOWER_A_CORNER_OF_LAND),
00531 NWidget(WWT_IMGBTN, COLOUR_GREY, ETTW_RAISE_LAND), SetMinimalSize(22, 22),
00532 SetFill(0, 1), SetDataTip(SPR_IMG_TERRAFORM_UP, STR_LANDSCAPING_TOOLTIP_RAISE_A_CORNER_OF_LAND),
00533 NWidget(WWT_IMGBTN, COLOUR_GREY, ETTW_LEVEL_LAND), SetMinimalSize(22, 22),
00534 SetFill(0, 1), SetDataTip(SPR_IMG_LEVEL_LAND, STR_LANDSCAPING_LEVEL_LAND_TOOLTIP),
00535 NWidget(WWT_IMGBTN, COLOUR_GREY, ETTW_PLACE_ROCKS), SetMinimalSize(22, 22),
00536 SetFill(0, 1), SetDataTip(SPR_IMG_ROCKS, STR_TERRAFORM_TOOLTIP_PLACE_ROCKY_AREAS_ON_LANDSCAPE),
00537 NWidget(NWID_SELECTION, INVALID_COLOUR, ETTW_SHOW_PLACE_DESERT),
00538 NWidget(WWT_IMGBTN, COLOUR_GREY, ETTW_PLACE_DESERT), SetMinimalSize(22, 22),
00539 SetFill(0, 1), SetDataTip(SPR_IMG_DESERT, STR_TERRAFORM_TOOLTIP_DEFINE_DESERT_AREA),
00540 EndContainer(),
00541 NWidget(WWT_IMGBTN, COLOUR_GREY, ETTW_PLACE_OBJECT), SetMinimalSize(23, 22),
00542 SetFill(0, 1), SetDataTip(SPR_IMG_TRANSMITTER, STR_SCENEDIT_TOOLBAR_PLACE_OBJECT),
00543 NWidget(WWT_IMGBTN, COLOUR_GREY, ETTW_MEASUREMENT_TOOL), SetMinimalSize(22,22),
00544 SetFill(0, 1), SetDataTip(SPR_IMG_QUERY, STR_LANDSCAPING_TOOLTIP_RULER_TOOL),
00545 NWidget(NWID_SPACER), SetFill(1, 0),
00546 EndContainer(),
00547 NWidget(NWID_HORIZONTAL),
00548 NWidget(NWID_SPACER), SetFill(1, 0),
00549 NWidget(WWT_EMPTY, COLOUR_DARK_GREEN, ETTW_DOTS), SetMinimalSize(59, 31), SetDataTip(STR_EMPTY, STR_NULL),
00550 NWidget(NWID_SPACER), SetFill(1, 0),
00551 NWidget(NWID_VERTICAL),
00552 NWidget(NWID_SPACER), SetFill(0, 1),
00553 NWidget(WWT_IMGBTN, COLOUR_GREY, ETTW_INCREASE_SIZE), SetMinimalSize(12, 12), SetDataTip(SPR_ARROW_UP, STR_TERRAFORM_TOOLTIP_INCREASE_SIZE_OF_LAND_AREA),
00554 NWidget(NWID_SPACER), SetMinimalSize(0, 1),
00555 NWidget(WWT_IMGBTN, COLOUR_GREY, ETTW_DECREASE_SIZE), SetMinimalSize(12, 12), SetDataTip(SPR_ARROW_DOWN, STR_TERRAFORM_TOOLTIP_DECREASE_SIZE_OF_LAND_AREA),
00556 NWidget(NWID_SPACER), SetFill(0, 1),
00557 EndContainer(),
00558 NWidget(NWID_SPACER), SetMinimalSize(2, 0),
00559 EndContainer(),
00560 NWidget(NWID_SPACER), SetMinimalSize(0, 6),
00561 NWidget(WWT_TEXTBTN, COLOUR_GREY, ETTW_NEW_SCENARIO), SetMinimalSize(160, 12),
00562 SetFill(1, 0), SetDataTip(STR_TERRAFORM_SE_NEW_WORLD, STR_TERRAFORM_TOOLTIP_GENERATE_RANDOM_LAND), SetPadding(0, 2, 0, 2),
00563 NWidget(WWT_TEXTBTN, COLOUR_GREY, ETTW_RESET_LANDSCAPE), SetMinimalSize(160, 12),
00564 SetFill(1, 0), SetDataTip(STR_TERRAFORM_RESET_LANDSCAPE, STR_TERRAFORM_RESET_LANDSCAPE_TOOLTIP), SetPadding(1, 2, 2, 2),
00565 EndContainer(),
00566 };
00567
00573 static void ResetLandscapeConfirmationCallback(Window *w, bool confirmed)
00574 {
00575 if (confirmed) {
00576
00577
00578 _generating_world = true;
00579
00580
00581 Company *c;
00582 FOR_ALL_COMPANIES(c) {
00583 ChangeOwnershipOfCompanyItems(c->index, INVALID_OWNER);
00584 delete c;
00585 }
00586
00587 _generating_world = false;
00588
00589
00590 BaseStation *st;
00591 FOR_ALL_BASE_STATIONS(st) {
00592
00593 if (IsBuoyTile(st->xy)) DoCommand(st->xy, 0, 0, DC_EXEC | DC_BANKRUPT, CMD_LANDSCAPE_CLEAR);
00594 if (!st->IsInUse()) delete st;
00595 }
00596
00597
00598 EngineOverrideManager::ResetToCurrentNewGRFConfig();
00599
00600 MarkWholeScreenDirty();
00601 }
00602 }
00603
00605 struct ScenarioEditorLandscapeGenerationWindow : Window {
00606 int last_user_action;
00607
00608 ScenarioEditorLandscapeGenerationWindow(const WindowDesc *desc, WindowNumber window_number) : Window()
00609 {
00610 this->CreateNestedTree(desc);
00611 NWidgetStacked *show_desert = this->GetWidget<NWidgetStacked>(ETTW_SHOW_PLACE_DESERT);
00612 show_desert->SetDisplayedPlane(_settings_game.game_creation.landscape == LT_TROPIC ? 0 : SZSP_NONE);
00613 this->FinishInitNested(desc, window_number);
00614 this->last_user_action = WIDGET_LIST_END;
00615 }
00616
00617 virtual void OnPaint()
00618 {
00619 this->DrawWidgets();
00620
00621 if (this->IsWidgetLowered(ETTW_LOWER_LAND) || this->IsWidgetLowered(ETTW_RAISE_LAND)) {
00622 SetTileSelectSize(_terraform_size, _terraform_size);
00623 }
00624 }
00625
00626 virtual void DrawWidget(const Rect &r, int widget) const
00627 {
00628 if (widget != ETTW_DOTS) return;
00629
00630 int center_x = RoundDivSU(r.left + r.right, 2);
00631 int center_y = RoundDivSU(r.top + r.bottom, 2);
00632
00633 int n = _terraform_size * _terraform_size;
00634 const int8 *coords = &_multi_terraform_coords[0][0];
00635
00636 assert(n != 0);
00637 do {
00638 DrawSprite(SPR_WHITE_POINT, PAL_NONE, center_x + coords[0], center_y + coords[1]);
00639 coords += 2;
00640 } while (--n);
00641 }
00642
00643 virtual EventState OnKeyPress(uint16 key, uint16 keycode)
00644 {
00645 int num = CheckHotkeyMatch(terraform_editor_hotkeys, keycode, this);
00646 if (num == -1) return ES_NOT_HANDLED;
00647 this->OnClick(Point(), num, 1);
00648 return ES_HANDLED;
00649 }
00650
00651 virtual void OnClick(Point pt, int widget, int click_count)
00652 {
00653 if (widget < ETTW_BUTTONS_START) return;
00654
00655 switch (widget) {
00656 case ETTW_DEMOLISH:
00657 HandlePlacePushButton(this, ETTW_DEMOLISH, ANIMCURSOR_DEMOLISH, HT_RECT | HT_DIAGONAL);
00658 this->last_user_action = widget;
00659 break;
00660
00661 case ETTW_LOWER_LAND:
00662 HandlePlacePushButton(this, ETTW_LOWER_LAND, ANIMCURSOR_LOWERLAND, HT_POINT);
00663 this->last_user_action = widget;
00664 break;
00665
00666 case ETTW_RAISE_LAND:
00667 HandlePlacePushButton(this, ETTW_RAISE_LAND, ANIMCURSOR_RAISELAND, HT_POINT);
00668 this->last_user_action = widget;
00669 break;
00670
00671 case ETTW_LEVEL_LAND:
00672 HandlePlacePushButton(this, ETTW_LEVEL_LAND, SPR_CURSOR_LEVEL_LAND, HT_POINT | HT_DIAGONAL);
00673 this->last_user_action = widget;
00674 break;
00675
00676 case ETTW_PLACE_ROCKS:
00677 HandlePlacePushButton(this, ETTW_PLACE_ROCKS, SPR_CURSOR_ROCKY_AREA, HT_RECT);
00678 this->last_user_action = widget;
00679 break;
00680
00681 case ETTW_PLACE_DESERT:
00682 HandlePlacePushButton(this, ETTW_PLACE_DESERT, SPR_CURSOR_DESERT, HT_RECT);
00683 this->last_user_action = widget;
00684 break;
00685
00686 case ETTW_PLACE_OBJECT:
00687 if (HandlePlacePushButton(this, ETTW_PLACE_OBJECT, SPR_CURSOR_TRANSMITTER, HT_RECT)) {
00688 ShowBuildObjectPicker(this);
00689 this->last_user_action = widget;
00690 }
00691 break;
00692
00693 case ETTW_MEASUREMENT_TOOL:
00694 HandlePlacePushButton(this, ETTW_MEASUREMENT_TOOL, SPR_CURSOR_QUERY, HT_RECT);
00695 this->last_user_action = widget;
00696 break;
00697
00698 case ETTW_INCREASE_SIZE:
00699 case ETTW_DECREASE_SIZE: {
00700 int size = (widget == ETTW_INCREASE_SIZE) ? 1 : -1;
00701 this->HandleButtonClick(widget);
00702 size += _terraform_size;
00703
00704 if (!IsInsideMM(size, 1, 8 + 1)) return;
00705 _terraform_size = size;
00706
00707 SndPlayFx(SND_15_BEEP);
00708 this->SetDirty();
00709 break;
00710 }
00711
00712 case ETTW_NEW_SCENARIO:
00713 this->HandleButtonClick(widget);
00714 ShowCreateScenario();
00715 break;
00716
00717 case ETTW_RESET_LANDSCAPE:
00718 ShowQuery(STR_QUERY_RESET_LANDSCAPE_CAPTION, STR_RESET_LANDSCAPE_CONFIRMATION_TEXT, NULL, ResetLandscapeConfirmationCallback);
00719 break;
00720
00721 default: NOT_REACHED();
00722 }
00723 }
00724
00725 virtual void OnTimeout()
00726 {
00727 for (uint i = ETTW_START; i < this->nested_array_size; i++) {
00728 if (i == ETTW_BUTTONS_START) i = ETTW_BUTTONS_END;
00729 if (this->IsWidgetLowered(i)) {
00730 this->RaiseWidget(i);
00731 this->SetWidgetDirty(i);
00732 }
00733 }
00734 }
00735
00736 virtual void OnPlaceObject(Point pt, TileIndex tile)
00737 {
00738 switch (this->last_user_action) {
00739 case ETTW_DEMOLISH:
00740 PlaceProc_DemolishArea(tile);
00741 break;
00742
00743 case ETTW_LOWER_LAND:
00744 CommonRaiseLowerBigLand(tile, 0);
00745 break;
00746
00747 case ETTW_RAISE_LAND:
00748 CommonRaiseLowerBigLand(tile, 1);
00749 break;
00750
00751 case ETTW_LEVEL_LAND:
00752 VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_LEVEL_AREA);
00753 break;
00754
00755 case ETTW_PLACE_ROCKS:
00756 VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_CREATE_ROCKS);
00757 break;
00758
00759 case ETTW_PLACE_DESERT:
00760 VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_CREATE_DESERT);
00761 break;
00762
00763 case ETTW_PLACE_OBJECT:
00764 PlaceProc_Object(tile);
00765 break;
00766
00767 case ETTW_MEASUREMENT_TOOL:
00768 VpStartPlaceSizing(tile, VPM_A_B_LINE, DDSP_MEASURE);
00769 break;
00770
00771 default: NOT_REACHED();
00772 }
00773 }
00774
00775 virtual void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt)
00776 {
00777 VpSelectTilesWithMethod(pt.x, pt.y, select_method);
00778 }
00779
00780 virtual void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile)
00781 {
00782 if (pt.x != -1) {
00783 switch (select_proc) {
00784 default: NOT_REACHED();
00785 case DDSP_CREATE_ROCKS:
00786 case DDSP_CREATE_DESERT:
00787 case DDSP_RAISE_AND_LEVEL_AREA:
00788 case DDSP_LOWER_AND_LEVEL_AREA:
00789 case DDSP_LEVEL_AREA:
00790 case DDSP_DEMOLISH_AREA:
00791 GUIPlaceProcDragXY(select_proc, start_tile, end_tile);
00792 break;
00793 case DDSP_MEASURE:
00794
00795 break;
00796 }
00797 }
00798 }
00799
00800 virtual void OnPlaceObjectAbort()
00801 {
00802 this->RaiseButtons();
00803 this->SetDirty();
00804 DeleteWindowById(WC_BUILD_OBJECT, 0);
00805 }
00806
00807 static Hotkey<ScenarioEditorLandscapeGenerationWindow> terraform_editor_hotkeys[];
00808 };
00809
00810 Hotkey<ScenarioEditorLandscapeGenerationWindow> ScenarioEditorLandscapeGenerationWindow::terraform_editor_hotkeys[] = {
00811 Hotkey<ScenarioEditorLandscapeGenerationWindow>('D' | WKC_GLOBAL_HOTKEY, "dynamite", ETTW_DEMOLISH),
00812 Hotkey<ScenarioEditorLandscapeGenerationWindow>('Q' | WKC_GLOBAL_HOTKEY, "lower", ETTW_LOWER_LAND),
00813 Hotkey<ScenarioEditorLandscapeGenerationWindow>('W' | WKC_GLOBAL_HOTKEY, "raise", ETTW_RAISE_LAND),
00814 Hotkey<ScenarioEditorLandscapeGenerationWindow>('E' | WKC_GLOBAL_HOTKEY, "level", ETTW_LEVEL_LAND),
00815 Hotkey<ScenarioEditorLandscapeGenerationWindow>('R', "rocky", ETTW_PLACE_ROCKS),
00816 Hotkey<ScenarioEditorLandscapeGenerationWindow>('T', "desert", ETTW_PLACE_DESERT),
00817 Hotkey<ScenarioEditorLandscapeGenerationWindow>('O', "object", ETTW_PLACE_OBJECT),
00818 Hotkey<ScenarioEditorLandscapeGenerationWindow>('R' | WKC_SHIFT, "ruler", ETTW_MEASUREMENT_TOOL),
00819 HOTKEY_LIST_END(ScenarioEditorLandscapeGenerationWindow)
00820 };
00821
00822 Hotkey<ScenarioEditorLandscapeGenerationWindow> *_terraform_editor_hotkeys = ScenarioEditorLandscapeGenerationWindow::terraform_editor_hotkeys;
00823
00824 static const WindowDesc _scen_edit_land_gen_desc(
00825 WDP_AUTO, 0, 0,
00826 WC_SCEN_LAND_GEN, WC_NONE,
00827 WDF_CONSTRUCTION,
00828 _nested_scen_edit_land_gen_widgets, lengthof(_nested_scen_edit_land_gen_widgets)
00829 );
00830
00835 Window *ShowEditorTerraformToolbar()
00836 {
00837 return AllocateWindowDescFront<ScenarioEditorLandscapeGenerationWindow>(&_scen_edit_land_gen_desc, 0);
00838 }
00839
00840 EventState TerraformToolbarEditorGlobalHotkeys(uint16 key, uint16 keycode)
00841 {
00842 int num = CheckHotkeyMatch<ScenarioEditorLandscapeGenerationWindow>(_terraform_editor_hotkeys, keycode, NULL, true);
00843 if (num == -1) return ES_NOT_HANDLED;
00844 Window *w = ShowEditorTerraformToolbar();
00845 if (w == NULL) return ES_NOT_HANDLED;
00846 return w->OnKeyPress(key, keycode);
00847 }