mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2025-03-06 14:27:16 +00:00
(svn r11313) -Codechange: prepare several pieces of code so the can handle some new slopes. Patch by frosch.
This commit is contained in:
parent
8212088c03
commit
5289aa2010
@ -7,6 +7,7 @@
|
|||||||
#include "bridge_map.h"
|
#include "bridge_map.h"
|
||||||
#include "bridge.h"
|
#include "bridge.h"
|
||||||
#include "variables.h"
|
#include "variables.h"
|
||||||
|
#include "landscape.h"
|
||||||
|
|
||||||
|
|
||||||
TileIndex GetBridgeEnd(TileIndex tile, DiagDirection dir)
|
TileIndex GetBridgeEnd(TileIndex tile, DiagDirection dir)
|
||||||
@ -46,9 +47,6 @@ uint GetBridgeHeight(TileIndex t)
|
|||||||
Slope tileh = GetTileSlope(t, &h);
|
Slope tileh = GetTileSlope(t, &h);
|
||||||
Foundation f = GetBridgeFoundation(tileh, DiagDirToAxis(GetBridgeRampDirection(t)));
|
Foundation f = GetBridgeFoundation(tileh, DiagDirToAxis(GetBridgeRampDirection(t)));
|
||||||
|
|
||||||
/* one height level extra if the ramp is on a flat foundation */
|
/* one height level extra for the ramp */
|
||||||
return
|
return h + TILE_HEIGHT + ApplyFoundationToSlope(f, &tileh);
|
||||||
h + TILE_HEIGHT +
|
|
||||||
(IsLeveledFoundation(f) ? TILE_HEIGHT : 0) +
|
|
||||||
(IsSteepSlope(tileh) ? TILE_HEIGHT : 0);
|
|
||||||
}
|
}
|
||||||
|
@ -213,6 +213,10 @@ static void DrawCatenaryRailway(const TileInfo *ti)
|
|||||||
/* Note that ti->tileh has already been adjusted for Foundations */
|
/* Note that ti->tileh has already been adjusted for Foundations */
|
||||||
Slope tileh[TS_END] = { ti->tileh, SLOPE_FLAT };
|
Slope tileh[TS_END] = { ti->tileh, SLOPE_FLAT };
|
||||||
|
|
||||||
|
/* Half tile slopes coincide only with horizontal/vertical track.
|
||||||
|
* Faking a flat slope results in the correct sprites on positions. */
|
||||||
|
if (IsHalftileSlope(tileh[TS_HOME])) tileh[TS_HOME] = SLOPE_FLAT;
|
||||||
|
|
||||||
TLG tlg = GetTLG(ti->tile);
|
TLG tlg = GetTLG(ti->tile);
|
||||||
byte PCPstatus = 0;
|
byte PCPstatus = 0;
|
||||||
byte OverridePCP = 0;
|
byte OverridePCP = 0;
|
||||||
@ -291,6 +295,10 @@ static void DrawCatenaryRailway(const TileInfo *ti)
|
|||||||
|
|
||||||
ApplyFoundationToSlope(foundation, &tileh[TS_NEIGHBOUR]);
|
ApplyFoundationToSlope(foundation, &tileh[TS_NEIGHBOUR]);
|
||||||
|
|
||||||
|
/* Half tile slopes coincide only with horizontal/vertical track.
|
||||||
|
* Faking a flat slope results in the correct sprites on positions. */
|
||||||
|
if (IsHalftileSlope(tileh[TS_NEIGHBOUR])) tileh[TS_NEIGHBOUR] = SLOPE_FLAT;
|
||||||
|
|
||||||
AdjustTileh(neighbour, &tileh[TS_NEIGHBOUR]);
|
AdjustTileh(neighbour, &tileh[TS_NEIGHBOUR]);
|
||||||
|
|
||||||
/* If we have a straight (and level) track, we want a pylon only every 2 tiles
|
/* If we have a straight (and level) track, we want a pylon only every 2 tiles
|
||||||
|
@ -104,9 +104,31 @@ uint ApplyFoundationToSlope(Foundation f, Slope *s)
|
|||||||
|
|
||||||
uint GetPartialZ(int x, int y, Slope corners)
|
uint GetPartialZ(int x, int y, Slope corners)
|
||||||
{
|
{
|
||||||
|
if (IsHalftileSlope(corners)) {
|
||||||
|
switch (GetHalftileSlopeCorner(corners)) {
|
||||||
|
case CORNER_W:
|
||||||
|
if (x - y >= 0) return GetSlopeMaxZ(corners);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CORNER_S:
|
||||||
|
if (x - (y ^ 0xF) >= 0) return GetSlopeMaxZ(corners);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CORNER_E:
|
||||||
|
if (y - x >= 0) return GetSlopeMaxZ(corners);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CORNER_N:
|
||||||
|
if ((y ^ 0xF) - x >= 0) return GetSlopeMaxZ(corners);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: NOT_REACHED();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int z = 0;
|
int z = 0;
|
||||||
|
|
||||||
switch (corners) {
|
switch (corners & ~SLOPE_HALFTILE_MASK) {
|
||||||
case SLOPE_W:
|
case SLOPE_W:
|
||||||
if (x - y >= 0)
|
if (x - y >= 0)
|
||||||
z = (x - y) >> 1;
|
z = (x - y) >> 1;
|
||||||
@ -209,6 +231,8 @@ uint GetSlopeZ(int x, int y)
|
|||||||
/**
|
/**
|
||||||
* Determine the Z height of the corners of a specific tile edge
|
* Determine the Z height of the corners of a specific tile edge
|
||||||
*
|
*
|
||||||
|
* @note If a tile has a non-continuous halftile foundation, a corner can have different heights wrt. it's edges.
|
||||||
|
*
|
||||||
* @pre z1 and z2 must be initialized (typ. with TileZ). The corner heights just get added.
|
* @pre z1 and z2 must be initialized (typ. with TileZ). The corner heights just get added.
|
||||||
*
|
*
|
||||||
* @param tileh The slope of the tile.
|
* @param tileh The slope of the tile.
|
||||||
@ -227,10 +251,14 @@ void GetSlopeZOnEdge(Slope tileh, DiagDirection edge, int *z1, int *z2)
|
|||||||
{SLOPE_W, SLOPE_N, SLOPE_STEEP_W, SLOPE_STEEP_N}, // DIAGDIR_NW, z1 = W, z2 = N
|
{SLOPE_W, SLOPE_N, SLOPE_STEEP_W, SLOPE_STEEP_N}, // DIAGDIR_NW, z1 = W, z2 = N
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int halftile_test = (IsHalftileSlope(tileh) ? SlopeWithOneCornerRaised(GetHalftileSlopeCorner(tileh)) : 0);
|
||||||
|
if (halftile_test == corners[edge][0]) *z2 += TILE_HEIGHT; // The slope is non-continuous in z2. z2 is on the upper side.
|
||||||
|
if (halftile_test == corners[edge][1]) *z1 += TILE_HEIGHT; // The slope is non-continuous in z1. z1 is on the upper side.
|
||||||
|
|
||||||
if ((tileh & corners[edge][0]) != 0) *z1 += TILE_HEIGHT; // z1 is raised
|
if ((tileh & corners[edge][0]) != 0) *z1 += TILE_HEIGHT; // z1 is raised
|
||||||
if ((tileh & corners[edge][1]) != 0) *z2 += TILE_HEIGHT; // z2 is raised
|
if ((tileh & corners[edge][1]) != 0) *z2 += TILE_HEIGHT; // z2 is raised
|
||||||
if (tileh == corners[edge][2]) *z1 += TILE_HEIGHT; // z1 is highest corner of a steep slope
|
if ((tileh & ~SLOPE_HALFTILE_MASK) == corners[edge][2]) *z1 += TILE_HEIGHT; // z1 is highest corner of a steep slope
|
||||||
if (tileh == corners[edge][3]) *z2 += TILE_HEIGHT; // z2 is highest corner of a steep slope
|
if ((tileh & ~SLOPE_HALFTILE_MASK) == corners[edge][3]) *z2 += TILE_HEIGHT; // z2 is highest corner of a steep slope
|
||||||
}
|
}
|
||||||
|
|
||||||
static Slope GetFoundationSlope(TileIndex tile, uint* z)
|
static Slope GetFoundationSlope(TileIndex tile, uint* z)
|
||||||
|
23
src/npf.cpp
23
src/npf.cpp
@ -192,18 +192,21 @@ static inline uint NPFBridgeCost(AyStarNode *current)
|
|||||||
static uint NPFSlopeCost(AyStarNode* current)
|
static uint NPFSlopeCost(AyStarNode* current)
|
||||||
{
|
{
|
||||||
TileIndex next = current->tile + TileOffsByDiagDir(TrackdirToExitdir((Trackdir)current->direction));
|
TileIndex next = current->tile + TileOffsByDiagDir(TrackdirToExitdir((Trackdir)current->direction));
|
||||||
int x,y;
|
|
||||||
int8 z1,z2;
|
|
||||||
|
|
||||||
x = TileX(current->tile) * TILE_SIZE;
|
/* Get center of tiles */
|
||||||
y = TileY(current->tile) * TILE_SIZE;
|
int x1 = TileX(current->tile) * TILE_SIZE + TILE_SIZE / 2;
|
||||||
/* get the height of the center of the current tile */
|
int y1 = TileY(current->tile) * TILE_SIZE + TILE_SIZE / 2;
|
||||||
z1 = GetSlopeZ(x + TILE_SIZE / 2, y + TILE_SIZE / 2);
|
int x2 = TileX(next) * TILE_SIZE + TILE_SIZE / 2;
|
||||||
|
int y2 = TileY(next) * TILE_SIZE + TILE_SIZE / 2;
|
||||||
|
|
||||||
x = TileX(next) * TILE_SIZE;
|
int dx4 = (x2 - x1) / 4;
|
||||||
y = TileY(next) * TILE_SIZE;
|
int dy4 = (y2 - y1) / 4;
|
||||||
/* get the height of the center of the next tile */
|
|
||||||
z2 = GetSlopeZ(x + TILE_SIZE / 2, y + TILE_SIZE / 2);
|
/* Get the height on both sides of the tile edge.
|
||||||
|
* Avoid testing the height on the tile-center. This will fail for halftile-foundations.
|
||||||
|
*/
|
||||||
|
int z1 = GetSlopeZ(x1 + dx4, y1 + dy4);
|
||||||
|
int z2 = GetSlopeZ(x2 - dx4, y2 - dy4);
|
||||||
|
|
||||||
if (z2 - z1 > 1) {
|
if (z2 - z1 > 1) {
|
||||||
/* Slope up */
|
/* Slope up */
|
||||||
|
@ -1238,6 +1238,22 @@ static CommandCost ClearTile_Track(TileIndex tile, byte flags)
|
|||||||
|
|
||||||
#include "table/track_land.h"
|
#include "table/track_land.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get surface height in point (x,y)
|
||||||
|
* On tiles with halftile foundations move (x,y) to a save point wrt. track
|
||||||
|
*/
|
||||||
|
static uint GetSaveSlopeZ(uint x, uint y, Track track)
|
||||||
|
{
|
||||||
|
switch (track) {
|
||||||
|
case TRACK_UPPER: x &= ~0xF; y &= ~0xF; break;
|
||||||
|
case TRACK_LOWER: x |= 0xF; y |= 0xF; break;
|
||||||
|
case TRACK_LEFT: x |= 0xF; y &= ~0xF; break;
|
||||||
|
case TRACK_RIGHT: x &= ~0xF; y |= 0xF; break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
return GetSlopeZ(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
static void DrawSingleSignal(TileIndex tile, Track track, byte condition, uint image, uint pos)
|
static void DrawSingleSignal(TileIndex tile, Track track, byte condition, uint image, uint pos)
|
||||||
{
|
{
|
||||||
bool side = (_opt.road_side != 0) && _patches.signal_side;
|
bool side = (_opt.road_side != 0) && _patches.signal_side;
|
||||||
@ -1281,7 +1297,7 @@ static void DrawSingleSignal(TileIndex tile, Track track, byte condition, uint i
|
|||||||
sprite = _signal_base + (GetSignalType(tile, track) - 1) * 16 + GetSignalVariant(tile, track) * 64 + image + condition;
|
sprite = _signal_base + (GetSignalType(tile, track) - 1) * 16 + GetSignalVariant(tile, track) * 64 + image + condition;
|
||||||
}
|
}
|
||||||
|
|
||||||
AddSortableSpriteToDraw(sprite, PAL_NONE, x, y, 1, 1, BB_HEIGHT_UNDER_BRIDGE, GetSlopeZ(x,y));
|
AddSortableSpriteToDraw(sprite, PAL_NONE, x, y, 1, 1, BB_HEIGHT_UNDER_BRIDGE, GetSaveSlopeZ(x, y, track));
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32 _drawtile_track_palette;
|
static uint32 _drawtile_track_palette;
|
||||||
@ -1338,6 +1354,7 @@ static void DrawTrackFence_NS_1(const TileInfo *ti)
|
|||||||
{
|
{
|
||||||
int z = ti->z;
|
int z = ti->z;
|
||||||
if (ti->tileh & SLOPE_W) z += TILE_HEIGHT;
|
if (ti->tileh & SLOPE_W) z += TILE_HEIGHT;
|
||||||
|
if (IsSteepSlope(ti->tileh)) z += TILE_HEIGHT;
|
||||||
AddSortableSpriteToDraw(SPR_TRACK_FENCE_FLAT_VERT, _drawtile_track_palette,
|
AddSortableSpriteToDraw(SPR_TRACK_FENCE_FLAT_VERT, _drawtile_track_palette,
|
||||||
ti->x + TILE_SIZE / 2, ti->y + TILE_SIZE / 2, 1, 1, 4, z);
|
ti->x + TILE_SIZE / 2, ti->y + TILE_SIZE / 2, 1, 1, 4, z);
|
||||||
}
|
}
|
||||||
@ -1349,6 +1366,7 @@ static void DrawTrackFence_NS_2(const TileInfo *ti)
|
|||||||
{
|
{
|
||||||
int z = ti->z;
|
int z = ti->z;
|
||||||
if (ti->tileh & SLOPE_E) z += TILE_HEIGHT;
|
if (ti->tileh & SLOPE_E) z += TILE_HEIGHT;
|
||||||
|
if (IsSteepSlope(ti->tileh)) z += TILE_HEIGHT;
|
||||||
AddSortableSpriteToDraw(SPR_TRACK_FENCE_FLAT_VERT, _drawtile_track_palette,
|
AddSortableSpriteToDraw(SPR_TRACK_FENCE_FLAT_VERT, _drawtile_track_palette,
|
||||||
ti->x + TILE_SIZE / 2, ti->y + TILE_SIZE / 2, 1, 1, 4, z);
|
ti->x + TILE_SIZE / 2, ti->y + TILE_SIZE / 2, 1, 1, 4, z);
|
||||||
}
|
}
|
||||||
@ -1360,6 +1378,7 @@ static void DrawTrackFence_WE_1(const TileInfo *ti)
|
|||||||
{
|
{
|
||||||
int z = ti->z;
|
int z = ti->z;
|
||||||
if (ti->tileh & SLOPE_N) z += TILE_HEIGHT;
|
if (ti->tileh & SLOPE_N) z += TILE_HEIGHT;
|
||||||
|
if (IsSteepSlope(ti->tileh)) z += TILE_HEIGHT;
|
||||||
AddSortableSpriteToDraw(SPR_TRACK_FENCE_FLAT_HORZ, _drawtile_track_palette,
|
AddSortableSpriteToDraw(SPR_TRACK_FENCE_FLAT_HORZ, _drawtile_track_palette,
|
||||||
ti->x + TILE_SIZE / 2, ti->y + TILE_SIZE / 2, 1, 1, 4, z);
|
ti->x + TILE_SIZE / 2, ti->y + TILE_SIZE / 2, 1, 1, 4, z);
|
||||||
}
|
}
|
||||||
@ -1371,6 +1390,7 @@ static void DrawTrackFence_WE_2(const TileInfo *ti)
|
|||||||
{
|
{
|
||||||
int z = ti->z;
|
int z = ti->z;
|
||||||
if (ti->tileh & SLOPE_S) z += TILE_HEIGHT;
|
if (ti->tileh & SLOPE_S) z += TILE_HEIGHT;
|
||||||
|
if (IsSteepSlope(ti->tileh)) z += TILE_HEIGHT;
|
||||||
AddSortableSpriteToDraw(SPR_TRACK_FENCE_FLAT_HORZ, _drawtile_track_palette,
|
AddSortableSpriteToDraw(SPR_TRACK_FENCE_FLAT_HORZ, _drawtile_track_palette,
|
||||||
ti->x + TILE_SIZE / 2, ti->y + TILE_SIZE / 2, 1, 1, 4, z);
|
ti->x + TILE_SIZE / 2, ti->y + TILE_SIZE / 2, 1, 1, 4, z);
|
||||||
}
|
}
|
||||||
|
85
src/slope.h
85
src/slope.h
@ -8,6 +8,17 @@
|
|||||||
#ifndef SLOPE_H
|
#ifndef SLOPE_H
|
||||||
#define SLOPE_H
|
#define SLOPE_H
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enumeration of tile corners
|
||||||
|
*/
|
||||||
|
enum Corner {
|
||||||
|
CORNER_W = 0,
|
||||||
|
CORNER_S = 1,
|
||||||
|
CORNER_E = 2,
|
||||||
|
CORNER_N = 3,
|
||||||
|
CORNER_END
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enumeration for the slope-type.
|
* Enumeration for the slope-type.
|
||||||
*
|
*
|
||||||
@ -15,6 +26,14 @@
|
|||||||
* direction north, east, south and west. The top corner of a tile
|
* direction north, east, south and west. The top corner of a tile
|
||||||
* is the north-part of the tile. The whole slope is encoded with
|
* is the north-part of the tile. The whole slope is encoded with
|
||||||
* 5 bits, 4 bits for each corner and 1 bit for a steep-flag.
|
* 5 bits, 4 bits for each corner and 1 bit for a steep-flag.
|
||||||
|
*
|
||||||
|
* For halftile slopes an extra 3 bits are used to represent this
|
||||||
|
* properly; 1 bit for a halftile-flag and 2 bits to encode which
|
||||||
|
* extra side (corner) is leveled when the slope of the first 5
|
||||||
|
* bits is applied. This means that there can only be one leveled
|
||||||
|
* slope for steep slopes, which is logical because two leveled
|
||||||
|
* slopes would mean that it is not a steep slope as halftile
|
||||||
|
* slopes only span one height level.
|
||||||
*/
|
*/
|
||||||
enum Slope {
|
enum Slope {
|
||||||
SLOPE_FLAT = 0x00, ///< a flat tile
|
SLOPE_FLAT = 0x00, ///< a flat tile
|
||||||
@ -37,18 +56,14 @@ enum Slope {
|
|||||||
SLOPE_STEEP_W = SLOPE_STEEP | SLOPE_NWS, ///< a steep slope falling to east (from west)
|
SLOPE_STEEP_W = SLOPE_STEEP | SLOPE_NWS, ///< a steep slope falling to east (from west)
|
||||||
SLOPE_STEEP_S = SLOPE_STEEP | SLOPE_WSE, ///< a steep slope falling to north (from south)
|
SLOPE_STEEP_S = SLOPE_STEEP | SLOPE_WSE, ///< a steep slope falling to north (from south)
|
||||||
SLOPE_STEEP_E = SLOPE_STEEP | SLOPE_SEN, ///< a steep slope falling to west (from east)
|
SLOPE_STEEP_E = SLOPE_STEEP | SLOPE_SEN, ///< a steep slope falling to west (from east)
|
||||||
SLOPE_STEEP_N = SLOPE_STEEP | SLOPE_ENW ///< a steep slope falling to south (from north)
|
SLOPE_STEEP_N = SLOPE_STEEP | SLOPE_ENW, ///< a steep slope falling to south (from north)
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
SLOPE_HALFTILE = 0x20, ///< one halftile is leveled (non continuous slope)
|
||||||
* Enumeration of tile corners
|
SLOPE_HALFTILE_MASK = 0xE0, ///< three bits used for halftile slopes
|
||||||
*/
|
SLOPE_HALFTILE_W = SLOPE_HALFTILE | (CORNER_W << 6), ///< the west halftile is leveled (non continuous slope)
|
||||||
enum Corner {
|
SLOPE_HALFTILE_S = SLOPE_HALFTILE | (CORNER_S << 6), ///< the south halftile is leveled (non continuous slope)
|
||||||
CORNER_W = 0,
|
SLOPE_HALFTILE_E = SLOPE_HALFTILE | (CORNER_E << 6), ///< the east halftile is leveled (non continuous slope)
|
||||||
CORNER_S = 1,
|
SLOPE_HALFTILE_N = SLOPE_HALFTILE | (CORNER_N << 6), ///< the north halftile is leveled (non continuous slope)
|
||||||
CORNER_E = 2,
|
|
||||||
CORNER_N = 3,
|
|
||||||
CORNER_END
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -73,6 +88,17 @@ static inline bool IsSteepSlope(Slope s)
|
|||||||
return (s & SLOPE_STEEP) != 0;
|
return (s & SLOPE_STEEP) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks for non-continuous slope on halftile foundations.
|
||||||
|
*
|
||||||
|
* @param s The given #Slope.
|
||||||
|
* @return True if the slope is non-continuous, else false.
|
||||||
|
*/
|
||||||
|
static inline bool IsHalftileSlope(Slope s)
|
||||||
|
{
|
||||||
|
return (s & SLOPE_HALFTILE) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the complement of a slope.
|
* Return the complement of a slope.
|
||||||
*
|
*
|
||||||
@ -80,37 +106,40 @@ static inline bool IsSteepSlope(Slope s)
|
|||||||
* slope is a slope with raised corner which aren't raised in the given
|
* slope is a slope with raised corner which aren't raised in the given
|
||||||
* slope.
|
* slope.
|
||||||
*
|
*
|
||||||
* @pre The slope must not be steep.
|
* @pre The slope must neither be steep nor a halftile slope.
|
||||||
* @param s The #Slope to get the complement.
|
* @param s The #Slope to get the complement.
|
||||||
* @return a complement Slope of the given slope.
|
* @return a complement Slope of the given slope.
|
||||||
*/
|
*/
|
||||||
static inline Slope ComplementSlope(Slope s)
|
static inline Slope ComplementSlope(Slope s)
|
||||||
{
|
{
|
||||||
assert(!IsSteepSlope(s));
|
assert(!IsSteepSlope(s) && !IsHalftileSlope(s));
|
||||||
return (Slope)(0xF ^ s);
|
return (Slope)(0xF ^ s);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests if a slope has a highest corner (i.e. one corner raised or a steep slope).
|
* Tests if a slope has a highest corner (i.e. one corner raised or a steep slope).
|
||||||
*
|
*
|
||||||
|
* Note: A halftile slope is ignored.
|
||||||
|
*
|
||||||
* @param s The #Slope.
|
* @param s The #Slope.
|
||||||
* @return true iff the slope has a highest corner.
|
* @return true iff the slope has a highest corner.
|
||||||
*/
|
*/
|
||||||
static inline bool HasSlopeHighestCorner(Slope s)
|
static inline bool HasSlopeHighestCorner(Slope s)
|
||||||
{
|
{
|
||||||
|
s = (Slope)(s & ~SLOPE_HALFTILE_MASK);
|
||||||
return IsSteepSlope(s) || (s == SLOPE_W) || (s == SLOPE_S) || (s == SLOPE_E) || (s == SLOPE_N);
|
return IsSteepSlope(s) || (s == SLOPE_W) || (s == SLOPE_S) || (s == SLOPE_E) || (s == SLOPE_N);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the highest corner of a slope (one corner raised or a steep slope).
|
* Returns the highest corner of a slope (one corner raised or a steep slope).
|
||||||
*
|
*
|
||||||
* @pre The slope must be a slope with one corner raised or a steep slope.
|
* @pre The slope must be a slope with one corner raised or a steep slope. A halftile slope is ignored.
|
||||||
* @param s The #Slope.
|
* @param s The #Slope.
|
||||||
* @return Highest corner.
|
* @return Highest corner.
|
||||||
*/
|
*/
|
||||||
static inline Corner GetHighestSlopeCorner(Slope s)
|
static inline Corner GetHighestSlopeCorner(Slope s)
|
||||||
{
|
{
|
||||||
switch (s) {
|
switch (s & ~SLOPE_HALFTILE_MASK) {
|
||||||
case SLOPE_W:
|
case SLOPE_W:
|
||||||
case SLOPE_STEEP_W: return CORNER_W;
|
case SLOPE_STEEP_W: return CORNER_W;
|
||||||
case SLOPE_S:
|
case SLOPE_S:
|
||||||
@ -123,6 +152,19 @@ static inline Corner GetHighestSlopeCorner(Slope s)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the leveled halftile of a halftile slope.
|
||||||
|
*
|
||||||
|
* @pre The slope must be a halftile slope.
|
||||||
|
* @param s The #Slope.
|
||||||
|
* @return The corner of the leveled halftile.
|
||||||
|
*/
|
||||||
|
static inline Corner GetHalftileSlopeCorner(Slope s)
|
||||||
|
{
|
||||||
|
assert(IsHalftileSlope(s));
|
||||||
|
return (Corner)((s >> 6) & 3);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the height of the highest corner of a slope relative to TileZ (= minimal height)
|
* Returns the height of the highest corner of a slope relative to TileZ (= minimal height)
|
||||||
*
|
*
|
||||||
@ -170,6 +212,19 @@ static inline Slope SlopeWithThreeCornersRaised(Corner corner)
|
|||||||
return ComplementSlope(SlopeWithOneCornerRaised(corner));
|
return ComplementSlope(SlopeWithOneCornerRaised(corner));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a halftile slope to a slope.
|
||||||
|
*
|
||||||
|
* @param s #Slope without a halftile slope.
|
||||||
|
* @param corner The #Corner of the halftile.
|
||||||
|
* @return The #Slope s with the halftile slope added.
|
||||||
|
*/
|
||||||
|
static inline Slope HalftileSlope(Slope s, Corner corner)
|
||||||
|
{
|
||||||
|
assert(IsValidCorner(corner));
|
||||||
|
return (Slope)(s | SLOPE_HALFTILE | (corner << 6));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enumeration for Foundations.
|
* Enumeration for Foundations.
|
||||||
|
@ -362,11 +362,17 @@ static Point TranslateXYToTileCoord(const ViewPort *vp, int x, int y)
|
|||||||
a = clamp(a, 0, (int)(MapMaxX() * TILE_SIZE) - 1);
|
a = clamp(a, 0, (int)(MapMaxX() * TILE_SIZE) - 1);
|
||||||
b = clamp(b, 0, (int)(MapMaxY() * TILE_SIZE) - 1);
|
b = clamp(b, 0, (int)(MapMaxY() * TILE_SIZE) - 1);
|
||||||
|
|
||||||
z = GetSlopeZ(a, b ) / 2;
|
/* (a, b) is the X/Y-world coordinate that belongs to (x,y) if the landscape would be completely flat on height 0.
|
||||||
z = GetSlopeZ(a + z, b + z) / 2;
|
* Now find the Z-world coordinate by fix point iteration.
|
||||||
z = GetSlopeZ(a + z, b + z) / 2;
|
* This is a bit tricky because the tile height is non-continuous at foundations.
|
||||||
z = GetSlopeZ(a + z, b + z) / 2;
|
* The clicked point should be approached from the back, otherwise there are regions that are not clickable.
|
||||||
z = GetSlopeZ(a + z, b + z) / 2;
|
* (FOUNDATION_HALFTILE_LOWER on SLOPE_STEEP_S hides north halftile completely)
|
||||||
|
* So give it a z-malus of 4 in the first iterations.
|
||||||
|
*/
|
||||||
|
z = 0;
|
||||||
|
for (int i = 0; i < 5; i++) z = GetSlopeZ(a + max(z, 4u) - 4, b + max(z, 4u) - 4) / 2;
|
||||||
|
for (uint malus = 3; malus > 0; malus--) z = GetSlopeZ(a + max(z, malus) - malus, b + max(z, malus) - malus) / 2;
|
||||||
|
for (int i = 0; i < 5; i++) z = GetSlopeZ(a + z, b + z) / 2;
|
||||||
|
|
||||||
pt.x = a + z;
|
pt.x = a + z;
|
||||||
pt.y = b + z;
|
pt.y = b + z;
|
||||||
|
Loading…
Reference in New Issue
Block a user