00001
00002
00005 #include "stdafx.h"
00006 #include "direction_type.h"
00007 #include "openttd.h"
00008 #include "tile_cmd.h"
00009 #include "landscape.h"
00010 #include "gui.h"
00011 #include "window_gui.h"
00012 #include "station_gui.h"
00013 #include "terraform_gui.h"
00014 #include "viewport_func.h"
00015 #include "gfx_func.h"
00016 #include "command_func.h"
00017 #include "town_type.h"
00018 #include "waypoint.h"
00019 #include "debug.h"
00020 #include "variables.h"
00021 #include "newgrf_callbacks.h"
00022 #include "newgrf_station.h"
00023 #include "train.h"
00024 #include "strings_func.h"
00025 #include "functions.h"
00026 #include "window_func.h"
00027 #include "date_func.h"
00028 #include "sound_func.h"
00029 #include "company_func.h"
00030 #include "settings_type.h"
00031 #include "widgets/dropdown_type.h"
00032 #include "widgets/dropdown_func.h"
00033 #include "tunnelbridge.h"
00034 #include "tilehighlight_func.h"
00035
00036 #include "bridge_map.h"
00037 #include "rail_map.h"
00038 #include "road_map.h"
00039 #include "station_map.h"
00040 #include "tunnel_map.h"
00041 #include "tunnelbridge_map.h"
00042
00043 #include "table/sprites.h"
00044 #include "table/strings.h"
00045
00046 static RailType _cur_railtype;
00047 static bool _remove_button_clicked;
00048 static DiagDirection _build_depot_direction;
00049 static byte _waypoint_count = 1;
00050 static byte _cur_waypoint_type;
00051 static bool _convert_signal_button;
00052 static SignalVariant _cur_signal_variant;
00053 static SignalType _cur_signal_type;
00054
00055
00056 static const SignalType _default_signal_type[] = {SIGTYPE_NORMAL, SIGTYPE_PBS, SIGTYPE_PBS_ONEWAY};
00057
00058 struct RailStationGUISettings {
00059 Axis orientation;
00060 byte numtracks;
00061 byte platlength;
00062 bool dragdrop;
00063
00064 bool newstations;
00065 StationClassIDByte station_class;
00066 byte station_type;
00067 byte station_count;
00068 };
00069 static RailStationGUISettings _railstation;
00070
00071
00072 static void HandleStationPlacement(TileIndex start, TileIndex end);
00073 static void ShowBuildTrainDepotPicker(Window *parent);
00074 static void ShowBuildWaypointPicker(Window *parent);
00075 static void ShowStationBuilder(Window *parent);
00076 static void ShowSignalBuilder(Window *parent);
00077
00078 void CcPlaySound1E(bool success, TileIndex tile, uint32 p1, uint32 p2)
00079 {
00080 if (success) SndPlayTileFx(SND_20_SPLAT_2, tile);
00081 }
00082
00083 static void GenericPlaceRail(TileIndex tile, int cmd)
00084 {
00085 DoCommandP(tile, _cur_railtype, cmd, CcPlaySound1E,
00086 _remove_button_clicked ?
00087 CMD_REMOVE_SINGLE_RAIL | CMD_MSG(STR_1012_CAN_T_REMOVE_RAILROAD_TRACK) | CMD_NO_WATER :
00088 CMD_BUILD_SINGLE_RAIL | CMD_MSG(STR_1011_CAN_T_BUILD_RAILROAD_TRACK) | CMD_NO_WATER
00089 );
00090 }
00091
00092 static void PlaceRail_N(TileIndex tile)
00093 {
00094 int cmd = _tile_fract_coords.x > _tile_fract_coords.y ? 4 : 5;
00095 GenericPlaceRail(tile, cmd);
00096 }
00097
00098 static void PlaceRail_NE(TileIndex tile)
00099 {
00100 VpStartPlaceSizing(tile, VPM_FIX_Y, DDSP_PLACE_RAIL_NE);
00101 }
00102
00103 static void PlaceRail_E(TileIndex tile)
00104 {
00105 int cmd = _tile_fract_coords.x + _tile_fract_coords.y <= 15 ? 2 : 3;
00106 GenericPlaceRail(tile, cmd);
00107 }
00108
00109 static void PlaceRail_NW(TileIndex tile)
00110 {
00111 VpStartPlaceSizing(tile, VPM_FIX_X, DDSP_PLACE_RAIL_NW);
00112 }
00113
00114 static void PlaceRail_AutoRail(TileIndex tile)
00115 {
00116 VpStartPlaceSizing(tile, VPM_RAILDIRS, DDSP_PLACE_AUTORAIL);
00117 }
00118
00125 static void PlaceExtraDepotRail(TileIndex tile, uint16 extra)
00126 {
00127 if (GetRailTileType(tile) != RAIL_TILE_NORMAL) return;
00128 if ((GetTrackBits(tile) & GB(extra, 8, 8)) == 0) return;
00129
00130 DoCommandP(tile, _cur_railtype, extra & 0xFF, NULL, CMD_BUILD_SINGLE_RAIL | CMD_NO_WATER);
00131 }
00132
00134 static const uint16 _place_depot_extra[12] = {
00135 0x0604, 0x2102, 0x1202, 0x0505,
00136 0x2400, 0x2801, 0x1800, 0x1401,
00137 0x2203, 0x0904, 0x0A05, 0x1103,
00138 };
00139
00140
00141 void CcRailDepot(bool success, TileIndex tile, uint32 p1, uint32 p2)
00142 {
00143 if (success) {
00144 DiagDirection dir = (DiagDirection)p2;
00145
00146 SndPlayTileFx(SND_20_SPLAT_2, tile);
00147 ResetObjectToPlace();
00148
00149 tile += TileOffsByDiagDir(dir);
00150
00151 if (IsTileType(tile, MP_RAILWAY)) {
00152 PlaceExtraDepotRail(tile, _place_depot_extra[dir]);
00153 PlaceExtraDepotRail(tile, _place_depot_extra[dir + 4]);
00154 PlaceExtraDepotRail(tile, _place_depot_extra[dir + 8]);
00155 }
00156 }
00157 }
00158
00159 static void PlaceRail_Depot(TileIndex tile)
00160 {
00161 DoCommandP(tile, _cur_railtype, _build_depot_direction, CcRailDepot,
00162 CMD_BUILD_TRAIN_DEPOT | CMD_NO_WATER | CMD_MSG(STR_100E_CAN_T_BUILD_TRAIN_DEPOT));
00163 }
00164
00165 static void PlaceRail_Waypoint(TileIndex tile)
00166 {
00167 if (_remove_button_clicked) {
00168 DoCommandP(tile, 0, 0, CcPlaySound1E, CMD_REMOVE_TRAIN_WAYPOINT | CMD_MSG(STR_CANT_REMOVE_TRAIN_WAYPOINT));
00169 } else {
00170 DoCommandP(tile, _cur_waypoint_type, 0, CcPlaySound1E, CMD_BUILD_TRAIN_WAYPOINT | CMD_MSG(STR_CANT_BUILD_TRAIN_WAYPOINT));
00171 }
00172 }
00173
00174 void CcStation(bool success, TileIndex tile, uint32 p1, uint32 p2)
00175 {
00176 if (success) {
00177 SndPlayTileFx(SND_20_SPLAT_2, tile);
00178
00179 if (_railstation.station_class == STAT_CLASS_DFLT && _railstation.station_type == 0) ResetObjectToPlace();
00180 }
00181 }
00182
00183 static void PlaceRail_Station(TileIndex tile)
00184 {
00185 if (_remove_button_clicked) {
00186 VpStartPlaceSizing(tile, VPM_X_AND_Y_LIMITED, DDSP_REMOVE_STATION);
00187 VpSetPlaceSizingLimit(-1);
00188 } else if (_railstation.dragdrop) {
00189 VpStartPlaceSizing(tile, VPM_X_AND_Y_LIMITED, DDSP_BUILD_STATION);
00190 VpSetPlaceSizingLimit(_settings_game.station.station_spread);
00191 } else {
00192 DoCommandP(tile,
00193 _railstation.orientation | (_railstation.numtracks << 8) | (_railstation.platlength << 16) | (_ctrl_pressed << 24),
00194 _cur_railtype | (_railstation.station_class << 8) | (_railstation.station_type << 16), CcStation,
00195 CMD_BUILD_RAILROAD_STATION | CMD_NO_WATER | CMD_MSG(STR_100F_CAN_T_BUILD_RAILROAD_STATION));
00196 }
00197 }
00198
00204 static void GenericPlaceSignals(TileIndex tile)
00205 {
00206 TrackBits trackbits = TrackStatusToTrackBits(GetTileTrackStatus(tile, TRANSPORT_RAIL, 0));
00207
00208 if (trackbits & TRACK_BIT_VERT) {
00209 trackbits = (_tile_fract_coords.x <= _tile_fract_coords.y) ? TRACK_BIT_RIGHT : TRACK_BIT_LEFT;
00210 }
00211
00212 if (trackbits & TRACK_BIT_HORZ) {
00213 trackbits = (_tile_fract_coords.x + _tile_fract_coords.y <= 15) ? TRACK_BIT_UPPER : TRACK_BIT_LOWER;
00214 }
00215
00216 Track track = FindFirstTrack(trackbits);
00217
00218 if (_remove_button_clicked) {
00219 DoCommandP(tile, track, 0, CcPlaySound1E,
00220 CMD_REMOVE_SIGNALS | CMD_MSG(STR_1013_CAN_T_REMOVE_SIGNALS_FROM));
00221 } else {
00222 const Window *w = FindWindowById(WC_BUILD_SIGNAL, 0);
00223
00224
00225 static const uint cycle_bounds[] = {SIGTYPE_NORMAL | (SIGTYPE_LAST_NOPBS << 3), SIGTYPE_PBS | (SIGTYPE_LAST << 3), SIGTYPE_NORMAL | (SIGTYPE_LAST << 3)};
00226
00227
00228 uint32 p1 = track;
00229
00230 if (w != NULL) {
00231
00232 SB(p1, 3, 1, _ctrl_pressed);
00233 SB(p1, 4, 1, _cur_signal_variant);
00234 SB(p1, 5, 3, _cur_signal_type);
00235 SB(p1, 8, 1, _convert_signal_button);
00236 SB(p1, 9, 6, cycle_bounds[_settings_client.gui.cycle_signal_types]);
00237 } else {
00238 SB(p1, 3, 1, _ctrl_pressed);
00239 SB(p1, 4, 1, (_cur_year < _settings_client.gui.semaphore_build_before ? SIG_SEMAPHORE : SIG_ELECTRIC));
00240 SB(p1, 5, 3, _default_signal_type[_settings_client.gui.default_signal_type]);
00241 SB(p1, 8, 1, 0);
00242 SB(p1, 9, 6, cycle_bounds[_settings_client.gui.cycle_signal_types]);
00243 }
00244
00245 DoCommandP(tile, p1, 0, CcPlaySound1E, CMD_BUILD_SIGNALS |
00246 CMD_MSG((w != NULL && _convert_signal_button) ? STR_SIGNAL_CAN_T_CONVERT_SIGNALS_HERE : STR_1010_CAN_T_BUILD_SIGNALS_HERE));
00247 }
00248 }
00249
00250 static void PlaceRail_Bridge(TileIndex tile)
00251 {
00252 VpStartPlaceSizing(tile, VPM_X_OR_Y, DDSP_BUILD_BRIDGE);
00253 }
00254
00256 void CcBuildRailTunnel(bool success, TileIndex tile, uint32 p1, uint32 p2)
00257 {
00258 if (success) {
00259 SndPlayTileFx(SND_20_SPLAT_2, tile);
00260 ResetObjectToPlace();
00261 } else {
00262 SetRedErrorSquare(_build_tunnel_endtile);
00263 }
00264 }
00265
00266 static void PlaceRail_Tunnel(TileIndex tile)
00267 {
00268 DoCommandP(tile, _cur_railtype, 0, CcBuildRailTunnel,
00269 CMD_BUILD_TUNNEL | CMD_MSG(STR_5016_CAN_T_BUILD_TUNNEL_HERE));
00270 }
00271
00272 static void PlaceRail_ConvertRail(TileIndex tile)
00273 {
00274 VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_CONVERT_RAIL);
00275 }
00276
00277 static void PlaceRail_AutoSignals(TileIndex tile)
00278 {
00279 VpStartPlaceSizing(tile, VPM_SIGNALDIRS, DDSP_BUILD_SIGNALS);
00280 }
00281
00282
00284 enum RailToolbarWidgets {
00285 RTW_CLOSEBOX = 0,
00286 RTW_CAPTION,
00287 RTW_STICKY,
00288 RTW_SPACER,
00289 RTW_BUILD_NS,
00290 RTW_BUILD_X,
00291 RTW_BUILD_EW,
00292 RTW_BUILD_Y,
00293 RTW_AUTORAIL,
00294 RTW_DEMOLISH,
00295 RTW_BUILD_DEPOT,
00296 RTW_BUILD_WAYPOINT,
00297 RTW_BUILD_STATION,
00298 RTW_BUILD_SIGNALS,
00299 RTW_BUILD_BRIDGE,
00300 RTW_BUILD_TUNNEL,
00301 RTW_REMOVE,
00302 RTW_CONVERT_RAIL,
00303 };
00304
00305
00309 static void ToggleRailButton_Remove(Window *w)
00310 {
00311 w->ToggleWidgetLoweredState(RTW_REMOVE);
00312 w->InvalidateWidget(RTW_REMOVE);
00313 _remove_button_clicked = w->IsWidgetLowered(RTW_REMOVE);
00314 SetSelectionRed(_remove_button_clicked);
00315 }
00316
00321 static bool RailToolbar_CtrlChanged(Window *w)
00322 {
00323 if (w->IsWidgetDisabled(RTW_REMOVE)) return false;
00324
00325
00326 for (uint i = RTW_BUILD_NS; i <= RTW_BUILD_STATION; i++) {
00327 if ((i <= RTW_AUTORAIL || i >= RTW_BUILD_WAYPOINT) && w->IsWidgetLowered(i)) {
00328 ToggleRailButton_Remove(w);
00329 return true;
00330 }
00331 }
00332
00333 return false;
00334 }
00335
00336
00342 static void BuildRailClick_N(Window *w)
00343 {
00344 HandlePlacePushButton(w, RTW_BUILD_NS, GetRailTypeInfo(_cur_railtype)->cursor.rail_ns, VHM_RECT, PlaceRail_N);
00345 }
00346
00352 static void BuildRailClick_NE(Window *w)
00353 {
00354 HandlePlacePushButton(w, RTW_BUILD_X, GetRailTypeInfo(_cur_railtype)->cursor.rail_swne, VHM_RECT, PlaceRail_NE);
00355 }
00356
00362 static void BuildRailClick_E(Window *w)
00363 {
00364 HandlePlacePushButton(w, RTW_BUILD_EW, GetRailTypeInfo(_cur_railtype)->cursor.rail_ew, VHM_RECT, PlaceRail_E);
00365 }
00366
00372 static void BuildRailClick_NW(Window *w)
00373 {
00374 HandlePlacePushButton(w, RTW_BUILD_Y, GetRailTypeInfo(_cur_railtype)->cursor.rail_nwse, VHM_RECT, PlaceRail_NW);
00375 }
00376
00382 static void BuildRailClick_AutoRail(Window *w)
00383 {
00384 HandlePlacePushButton(w, RTW_AUTORAIL, GetRailTypeInfo(_cur_railtype)->cursor.autorail, VHM_RAIL, PlaceRail_AutoRail);
00385 }
00386
00392 static void BuildRailClick_Demolish(Window *w)
00393 {
00394 HandlePlacePushButton(w, RTW_DEMOLISH, ANIMCURSOR_DEMOLISH, VHM_RECT, PlaceProc_DemolishArea);
00395 }
00396
00402 static void BuildRailClick_Depot(Window *w)
00403 {
00404 if (HandlePlacePushButton(w, RTW_BUILD_DEPOT, GetRailTypeInfo(_cur_railtype)->cursor.depot, VHM_RECT, PlaceRail_Depot)) {
00405 ShowBuildTrainDepotPicker(w);
00406 }
00407 }
00408
00415 static void BuildRailClick_Waypoint(Window *w)
00416 {
00417 _waypoint_count = GetNumCustomStations(STAT_CLASS_WAYP);
00418 if (HandlePlacePushButton(w, RTW_BUILD_WAYPOINT, SPR_CURSOR_WAYPOINT, VHM_RECT, PlaceRail_Waypoint) &&
00419 _waypoint_count > 1) {
00420 ShowBuildWaypointPicker(w);
00421 }
00422 }
00423
00429 static void BuildRailClick_Station(Window *w)
00430 {
00431 if (HandlePlacePushButton(w, RTW_BUILD_STATION, SPR_CURSOR_RAIL_STATION, VHM_RECT, PlaceRail_Station)) ShowStationBuilder(w);
00432 }
00433
00440 static void BuildRailClick_AutoSignals(Window *w)
00441 {
00442 if (_settings_client.gui.enable_signal_gui != _ctrl_pressed) {
00443 if (HandlePlacePushButton(w, RTW_BUILD_SIGNALS, ANIMCURSOR_BUILDSIGNALS, VHM_RECT, PlaceRail_AutoSignals)) ShowSignalBuilder(w);
00444 } else {
00445 HandlePlacePushButton(w, RTW_BUILD_SIGNALS, ANIMCURSOR_BUILDSIGNALS, VHM_RECT, PlaceRail_AutoSignals);
00446 }
00447 }
00448
00454 static void BuildRailClick_Bridge(Window *w)
00455 {
00456 HandlePlacePushButton(w, RTW_BUILD_BRIDGE, SPR_CURSOR_BRIDGE, VHM_RECT, PlaceRail_Bridge);
00457 }
00458
00464 static void BuildRailClick_Tunnel(Window *w)
00465 {
00466 HandlePlacePushButton(w, RTW_BUILD_TUNNEL, GetRailTypeInfo(_cur_railtype)->cursor.tunnel, VHM_SPECIAL, PlaceRail_Tunnel);
00467 }
00468
00474 static void BuildRailClick_Remove(Window *w)
00475 {
00476 if (w->IsWidgetDisabled(RTW_REMOVE)) return;
00477 ToggleRailButton_Remove(w);
00478 SndPlayFx(SND_15_BEEP);
00479
00480
00481 if (w->IsWidgetLowered(RTW_BUILD_STATION)) {
00482 if (_remove_button_clicked) {
00483
00484 if (!_railstation.dragdrop) {
00485 SetTileSelectSize(1, 1);
00486 } else {
00487 VpSetPlaceSizingLimit(-1);
00488 }
00489 } else {
00490
00491 if (!_railstation.dragdrop) {
00492 int x = _railstation.numtracks;
00493 int y = _railstation.platlength;
00494 if (_railstation.orientation == 0) Swap(x, y);
00495 SetTileSelectSize(x, y);
00496 } else {
00497 VpSetPlaceSizingLimit(_settings_game.station.station_spread);
00498 }
00499 }
00500 }
00501 }
00502
00509 static void BuildRailClick_Convert(Window *w)
00510 {
00511 HandlePlacePushButton(w, RTW_CONVERT_RAIL, GetRailTypeInfo(_cur_railtype)->cursor.convert, VHM_RECT, PlaceRail_ConvertRail);
00512 }
00513
00514
00515 static void DoRailroadTrack(int mode)
00516 {
00517 DoCommandP(TileVirtXY(_thd.selstart.x, _thd.selstart.y), TileVirtXY(_thd.selend.x, _thd.selend.y), _cur_railtype | (mode << 4), NULL,
00518 _remove_button_clicked ?
00519 CMD_REMOVE_RAILROAD_TRACK | CMD_NO_WATER | CMD_MSG(STR_1012_CAN_T_REMOVE_RAILROAD_TRACK) :
00520 CMD_BUILD_RAILROAD_TRACK | CMD_NO_WATER | CMD_MSG(STR_1011_CAN_T_BUILD_RAILROAD_TRACK)
00521 );
00522 }
00523
00524 static void HandleAutodirPlacement()
00525 {
00526 TileHighlightData *thd = &_thd;
00527 int trackstat = thd->drawstyle & 0xF;
00528
00529 if (thd->drawstyle & HT_RAIL) {
00530 GenericPlaceRail(TileVirtXY(thd->selend.x, thd->selend.y), trackstat);
00531 return;
00532 }
00533
00534 DoRailroadTrack(trackstat);
00535 }
00536
00543 static void HandleAutoSignalPlacement()
00544 {
00545 TileHighlightData *thd = &_thd;
00546 uint32 p2 = GB(thd->drawstyle, 0, 3);
00547
00548 if (thd->drawstyle == HT_RECT) {
00549 GenericPlaceSignals(TileVirtXY(thd->selend.x, thd->selend.y));
00550 return;
00551 }
00552
00553 const Window *w = FindWindowById(WC_BUILD_SIGNAL, 0);
00554
00555 if (w != NULL) {
00556
00557 SB(p2, 3, 1, 0);
00558 SB(p2, 4, 1, _cur_signal_variant);
00559 SB(p2, 6, 1, _ctrl_pressed);
00560 SB(p2, 7, 3, _cur_signal_type);
00561 SB(p2, 24, 8, _settings_client.gui.drag_signals_density);
00562 } else {
00563 SB(p2, 3, 1, 0);
00564 SB(p2, 4, 1, (_cur_year < _settings_client.gui.semaphore_build_before ? SIG_SEMAPHORE : SIG_ELECTRIC));
00565 SB(p2, 6, 1, _ctrl_pressed);
00566 SB(p2, 7, 3, _default_signal_type[_settings_client.gui.default_signal_type]);
00567 SB(p2, 24, 8, _settings_client.gui.drag_signals_density);
00568 }
00569
00570
00571
00572 DoCommandP(
00573 TileVirtXY(thd->selstart.x, thd->selstart.y),
00574 TileVirtXY(thd->selend.x, thd->selend.y),
00575 p2,
00576 CcPlaySound1E,
00577 _remove_button_clicked ?
00578 CMD_REMOVE_SIGNAL_TRACK | CMD_NO_WATER | CMD_MSG(STR_1013_CAN_T_REMOVE_SIGNALS_FROM) :
00579 CMD_BUILD_SIGNAL_TRACK | CMD_NO_WATER | CMD_MSG(STR_1010_CAN_T_BUILD_SIGNALS_HERE)
00580 );
00581 }
00582
00583
00584 typedef void OnButtonClick(Window *w);
00585
00587 struct RailBuildingGUIButtonData {
00588 uint16 keycode;
00589 OnButtonClick *click_proc;
00590 };
00591
00596 static const RailBuildingGUIButtonData _rail_build_button_data[] = {
00597 {'1', BuildRailClick_N },
00598 {'2', BuildRailClick_NE },
00599 {'3', BuildRailClick_E },
00600 {'4', BuildRailClick_NW },
00601 {'5', BuildRailClick_AutoRail },
00602 {'6', BuildRailClick_Demolish },
00603 {'7', BuildRailClick_Depot },
00604 {'8', BuildRailClick_Waypoint },
00605 {'9', BuildRailClick_Station },
00606 {'S', BuildRailClick_AutoSignals},
00607 {'B', BuildRailClick_Bridge },
00608 {'T', BuildRailClick_Tunnel },
00609 {'R', BuildRailClick_Remove },
00610 {'C', BuildRailClick_Convert }
00611 };
00612
00618 struct BuildRailToolbarWindow : Window {
00619 BuildRailToolbarWindow(const WindowDesc *desc, WindowNumber window_number) : Window(desc, window_number)
00620 {
00621 this->DisableWidget(RTW_REMOVE);
00622
00623 this->FindWindowPlacementAndResize(desc);
00624 if (_settings_client.gui.link_terraform_toolbar) ShowTerraformToolbar(this);
00625 }
00626
00627 ~BuildRailToolbarWindow()
00628 {
00629 if (_settings_client.gui.link_terraform_toolbar) DeleteWindowById(WC_SCEN_LAND_GEN, 0);
00630 }
00631
00632 void UpdateRemoveWidgetStatus(int clicked_widget)
00633 {
00634 switch (clicked_widget) {
00635 case RTW_REMOVE:
00636
00637
00638 return;
00639 break;
00640 case RTW_BUILD_NS:
00641 case RTW_BUILD_X:
00642 case RTW_BUILD_EW:
00643 case RTW_BUILD_Y:
00644 case RTW_AUTORAIL:
00645 case RTW_BUILD_WAYPOINT:
00646 case RTW_BUILD_STATION:
00647 case RTW_BUILD_SIGNALS:
00648
00649
00650 this->SetWidgetDisabledState(RTW_REMOVE, !this->IsWidgetLowered(clicked_widget));
00651 break;
00652
00653 default:
00654
00655
00656 this->DisableWidget(RTW_REMOVE);
00657 this->RaiseWidget(RTW_REMOVE);
00658 break;
00659 }
00660 }
00661
00662 virtual void OnPaint()
00663 {
00664 this->DrawWidgets();
00665 }
00666
00667 virtual void OnClick(Point pt, int widget)
00668 {
00669 if (widget >= RTW_BUILD_NS) {
00670 _remove_button_clicked = false;
00671 _rail_build_button_data[widget - RTW_BUILD_NS].click_proc(this);
00672 }
00673 this->UpdateRemoveWidgetStatus(widget);
00674 if (_ctrl_pressed) RailToolbar_CtrlChanged(this);
00675 }
00676
00677 virtual EventState OnKeyPress(uint16 key, uint16 keycode)
00678 {
00679 EventState state = ES_NOT_HANDLED;
00680 for (uint8 i = 0; i != lengthof(_rail_build_button_data); i++) {
00681 if (keycode == _rail_build_button_data[i].keycode) {
00682 _remove_button_clicked = false;
00683 _rail_build_button_data[i].click_proc(this);
00684 this->UpdateRemoveWidgetStatus(i + RTW_BUILD_NS);
00685 if (_ctrl_pressed) RailToolbar_CtrlChanged(this);
00686 state = ES_HANDLED;
00687 break;
00688 }
00689 }
00690 MarkTileDirty(_thd.pos.x, _thd.pos.y);
00691 return state;
00692 }
00693
00694 virtual void OnPlaceObject(Point pt, TileIndex tile)
00695 {
00696 _place_proc(tile);
00697 }
00698
00699 virtual void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt)
00700 {
00701
00702 if (FindWindowById(WC_BUILD_SIGNAL, 0) != NULL && _convert_signal_button && this->IsWidgetLowered(RTW_BUILD_SIGNALS)) return;
00703
00704 VpSelectTilesWithMethod(pt.x, pt.y, select_method);
00705 }
00706
00707 virtual void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile)
00708 {
00709 if (pt.x != -1) {
00710 switch (select_proc) {
00711 default: NOT_REACHED();
00712 case DDSP_BUILD_BRIDGE:
00713 ResetObjectToPlace();
00714 ShowBuildBridgeWindow(start_tile, end_tile, TRANSPORT_RAIL, _cur_railtype);
00715 break;
00716
00717 case DDSP_PLACE_AUTORAIL:
00718 HandleAutodirPlacement();
00719 break;
00720
00721 case DDSP_BUILD_SIGNALS:
00722 HandleAutoSignalPlacement();
00723 break;
00724
00725 case DDSP_DEMOLISH_AREA:
00726 GUIPlaceProcDragXY(select_proc, start_tile, end_tile);
00727 break;
00728
00729 case DDSP_CONVERT_RAIL:
00730 DoCommandP(end_tile, start_tile, _cur_railtype, CcPlaySound10, CMD_CONVERT_RAIL | CMD_MSG(STR_CANT_CONVERT_RAIL));
00731 break;
00732
00733 case DDSP_REMOVE_STATION:
00734 case DDSP_BUILD_STATION:
00735 if (_remove_button_clicked) {
00736 DoCommandP(end_tile, start_tile, 0, CcPlaySound1E, CMD_REMOVE_FROM_RAILROAD_STATION | CMD_MSG(STR_CANT_REMOVE_PART_OF_STATION));
00737 break;
00738 }
00739 HandleStationPlacement(start_tile, end_tile);
00740 break;
00741
00742 case DDSP_PLACE_RAIL_NE:
00743 case DDSP_PLACE_RAIL_NW:
00744 DoRailroadTrack(select_proc == DDSP_PLACE_RAIL_NE ? TRACK_X : TRACK_Y);
00745 break;
00746 }
00747 }
00748 }
00749
00750 virtual void OnPlaceObjectAbort()
00751 {
00752 this->RaiseButtons();
00753 this->DisableWidget(RTW_REMOVE);
00754 this->InvalidateWidget(RTW_REMOVE);
00755
00756 delete FindWindowById(WC_BUILD_SIGNAL, 0);
00757 delete FindWindowById(WC_BUILD_STATION, 0);
00758 delete FindWindowById(WC_BUILD_DEPOT, 0);
00759 }
00760
00761 virtual void OnPlacePresize(Point pt, TileIndex tile)
00762 {
00763 DoCommand(tile, 0, 0, DC_AUTO, CMD_BUILD_TUNNEL);
00764 VpSetPresizeRange(tile, _build_tunnel_endtile == 0 ? tile : _build_tunnel_endtile);
00765 }
00766
00767 virtual EventState OnCTRLStateChange()
00768 {
00769
00770 if (!this->IsWidgetLowered(RTW_BUILD_STATION) && RailToolbar_CtrlChanged(this)) return ES_HANDLED;
00771 return ES_NOT_HANDLED;
00772 }
00773 };
00774
00776 static const Widget _build_rail_widgets[] = {
00777 { WWT_CLOSEBOX, RESIZE_NONE, COLOUR_DARK_GREEN, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
00778 { WWT_CAPTION, RESIZE_NONE, COLOUR_DARK_GREEN, 11, 337, 0, 13, STR_100A_RAILROAD_CONSTRUCTION, STR_018C_WINDOW_TITLE_DRAG_THIS},
00779 { WWT_STICKYBOX, RESIZE_NONE, COLOUR_DARK_GREEN, 338, 349, 0, 13, 0x0, STR_STICKY_BUTTON},
00780
00781 { WWT_PANEL, RESIZE_NONE, COLOUR_DARK_GREEN, 110, 113, 14, 35, 0x0, STR_NULL},
00782
00783 { WWT_IMGBTN, RESIZE_NONE, COLOUR_DARK_GREEN, 0, 21, 14, 35, SPR_IMG_RAIL_NS, STR_1018_BUILD_RAILROAD_TRACK},
00784 { WWT_IMGBTN, RESIZE_NONE, COLOUR_DARK_GREEN, 22, 43, 14, 35, SPR_IMG_RAIL_NE, STR_1018_BUILD_RAILROAD_TRACK},
00785 { WWT_IMGBTN, RESIZE_NONE, COLOUR_DARK_GREEN, 44, 65, 14, 35, SPR_IMG_RAIL_EW, STR_1018_BUILD_RAILROAD_TRACK},
00786 { WWT_IMGBTN, RESIZE_NONE, COLOUR_DARK_GREEN, 66, 87, 14, 35, SPR_IMG_RAIL_NW, STR_1018_BUILD_RAILROAD_TRACK},
00787 { WWT_IMGBTN, RESIZE_NONE, COLOUR_DARK_GREEN, 88, 109, 14, 35, SPR_IMG_AUTORAIL, STR_BUILD_AUTORAIL_TIP},
00788
00789 { WWT_IMGBTN, RESIZE_NONE, COLOUR_DARK_GREEN, 114, 135, 14, 35, SPR_IMG_DYNAMITE, STR_018D_DEMOLISH_BUILDINGS_ETC},
00790 { WWT_IMGBTN, RESIZE_NONE, COLOUR_DARK_GREEN, 136, 157, 14, 35, SPR_IMG_DEPOT_RAIL, STR_1019_BUILD_TRAIN_DEPOT_FOR_BUILDING},
00791 { WWT_IMGBTN, RESIZE_NONE, COLOUR_DARK_GREEN, 158, 179, 14, 35, SPR_IMG_WAYPOINT, STR_CONVERT_RAIL_TO_WAYPOINT_TIP},
00792
00793 { WWT_IMGBTN, RESIZE_NONE, COLOUR_DARK_GREEN, 180, 221, 14, 35, SPR_IMG_RAIL_STATION, STR_101A_BUILD_RAILROAD_STATION},
00794 { WWT_IMGBTN, RESIZE_NONE, COLOUR_DARK_GREEN, 222, 243, 14, 35, SPR_IMG_RAIL_SIGNALS, STR_101B_BUILD_RAILROAD_SIGNALS},
00795 { WWT_IMGBTN, RESIZE_NONE, COLOUR_DARK_GREEN, 244, 285, 14, 35, SPR_IMG_BRIDGE, STR_101C_BUILD_RAILROAD_BRIDGE},
00796 { WWT_IMGBTN, RESIZE_NONE, COLOUR_DARK_GREEN, 286, 305, 14, 35, SPR_IMG_TUNNEL_RAIL, STR_101D_BUILD_RAILROAD_TUNNEL},
00797 { WWT_IMGBTN, RESIZE_NONE, COLOUR_DARK_GREEN, 306, 327, 14, 35, SPR_IMG_REMOVE, STR_101E_TOGGLE_BUILD_REMOVE_FOR},
00798 { WWT_IMGBTN, RESIZE_NONE, COLOUR_DARK_GREEN, 328, 349, 14, 35, SPR_IMG_CONVERT_RAIL, STR_CONVERT_RAIL_TIP},
00799
00800 { WIDGETS_END},
00801 };
00802
00803 static const WindowDesc _build_rail_desc = {
00804 WDP_ALIGN_TBR, 22, 350, 36, 350, 36,
00805 WC_BUILD_TOOLBAR, WC_NONE,
00806