00001
00002
00005 #include "stdafx.h"
00006 #include "openttd.h"
00007 #include "tile_map.h"
00008 #include "station.h"
00009 #include "gui.h"
00010 #include "terraform_gui.h"
00011 #include "window_gui.h"
00012 #include "station_gui.h"
00013 #include "command_func.h"
00014 #include "settings_type.h"
00015 #include "water.h"
00016 #include "window_func.h"
00017 #include "vehicle_func.h"
00018 #include "sound_func.h"
00019 #include "viewport_func.h"
00020 #include "gfx_func.h"
00021 #include "player_func.h"
00022 #include "slope_func.h"
00023
00024 #include "table/sprites.h"
00025 #include "table/strings.h"
00026
00027 static void ShowBuildDockStationPicker();
00028 static void ShowBuildDocksDepotPicker();
00029
00030 static Axis _ship_depot_direction;
00031
00032 void CcBuildDocks(bool success, TileIndex tile, uint32 p1, uint32 p2)
00033 {
00034 if (success) {
00035 SndPlayTileFx(SND_02_SPLAT, tile);
00036 ResetObjectToPlace();
00037 }
00038 }
00039
00040 void CcBuildCanal(bool success, TileIndex tile, uint32 p1, uint32 p2)
00041 {
00042 if (success) SndPlayTileFx(SND_02_SPLAT, tile);
00043 }
00044
00045
00046 static void PlaceDocks_Dock(TileIndex tile)
00047 {
00048 DoCommandP(tile, _ctrl_pressed, 0, CcBuildDocks, CMD_BUILD_DOCK | CMD_MSG(STR_9802_CAN_T_BUILD_DOCK_HERE));
00049 }
00050
00051 static void PlaceDocks_Depot(TileIndex tile)
00052 {
00053 DoCommandP(tile, _ship_depot_direction, 0, CcBuildDocks, CMD_BUILD_SHIP_DEPOT | CMD_MSG(STR_3802_CAN_T_BUILD_SHIP_DEPOT));
00054 }
00055
00056 static void PlaceDocks_Buoy(TileIndex tile)
00057 {
00058 DoCommandP(tile, 0, 0, CcBuildDocks, CMD_BUILD_BUOY | CMD_MSG(STR_9835_CAN_T_POSITION_BUOY_HERE));
00059 }
00060
00061 static void PlaceDocks_DemolishArea(TileIndex tile)
00062 {
00063 VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_DEMOLISH_AREA);
00064 }
00065
00066 static void PlaceDocks_BuildCanal(TileIndex tile)
00067 {
00068 VpStartPlaceSizing(tile, VPM_X_OR_Y, DDSP_CREATE_WATER);
00069 }
00070
00071 static void PlaceDocks_BuildLock(TileIndex tile)
00072 {
00073 DoCommandP(tile, 0, 0, CcBuildDocks, CMD_BUILD_LOCK | CMD_MSG(STR_CANT_BUILD_LOCKS));
00074 }
00075
00076
00077 enum {
00078 DTW_CANAL = 3,
00079 DTW_LOCK = 4,
00080 DTW_DEMOLISH = 6,
00081 DTW_DEPOT = 7,
00082 DTW_STATION = 8,
00083 DTW_BUOY = 9
00084 };
00085
00086
00087 static void BuildDocksClick_Canal(Window *w)
00088 {
00089 HandlePlacePushButton(w, DTW_CANAL, SPR_CURSOR_CANAL, VHM_RECT, PlaceDocks_BuildCanal);
00090 }
00091
00092 static void BuildDocksClick_Lock(Window *w)
00093 {
00094 HandlePlacePushButton(w, DTW_LOCK, SPR_CURSOR_LOCK, VHM_RECT, PlaceDocks_BuildLock);
00095 }
00096
00097 static void BuildDocksClick_Demolish(Window *w)
00098 {
00099 HandlePlacePushButton(w, DTW_DEMOLISH, ANIMCURSOR_DEMOLISH, VHM_RECT, PlaceDocks_DemolishArea);
00100 }
00101
00102 static void BuildDocksClick_Depot(Window *w)
00103 {
00104 if (!CanBuildVehicleInfrastructure(VEH_SHIP)) return;
00105 if (HandlePlacePushButton(w, DTW_DEPOT, SPR_CURSOR_SHIP_DEPOT, VHM_RECT, PlaceDocks_Depot)) ShowBuildDocksDepotPicker();
00106 }
00107
00108 static void BuildDocksClick_Dock(Window *w)
00109 {
00110 if (!CanBuildVehicleInfrastructure(VEH_SHIP)) return;
00111 if (HandlePlacePushButton(w, DTW_STATION, SPR_CURSOR_DOCK, VHM_SPECIAL, PlaceDocks_Dock)) ShowBuildDockStationPicker();
00112 }
00113
00114 static void BuildDocksClick_Buoy(Window *w)
00115 {
00116 if (!CanBuildVehicleInfrastructure(VEH_SHIP)) return;
00117 HandlePlacePushButton(w, DTW_BUOY, SPR_CURSOR_BOUY, VHM_RECT, PlaceDocks_Buoy);
00118 }
00119
00120
00121 typedef void OnButtonClick(Window *w);
00122 static OnButtonClick * const _build_docks_button_proc[] = {
00123 BuildDocksClick_Canal,
00124 BuildDocksClick_Lock,
00125 NULL,
00126 BuildDocksClick_Demolish,
00127 BuildDocksClick_Depot,
00128 BuildDocksClick_Dock,
00129 BuildDocksClick_Buoy
00130 };
00131
00132 static void BuildDocksToolbWndProc(Window *w, WindowEvent *e)
00133 {
00134 switch (e->event) {
00135 case WE_PAINT:
00136 DrawWindowWidgets(w);
00137 w->SetWidgetsDisabledState(!CanBuildVehicleInfrastructure(VEH_SHIP), 7, 8, 9, WIDGET_LIST_END);
00138 break;
00139
00140 case WE_CLICK:
00141 if (e->we.click.widget - 3 >= 0 && e->we.click.widget != 5) _build_docks_button_proc[e->we.click.widget - 3](w);
00142 break;
00143
00144 case WE_KEYPRESS:
00145 switch (e->we.keypress.keycode) {
00146 case '1': BuildDocksClick_Canal(w); break;
00147 case '2': BuildDocksClick_Lock(w); break;
00148 case '3': BuildDocksClick_Demolish(w); break;
00149 case '4': BuildDocksClick_Depot(w); break;
00150 case '5': BuildDocksClick_Dock(w); break;
00151 case '6': BuildDocksClick_Buoy(w); break;
00152 default: return;
00153 }
00154 break;
00155
00156 case WE_PLACE_OBJ:
00157 _place_proc(e->we.place.tile);
00158 break;
00159
00160 case WE_PLACE_DRAG: {
00161 VpSelectTilesWithMethod(e->we.place.pt.x, e->we.place.pt.y, e->we.place.select_method);
00162 return;
00163 }
00164
00165 case WE_PLACE_MOUSEUP:
00166 if (e->we.place.pt.x != -1) {
00167 switch (e->we.place.select_proc) {
00168 case DDSP_DEMOLISH_AREA:
00169 GUIPlaceProcDragXY(e);
00170 break;
00171 case DDSP_CREATE_WATER:
00172 DoCommandP(e->we.place.tile, e->we.place.starttile, 0, CcBuildCanal, CMD_BUILD_CANAL | CMD_MSG(STR_CANT_BUILD_CANALS));
00173 break;
00174 default: break;
00175 }
00176 }
00177 break;
00178
00179 case WE_ABORT_PLACE_OBJ:
00180 w->RaiseButtons();
00181
00182 w = FindWindowById(WC_BUILD_STATION, 0);
00183 if (w != NULL) WP(w, def_d).close = true;
00184
00185 w = FindWindowById(WC_BUILD_DEPOT, 0);
00186 if (w != NULL) WP(w, def_d).close = true;
00187 break;
00188
00189 case WE_PLACE_PRESIZE: {
00190 TileIndex tile_from;
00191 TileIndex tile_to;
00192
00193 tile_from = e->we.place.tile;
00194
00195 DiagDirection dir = GetInclinedSlopeDirection(GetTileSlope(tile_from, NULL));
00196 tile_to = (dir != INVALID_DIAGDIR ? TileAddByDiagDir(tile_from, ReverseDiagDir(dir)) : tile_from);
00197
00198 VpSetPresizeRange(tile_from, tile_to);
00199 } break;
00200
00201 case WE_DESTROY:
00202 if (_patches.link_terraform_toolbar) DeleteWindowById(WC_SCEN_LAND_GEN, 0);
00203 break;
00204 }
00205 }
00206
00207 static const Widget _build_docks_toolb_widgets[] = {
00208 { WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
00209 { WWT_CAPTION, RESIZE_NONE, 7, 11, 123, 0, 13, STR_9801_DOCK_CONSTRUCTION, STR_018C_WINDOW_TITLE_DRAG_THIS},
00210 { WWT_STICKYBOX, RESIZE_NONE, 7, 124, 135, 0, 13, 0x0, STR_STICKY_BUTTON},
00211 { WWT_IMGBTN, RESIZE_NONE, 7, 0, 21, 14, 35, SPR_IMG_BUILD_CANAL, STR_BUILD_CANALS_TIP},
00212 { WWT_IMGBTN, RESIZE_NONE, 7, 22, 43, 14, 35, SPR_IMG_BUILD_LOCK, STR_BUILD_LOCKS_TIP},
00213
00214 { WWT_PANEL, RESIZE_NONE, 7, 44, 47, 14, 35, 0x0, STR_NULL},
00215
00216 { WWT_IMGBTN, RESIZE_NONE, 7, 48, 69, 14, 35, SPR_IMG_DYNAMITE, STR_018D_DEMOLISH_BUILDINGS_ETC},
00217 { WWT_IMGBTN, RESIZE_NONE, 7, 70, 91, 14, 35, SPR_IMG_SHIP_DEPOT, STR_981E_BUILD_SHIP_DEPOT_FOR_BUILDING},
00218 { WWT_IMGBTN, RESIZE_NONE, 7, 92, 113, 14, 35, SPR_IMG_SHIP_DOCK, STR_981D_BUILD_SHIP_DOCK},
00219 { WWT_IMGBTN, RESIZE_NONE, 7, 114, 135, 14, 35, SPR_IMG_BOUY, STR_9834_POSITION_BUOY_WHICH_CAN},
00220 { WIDGETS_END},
00221 };
00222
00223 static const WindowDesc _build_docks_toolbar_desc = {
00224 WDP_ALIGN_TBR, 22, 136, 36, 136, 36,
00225 WC_BUILD_TOOLBAR, WC_NONE,
00226 WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_STICKY_BUTTON,
00227 _build_docks_toolb_widgets,
00228 BuildDocksToolbWndProc
00229 };
00230
00231 void ShowBuildDocksToolbar()
00232 {
00233 if (!IsValidPlayer(_current_player)) return;
00234
00235 DeleteWindowById(WC_BUILD_TOOLBAR, 0);
00236 Window *w = AllocateWindowDesc(&_build_docks_toolbar_desc);
00237 if (_patches.link_terraform_toolbar) ShowTerraformToolbar(w);
00238 }
00239
00240 static void BuildDockStationWndProc(Window *w, WindowEvent *e)
00241 {
00242 switch (e->event) {
00243 case WE_CREATE: w->LowerWidget(_station_show_coverage + 3); break;
00244
00245 case WE_PAINT: {
00246 int rad = (_patches.modified_catchment) ? CA_DOCK : CA_UNMODIFIED;
00247
00248 if (WP(w, def_d).close) return;
00249 DrawWindowWidgets(w);
00250
00251 if (_station_show_coverage) {
00252 SetTileSelectBigSize(-rad, -rad, 2 * rad, 2 * rad);
00253 } else {
00254 SetTileSelectSize(1, 1);
00255 }
00256
00257 int text_end = DrawStationCoverageAreaText(4, 50, SCT_ALL, rad) + 4;
00258 if (text_end > w->widget[2].bottom) {
00259 SetWindowDirty(w);
00260 ResizeWindowForWidget(w, 2, 0, text_end - w->widget[2].bottom);
00261 SetWindowDirty(w);
00262 }
00263
00264 break;
00265 }
00266
00267 case WE_CLICK:
00268 switch (e->we.click.widget) {
00269 case 3:
00270 case 4:
00271 w->RaiseWidget(_station_show_coverage + 3);
00272 _station_show_coverage = (e->we.click.widget != 3);
00273 w->LowerWidget(_station_show_coverage + 3);
00274 SndPlayFx(SND_15_BEEP);
00275 SetWindowDirty(w);
00276 break;
00277 }
00278 break;
00279
00280 case WE_MOUSELOOP:
00281 if (WP(w, def_d).close) {
00282 DeleteWindow(w);
00283 return;
00284 }
00285
00286 CheckRedrawStationCoverage(w);
00287 break;
00288
00289 case WE_DESTROY:
00290 if (!WP(w, def_d).close) ResetObjectToPlace();
00291 break;
00292 }
00293 }
00294
00295 static const Widget _build_dock_station_widgets[] = {
00296 { WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
00297 { WWT_CAPTION, RESIZE_NONE, 7, 11, 147, 0, 13, STR_3068_DOCK, STR_018C_WINDOW_TITLE_DRAG_THIS},
00298 { WWT_PANEL, RESIZE_NONE, 7, 0, 147, 14, 74, 0x0, STR_NULL},
00299 { WWT_TEXTBTN, RESIZE_NONE, 14, 14, 73, 30, 40, STR_02DB_OFF, STR_3065_DON_T_HIGHLIGHT_COVERAGE},
00300 { WWT_TEXTBTN, RESIZE_NONE, 14, 74, 133, 30, 40, STR_02DA_ON, STR_3064_HIGHLIGHT_COVERAGE_AREA},
00301 { WWT_LABEL, RESIZE_NONE, 7, 0, 147, 17, 30, STR_3066_COVERAGE_AREA_HIGHLIGHT, STR_NULL},
00302 { WIDGETS_END},
00303 };
00304
00305 static const WindowDesc _build_dock_station_desc = {
00306 WDP_AUTO, WDP_AUTO, 148, 75, 148, 75,
00307 WC_BUILD_STATION, WC_BUILD_TOOLBAR,
00308 WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
00309 _build_dock_station_widgets,
00310 BuildDockStationWndProc
00311 };
00312
00313 static void ShowBuildDockStationPicker()
00314 {
00315 AllocateWindowDesc(&_build_dock_station_desc);
00316 }
00317
00318 static void UpdateDocksDirection()
00319 {
00320 if (_ship_depot_direction != AXIS_X) {
00321 SetTileSelectSize(1, 2);
00322 } else {
00323 SetTileSelectSize(2, 1);
00324 }
00325 }
00326
00327 static void BuildDocksDepotWndProc(Window *w, WindowEvent *e)
00328 {
00329 switch (e->event) {
00330 case WE_CREATE: w->LowerWidget(_ship_depot_direction + 3); break;
00331
00332 case WE_PAINT:
00333 DrawWindowWidgets(w);
00334
00335 DrawShipDepotSprite(67, 35, 0);
00336 DrawShipDepotSprite(35, 51, 1);
00337 DrawShipDepotSprite(135, 35, 2);
00338 DrawShipDepotSprite(167, 51, 3);
00339 return;
00340
00341 case WE_CLICK: {
00342 switch (e->we.click.widget) {
00343 case 3:
00344 case 4:
00345 w->RaiseWidget(_ship_depot_direction + 3);
00346 _ship_depot_direction = (e->we.click.widget == 3 ? AXIS_X : AXIS_Y);
00347 w->LowerWidget(_ship_depot_direction + 3);
00348 SndPlayFx(SND_15_BEEP);
00349 UpdateDocksDirection();
00350 SetWindowDirty(w);
00351 break;
00352 }
00353 } break;
00354
00355 case WE_MOUSELOOP:
00356 if (WP(w, def_d).close) DeleteWindow(w);
00357 break;
00358
00359 case WE_DESTROY:
00360 if (!WP(w, def_d).close) ResetObjectToPlace();
00361 break;
00362 }
00363 }
00364
00365 static const Widget _build_docks_depot_widgets[] = {
00366 { WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
00367 { WWT_CAPTION, RESIZE_NONE, 7, 11, 203, 0, 13, STR_3800_SHIP_DEPOT_ORIENTATION, STR_018C_WINDOW_TITLE_DRAG_THIS},
00368 { WWT_PANEL, RESIZE_NONE, 7, 0, 203, 14, 85, 0x0, STR_NULL},
00369 { WWT_PANEL, RESIZE_NONE, 14, 3, 100, 17, 82, 0x0, STR_3803_SELECT_SHIP_DEPOT_ORIENTATION},
00370 { WWT_PANEL, RESIZE_NONE, 14, 103, 200, 17, 82, 0x0, STR_3803_SELECT_SHIP_DEPOT_ORIENTATION},
00371 { WIDGETS_END},
00372 };
00373
00374 static const WindowDesc _build_docks_depot_desc = {
00375 WDP_AUTO, WDP_AUTO, 204, 86, 204, 86,
00376 WC_BUILD_DEPOT, WC_BUILD_TOOLBAR,
00377 WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
00378 _build_docks_depot_widgets,
00379 BuildDocksDepotWndProc
00380 };
00381
00382
00383 static void ShowBuildDocksDepotPicker()
00384 {
00385 AllocateWindowDesc(&_build_docks_depot_desc);
00386 UpdateDocksDirection();
00387 }
00388
00389
00390 void InitializeDockGui()
00391 {
00392 _ship_depot_direction = AXIS_X;
00393 }