tron@2186: /* $Id$ */ tron@2186: truelight@0: #include "stdafx.h" Darkvater@1891: #include "openttd.h" tron@1363: #include "table/sprites.h" tron@507: #include "table/strings.h" tron@2163: #include "functions.h" tron@2154: #include "player.h" Darkvater@1632: #include "tile.h" truelight@0: #include "window.h" truelight@0: #include "gui.h" truelight@0: #include "viewport.h" tron@2790: #include "gfx.h" tron@337: #include "sound.h" truelight@0: #include "command.h" truelight@0: #include "vehicle.h" truelight@988: #include "signs.h" tron@2159: #include "variables.h" truelight@0: tron@1977: void CcTerraform(bool success, TileIndex tile, uint32 p1, uint32 p2) truelight@0: { truelight@0: if (success) { tron@541: SndPlayTileFx(SND_1F_SPLAT, tile); truelight@0: } else { truelight@0: SetRedErrorSquare(_terraform_err_tile); truelight@0: } truelight@0: } truelight@0: tron@1977: static void GenericRaiseLowerLand(TileIndex tile, int mode) truelight@0: { truelight@0: if (mode) { truelight@193: DoCommandP(tile, 8, (uint32)mode, CcTerraform, CMD_TERRAFORM_LAND | CMD_AUTO | CMD_MSG(STR_0808_CAN_T_RAISE_LAND_HERE)); truelight@0: } else { truelight@193: DoCommandP(tile, 8, (uint32)mode, CcTerraform, CMD_TERRAFORM_LAND | CMD_AUTO | CMD_MSG(STR_0809_CAN_T_LOWER_LAND_HERE)); truelight@0: } truelight@0: } truelight@0: Darkvater@1632: /** Scenario editor command that generates desert areas */ Darkvater@1632: static void GenerateDesertArea(TileIndex end, TileIndex start) Darkvater@1632: { Darkvater@1632: int size_x, size_y; Darkvater@1632: int sx = TileX(start); Darkvater@1632: int sy = TileY(start); Darkvater@1632: int ex = TileX(end); Darkvater@1632: int ey = TileY(end); Darkvater@1632: Darkvater@1632: if (_game_mode != GM_EDITOR) return; Darkvater@1632: Darkvater@1632: if (ex < sx) intswap(ex, sx); Darkvater@1632: if (ey < sy) intswap(ey, sy); Darkvater@1632: size_x = (ex - sx) + 1; Darkvater@1632: size_y = (ey - sy) + 1; Darkvater@1632: Darkvater@1710: _generating_world = true; tron@1981: BEGIN_TILE_LOOP(tile, size_x, size_y, TileXY(sx, sy)) { Darkvater@1710: if (GetTileType(tile) != MP_WATER) { Darkvater@1710: SetMapExtraBits(tile, (_ctrl_pressed) ? 0 : 1); Darkvater@1780: DoCommandP(tile, 0, 0, NULL, CMD_LANDSCAPE_CLEAR); Darkvater@1710: MarkTileDirtyByTile(tile); Darkvater@1710: } Darkvater@1632: } END_TILE_LOOP(tile, size_x, size_y, 0); Darkvater@1710: _generating_world = false; Darkvater@1632: } Darkvater@1632: Darkvater@2615: /** Scenario editor command that generates desert areas */ Darkvater@2615: static void GenerateRockyArea(TileIndex end, TileIndex start) Darkvater@2615: { Darkvater@2615: int size_x, size_y; Darkvater@2615: bool success = false; Darkvater@2615: int sx = TileX(start); Darkvater@2615: int sy = TileY(start); Darkvater@2615: int ex = TileX(end); Darkvater@2615: int ey = TileY(end); Darkvater@2615: Darkvater@2615: if (_game_mode != GM_EDITOR) return; Darkvater@2615: Darkvater@2615: if (ex < sx) intswap(ex, sx); Darkvater@2615: if (ey < sy) intswap(ey, sy); Darkvater@2615: size_x = (ex - sx) + 1; Darkvater@2615: size_y = (ey - sy) + 1; Darkvater@2615: Darkvater@2615: BEGIN_TILE_LOOP(tile, size_x, size_y, TileXY(sx, sy)) { Darkvater@2615: if (IsTileType(tile, MP_CLEAR) || IsTileType(tile, MP_TREES)) { Darkvater@2615: ModifyTile(tile, MP_SETTYPE(MP_CLEAR) | MP_MAP5, (_m[tile].m5 & ~0x1C) | 0xB); Darkvater@2615: success = true; Darkvater@2615: } Darkvater@2615: } END_TILE_LOOP(tile, size_x, size_y, 0); Darkvater@2615: Darkvater@2615: if (success) SndPlayTileFx(SND_1F_SPLAT, end); Darkvater@2615: } Darkvater@2615: Darkvater@1632: /** Darkvater@1632: * A central place to handle all X_AND_Y dragged GUI functions. Darkvater@1632: * @param we @WindowEvent variable holding in its higher bits (excluding the lower Darkvater@1632: * 4, since that defined the X_Y drag) the type of action to be performed Darkvater@1632: * @return Returns true if the action was found and handled, and false otherwise. This Darkvater@1632: * allows for additional implements that are more local. For example X_Y drag Darkvater@1632: * of convertrail which belongs in rail_gui.c and not terraform_gui.c Darkvater@1632: **/ Darkvater@1632: bool GUIPlaceProcDragXY(const WindowEvent *we) Darkvater@1632: { Darkvater@1632: TileIndex start_tile = we->place.starttile; Darkvater@1632: TileIndex end_tile = we->place.tile; Darkvater@1632: Darkvater@1632: switch (we->place.userdata >> 4) { Darkvater@1632: case GUI_PlaceProc_DemolishArea >> 4: Darkvater@1632: DoCommandP(end_tile, start_tile, 0, CcPlaySound10, CMD_CLEAR_AREA | CMD_MSG(STR_00B5_CAN_T_CLEAR_THIS_AREA)); Darkvater@1632: break; Darkvater@1632: case GUI_PlaceProc_LevelArea >> 4: Darkvater@1632: DoCommandP(end_tile, start_tile, 0, CcPlaySound10, CMD_LEVEL_LAND | CMD_AUTO); Darkvater@1632: break; Darkvater@2615: case GUI_PlaceProc_RockyArea >> 4: Darkvater@2615: GenerateRockyArea(end_tile, start_tile); Darkvater@2615: break; Darkvater@1632: case GUI_PlaceProc_DesertArea >> 4: Darkvater@1632: GenerateDesertArea(end_tile, start_tile); Darkvater@1632: break; Darkvater@1632: case GUI_PlaceProc_WaterArea >> 4: Darkvater@1632: DoCommandP(end_tile, start_tile, 0, CcBuildCanal, CMD_BUILD_CANAL | CMD_AUTO | CMD_MSG(STR_CANT_BUILD_CANALS)); Darkvater@1632: break; Darkvater@1632: default: return false; Darkvater@1632: } Darkvater@1632: Darkvater@1632: return true; Darkvater@1632: } truelight@0: truelight@0: typedef void OnButtonClick(Window *w); truelight@0: truelight@0: static const uint16 _terraform_keycodes[] = { dominik@606: 'Q', dominik@606: 'W', dominik@606: 'E', dominik@936: 'D', dominik@606: 'U', dominik@606: 'I', dominik@613: 'O', truelight@0: }; truelight@0: tron@1977: void PlaceProc_DemolishArea(TileIndex tile) truelight@0: { Darkvater@1632: VpStartPlaceSizing(tile, VPM_X_AND_Y | GUI_PlaceProc_DemolishArea); truelight@0: } truelight@0: tron@2817: static void PlaceProc_RaiseLand(TileIndex tile) truelight@0: { truelight@0: GenericRaiseLowerLand(tile, 1); truelight@0: } truelight@0: tron@2817: static void PlaceProc_LowerLand(TileIndex tile) truelight@0: { truelight@0: GenericRaiseLowerLand(tile, 0); truelight@0: } truelight@0: tron@1977: void PlaceProc_LevelLand(TileIndex tile) truelight@0: { Darkvater@1632: VpStartPlaceSizing(tile, VPM_X_AND_Y | GUI_PlaceProc_LevelArea); truelight@0: } truelight@0: tron@1977: static void PlaceProc_PlantTree(TileIndex tile) {} truelight@0: truelight@0: static void TerraformClick_Lower(Window *w) truelight@0: { darkvater@756: HandlePlacePushButton(w, 4, ANIMCURSOR_LOWERLAND, 2, PlaceProc_LowerLand); truelight@0: } truelight@0: truelight@0: static void TerraformClick_Raise(Window *w) truelight@0: { darkvater@756: HandlePlacePushButton(w, 5, ANIMCURSOR_RAISELAND, 2, PlaceProc_RaiseLand); truelight@0: } truelight@0: truelight@0: static void TerraformClick_Level(Window *w) truelight@0: { Darkvater@1919: HandlePlacePushButton(w, 6, SPR_CURSOR_LEVEL_LAND, 2, PlaceProc_LevelLand); truelight@0: } truelight@0: dominik@936: static void TerraformClick_Dynamite(Window *w) dominik@936: { Darkvater@1914: HandlePlacePushButton(w, 7, ANIMCURSOR_DEMOLISH , 1, PlaceProc_DemolishArea); dominik@936: } dominik@936: truelight@0: static void TerraformClick_BuyLand(Window *w) truelight@0: { Darkvater@1914: HandlePlacePushButton(w, 8, SPR_CURSOR_BUY_LAND, 1, PlaceProc_BuyLand); truelight@0: } truelight@0: truelight@0: static void TerraformClick_Trees(Window *w) truelight@0: { Darkvater@1914: if (HandlePlacePushButton(w, 9, SPR_CURSOR_MOUSE, 1, PlaceProc_PlantTree)) ShowBuildTreesToolbar(); truelight@0: } truelight@0: truelight@0: static void TerraformClick_PlaceSign(Window *w) truelight@0: { Darkvater@1914: HandlePlacePushButton(w, 10, SPR_CURSOR_SIGN, 1, PlaceProc_Sign); truelight@0: } truelight@0: truelight@0: static OnButtonClick * const _terraform_button_proc[] = { truelight@0: TerraformClick_Lower, truelight@0: TerraformClick_Raise, truelight@0: TerraformClick_Level, dominik@936: TerraformClick_Dynamite, truelight@0: TerraformClick_BuyLand, truelight@0: TerraformClick_Trees, truelight@0: TerraformClick_PlaceSign, truelight@0: }; truelight@0: truelight@0: static void TerraformToolbWndProc(Window *w, WindowEvent *e) truelight@0: { truelight@0: switch(e->event) { truelight@0: case WE_PAINT: truelight@0: DrawWindowWidgets(w); truelight@0: break; tron@2639: truelight@0: case WE_CLICK: tron@2639: if (e->click.widget >= 4) _terraform_button_proc[e->click.widget - 4](w); truelight@0: break; truelight@0: tron@2639: case WE_KEYPRESS: { tron@2639: uint i; dominik@616: tron@2639: for (i = 0; i != lengthof(_terraform_keycodes); i++) { truelight@0: if (e->keypress.keycode == _terraform_keycodes[i]) { truelight@0: e->keypress.cont = false; truelight@0: _terraform_button_proc[i](w); truelight@0: break; truelight@0: } tron@2639: } tron@2639: break; truelight@0: } truelight@0: truelight@0: case WE_PLACE_OBJ: truelight@0: _place_proc(e->place.tile); truelight@0: return; truelight@0: truelight@0: case WE_PLACE_DRAG: truelight@0: VpSelectTilesWithMethod(e->place.pt.x, e->place.pt.y, e->place.userdata & 0xF); truelight@0: break; truelight@0: truelight@0: case WE_PLACE_MOUSEUP: truelight@0: if (e->click.pt.x != -1) { Darkvater@1632: if ((e->place.userdata & 0xF) == VPM_X_AND_Y) // dragged actions Darkvater@1632: GUIPlaceProcDragXY(e); truelight@0: } truelight@0: break; truelight@0: truelight@0: case WE_ABORT_PLACE_OBJ: darkvater@756: UnclickWindowButtons(w); truelight@0: SetWindowDirty(w); truelight@0: truelight@0: w = FindWindowById(WC_BUILD_STATION, 0); truelight@0: if (w != NULL) WP(w,def_d).close=true; truelight@0: w = FindWindowById(WC_BUILD_DEPOT, 0); truelight@0: if (w != NULL) WP(w,def_d).close=true; truelight@0: break; truelight@0: truelight@0: case WE_PLACE_PRESIZE: { truelight@0: } break; truelight@0: } truelight@0: } truelight@0: truelight@0: static const Widget _terraform_widgets[] = { Darkvater@1632: { WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, Darkvater@1632: { WWT_CAPTION, RESIZE_NONE, 7, 11, 145, 0, 13, STR_LANDSCAPING_TOOLBAR, STR_018C_WINDOW_TITLE_DRAG_THIS}, Darkvater@1632: {WWT_STICKYBOX, RESIZE_NONE, 7, 146, 157, 0, 13, STR_NULL, STR_STICKY_BUTTON}, truelight@867: Darkvater@1632: { WWT_PANEL, RESIZE_NONE, 7, 66, 69, 14, 35, STR_NULL, STR_NULL}, Darkvater@1632: { WWT_PANEL, RESIZE_NONE, 7, 0, 21, 14, 35, SPR_IMG_TERRAFORM_DOWN, STR_018E_LOWER_A_CORNER_OF_LAND}, Darkvater@1632: { WWT_PANEL, RESIZE_NONE, 7, 22, 43, 14, 35, SPR_IMG_TERRAFORM_UP, STR_018F_RAISE_A_CORNER_OF_LAND}, Darkvater@1632: { WWT_PANEL, RESIZE_NONE, 7, 44, 65, 14, 35, SPR_IMG_LEVEL_LAND, STR_LEVEL_LAND_TOOLTIP}, Darkvater@1632: { WWT_PANEL, RESIZE_NONE, 7, 70, 91, 14, 35, SPR_IMG_DYNAMITE, STR_018D_DEMOLISH_BUILDINGS_ETC}, Darkvater@1632: { WWT_PANEL, RESIZE_NONE, 7, 92, 113, 14, 35, SPR_IMG_BUY_LAND, STR_0329_PURCHASE_LAND_FOR_FUTURE}, Darkvater@1632: { WWT_PANEL, RESIZE_NONE, 7, 114, 135, 14, 35, SPR_IMG_PLANTTREES, STR_0185_PLANT_TREES_PLACE_SIGNS}, Darkvater@1632: { WWT_PANEL, RESIZE_NONE, 7, 136, 157, 14, 35, SPR_IMG_PLACE_SIGN, STR_0289_PLACE_SIGN}, truelight@0: darkvater@176: { WIDGETS_END}, truelight@0: }; truelight@0: truelight@0: static const WindowDesc _terraform_desc = { darkvater@987: 640-157, 22+36, 158, 36, truelight@0: WC_SCEN_LAND_GEN,0, darkvater@756: WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_STICKY_BUTTON, truelight@0: _terraform_widgets, truelight@0: TerraformToolbWndProc truelight@0: }; truelight@0: tron@1093: void ShowTerraformToolbar(void) truelight@0: { dominik@946: if (_current_player == OWNER_SPECTATOR) return; truelight@0: AllocateWindowDescFront(&_terraform_desc, 0); truelight@0: }