Merge branch 'polyline_track_tool' into jgrpp

# Conflicts:
#	src/rail_cmd.cpp
#	src/rail_gui.cpp
#	src/viewport.cpp
#	src/viewport_func.h
This commit is contained in:
Jonathan G Rennison
2016-04-13 21:14:47 +01:00
13 changed files with 762 additions and 166 deletions

View File

@@ -57,9 +57,14 @@ static SignalVariant _cur_signal_variant; ///< set the signal variant (for si
static SignalType _cur_signal_type; ///< set the signal type (for signal GUI)
static uint _cur_signal_button; ///< set the signal button (for signal GUI)
extern TileIndex _rail_track_endtile; // rail_cmd.cpp
/* Map the setting: default_signal_type to the corresponding signal type */
static const SignalType _default_signal_type[] = {SIGTYPE_NORMAL, SIGTYPE_PBS, SIGTYPE_PBS_ONEWAY};
static const int HOTKEY_POLYRAIL = 0x1000;
static const int HOTKEY_NEW_POLYRAIL = 0x1001;
struct RailStationGUISettings {
Axis orientation; ///< Currently selected rail station orientation
@@ -96,13 +101,21 @@ void CcPlaySound1E(const CommandCost &result, TileIndex tile, uint32 p1, uint32
if (result.Succeeded() && _settings_client.sound.confirm) SndPlayTileFx(SND_20_SPLAT_RAIL, tile);
}
static void GenericPlaceRail(TileIndex tile, int cmd)
static CommandContainer GenericPlaceRailCmd(TileIndex tile, Track track)
{
DoCommandP(tile, _cur_railtype, cmd,
_remove_button_clicked ?
CMD_REMOVE_SINGLE_RAIL | CMD_MSG(STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK) :
CMD_BUILD_SINGLE_RAIL | CMD_MSG(STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK),
CcPlaySound1E);
CommandContainer ret = {
tile, // tile
_cur_railtype, // p1
track, // p2
_remove_button_clicked ?
CMD_REMOVE_SINGLE_RAIL | CMD_MSG(STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK) :
CMD_BUILD_SINGLE_RAIL | CMD_MSG(STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK), // cmd
CcPlaySound1E, // callback
0,
"" // text
};
return ret;
}
/**
@@ -298,6 +311,7 @@ void CcBuildRailTunnel(const CommandCost &result, TileIndex tile, uint32 p1, uin
if (result.Succeeded()) {
if (_settings_client.sound.confirm) SndPlayTileFx(SND_20_SPLAT_RAIL, tile);
if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace();
StoreRailPlacementEndpoints(tile, _build_tunnel_endtile, TileX(tile) == TileX(_build_tunnel_endtile) ? TRACK_Y : TRACK_X, false);
} else {
SetRedErrorSquare(_build_tunnel_endtile);
}
@@ -327,7 +341,7 @@ static bool RailToolbar_CtrlChanged(Window *w)
/* allow ctrl to switch remove mode only for these widgets */
for (uint i = WID_RAT_BUILD_NS; i <= WID_RAT_BUILD_STATION; i++) {
if ((i <= WID_RAT_AUTORAIL || i >= WID_RAT_BUILD_WAYPOINT) && w->IsWidgetLowered(i)) {
if ((i <= WID_RAT_POLYRAIL || i >= WID_RAT_BUILD_WAYPOINT) && w->IsWidgetLowered(i)) {
ToggleRailButton_Remove(w);
return true;
}
@@ -371,25 +385,46 @@ static void BuildRailClick_Remove(Window *w)
}
}
static void DoRailroadTrack(int mode)
static CommandContainer DoRailroadTrackCmd(TileIndex start_tile, TileIndex end_tile, Track track)
{
DoCommandP(TileVirtXY(_thd.selstart.x, _thd.selstart.y), TileVirtXY(_thd.selend.x, _thd.selend.y), _cur_railtype | (mode << 5),
_remove_button_clicked ?
CMD_REMOVE_RAILROAD_TRACK | CMD_MSG(STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK) :
CMD_BUILD_RAILROAD_TRACK | CMD_MSG(STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK),
CcPlaySound1E);
CommandContainer ret = {
start_tile, // tile
end_tile, // p1
_cur_railtype | (track << 5), // p2
_remove_button_clicked ?
CMD_REMOVE_RAILROAD_TRACK | CMD_MSG(STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK) :
CMD_BUILD_RAILROAD_TRACK | CMD_MSG(STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK), // cmd
CcPlaySound1E, // callback
0,
"" // text
};
return ret;
}
static void HandleAutodirPlacement()
{
int trackstat = _thd.drawstyle & HT_DIR_MASK; // 0..5
Track track = (Track)(_thd.drawstyle & HT_DIR_MASK); // 0..5
TileIndex start_tile = TileVirtXY(_thd.selstart.x, _thd.selstart.y);
TileIndex end_tile = TileVirtXY(_thd.selend.x, _thd.selend.y);
if (_thd.drawstyle & HT_RAIL) { // one tile case
GenericPlaceRail(TileVirtXY(_thd.selend.x, _thd.selend.y), trackstat);
return;
CommandContainer cmd = (_thd.drawstyle & HT_RAIL) ?
GenericPlaceRailCmd(end_tile, track) : // one tile case
DoRailroadTrackCmd(start_tile, end_tile, track); // multitile selection
/* When overbuilding existing tracks in polyline mode we just want to move the
* snap point without altering the user with the "already built" error. Don't
* execute the command right away, firstly check if tracks are being overbuilt. */
if (!(_thd.place_mode & HT_POLY) || _shift_pressed ||
DoCommand(&cmd, DC_AUTO | DC_NO_WATER).GetErrorMessage() != STR_ERROR_ALREADY_BUILT) {
/* place tracks */
if (!DoCommandP(&cmd)) return;
}
DoRailroadTrack(trackstat);
/* save new snap points for the polyline tool */
if (!_shift_pressed && _rail_track_endtile != INVALID_TILE) {
StoreRailPlacementEndpoints(start_tile, _rail_track_endtile, track, true);
}
}
/**
@@ -483,6 +518,7 @@ struct BuildRailToolbarWindow : Window {
this->GetWidget<NWidgetCore>(WID_RAT_BUILD_EW)->widget_data = rti->gui_sprites.build_ew_rail;
this->GetWidget<NWidgetCore>(WID_RAT_BUILD_Y)->widget_data = rti->gui_sprites.build_y_rail;
this->GetWidget<NWidgetCore>(WID_RAT_AUTORAIL)->widget_data = rti->gui_sprites.auto_rail;
this->GetWidget<NWidgetCore>(WID_RAT_POLYRAIL)->widget_data = rti->gui_sprites.auto_rail;
this->GetWidget<NWidgetCore>(WID_RAT_BUILD_DEPOT)->widget_data = rti->gui_sprites.build_depot;
this->GetWidget<NWidgetCore>(WID_RAT_CONVERT_RAIL)->widget_data = rti->gui_sprites.convert_rail;
this->GetWidget<NWidgetCore>(WID_RAT_BUILD_TUNNEL)->widget_data = rti->gui_sprites.build_tunnel;
@@ -511,6 +547,7 @@ struct BuildRailToolbarWindow : Window {
case WID_RAT_BUILD_EW:
case WID_RAT_BUILD_Y:
case WID_RAT_AUTORAIL:
case WID_RAT_POLYRAIL:
case WID_RAT_BUILD_WAYPOINT:
case WID_RAT_BUILD_STATION:
case WID_RAT_BUILD_SIGNALS:
@@ -542,6 +579,15 @@ struct BuildRailToolbarWindow : Window {
}
}
virtual void DrawWidget(const Rect &r, int widget) const
{
if (widget == WID_RAT_POLYRAIL) {
Dimension d = GetSpriteSize(SPR_BLOT);
uint offset = this->IsWidgetLowered(WID_RAT_POLYRAIL) ? 1 : 0;
DrawSprite(SPR_BLOT, PALETTE_TO_GREY, (r.left + r.right - d.width) / 2 + offset, (r.top + r.bottom - d.height) / 2 + offset);
}
}
virtual void OnClick(Point pt, int widget, int click_count)
{
if (widget < WID_RAT_BUILD_NS) return;
@@ -573,6 +619,40 @@ struct BuildRailToolbarWindow : Window {
this->last_user_action = widget;
break;
case WID_RAT_POLYRAIL: {
bool was_snap = CurrentlySnappingRailPlacement();
bool was_open = this->IsWidgetLowered(WID_RAT_POLYRAIL);
bool do_snap;
bool do_open;
/* "polyrail" hotkey - activate polyline tool in snapping mode, close the tool if snapping mode is already active
* "new_polyrail" hotkey - activate polyline tool in non-snapping (new line) mode, close the tool if non-snapping mode is already active
* button ctrl-clicking - switch between snapping and non-snapping modes, open the tool in non-snapping mode if it is closed
* button clicking - open the tool in non-snapping mode, close the tool if it is opened */
if (this->last_user_action == HOTKEY_POLYRAIL) {
do_snap = true;
do_open = !was_open || !was_snap;
} else if (this->last_user_action == HOTKEY_NEW_POLYRAIL) {
do_snap = false;
do_open = !was_open || was_snap;
} else if (_ctrl_pressed) {
do_snap = !was_open || !was_snap;
do_open = true;
} else {
do_snap = false;
do_open = !was_open;
}
/* close the tool explicitly so it can be re-opened in different snapping mode */
if (was_open) ResetObjectToPlace();
/* open the tool in desired mode */
if (do_open && HandlePlacePushButton(this, WID_RAT_POLYRAIL, GetRailTypeInfo(railtype)->cursor.autorail, do_snap ? (HT_RAIL | HT_POLY) : (HT_RAIL | HT_NEW_POLY))) {
/* if we are re-opening the tool but we couldn't switch the snapping
* then close the tool instead of appearing to be doing nothing */
if (was_open && do_snap != CurrentlySnappingRailPlacement()) ResetObjectToPlace();
}
this->last_user_action = WID_RAT_POLYRAIL;
break;
}
case WID_RAT_DEMOLISH:
HandlePlacePushButton(this, WID_RAT_DEMOLISH, ANIMCURSOR_DEMOLISH, HT_RECT | HT_DIAGONAL);
this->last_user_action = widget;
@@ -637,7 +717,15 @@ struct BuildRailToolbarWindow : Window {
virtual EventState OnHotkey(int hotkey)
{
MarkTileDirtyByTile(TileVirtXY(_thd.pos.x, _thd.pos.y)); // redraw tile selection
return Window::OnHotkey(hotkey);
if (hotkey == HOTKEY_POLYRAIL || hotkey == HOTKEY_NEW_POLYRAIL) {
/* Indicate to the OnClick that the action comes from a hotkey rather
* then from a click and that the CTRL state should be ignored. */
this->last_user_action = hotkey;
hotkey = WID_RAT_POLYRAIL;
}
return this->Window::OnHotkey(hotkey);
}
virtual void OnPlaceObject(Point pt, TileIndex tile)
@@ -660,6 +748,7 @@ struct BuildRailToolbarWindow : Window {
break;
case WID_RAT_AUTORAIL:
case WID_RAT_POLYRAIL:
VpStartPlaceSizing(tile, VPM_RAILDIRS, DDSP_PLACE_RAIL);
break;
@@ -807,6 +896,8 @@ static EventState RailToolbarGlobalHotkeys(int hotkey)
}
const uint16 _railtoolbar_autorail_keys[] = {'5', 'A' | WKC_GLOBAL_HOTKEY, 0};
const uint16 _railtoolbar_polyrail_keys[] = {'5' | WKC_CTRL, 'A' | WKC_CTRL | WKC_GLOBAL_HOTKEY, 0};
const uint16 _railtoolbar_new_poly_keys[] = {'5' | WKC_CTRL | WKC_SHIFT, 'A' | WKC_CTRL | WKC_SHIFT | WKC_GLOBAL_HOTKEY, 0};
static Hotkey railtoolbar_hotkeys[] = {
Hotkey('1', "build_ns", WID_RAT_BUILD_NS),
@@ -814,6 +905,8 @@ static Hotkey railtoolbar_hotkeys[] = {
Hotkey('3', "build_ew", WID_RAT_BUILD_EW),
Hotkey('4', "build_y", WID_RAT_BUILD_Y),
Hotkey(_railtoolbar_autorail_keys, "autorail", WID_RAT_AUTORAIL),
Hotkey(_railtoolbar_polyrail_keys, "polyrail", HOTKEY_POLYRAIL),
Hotkey(_railtoolbar_new_poly_keys, "new_polyrail", HOTKEY_NEW_POLYRAIL),
Hotkey('6', "demolish", WID_RAT_DEMOLISH),
Hotkey('7', "depot", WID_RAT_BUILD_DEPOT),
Hotkey('8', "waypoint", WID_RAT_BUILD_WAYPOINT),
@@ -844,6 +937,8 @@ static const NWidgetPart _nested_build_rail_widgets[] = {
SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_RAIL_NW, STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK),
NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_RAT_AUTORAIL),
SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_AUTORAIL, STR_RAIL_TOOLBAR_TOOLTIP_BUILD_AUTORAIL),
NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_RAT_POLYRAIL),
SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_AUTORAIL, STR_RAIL_TOOLBAR_TOOLTIP_BUILD_POLYRAIL),
NWidget(WWT_PANEL, COLOUR_DARK_GREEN), SetMinimalSize(4, 22), SetDataTip(0x0, STR_NULL), EndContainer(),