mirror of https://github.com/OpenTTD/OpenTTD
(svn r1571) Feature: Visually enhanced autorail placing
When using the autorail tool, the rail pieces which are going to be build are highlighted. If a piece is shown in red, this indicates that the slope/rail combination is impossible. It does not tell you if the rail line construction might not be possible because of other obstacles, e.g. houses or water.release/0.4.5
parent
28df4a0e25
commit
aaf09ceb26
Binary file not shown.
BIN
data/openttd.grf
BIN
data/openttd.grf
Binary file not shown.
14
main_gui.c
14
main_gui.c
|
@ -111,7 +111,19 @@ void HandleOnEditText(WindowEvent *e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// this code is shared for the majority of the pushbuttons
|
/**
|
||||||
|
* This code is shared for the majority of the pushbuttons.
|
||||||
|
* Handles e.g. the pressing of a button (to build things), playing of click sound and sets certain parameters
|
||||||
|
*
|
||||||
|
* @param w Window which called the function
|
||||||
|
* @param widget ID of the widget (=button) that called this function
|
||||||
|
* @param cursor How should the cursor image change? E.g. cursor with depot image in it
|
||||||
|
* @param mode Tile highlighting mode, e.g. drawing a rectangle or a dot on the ground
|
||||||
|
* @param placeproc Procedure which will be called when someone clicks on the map
|
||||||
|
|
||||||
|
* @return true if the button is clicked, false if it's unclicked
|
||||||
|
*/
|
||||||
|
|
||||||
bool HandlePlacePushButton(Window *w, int widget, uint32 cursor, int mode, PlaceProc *placeproc)
|
bool HandlePlacePushButton(Window *w, int widget, uint32 cursor, int mode, PlaceProc *placeproc)
|
||||||
{
|
{
|
||||||
uint32 mask = 1 << widget;
|
uint32 mask = 1 << widget;
|
||||||
|
|
99
rail_gui.c
99
rail_gui.c
|
@ -232,7 +232,7 @@ static void BuildRailClick_NW(Window *w)
|
||||||
|
|
||||||
static void BuildRailClick_AutoRail(Window *w)
|
static void BuildRailClick_AutoRail(Window *w)
|
||||||
{
|
{
|
||||||
HandlePlacePushButton(w, 8, _cur_railtype + SPR_OPENTTD_BASE + 4, 1, PlaceRail_AutoRail);
|
HandlePlacePushButton(w, 8, _cur_railtype + SPR_CURSOR_AUTORAIL, VHM_RAIL, PlaceRail_AutoRail);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void BuildRailClick_Demolish(Window *w)
|
static void BuildRailClick_Demolish(Window *w)
|
||||||
|
@ -266,7 +266,7 @@ static void BuildRailClick_Station(Window *w)
|
||||||
|
|
||||||
static void BuildRailClick_AutoSignals(Window *w)
|
static void BuildRailClick_AutoSignals(Window *w)
|
||||||
{
|
{
|
||||||
HandlePlacePushButton(w, 13, ANIMCURSOR_BUILDSIGNALS , 1, PlaceRail_AutoSignals);
|
HandlePlacePushButton(w, 13, ANIMCURSOR_BUILDSIGNALS, VHM_RECT, PlaceRail_AutoSignals);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void BuildRailClick_Bridge(Window *w)
|
static void BuildRailClick_Bridge(Window *w)
|
||||||
|
@ -320,6 +320,10 @@ static void DoRailroadTrack(int mode)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This code was used for ludde's special autorail autocomplete.
|
||||||
|
* It analyzes the adjecent tiles and bases it's decision which
|
||||||
|
* rail piece to place on this.
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
byte bit, a,b, mouse;
|
byte bit, a,b, mouse;
|
||||||
} BestFitStruct;
|
} BestFitStruct;
|
||||||
|
@ -432,7 +436,9 @@ static int GetBestFit1x1(int x, int y)
|
||||||
|
|
||||||
return best;
|
return best;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
// This function is more or less a hack because DoRailroadTrack() would otherwise screw up
|
||||||
static void SwapSelection()
|
static void SwapSelection()
|
||||||
{
|
{
|
||||||
TileHighlightData *thd = &_thd;
|
TileHighlightData *thd = &_thd;
|
||||||
|
@ -442,6 +448,8 @@ static void SwapSelection()
|
||||||
thd->selend = pt;
|
thd->selend = pt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* see above, residue from ludde's special autorail autocomplete
|
||||||
|
|
||||||
static bool Check2x1AutoRail(int mode)
|
static bool Check2x1AutoRail(int mode)
|
||||||
{
|
{
|
||||||
TileHighlightData *thd = &_thd;
|
TileHighlightData *thd = &_thd;
|
||||||
|
@ -474,46 +482,61 @@ static bool Check2x1AutoRail(int mode)
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
static void HandleAutodirPlacement()
|
static void HandleAutodirPlacement()
|
||||||
{
|
{
|
||||||
TileHighlightData *thd = &_thd;
|
TileHighlightData *thd = &_thd;
|
||||||
int bit;
|
int bit;
|
||||||
|
int dx = thd->selstart.x - (thd->selend.x&~0xF);
|
||||||
|
int dy = thd->selstart.y - (thd->selend.y&~0xF);
|
||||||
|
|
||||||
if (thd->drawstyle == HT_RECT) {
|
if (thd->drawstyle & HT_RAIL) { // one tile case
|
||||||
int dx = thd->selstart.x - (thd->selend.x&~0xF);
|
bit = thd->drawstyle & 0xF;
|
||||||
int dy = thd->selstart.y - (thd->selend.y&~0xF);
|
GenericPlaceRail(TILE_FROM_XY(thd->selend.x, thd->selend.y), bit);
|
||||||
|
} else if ( !(thd->drawstyle & 0xE) ) { // x/y dir
|
||||||
if (dx == 0 && dy == 0 ) {
|
if (dx == 0) { // Y dir
|
||||||
// 1x1 tile
|
DoRailroadTrack(1);
|
||||||
bit = GetBestFit1x1(thd->selend.x, thd->selend.y);
|
|
||||||
if (bit == -1) return;
|
|
||||||
GenericPlaceRail(TILE_FROM_XY(thd->selend.x, thd->selend.y), bit);
|
|
||||||
} else if (dx == 0) {
|
|
||||||
if (dy == -16) {
|
|
||||||
if (Check2x1AutoRail(0)) return;
|
|
||||||
} else if (dy == 16) {
|
|
||||||
if (Check2x1AutoRail(1)) return;
|
|
||||||
}
|
|
||||||
// same x coordinate
|
|
||||||
DoRailroadTrack(VPM_FIX_X);
|
|
||||||
} else {
|
} else {
|
||||||
// same y coordinate
|
DoRailroadTrack(2);
|
||||||
// check it's it -16 or 16, then we must check if it should be normal tiles or special tiles.
|
}
|
||||||
if (dx == -16) {
|
} else if (myabs(dx)+myabs(dy) >= 32) { // long line (more than 2 tiles)
|
||||||
if (Check2x1AutoRail(2)) return;
|
if(thd->drawstyle == (HT_LINE | HT_DIR_HU))
|
||||||
} else if (dx == 16) {
|
DoRailroadTrack(0);
|
||||||
if (Check2x1AutoRail(3)) return;
|
if(thd->drawstyle == (HT_LINE | HT_DIR_HL))
|
||||||
}
|
DoRailroadTrack(3);
|
||||||
DoRailroadTrack(VPM_FIX_Y);
|
if(thd->drawstyle == (HT_LINE | HT_DIR_VL))
|
||||||
|
DoRailroadTrack(3);
|
||||||
|
if(thd->drawstyle == (HT_LINE | HT_DIR_VR))
|
||||||
|
DoRailroadTrack(0);
|
||||||
|
} else { // 2x1 pieces line
|
||||||
|
if(thd->drawstyle == (HT_LINE | HT_DIR_HU)) {
|
||||||
|
DoRailroadTrack(0);
|
||||||
|
} else if (thd->drawstyle == (HT_LINE | HT_DIR_HL)) {
|
||||||
|
SwapSelection();
|
||||||
|
DoRailroadTrack(0);
|
||||||
|
SwapSelection();
|
||||||
|
} else if (thd->drawstyle == (HT_LINE | HT_DIR_VL)) {
|
||||||
|
if(dx == 0) {
|
||||||
|
SwapSelection();
|
||||||
|
DoRailroadTrack(0);
|
||||||
|
SwapSelection();
|
||||||
|
} else {
|
||||||
|
DoRailroadTrack(3);
|
||||||
|
}
|
||||||
|
} else if (thd->drawstyle == (HT_LINE | HT_DIR_VR)) {
|
||||||
|
if(dx == 0) {
|
||||||
|
DoRailroadTrack(0);
|
||||||
|
} else {
|
||||||
|
SwapSelection();
|
||||||
|
DoRailroadTrack(3);
|
||||||
|
SwapSelection();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
DoRailroadTrack(thd->drawstyle & 1 ? 0 : 3);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void HandleAutoSignalPlacement()
|
static void HandleAutoSignalPlacement(void)
|
||||||
{
|
{
|
||||||
TileHighlightData *thd = &_thd;
|
TileHighlightData *thd = &_thd;
|
||||||
int mode = 0;
|
int mode = 0;
|
||||||
|
@ -525,7 +548,7 @@ static void HandleAutoSignalPlacement()
|
||||||
if (dx == 0 && dy == 0 ) // 1x1 tile signals
|
if (dx == 0 && dy == 0 ) // 1x1 tile signals
|
||||||
GenericPlaceSignals(TILE_FROM_XY(thd->selend.x, thd->selend.y));
|
GenericPlaceSignals(TILE_FROM_XY(thd->selend.x, thd->selend.y));
|
||||||
else { // signals have been dragged
|
else { // signals have been dragged
|
||||||
if (thd->drawstyle == HT_RECT) { // X,Y direction
|
if (!(thd->drawstyle & 0xE)) { // X,Y direction
|
||||||
if (dx == 0)
|
if (dx == 0)
|
||||||
mode = VPM_FIX_X;
|
mode = VPM_FIX_X;
|
||||||
else if (dy == 0)
|
else if (dy == 0)
|
||||||
|
@ -533,16 +556,18 @@ static void HandleAutoSignalPlacement()
|
||||||
|
|
||||||
trackstat = 0xC0;
|
trackstat = 0xC0;
|
||||||
} else { // W-E or N-S direction
|
} else { // W-E or N-S direction
|
||||||
mode = thd->drawstyle & 1 ? 0 : 3;
|
if ((thd->drawstyle & 0xF) == 2 || (thd->drawstyle & 0xF) == 5)
|
||||||
|
mode = 0;
|
||||||
|
else
|
||||||
|
mode = 3;
|
||||||
|
|
||||||
if (dx == dy || abs(dx - dy) == 16) // North<->South track |
|
if (dx == dy || abs(dx - dy) == 16) // North<->South track |
|
||||||
trackstat = (thd->drawstyle & 1) ? 0x20 : 0x10;
|
trackstat = (thd->drawstyle & 1) ? 0x20 : 0x10;
|
||||||
else if (dx == -dy || abs(dx + dy) == 16) // East<->West track --
|
else if (dx == -dy || abs(dx + dy) == 16) // East<->West track --
|
||||||
trackstat = (thd->drawstyle & 1) ? 4 : 8;
|
trackstat = (thd->drawstyle & 1) ? 8 : 4;
|
||||||
}
|
}
|
||||||
|
// _patches.drag_signals_density is given as a parameter such that each user in a network
|
||||||
/* _patches.drag_signals_density is given as a parameter such that each user in a network
|
// game can specify his/her own signal density
|
||||||
* game can specify his/her own signal density */
|
|
||||||
DoCommandP(TILE_FROM_XY(thd->selstart.x, thd->selstart.y), TILE_FROM_XY(thd->selend.x, thd->selend.y),
|
DoCommandP(TILE_FROM_XY(thd->selstart.x, thd->selstart.y), TILE_FROM_XY(thd->selend.x, thd->selend.y),
|
||||||
(mode << 4) | (_remove_button_clicked + (_ctrl_pressed ? 8 : 0)) | (trackstat << 8) | (_patches.drag_signals_density << 24),
|
(mode << 4) | (_remove_button_clicked + (_ctrl_pressed ? 8 : 0)) | (trackstat << 8) | (_patches.drag_signals_density << 24),
|
||||||
CcPlaySound1E,
|
CcPlaySound1E,
|
||||||
|
|
|
@ -883,6 +883,9 @@ static void LoadSpriteTables()
|
||||||
|
|
||||||
LoadGrfIndexed("trkfoundw.grf", _slopes_spriteindexes[_opt.landscape], i++);
|
LoadGrfIndexed("trkfoundw.grf", _slopes_spriteindexes[_opt.landscape], i++);
|
||||||
|
|
||||||
|
load_index = SPR_AUTORAIL_BASE;
|
||||||
|
load_index += LoadGrfFile("autorail.grf", load_index, i++);
|
||||||
|
|
||||||
load_index = SPR_CANALS_BASE;
|
load_index = SPR_CANALS_BASE;
|
||||||
load_index += LoadGrfFile("canalsw.grf", load_index, i++);
|
load_index += LoadGrfFile("canalsw.grf", load_index, i++);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
/* Rail selection types (directions):
|
||||||
|
/ \ / \ / \ / \ / \ / \
|
||||||
|
/ /\ /\ \ /===\ / \ /| \ / |\
|
||||||
|
\/ / \ \/ \ / \===/ \| / \ |/
|
||||||
|
\ / \ / \ / \ / \ / \ /
|
||||||
|
0 1 2 3 4 5
|
||||||
|
*/
|
||||||
|
|
||||||
|
// mark invalid tiles red
|
||||||
|
#define RED(c) c | PALETTE_SEL_TILE_RED
|
||||||
|
|
||||||
|
// table maps each of the six rail directions and tileh combinations to a sprite
|
||||||
|
// invalid entries are required to make sure that this array can be quickly accessed
|
||||||
|
const int AutorailTilehSprite[31][6] = {
|
||||||
|
// type 0 1 2 3 4 5
|
||||||
|
{ 0, 8, 16, 25, 34, 42 }, // tileh = 0
|
||||||
|
{ 5, 13, RED(22), RED(31), 35, 42 }, // tileh = 1
|
||||||
|
{ 5, 10, 16, 26, RED(38), RED(46) }, // tileh = 2
|
||||||
|
{ 5, 9, RED(23), 26, 35, RED(46) }, // tileh = 3
|
||||||
|
{ 2, 10, RED(19), RED(28), 34, 43 }, // tileh = 4
|
||||||
|
{ 1, 9, 17, 26, 35, 43 }, // tileh = 5
|
||||||
|
{ 1, 10, RED(20), 26, RED(38), 43 }, // tileh = 6
|
||||||
|
{ 1, 9, 17, 26, 35, 43 }, // tileh = 7
|
||||||
|
{ 2, 13, 17, 25, RED(40), RED(48) }, // tileh = 8
|
||||||
|
{ 1, 13, 17, RED(32), 35, RED(48) }, // tileh = 9
|
||||||
|
{ 2, 9, 17, 26, 35, 43 }, // tileh = 10
|
||||||
|
{ 1, 9, 17, 26, 35, 43 }, // tileh = 11
|
||||||
|
{ 2, 9, 17, RED(29), RED(40), 43 }, // tileh = 12
|
||||||
|
{ 1, 9, 17, 26, 35, 43 }, // tileh = 13
|
||||||
|
{ 1, 9, 17, 26, 35, 43 }, // tileh = 14
|
||||||
|
{ 0, 1, 2, 3, 4, 5 }, // invalid (15)
|
||||||
|
{ 0, 1, 2, 3, 4, 5 }, // invalid (16)
|
||||||
|
{ 0, 1, 2, 3, 4, 5 }, // invalid (17)
|
||||||
|
{ 0, 1, 2, 3, 4, 5 }, // invalid (18)
|
||||||
|
{ 0, 1, 2, 3, 4, 5 }, // invalid (19)
|
||||||
|
{ 0, 1, 2, 3, 4, 5 }, // invalid (20)
|
||||||
|
{ 0, 1, 2, 3, 4, 5 }, // invalid (21)
|
||||||
|
{ 0, 1, 2, 3, 4, 5 }, // invalid (22)
|
||||||
|
{ RED(6), RED(11), RED(17), RED(27), RED(39), RED(47) }, // tileh = 23
|
||||||
|
{ 0, 1, 2, 3, 4, 5 }, // invalid (24)
|
||||||
|
{ 0, 1, 2, 3, 4, 5 }, // invalid (25)
|
||||||
|
{ 0, 1, 2, 3, 4, 5 }, // invalid (26)
|
||||||
|
{ RED(7), RED(15), RED(24), RED(33), RED(36), RED(44) }, // tileh = 27
|
||||||
|
{ 0, 1, 2, 3, 4, 5 }, // invalid (28)
|
||||||
|
{ RED(3), RED(14), RED(18), RED(26), RED(41), RED(49) }, // tileh = 29
|
||||||
|
{ RED(4), RED(12), RED(21), RED(30), RED(37), RED(45) }, // tileh = 30
|
||||||
|
};
|
||||||
|
#undef RED
|
||||||
|
|
||||||
|
|
||||||
|
// maps each pixel of a tile (16x16) to a selection type
|
||||||
|
// (0,0) is the top corner, (16,16) the bottom corner
|
||||||
|
const int AutorailPiece[16][16] = {
|
||||||
|
{ 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5 },
|
||||||
|
{ 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5 },
|
||||||
|
{ 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5 },
|
||||||
|
{ 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5 },
|
||||||
|
{ 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5 },
|
||||||
|
{ 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5 },
|
||||||
|
{ 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 },
|
||||||
|
{ 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1 },
|
||||||
|
{ 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1 },
|
||||||
|
{ 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
|
||||||
|
{ 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3 },
|
||||||
|
{ 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3 },
|
||||||
|
{ 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3 },
|
||||||
|
{ 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3 },
|
||||||
|
{ 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3 },
|
||||||
|
{ 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3 }
|
||||||
|
};
|
|
@ -44,7 +44,8 @@ enum Sprites {
|
||||||
/* Extra graphic spritenumbers */
|
/* Extra graphic spritenumbers */
|
||||||
SPR_CANALS_BASE = 5126,
|
SPR_CANALS_BASE = 5126,
|
||||||
SPR_SLOPES_BASE = SPR_CANALS_BASE + 70,
|
SPR_SLOPES_BASE = SPR_CANALS_BASE + 70,
|
||||||
SPR_OPENTTD_BASE = SPR_SLOPES_BASE + 74, //5270
|
SPR_AUTORAIL_BASE = SPR_SLOPES_BASE + 78,
|
||||||
|
SPR_OPENTTD_BASE = SPR_AUTORAIL_BASE + 55, // can be lowered once autorail.grf is finalized
|
||||||
|
|
||||||
SPR_BLOT = SPR_OPENTTD_BASE + 32, // colored circle (mainly used as vehicle profit marker and for sever compatibility)
|
SPR_BLOT = SPR_OPENTTD_BASE + 32, // colored circle (mainly used as vehicle profit marker and for sever compatibility)
|
||||||
|
|
||||||
|
|
242
viewport.c
242
viewport.c
|
@ -595,11 +595,7 @@ static int dbg_draw_pushed(const TileInfo *ti)
|
||||||
|
|
||||||
static void DrawSelectionSprite(uint32 image, const TileInfo *ti)
|
static void DrawSelectionSprite(uint32 image, const TileInfo *ti)
|
||||||
{
|
{
|
||||||
if (_added_tile_sprite) {
|
AddSortableSpriteToDraw(image, ti->x, ti->y, 0x10, 0x10, 1, ti->z + 7);
|
||||||
DrawGroundSpriteAt(image, ti->x, ti->y, ti->z + 7);
|
|
||||||
} else {
|
|
||||||
AddSortableSpriteToDraw(image, ti->x, ti->y, 0x10, 0x10, 1, ti->z + 7);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool IsPartOfAutoLine(int px, int py)
|
static bool IsPartOfAutoLine(int px, int py)
|
||||||
|
@ -610,10 +606,12 @@ static bool IsPartOfAutoLine(int px, int py)
|
||||||
py -= thd->selstart.y;
|
py -= thd->selstart.y;
|
||||||
|
|
||||||
switch(thd->drawstyle) {
|
switch(thd->drawstyle) {
|
||||||
case HT_LINE | 0: return px == py || px == py + 16;
|
case HT_LINE | HT_DIR_X: return py == 0; // x direction
|
||||||
case HT_LINE | 1: return px == py || px == py - 16;
|
case HT_LINE | HT_DIR_Y: return px == 0; // y direction
|
||||||
case HT_LINE | 2: return px == -py || px == -py + 16;
|
case HT_LINE | HT_DIR_HU: return px == -py || px == -py - 16; // horizontal upper
|
||||||
case HT_LINE | 3: return px == -py || px == -py - 16;
|
case HT_LINE | HT_DIR_HL: return px == -py || px == -py + 16; // horizontal lower
|
||||||
|
case HT_LINE | HT_DIR_VL: return px == py || px == py + 16; // vertival left
|
||||||
|
case HT_LINE | HT_DIR_VR: return px == py || px == py - 16; // vertical right
|
||||||
default:
|
default:
|
||||||
NOT_REACHED();
|
NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
@ -622,6 +620,18 @@ static bool IsPartOfAutoLine(int px, int py)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// [direction][side]
|
||||||
|
static const int AutorailType[6][2] = {
|
||||||
|
{ HT_DIR_X, HT_DIR_X },
|
||||||
|
{ HT_DIR_Y, HT_DIR_Y },
|
||||||
|
{ HT_DIR_HU, HT_DIR_HL },
|
||||||
|
{ HT_DIR_HL, HT_DIR_HU },
|
||||||
|
{ HT_DIR_VL, HT_DIR_VR },
|
||||||
|
{ HT_DIR_VR, HT_DIR_VL }
|
||||||
|
};
|
||||||
|
|
||||||
|
#include "table/autorail.h"
|
||||||
|
|
||||||
static void DrawTileSelection(const TileInfo *ti)
|
static void DrawTileSelection(const TileInfo *ti)
|
||||||
{
|
{
|
||||||
uint32 image;
|
uint32 image;
|
||||||
|
@ -657,13 +667,32 @@ static void DrawTileSelection(const TileInfo *ti)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DrawGroundSpriteAt(_cur_dpi->zoom != 2 ? 0x306 : 0xFEE,ti->x, ti->y, z);
|
DrawGroundSpriteAt(_cur_dpi->zoom != 2 ? 0x306 : 0xFEE,ti->x, ti->y, z);
|
||||||
} else {
|
|
||||||
if (IsPartOfAutoLine(ti->x, ti->y)) {
|
} else if (thd->drawstyle & HT_RAIL /*&& thd->place_mode == VHM_RAIL*/) { // autorail highlight piece under cursor
|
||||||
image = 0x2F0 + _tileh_to_sprite[ti->tileh];
|
int type = thd->drawstyle & 0xF;
|
||||||
|
assert(type<=5);
|
||||||
|
image = SPR_AUTORAIL_BASE + AutorailTilehSprite[ ti->tileh ][ AutorailType[type][0] ];
|
||||||
|
|
||||||
|
if (thd->make_square_red) image |= 0x3048000;
|
||||||
|
DrawSelectionSprite(image, ti);
|
||||||
|
|
||||||
|
} else if (IsPartOfAutoLine(ti->x, ti->y)) { // autorail highlighting long line
|
||||||
|
int dir = thd->drawstyle & ~0xF0;
|
||||||
|
uint start = TILE_FROM_XY(thd->selstart.x, thd->selstart.y);
|
||||||
|
int diffx, diffy;
|
||||||
|
int side;
|
||||||
|
|
||||||
|
diffx = myabs(TileX(start)-TileX(ti->tile));
|
||||||
|
diffy = myabs(TileY(start)-TileY(ti->tile));
|
||||||
|
|
||||||
|
side = myabs( diffx-diffy );
|
||||||
|
if(dir<2) side = 0;
|
||||||
|
|
||||||
|
image = SPR_AUTORAIL_BASE + AutorailTilehSprite[ ti->tileh ][ AutorailType[dir][side] ];
|
||||||
|
|
||||||
if (thd->make_square_red) image |= 0x3048000;
|
if (thd->make_square_red) image |= 0x3048000;
|
||||||
DrawSelectionSprite(image, ti);
|
DrawSelectionSprite(image, ti);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1715,7 +1744,7 @@ void PlaceObject()
|
||||||
if (pt.x == -1)
|
if (pt.x == -1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (_thd.place_mode == 2) {
|
if (_thd.place_mode == VHM_POINT) {
|
||||||
pt.x += 8;
|
pt.x += 8;
|
||||||
pt.y += 8;
|
pt.y += 8;
|
||||||
}
|
}
|
||||||
|
@ -1810,7 +1839,15 @@ void SetTileSelectBigSize(int ox, int oy, int sx, int sy) {
|
||||||
thd->new_outersize.y = sy * 16;
|
thd->new_outersize.y = sy * 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* returns the best autorail highlight type from map coordinates */
|
||||||
|
static byte GetAutorailHT(int x, int y)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
i = AutorailPiece[x&0xF][y&0xF];
|
||||||
|
return HT_RAIL | i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// called regular to update tile highlighting in all cases
|
||||||
void UpdateTileSelection()
|
void UpdateTileSelection()
|
||||||
{
|
{
|
||||||
TileHighlightData *thd = _thd_ptr;
|
TileHighlightData *thd = _thd_ptr;
|
||||||
|
@ -1819,7 +1856,7 @@ void UpdateTileSelection()
|
||||||
|
|
||||||
thd->new_drawstyle = 0;
|
thd->new_drawstyle = 0;
|
||||||
|
|
||||||
if (thd->place_mode == 3) {
|
if (thd->place_mode == VHM_SPECIAL) {
|
||||||
x1 = thd->selend.x;
|
x1 = thd->selend.x;
|
||||||
y1 = thd->selend.y;
|
y1 = thd->selend.y;
|
||||||
if (x1 != -1) {
|
if (x1 != -1) {
|
||||||
|
@ -1836,23 +1873,29 @@ void UpdateTileSelection()
|
||||||
thd->new_size.y = y2 - y1 + 16;
|
thd->new_size.y = y2 - y1 + 16;
|
||||||
thd->new_drawstyle = thd->next_drawstyle;
|
thd->new_drawstyle = thd->next_drawstyle;
|
||||||
}
|
}
|
||||||
} else if (thd->place_mode != 0) {
|
} else if (thd->place_mode != VHM_NONE) {
|
||||||
pt = GetTileBelowCursor();
|
pt = GetTileBelowCursor();
|
||||||
x1 = pt.x;
|
x1 = pt.x;
|
||||||
y1 = pt.y;
|
y1 = pt.y;
|
||||||
if (x1 != -1) {
|
if (x1 != -1) {
|
||||||
if (thd->place_mode == 1) {
|
switch (thd->place_mode) {
|
||||||
thd->new_drawstyle = HT_RECT;
|
case VHM_RECT:
|
||||||
} else {
|
thd->new_drawstyle = HT_RECT;
|
||||||
thd->new_drawstyle = HT_POINT;
|
break;
|
||||||
x1 += 8;
|
case VHM_POINT:
|
||||||
y1 += 8;
|
thd->new_drawstyle = HT_POINT;
|
||||||
|
x1 += 8;
|
||||||
|
y1 += 8;
|
||||||
|
break;
|
||||||
|
case VHM_RAIL:
|
||||||
|
thd->new_drawstyle = GetAutorailHT(pt.x, pt.y); // draw one highlighted tile
|
||||||
}
|
}
|
||||||
thd->new_pos.x = x1 & ~0xF;
|
thd->new_pos.x = x1 & ~0xF;
|
||||||
thd->new_pos.y = y1 & ~0xF;
|
thd->new_pos.y = y1 & ~0xF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// redraw selection
|
||||||
if (thd->drawstyle != thd->new_drawstyle ||
|
if (thd->drawstyle != thd->new_drawstyle ||
|
||||||
thd->pos.x != thd->new_pos.x || thd->pos.y != thd->new_pos.y ||
|
thd->pos.x != thd->new_pos.x || thd->pos.y != thd->new_pos.y ||
|
||||||
thd->size.x != thd->new_size.x || thd->size.y != thd->new_size.y) {
|
thd->size.x != thd->new_size.x || thd->size.y != thd->new_size.y) {
|
||||||
|
@ -1871,21 +1914,24 @@ void UpdateTileSelection()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// highlighting tiles while only going over them with the mouse
|
||||||
void VpStartPlaceSizing(uint tile, int user)
|
void VpStartPlaceSizing(uint tile, int user)
|
||||||
{
|
{
|
||||||
TileHighlightData *thd;
|
TileHighlightData *thd;
|
||||||
|
|
||||||
thd = _thd_ptr;
|
thd = _thd_ptr;
|
||||||
thd->userdata = user;
|
thd->userdata = user;
|
||||||
thd->selend.x = TileX(tile) * 16;
|
thd->selend.x = TileX(tile) * 16;
|
||||||
thd->selstart.x = TileX(tile) * 16;
|
thd->selstart.x = TileX(tile) * 16;
|
||||||
thd->selend.y = TileY(tile) * 16;
|
thd->selend.y = TileY(tile) * 16;
|
||||||
thd->selstart.y = TileY(tile) * 16;
|
thd->selstart.y = TileY(tile) * 16;
|
||||||
if (thd->place_mode == 1) {
|
if (thd->place_mode == VHM_RECT) {
|
||||||
thd->place_mode = 3;
|
thd->place_mode = VHM_SPECIAL;
|
||||||
thd->next_drawstyle = HT_RECT;
|
thd->next_drawstyle = HT_RECT;
|
||||||
|
} else if (thd->place_mode == VHM_RAIL) { // autorail one piece
|
||||||
|
thd->place_mode = VHM_SPECIAL;
|
||||||
|
thd->next_drawstyle = thd->drawstyle;
|
||||||
} else {
|
} else {
|
||||||
thd->place_mode = 3;
|
thd->place_mode = VHM_SPECIAL;
|
||||||
thd->next_drawstyle = HT_POINT;
|
thd->next_drawstyle = HT_POINT;
|
||||||
}
|
}
|
||||||
_special_mouse_mode = WSM_SIZING;
|
_special_mouse_mode = WSM_SIZING;
|
||||||
|
@ -1912,51 +1958,114 @@ void VpStartPreSizing()
|
||||||
_special_mouse_mode = WSM_PRESIZE;
|
_special_mouse_mode = WSM_PRESIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void CalcRaildirsDrawstyle(TileHighlightData *thd, int x, int y)
|
/* returns information about the 2x1 piece to be build.
|
||||||
|
* The lower bits (0-3) are the track type. */
|
||||||
|
static byte Check2x1AutoRail(int mode)
|
||||||
|
{
|
||||||
|
TileHighlightData *thd = &_thd;
|
||||||
|
int fxpy = _tile_fract_coords.x + _tile_fract_coords.y;
|
||||||
|
int sxpy = (thd->selend.x & 0xF) + (thd->selend.y & 0xF);
|
||||||
|
int fxmy = _tile_fract_coords.x - _tile_fract_coords.y;
|
||||||
|
int sxmy = (thd->selend.x & 0xF) - (thd->selend.y & 0xF);
|
||||||
|
|
||||||
|
switch(mode) {
|
||||||
|
case 0: // end piece is lower right
|
||||||
|
if (fxpy >= 20 && sxpy <= 12) { /*SwapSelection(); DoRailroadTrack(0); */return 3; }
|
||||||
|
if (fxmy < -3 && sxmy > 3) {/* DoRailroadTrack(0); */return 5; }
|
||||||
|
return 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
if (fxmy > 3 && sxmy < -3) { /*SwapSelection(); DoRailroadTrack(0); */return 4; }
|
||||||
|
if (fxpy <= 12 && sxpy >= 20) { /*DoRailroadTrack(0); */return 2; }
|
||||||
|
return 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
if (fxmy > 3 && sxmy < -3) { /*DoRailroadTrack(3);*/ return 4; }
|
||||||
|
if (fxpy >= 20 && sxpy <= 12) { /*SwapSelection(); DoRailroadTrack(0); */return 3; }
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
if (fxmy < -3 && sxmy > 3) { /*SwapSelection(); DoRailroadTrack(3);*/ return 5; }
|
||||||
|
if (fxpy <= 12 && sxpy >= 20) { /*DoRailroadTrack(0); */return 2; }
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0; // avoids compiler warnings
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// while dragging
|
||||||
|
static void CalcRaildirsDrawstyle(TileHighlightData *thd, int x, int y, int method)
|
||||||
{
|
{
|
||||||
int d;
|
int d;
|
||||||
bool b;
|
byte b=6;
|
||||||
uint w,h;
|
uint w,h;
|
||||||
|
|
||||||
w = myabs((x & ~0xF) - thd->selstart.x) + 16;
|
int dx = thd->selstart.x - (thd->selend.x&~0xF);
|
||||||
h = myabs((y & ~0xF) - thd->selstart.y) + 16;
|
int dy = thd->selstart.y - (thd->selend.y&~0xF);
|
||||||
|
w = myabs(dx) + 16;
|
||||||
|
h = myabs(dy) + 16;
|
||||||
|
|
||||||
// vertical and horizontal lines are really simple
|
if (TILE_FROM_XY(thd->selstart.x, thd->selstart.y) == TILE_FROM_XY(x,y)) { // check if we're only within one tile
|
||||||
if (w == 16 || h == 16) {
|
if(method == VPM_RAILDIRS)
|
||||||
b = HT_RECT;
|
b = GetAutorailHT(x, y);
|
||||||
} else if (w * 2 < h) { // see if we're closer to rect?
|
else // rect for autosignals on one tile
|
||||||
x = thd->selstart.x;
|
b = HT_RECT;
|
||||||
b = HT_RECT;
|
} else if (h == 16) { // Is this in X direction?
|
||||||
} else if (w > h * 2) {
|
if (dx==16) // 2x1 special handling
|
||||||
|
b = (Check2x1AutoRail(3)) | HT_LINE;
|
||||||
|
else if (dx==-16)
|
||||||
|
b = (Check2x1AutoRail(2)) | HT_LINE;
|
||||||
|
else
|
||||||
|
b = HT_LINE | HT_DIR_X;
|
||||||
y = thd->selstart.y;
|
y = thd->selstart.y;
|
||||||
b = HT_RECT;
|
} else if (w == 16) { // Or Y direction?
|
||||||
} else {
|
if (dy==16) // 2x1 special handling
|
||||||
|
b = (Check2x1AutoRail(1)) | HT_LINE;
|
||||||
|
else if (dy==-16) // 2x1 other direction
|
||||||
|
b = (Check2x1AutoRail(0)) | HT_LINE;
|
||||||
|
else
|
||||||
|
b = HT_LINE | HT_DIR_Y;
|
||||||
|
x = thd->selstart.x;
|
||||||
|
} else if (w > h * 2) { // still count as x dir?
|
||||||
|
b = HT_LINE | HT_DIR_X;
|
||||||
|
y = thd->selstart.y;
|
||||||
|
} else if (h > w * 2) { // still count as y dir?
|
||||||
|
b = HT_LINE | HT_DIR_Y;
|
||||||
|
x = thd->selstart.x;
|
||||||
|
} else { // complicated direction
|
||||||
d = w - h;
|
d = w - h;
|
||||||
|
thd->selend.x = thd->selend.x&~0xF;
|
||||||
|
thd->selend.y = thd->selend.y&~0xF;
|
||||||
|
|
||||||
// four cases.
|
// four cases.
|
||||||
if (x > thd->selstart.x) {
|
if (x > thd->selstart.x) {
|
||||||
if (y > thd->selstart.y) {
|
if (y > thd->selstart.y) {
|
||||||
// south
|
// south
|
||||||
if (d ==0) b = (x & 0xF) > (y & 0xF) ? HT_LINE | 0 : HT_LINE | 1;
|
if (d ==0) b = (x & 0xF) > (y & 0xF) ? HT_LINE | HT_DIR_VL : HT_LINE | HT_DIR_VR;
|
||||||
else if (d >= 0) { x = thd->selstart.x + h; b = HT_LINE | 0; } // return px == py || px == py + 16;
|
else if (d >= 0) { x = thd->selstart.x + h; b = HT_LINE | HT_DIR_VL; } // return px == py || px == py + 16;
|
||||||
else { y = thd->selstart.y + w; b = HT_LINE | 1; } // return px == py || px == py - 16;
|
else { y = thd->selstart.y + w; b = HT_LINE | HT_DIR_VR; } // return px == py || px == py - 16;
|
||||||
} else {
|
} else {
|
||||||
// west
|
// west
|
||||||
if (d ==0) b = (x & 0xF) + (y & 0xF) >= 0x10 ? HT_LINE | 2 : HT_LINE | 3;
|
if (d ==0) b = (x & 0xF) + (y & 0xF) >= 0x10 ? HT_LINE | HT_DIR_HL : HT_LINE | HT_DIR_HU;
|
||||||
else if (d >= 0) { x = thd->selstart.x + h; b = HT_LINE | 2; }
|
else if (d >= 0) { x = thd->selstart.x + h; b = HT_LINE | HT_DIR_HL; }
|
||||||
else { y = thd->selstart.y - w; b = HT_LINE | 3; }
|
else { y = thd->selstart.y - w; b = HT_LINE | HT_DIR_HU; }
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (y > thd->selstart.y) {
|
if (y > thd->selstart.y) {
|
||||||
// east
|
// east
|
||||||
if (d ==0) b = (x & 0xF) + (y & 0xF) >= 0x10 ? HT_LINE | 2 : HT_LINE | 3;
|
if (d ==0) b = (x & 0xF) + (y & 0xF) >= 0x10 ? HT_LINE | HT_DIR_HL : HT_LINE | HT_DIR_HU;
|
||||||
else if (d >= 0) { x = thd->selstart.x - h; b = HT_LINE | 3; } // return px == -py || px == -py - 16;
|
else if (d >= 0) { x = thd->selstart.x - h; b = HT_LINE | HT_DIR_HU; } // return px == -py || px == -py - 16;
|
||||||
else { y = thd->selstart.y + w; b = HT_LINE | 2; } // return px == -py || px == -py + 16;
|
else { y = thd->selstart.y + w; b = HT_LINE | HT_DIR_HL; } // return px == -py || px == -py + 16;
|
||||||
} else {
|
} else {
|
||||||
// north
|
// north
|
||||||
if (d ==0) b = (x & 0xF) > (y & 0xF) ? HT_LINE | 0 : HT_LINE | 1;
|
if (d ==0) b = (x & 0xF) > (y & 0xF) ? HT_LINE | HT_DIR_VL : HT_LINE | HT_DIR_VR;
|
||||||
else if (d >= 0) { x = thd->selstart.x - h; b = HT_LINE | 1; } // return px == py || px == py - 16;
|
else if (d >= 0) { x = thd->selstart.x - h; b = HT_LINE | HT_DIR_VR; } // return px == py || px == py - 16;
|
||||||
else { y = thd->selstart.y - w; b = HT_LINE | 0; } //return px == py || px == py + 16;
|
else { y = thd->selstart.y - w; b = HT_LINE | HT_DIR_VL; } //return px == py || px == py + 16;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1965,11 +2074,11 @@ static void CalcRaildirsDrawstyle(TileHighlightData *thd, int x, int y)
|
||||||
thd->next_drawstyle = b;
|
thd->next_drawstyle = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// while dragging
|
||||||
void VpSelectTilesWithMethod(int x, int y, int method)
|
void VpSelectTilesWithMethod(int x, int y, int method)
|
||||||
{
|
{
|
||||||
TileHighlightData *thd = _thd_ptr;
|
TileHighlightData *thd = _thd_ptr;
|
||||||
int sx,sy;
|
int sx,sy;
|
||||||
|
|
||||||
if (x == -1) {
|
if (x == -1) {
|
||||||
thd->selend.x = -1;
|
thd->selend.x = -1;
|
||||||
return;
|
return;
|
||||||
|
@ -1977,14 +2086,14 @@ void VpSelectTilesWithMethod(int x, int y, int method)
|
||||||
|
|
||||||
// allow drag in any rail direction
|
// allow drag in any rail direction
|
||||||
if (method == VPM_RAILDIRS || method == VPM_SIGNALDIRS) {
|
if (method == VPM_RAILDIRS || method == VPM_SIGNALDIRS) {
|
||||||
CalcRaildirsDrawstyle(thd, x, y);
|
thd->selend.x = x;
|
||||||
|
thd->selend.y = y;
|
||||||
|
CalcRaildirsDrawstyle(thd, x, y, method);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_thd.next_drawstyle == HT_POINT) { x += 8; y += 8; }
|
if (_thd.next_drawstyle == HT_POINT) { x += 8; y += 8; }
|
||||||
|
|
||||||
//thd->next_drawstyle = HT_RECT;
|
|
||||||
|
|
||||||
sx = thd->selstart.x;
|
sx = thd->selstart.x;
|
||||||
sy = thd->selstart.y;
|
sy = thd->selstart.y;
|
||||||
|
|
||||||
|
@ -2017,6 +2126,7 @@ void VpSelectTilesWithMethod(int x, int y, int method)
|
||||||
thd->selend.y = y;
|
thd->selend.y = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// while dragging
|
||||||
bool VpHandlePlaceSizingDrag()
|
bool VpHandlePlaceSizingDrag()
|
||||||
{
|
{
|
||||||
Window *w;
|
Window *w;
|
||||||
|
@ -2027,13 +2137,14 @@ bool VpHandlePlaceSizingDrag()
|
||||||
|
|
||||||
e.place.userdata = _thd.userdata;
|
e.place.userdata = _thd.userdata;
|
||||||
|
|
||||||
|
// stop drag mode if the window has been closed
|
||||||
w = FindWindowById(_thd.window_class,_thd.window_number);
|
w = FindWindowById(_thd.window_class,_thd.window_number);
|
||||||
if (w == NULL) {
|
if (w == NULL) {
|
||||||
ResetObjectToPlace();
|
ResetObjectToPlace();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// while dragging...
|
// while dragging execute the drag procedure of the corresponding window (mostly VpSelectTilesWithMethod() )
|
||||||
if (_left_button_down) {
|
if (_left_button_down) {
|
||||||
e.event = WE_PLACE_DRAG;
|
e.event = WE_PLACE_DRAG;
|
||||||
e.place.pt = GetTileBelowCursor();
|
e.place.pt = GetTileBelowCursor();
|
||||||
|
@ -2044,8 +2155,16 @@ bool VpHandlePlaceSizingDrag()
|
||||||
// mouse button released..
|
// mouse button released..
|
||||||
// keep the selected tool, but reset it to the original mode.
|
// keep the selected tool, but reset it to the original mode.
|
||||||
_special_mouse_mode = WSM_NONE;
|
_special_mouse_mode = WSM_NONE;
|
||||||
_thd.place_mode = (_thd.next_drawstyle == HT_RECT || _thd.next_drawstyle & HT_LINE) ? 1 : 2;
|
if (_thd.next_drawstyle == HT_RECT)
|
||||||
|
_thd.place_mode = VHM_RECT;
|
||||||
|
else if ((e.place.userdata & 0xF) == VPM_SIGNALDIRS) // some might call this a hack... -- Dominik
|
||||||
|
_thd.place_mode = VHM_RECT;
|
||||||
|
else if (_thd.next_drawstyle & HT_LINE)
|
||||||
|
_thd.place_mode = VHM_RAIL;
|
||||||
|
else if (_thd.next_drawstyle & HT_RAIL)
|
||||||
|
_thd.place_mode = VHM_RAIL;
|
||||||
|
else
|
||||||
|
_thd.place_mode = VHM_POINT;
|
||||||
SetTileSelectSize(1, 1);
|
SetTileSelectSize(1, 1);
|
||||||
|
|
||||||
// and call the mouseup event.
|
// and call the mouseup event.
|
||||||
|
@ -2070,6 +2189,7 @@ void SetObjectToPlace(int icon, byte mode, WindowClass window_class, WindowNumbe
|
||||||
TileHighlightData *thd = _thd_ptr;
|
TileHighlightData *thd = _thd_ptr;
|
||||||
Window *w;
|
Window *w;
|
||||||
|
|
||||||
|
// undo clicking on button
|
||||||
if (thd->place_mode != 0) {
|
if (thd->place_mode != 0) {
|
||||||
thd->place_mode = 0;
|
thd->place_mode = 0;
|
||||||
w = FindWindowById(thd->window_class, thd->window_number);
|
w = FindWindowById(thd->window_class, thd->window_number);
|
||||||
|
@ -2081,7 +2201,7 @@ void SetObjectToPlace(int icon, byte mode, WindowClass window_class, WindowNumbe
|
||||||
|
|
||||||
thd->make_square_red = false;
|
thd->make_square_red = false;
|
||||||
|
|
||||||
if (mode == 4) {
|
if (mode == VHM_DRAG) { // mode 4 is for dragdropping trains in the depot window
|
||||||
mode = 0;
|
mode = 0;
|
||||||
_special_mouse_mode = WSM_DRAGDROP;
|
_special_mouse_mode = WSM_DRAGDROP;
|
||||||
} else {
|
} else {
|
||||||
|
@ -2092,7 +2212,7 @@ void SetObjectToPlace(int icon, byte mode, WindowClass window_class, WindowNumbe
|
||||||
thd->window_class = window_class;
|
thd->window_class = window_class;
|
||||||
thd->window_number = window_num;
|
thd->window_number = window_num;
|
||||||
|
|
||||||
if (mode == 3)
|
if (mode == VHM_SPECIAL) // special tools, like tunnels or docks start with presizing mode
|
||||||
VpStartPreSizing();
|
VpStartPreSizing();
|
||||||
|
|
||||||
if ( (int)icon < 0)
|
if ( (int)icon < 0)
|
||||||
|
|
33
viewport.h
33
viewport.h
|
@ -54,16 +54,39 @@ enum {
|
||||||
VPM_RAILDIRS = 3,
|
VPM_RAILDIRS = 3,
|
||||||
VPM_X_AND_Y = 4,
|
VPM_X_AND_Y = 4,
|
||||||
VPM_X_AND_Y_LIMITED = 5,
|
VPM_X_AND_Y_LIMITED = 5,
|
||||||
VPM_SIGNALDIRS = 6,
|
VPM_SIGNALDIRS = 6
|
||||||
|
};
|
||||||
|
|
||||||
|
// viewport highlight mode (for highlighting tiles below cursor)
|
||||||
|
enum {
|
||||||
|
VHM_NONE = 0, // default
|
||||||
|
VHM_RECT = 1, // rectangle (stations, depots, ...)
|
||||||
|
VHM_POINT = 2, // point (lower land, raise land, level land, ...)
|
||||||
|
VHM_SPECIAL = 3, // special mode used for highlighting while dragging (and for tunnels/docks)
|
||||||
|
VHM_DRAG = 4, // dragging items in the depot windows
|
||||||
|
VHM_RAIL = 5, // rail pieces
|
||||||
};
|
};
|
||||||
|
|
||||||
void VpSelectTilesWithMethod(int x, int y, int method);
|
void VpSelectTilesWithMethod(int x, int y, int method);
|
||||||
|
|
||||||
|
// highlighting draw styles
|
||||||
enum {
|
enum {
|
||||||
HT_NONE = 0,
|
HT_NONE = 0,
|
||||||
HT_RECT = 0x80,
|
HT_RECT = 0x80,
|
||||||
HT_POINT = 0x40,
|
HT_POINT = 0x40,
|
||||||
HT_LINE = 0x20,
|
HT_LINE = 0x20, /* used for autorail highlighting (longer streches)
|
||||||
|
* (uses lower bits to indicate direction) */
|
||||||
|
HT_RAIL = 0x10, /* autorail (one piece)
|
||||||
|
* (uses lower bits to indicate direction) */
|
||||||
|
|
||||||
|
/* lower bits (used with HT_LINE and HT_RAIL):
|
||||||
|
* (see ASCII art in autorail.h for a visual interpretation) */
|
||||||
|
HT_DIR_X = 0, // X direction
|
||||||
|
HT_DIR_Y = 1, // Y direction
|
||||||
|
HT_DIR_HU = 2, // horizontal upper
|
||||||
|
HT_DIR_HL = 3, // horizontal lower
|
||||||
|
HT_DIR_VL = 4, // vertical left
|
||||||
|
HT_DIR_VR = 5, // vertical right
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct TileHighlightData {
|
typedef struct TileHighlightData {
|
||||||
|
@ -81,9 +104,9 @@ typedef struct TileHighlightData {
|
||||||
byte dirty;
|
byte dirty;
|
||||||
byte sizelimit;
|
byte sizelimit;
|
||||||
|
|
||||||
byte drawstyle;
|
byte drawstyle; // lower bits 0-3 are reserved for detailed highlight information information
|
||||||
byte new_drawstyle;
|
byte new_drawstyle; // only used in UpdateTileSelection() to as a buffer to compare if there was a change between old and new
|
||||||
byte next_drawstyle;
|
byte next_drawstyle; // queued, but not yet drawn style
|
||||||
|
|
||||||
byte place_mode;
|
byte place_mode;
|
||||||
bool make_square_red;
|
bool make_square_red;
|
||||||
|
|
Loading…
Reference in New Issue