# dock_gui.cpp

Go to the documentation of this file.

    00001 /* $Id: dock_gui.cpp 12154 2008-02-15 23:57:03Z glx $ */
    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 }