Update polyline patch to version 11a

This commit is contained in:
Pavel Stupnikov
2017-04-12 03:23:39 +03:00
9 changed files with 217 additions and 62 deletions

View File

@@ -73,6 +73,7 @@ void CcBuildBridge(const CommandCost &result, TileIndex end_tile, uint32 p1, uin
DiagDirection start_direction = ReverseDiagDir(GetTunnelBridgeDirection(p1));
ConnectRoadToStructure(p1, start_direction);
}
StoreRailPlacementEndpoints(p1, end_tile, (TileX(p1) == TileX(end_tile)) ? TRACK_Y : TRACK_X, false);
}

View File

@@ -363,7 +363,7 @@ DECLARE_ENUM_AS_BIT_SET(DoCommandFlag)
*
* @param x The StringID to combine with a command-id
*/
#define CMD_MSG(x) ((x) << 16)
#define CMD_MSG(x) ((uint32)((x) << 16))
/**
* Defines some flags.

View File

@@ -110,6 +110,7 @@ void InitializeGame(uint size_x, uint size_y, bool reset_date, bool reset_settin
InitializeEconomy();
ResetObjectToPlace();
ResetRailPlacementEndpoints();
GamelogReset();
GamelogStartAction(GLAT_START);

View File

@@ -368,14 +368,14 @@ static void BuildRailClick_Remove(Window *w)
static CommandContainer DoRailroadTrackCmd(TileIndex start_tile, TileIndex end_tile, Track track)
{
CommandContainer ret = {
start_tile, // tile
end_tile, // p1
_cur_railtype | (track << 4), // p2
start_tile, // tile
end_tile, // p1
(uint32)(_cur_railtype | (track << 4)), // 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
CcPlaySound_SPLAT_RAIL, // callback
"" // text
CcPlaySound_SPLAT_RAIL, // callback
"" // text
};
return ret;
@@ -391,16 +391,19 @@ static void HandleAutodirPlacement()
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 */
/* When overbuilding existing tracks in polyline mode we want to move the
* snap point over the last overbuilt track piece. In such case we don't
* wan't to show any errors to the user. Don't execute the command right
* away, first check if overbuilding. */
if (_shift_pressed || !(_thd.place_mode & HT_POLY) ||
DoCommand(&cmd, DC_AUTO | DC_NO_WATER).GetErrorMessage() != STR_ERROR_ALREADY_BUILT ||
_rail_track_endtile == INVALID_TILE) {
/* Execute. */
if (!DoCommandP(&cmd)) return;
}
/* save new snap points for the polyline tool */
/* Save new snap points for the polyline tool, no matter if the command
* succeeded, the snapping will be extended over overbuilt track pieces. */
if (!_shift_pressed && _rail_track_endtile != INVALID_TILE) {
StoreRailPlacementEndpoints(start_tile, _rail_track_endtile, track, true);
}
@@ -667,7 +670,7 @@ struct BuildRailToolbarWindow : Window {
break;
case WID_RAT_POLYRAIL: {
bool was_snap = CurrentlySnappingRailPlacement();
bool was_snap = GetRailSnapMode() == RSM_SNAP_TO_RAIL;
bool was_open = this->IsWidgetLowered(WID_RAT_POLYRAIL);
bool do_snap;
bool do_open;
@@ -688,15 +691,13 @@ struct BuildRailToolbarWindow : Window {
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();
}
/* close/open the tool */
if (was_open != do_open) HandlePlacePushButton(this, WID_RAT_POLYRAIL, GetRailTypeInfo(railtype)->cursor.autorail, HT_RAIL | HT_POLY);
/* set snapping mode */
if (do_open) SetRailSnapMode(do_snap ? RSM_SNAP_TO_RAIL : RSM_NO_SNAP);
this->last_user_action = WID_RAT_POLYRAIL;
if (was_open == do_open) return; // prevent switching the "remove" button state
break;
}

View File

@@ -906,6 +906,7 @@ void SQGSWindow_Register(Squirrel *engine)
SQGSWindow.DefSQConst(engine, ScriptWindow::WID_RAT_BUILD_EW, "WID_RAT_BUILD_EW");
SQGSWindow.DefSQConst(engine, ScriptWindow::WID_RAT_BUILD_Y, "WID_RAT_BUILD_Y");
SQGSWindow.DefSQConst(engine, ScriptWindow::WID_RAT_AUTORAIL, "WID_RAT_AUTORAIL");
SQGSWindow.DefSQConst(engine, ScriptWindow::WID_RAT_POLYRAIL, "WID_RAT_POLYRAIL");
SQGSWindow.DefSQConst(engine, ScriptWindow::WID_RAT_DEMOLISH, "WID_RAT_DEMOLISH");
SQGSWindow.DefSQConst(engine, ScriptWindow::WID_RAT_BUILD_DEPOT, "WID_RAT_BUILD_DEPOT");
SQGSWindow.DefSQConst(engine, ScriptWindow::WID_RAT_BUILD_WAYPOINT, "WID_RAT_BUILD_WAYPOINT");

View File

@@ -1984,6 +1984,7 @@ public:
WID_RAT_BUILD_EW = ::WID_RAT_BUILD_EW, ///< Build rail along the game view X axis.
WID_RAT_BUILD_Y = ::WID_RAT_BUILD_Y, ///< Build rail along the game grid Y axis.
WID_RAT_AUTORAIL = ::WID_RAT_AUTORAIL, ///< Autorail tool.
WID_RAT_POLYRAIL = ::WID_RAT_POLYRAIL, ///< Polyline rail tool.
WID_RAT_DEMOLISH = ::WID_RAT_DEMOLISH, ///< Destroy something with dynamite!
WID_RAT_BUILD_DEPOT = ::WID_RAT_BUILD_DEPOT, ///< Build a depot.
WID_RAT_BUILD_WAYPOINT = ::WID_RAT_BUILD_WAYPOINT, ///< Build a waypoint.

View File

@@ -13,6 +13,7 @@
#define TILEHIGHLIGHT_FUNC_H
#include "gfx_type.h"
#include "tilearea_type.h"
#include "tilehighlight_type.h"
#include "track_type.h"
#include "industry_type.h"
@@ -32,12 +33,15 @@ void VpSetPlaceSizingLimit(int limit);
void UpdateTileSelection();
void StoreRailPlacementEndpoints(TileIndex start_tile, TileIndex end_tile, Track start_track, bool bidirectional = true);
void ResetRailPlacementSnapping();
bool CurrentlySnappingRailPlacement();
void SetIndustryForbiddenTilesHighlight(IndustryType type);
RailSnapMode GetRailSnapMode();
void SetRailSnapMode(RailSnapMode mode);
void StoreRailPlacementEndpoints(TileIndex start_tile, TileIndex end_tile, Track start_track, bool bidirectional = true);
void StoreRailStationPlacementEndpoints(const TileArea &ta, Axis station_axis);
void ResetRailPlacementEndpoints();
extern TileHighlightData _thd;
#endif /* TILEHIGHLIGHT_FUNC_H */

View File

@@ -29,7 +29,6 @@ enum HighLightStyle {
HT_VEHICLE = 0x100, ///< vehicle is accepted as target as well (bitmask)
HT_DIAGONAL = 0x200, ///< Also allow 'diagonal rectangles'. Only usable in combination with #HT_RECT or #HT_POINT.
HT_POLY = 0x400, ///< polyline mode; connect highlighted track with previous one
HT_NEW_POLY = 0xC00, ///< start completly new polyline; implies #HT_POLY
HT_DRAG_MASK = 0x0F8, ///< Mask for the tile drag-type modes.
/* lower bits (used with HT_LINE and HT_RAIL):
@@ -45,6 +44,12 @@ enum HighLightStyle {
};
DECLARE_ENUM_AS_BIT_SET(HighLightStyle)
/** Methods of rail track snapping. */
enum RailSnapMode {
RSM_NO_SNAP, ///< Not snapping.
RSM_SNAP_TO_TILE, ///< Snap to a tile.
RSM_SNAP_TO_RAIL, ///< Snap to other rail tracks.
};
/** Metadata about the current highlighting. */
struct TileHighlightData {

View File

@@ -86,7 +86,7 @@
#include "window_gui.h"
#include "linkgraph/linkgraph_gui.h"
#include "viewport_sprite_sorter.h"
#include "bridge_map.h"
#include "tunnelbridge_map.h"
#include <map>
@@ -154,12 +154,6 @@ typedef SmallVector<StringSpriteToDraw, 4> StringSpriteToDrawVector;
typedef SmallVector<ParentSpriteToDraw, 64> ParentSpriteToDrawVector;
typedef SmallVector<ChildScreenSpriteToDraw, 16> ChildScreenSpriteToDrawVector;
enum RailSnapMode {
RSM_NO_SNAP,
RSM_SNAP_TO_TILE,
RSM_SNAP_TO_RAIL,
};
/**
* Snapping point for a track.
*
@@ -213,15 +207,13 @@ bool _draw_dirty_blocks = false;
uint _dirty_block_colour = 0;
static VpSpriteSorter _vp_sprite_sorter = NULL;
static IndustryType _industry_forbidden_tiles = INVALID_INDUSTRYTYPE;
static RailSnapMode _rail_snap_mode = RSM_NO_SNAP; ///< Type of rail track snapping (polyline tool).
static LineSnapPoints _tile_snap_points; ///< Tile to which a rail track will be snapped to (polyline tool).
static LineSnapPoints _rail_snap_points; ///< Set of points where a rail track will be snapped to (polyline tool).
static LineSnapPoint _current_snap_lock; ///< Start point and direction at which selected track is locked on currently (while dragging in polyline mode).
static IndustryType _industry_forbidden_tiles = INVALID_INDUSTRYTYPE;
static RailSnapMode GetRailSnapMode();
static void SetRailSnapMode(RailSnapMode mode);
static TileIndex GetRailSnapTile();
static void SetRailSnapTile(TileIndex tile);
@@ -2415,6 +2407,7 @@ Window *TileHighlightData::GetCallbackWnd()
static HighLightStyle CalcPolyrailDrawstyle(Point pt, bool dragging);
/** Update size of the area occupied by the blue part of rail track highlight (polyline mode). */
static inline void CalcNewPolylineOutersize()
{
/* use the 'outersize' to mark the second (blue) part of a polyline selection */
@@ -2555,6 +2548,7 @@ void UpdateTileSelection()
_thd.selstart.y = y1 & ~TILE_UNIT_MASK;
_thd.selend.x = x1;
_thd.selend.y = y1;
_thd.dir2 = HT_DIR_END;
break;
default:
NOT_REACHED();
@@ -2827,6 +2821,14 @@ static int CalcHeightdiff(HighLightStyle style, uint distance, TileIndex start_t
return (int)(h1 - h0) * TILE_HEIGHT_STEP;
}
/**
* Show a tooltip indicating the length of highlighted rail track.
* @param style Style of the highlight.
* @param start_tile Tile where selection starts.
* @param end_tile Tile where selection ends.
* @param close_cond Close condition of the tooltip.
* @param show_single_tile_length Show a tooltip also when the length is 1 tile.
*/
static void ShowLengthMeasurement(HighLightStyle style, TileIndex start_tile, TileIndex end_tile, TooltipCloseCondition close_cond = TCC_LEFT_CLICK, bool show_single_tile_length = false)
{
static const StringID measure_strings_length[] = {STR_NULL, STR_MEASURE_LENGTH, STR_MEASURE_LENGTH_HEIGHTDIFF};
@@ -2887,6 +2889,16 @@ static const uint Y_DIRS = (1 << DIR_SE) | (1 << DIR_NW);
static const uint HORZ_DIRS = (1 << DIR_W) | (1 << DIR_E);
static const uint VERT_DIRS = (1 << DIR_N) | (1 << DIR_S);
/**
* Convert a given point and a given #Direction to best matching #Trackdir.
*
* For example, #DIR_N will be converted to #TRACKDIR_LEFT_N if the point
* is on left tile half or #TRACKDIR_RIGHT_N if the point is on right half.
*
* @param pt The point expressed in inner-tile world "units".
* @param dir The direction.
* @return The matching #Trackdir.
*/
Trackdir PointDirToTrackdir(const Point &pt, Direction dir)
{
Trackdir ret;
@@ -2908,9 +2920,18 @@ Trackdir PointDirToTrackdir(const Point &pt, Direction dir)
return ret;
}
/**
* Try to fit a pair of rail track lines (polyline) based on a given end point
* (mouse cursor position) and a given snap point (begin point).
*
* @param pt The end point expressed in inner-tile world "units".
* @param start The snap point, begin of the lines.
* @param[out] ret Coordinates of the lines (if found).
* @return Whether the lines were found.
*/
static bool FindPolyline(const Point &pt, const LineSnapPoint &start, Polyline *ret)
{
/* relative coordinats of the mouse point (offset against the snap point) */
/* relative coordinates of the mouse point (offset against the snap point) */
int x = pt.x - start.x;
int y = pt.y - start.y;
int we = y - x;
@@ -2927,7 +2948,7 @@ static bool FindPolyline(const Point &pt, const LineSnapPoint &start, Polyline *
uint d_ns = abs(RoundDivSU(ns, TILE_SIZE));
uint d_we = abs(RoundDivSU(we, TILE_SIZE));
/* Find on which quadrant is the mouse point (reltively to the snap point).
/* Find on which quadrant is the mouse point (relatively to the snap point).
* Numeration (clockwise like in Direction):
* ortho diag
* \ 2 / 2 | 3
@@ -2972,7 +2993,7 @@ static bool FindPolyline(const Point &pt, const LineSnapPoint &start, Polyline *
/* in the first place, choose this line whose first segment ends up closer
* to the mouse point (thus the second segment is shorter) */
int cmp = ortho_len2 - diag_len2;
/* if equeal, choose the shorter line */
/* if equal, choose the shorter line */
if (cmp == 0) cmp = ortho_len - diag_len;
/* finally look at small "units" and choose the line which is closer to the mouse point */
if (cmp == 0) cmp = min(abs(we), abs(ns)) - min(abs(x), abs(y));
@@ -3014,6 +3035,15 @@ static inline uint SqrDist(const Point &a, const Point &b)
return (b.x - a.x) * (b.x - a.x) + (b.y - a.y) * (b.y - a.y);
}
/**
* Find best matching pair of lines (polyline).
*
* @param pt The end point (mouse cursor position) expressed in inner-tile world "units".
* @param snap_points Array of snapping points, the best one will be chosen.
* @param num_points Length of the array.
* @param[out] ret Coordinates of the polyline (if found).
* @return The chosen snapping point or NULL if no matching line was found.
*/
static LineSnapPoint *FindBestPolyline(const Point &pt, LineSnapPoint *snap_points, uint num_points, Polyline *ret)
{
/* Find the best polyline (a pair of two lines - the white one and the blue
@@ -3240,6 +3270,12 @@ static void CalcRaildirsDrawstyle(int x, int y, int method)
ShowLengthMeasurement(b, TileVirtXY(_thd.selstart.x, _thd.selstart.y), TileVirtXY(_thd.selend.x, _thd.selend.y));
}
/**
* Calculate how tiles should be highlighted (polyline mode).
* @param pt Current mouse cursor position expressed in inner-tile world "units".
* @param dragging Whether currently drag-dropping, in this case direction of rail track line is locked.
* @return New highlight style.
*/
static HighLightStyle CalcPolyrailDrawstyle(Point pt, bool dragging)
{
RailSnapMode snap_mode = GetRailSnapMode();
@@ -3524,6 +3560,13 @@ EventState VpHandlePlaceSizingDrag()
return ES_HANDLED;
}
/**
* Change the cursor and mouse click/drag handling to a mode for performing special operations like tile area selection, object placement, etc.
* @param icon New shape of the mouse cursor.
* @param pal Palette to use.
* @param mode Mode to perform.
* @param w %Window requesting the mode change.
*/
void SetObjectToPlaceWnd(CursorID icon, PaletteID pal, HighLightStyle mode, Window *w)
{
SetObjectToPlace(icon, pal, mode, w->window_class, w->window_number);
@@ -3531,6 +3574,14 @@ void SetObjectToPlaceWnd(CursorID icon, PaletteID pal, HighLightStyle mode, Wind
#include "table/animcursors.h"
/**
* Change the cursor and mouse click/drag handling to a mode for performing special operations like tile area selection, object placement, etc.
* @param icon New shape of the mouse cursor.
* @param pal Palette to use.
* @param mode Mode to perform.
* @param window_class %Window class of the window requesting the mode change.
* @param window_num Number of the window in its class requesting the mode change.
*/
void SetObjectToPlace(CursorID icon, PaletteID pal, HighLightStyle mode, WindowClass window_class, WindowNumber window_num)
{
if (_thd.window_class != WC_INVALID) {
@@ -3567,10 +3618,6 @@ void SetObjectToPlace(CursorID icon, PaletteID pal, HighLightStyle mode, WindowC
VpStartPreSizing();
}
if (mode & HT_POLY) {
SetRailSnapMode((mode & HT_NEW_POLY) == HT_NEW_POLY ? RSM_NO_SNAP : RSM_SNAP_TO_RAIL);
}
if ((icon & ANIMCURSOR_FLAG) != 0) {
SetAnimatedMouseCursor(_animcursors[icon & ~ANIMCURSOR_FLAG]);
} else {
@@ -3579,6 +3626,7 @@ void SetObjectToPlace(CursorID icon, PaletteID pal, HighLightStyle mode, WindowC
}
/** Reset the cursor and mouse mode handling back to default (normal cursor, only clicking in windows). */
void ResetObjectToPlace()
{
SetObjectToPlace(SPR_CURSOR_MOUSE, PAL_NONE, HT_NONE, WC_MAIN_WINDOW, 0);
@@ -3622,18 +3670,56 @@ void InitializeSpriteSorter()
assert(_vp_sprite_sorter != NULL);
}
static LineSnapPoint LineSnapPointAtRailTrackEndpoint(TileIndex tile, DiagDirection exit_dir, bool bidirectional)
/**
* Construct a rail snapping point based on a spot where a rail tracks segment
* has been placed.
*
* The snapping point will allow to stick new segment of tracks to the line that
* was placed before.
*
* @param tile Tile where the placed segment ended.
* @param exit_dir Tile side at which the segment ended.
* @param bidirectional Whether to allow to reverse at this point
* (e.g. reversing after a bridges/tunnels is undesired).
* @param extended If not \c NULL, the snapping point will be extended over
* a bridge/tunnel/station etc. if the last placed segment touches such
* an object. Additional snapping point may be stored under \a extended
* if needed, otherwise it will be set to { -1, -1, 0 }.
* @return New rail snapping point.
*/
static LineSnapPoint LineSnapPointAtRailTrackEndpoint(TileIndex tile, DiagDirection exit_dir, bool bidirectional, LineSnapPoint *extended)
{
LineSnapPoint ret;
ret.x = (TILE_SIZE / 2) * (uint)(2 * TileX(tile) + TileIndexDiffCByDiagDir(exit_dir).x + 1);
ret.y = (TILE_SIZE / 2) * (uint)(2 * TileY(tile) + TileIndexDiffCByDiagDir(exit_dir).y + 1);
ret.dirs = 0;
SetBit(ret.dirs, DiagDirToDir(exit_dir));
SetBit(ret.dirs, ChangeDir(DiagDirToDir(exit_dir), DIRDIFF_45LEFT));
SetBit(ret.dirs, ChangeDir(DiagDirToDir(exit_dir), DIRDIFF_45RIGHT));
if (bidirectional) ret.dirs |= ROR<uint8>(ret.dirs, DIRDIFF_REVERSE);
if (extended != NULL) {
extended->x = -1;
extended->y = -1;
extended->dirs = 0;
}
/* Check whether to extend the snap point over a tunnel/bridge/station etc. */
tile = TileAddByDiagDir(tile, exit_dir);
if (extended != NULL && !IsTileType(tile, MP_RAILWAY) && !IsTileType(tile, MP_ROAD) &&
TrackStatusToTrackBits(GetTileTrackStatus(tile, TRANSPORT_RAIL, INVALID_DIAGDIR)) == AxisToTrackBits(DiagDirToAxis(exit_dir)) &&
IsTileOwner(tile, _local_company)) {
/* Check if this is a tunnel/bridge and move the tile to the other end if so. */
if (IsTileType(tile, MP_TUNNELBRIDGE)) tile = GetOtherTunnelBridgeEnd(tile);
LineSnapPoint ex = LineSnapPointAtRailTrackEndpoint(tile, exit_dir, false, extended);
if (!bidirectional) return ex; // if we are interested in forward direction only then return just the extended point
*extended = ex; // otherwise return two points, extended with forward direction and base with reverse direction
} else {
/* Add forward direction. */
SetBit(ret.dirs, DiagDirToDir(exit_dir));
}
/* Add reverse direction. */
if (bidirectional) SetBit(ret.dirs, ReverseDir(DiagDirToDir(exit_dir)));
/* Add 45 degree rotated directions. */
ret.dirs |= ROR<uint8>(ret.dirs, DIRDIFF_45LEFT);
ret.dirs |= ROR<uint8>(ret.dirs, DIRDIFF_45RIGHT);
return ret;
}
@@ -3664,8 +3750,9 @@ void StoreRailPlacementEndpoints(TileIndex start_tile, TileIndex end_tile, Track
if (distance % 2 != 0) exit_trackdir_at_end = NextTrackdir(exit_trackdir_at_end);
}
LineSnapPoint snap_start = LineSnapPointAtRailTrackEndpoint(start_tile, TrackdirToExitdir(exit_trackdir_at_start), bidirectional_exit);
LineSnapPoint snap_end = LineSnapPointAtRailTrackEndpoint(end_tile, TrackdirToExitdir(exit_trackdir_at_end), bidirectional_exit);
LineSnapPoint snap_start, snap_start_ex, snap_end, snap_end_ex;
snap_start = LineSnapPointAtRailTrackEndpoint(start_tile, TrackdirToExitdir(exit_trackdir_at_start), bidirectional_exit, &snap_start_ex);
snap_end = LineSnapPointAtRailTrackEndpoint(end_tile, TrackdirToExitdir(exit_trackdir_at_end), bidirectional_exit, &snap_end_ex);
/* Find if we already had these coordinates before. */
LineSnapPoint *snap;
bool had_start = false;
@@ -3676,31 +3763,72 @@ void StoreRailPlacementEndpoints(TileIndex start_tile, TileIndex end_tile, Track
}
/* Create new snap point set. */
if (had_start && had_end) {
/* just stop snaping, don't forget snap points */
/* just stop snapping, don't forget snap points */
SetRailSnapMode(RSM_NO_SNAP);
} else {
/* include only new points */
_rail_snap_points.Clear();
if (!had_start) *_rail_snap_points.Append() = snap_start;
if (!had_end) *_rail_snap_points.Append() = snap_end;
if (!had_start) {
*_rail_snap_points.Append() = snap_start;
if (snap_start_ex.dirs != 0) *_rail_snap_points.Append() = snap_start_ex;
}
if (!had_end) {
*_rail_snap_points.Append() = snap_end;
if (snap_end_ex.dirs != 0) *_rail_snap_points.Append() = snap_end_ex;
}
SetRailSnapMode(RSM_SNAP_TO_RAIL);
}
}
}
bool CurrentlySnappingRailPlacement()
/**
* Store the position of lastly built rail station; for highlighting purposes.
*
* In "polyline" highlighting mode, the stored end points will be used as snapping points for new tracks.
*
* @param ta Station area.
* @param station_axis Station axis.
*/
void StoreRailStationPlacementEndpoints(const TileArea &ta, Axis station_axis)
{
return (_thd.place_mode & HT_POLY) && GetRailSnapMode() == RSM_SNAP_TO_RAIL;
uint start_x = TileX(ta.tile);
uint start_y = TileY(ta.tile);
uint end_x = start_x + ta.w - 1;
uint end_y = start_y + ta.h - 1;
_rail_snap_points.Clear();
if (station_axis == AXIS_X) {
for (uint y = start_y; y <= end_y; y++) {
*_rail_snap_points.Append() = LineSnapPointAtRailTrackEndpoint(TileXY(start_x, y), DIAGDIR_NE, false, NULL);
*_rail_snap_points.Append() = LineSnapPointAtRailTrackEndpoint(TileXY(end_x, y), DIAGDIR_SW, false, NULL);
}
} else {
for (uint x = start_x; x <= end_x; x++) {
*_rail_snap_points.Append() = LineSnapPointAtRailTrackEndpoint(TileXY(x, start_y), DIAGDIR_NW, false, NULL);
*_rail_snap_points.Append() = LineSnapPointAtRailTrackEndpoint(TileXY(x, end_y), DIAGDIR_SE, false, NULL);
}
}
}
static RailSnapMode GetRailSnapMode()
/**
* Get current rail track snapping mode.
* @return Current snapping mode.
*
* @note This function will return #RSM_NO_SNAP if there are no snapping points
* set (yet), even thought the snapping was set to some different mode.
*/
RailSnapMode GetRailSnapMode()
{
if (_rail_snap_mode == RSM_SNAP_TO_TILE && _tile_snap_points.Length() == 0) return RSM_NO_SNAP;
if (_rail_snap_mode == RSM_SNAP_TO_RAIL && _rail_snap_points.Length() == 0) return RSM_NO_SNAP;
return _rail_snap_mode;
}
static void SetRailSnapMode(RailSnapMode mode)
/**
* Set current current rail track snapping mode.
* @param mode New snapping mode.
*/
void SetRailSnapMode(RailSnapMode mode)
{
_rail_snap_mode = mode;
@@ -3709,12 +3837,24 @@ static void SetRailSnapMode(RailSnapMode mode)
}
}
/**
* Get the tile that is set to be a snapping point for rail tracks (used when
* #RSM_SNAP_TO_TILE mode is active).
*
* @return The tile.
*/
static TileIndex GetRailSnapTile()
{
if (_tile_snap_points.Length() == 0) return INVALID_TILE;
return TileVirtXY(_tile_snap_points[DIAGDIR_NE].x, _tile_snap_points[DIAGDIR_NE].y);
}
/**
* Set the tile that is meant to be a snapping point for rail tracks (used when
* #RSM_SNAP_TO_TILE mode is active).
*
* @param tile The tile.
*/
static void SetRailSnapTile(TileIndex tile)
{
_tile_snap_points.Clear();
@@ -3722,12 +3862,13 @@ static void SetRailSnapTile(TileIndex tile)
for (DiagDirection dir = DIAGDIR_BEGIN; dir < DIAGDIR_END; dir++) {
LineSnapPoint *point = _tile_snap_points.Append();
*point = LineSnapPointAtRailTrackEndpoint(tile, dir, false);
*point = LineSnapPointAtRailTrackEndpoint(tile, dir, false, NULL);
point->dirs = ROR<uint8>(point->dirs, DIRDIFF_REVERSE);
}
}
void ResetRailPlacementSnapping()
/** Clear all stored rail snapping points and reset the snapping mode. */
void ResetRailPlacementEndpoints()
{
_rail_snap_mode = RSM_NO_SNAP;
_tile_snap_points.Clear();