mirror of https://github.com/OpenTTD/OpenTTD
Compare commits
3 Commits
6a8c6f5cfd
...
eddd460553
Author | SHA1 | Date |
---|---|---|
|
eddd460553 | |
|
6b6caa6fa8 | |
|
18dfad871a |
|
@ -48,10 +48,7 @@
|
||||||
|
|
||||||
void Aircraft::UpdateDeltaXY()
|
void Aircraft::UpdateDeltaXY()
|
||||||
{
|
{
|
||||||
this->x_offs = -1;
|
this->bounds = {{-1, -1, 0}, {2, 2, 0}, {}};
|
||||||
this->y_offs = -1;
|
|
||||||
this->x_extent = 2;
|
|
||||||
this->y_extent = 2;
|
|
||||||
|
|
||||||
switch (this->subtype) {
|
switch (this->subtype) {
|
||||||
default: NOT_REACHED();
|
default: NOT_REACHED();
|
||||||
|
@ -64,21 +61,21 @@ void Aircraft::UpdateDeltaXY()
|
||||||
case LANDING:
|
case LANDING:
|
||||||
case HELILANDING:
|
case HELILANDING:
|
||||||
case FLYING:
|
case FLYING:
|
||||||
this->x_extent = 24;
|
/* Bounds are not centred on the aircraft. */
|
||||||
this->y_extent = 24;
|
this->bounds.extent.x = 24;
|
||||||
|
this->bounds.extent.y = 24;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
this->z_extent = 5;
|
this->bounds.extent.z = 5;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AIR_SHADOW:
|
case AIR_SHADOW:
|
||||||
this->z_extent = 1;
|
this->bounds.extent.z = 1;
|
||||||
this->x_offs = 0;
|
this->bounds.origin = {};
|
||||||
this->y_offs = 0;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AIR_ROTOR:
|
case AIR_ROTOR:
|
||||||
this->z_extent = 1;
|
this->bounds.extent.z = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,36 +69,45 @@ static void DrawClearLandFence(const TileInfo *ti)
|
||||||
/* combine fences into one sprite object */
|
/* combine fences into one sprite object */
|
||||||
StartSpriteCombine();
|
StartSpriteCombine();
|
||||||
|
|
||||||
int maxz = GetSlopeMaxPixelZ(ti->tileh);
|
SpriteBounds bounds = {{}, {TILE_SIZE, TILE_SIZE, 4}, {}};
|
||||||
|
|
||||||
|
bounds.extent.z += GetSlopeMaxPixelZ(ti->tileh);
|
||||||
|
|
||||||
uint fence_nw = GetFence(ti->tile, DIAGDIR_NW);
|
uint fence_nw = GetFence(ti->tile, DIAGDIR_NW);
|
||||||
if (fence_nw != 0) {
|
if (fence_nw != 0) {
|
||||||
int z = GetSlopePixelZInCorner(ti->tileh, CORNER_W);
|
bounds.offset.x = 0;
|
||||||
|
bounds.offset.y = -static_cast<int>(TILE_SIZE);
|
||||||
|
bounds.offset.z = GetSlopePixelZInCorner(ti->tileh, CORNER_W);
|
||||||
SpriteID sprite = _clear_land_fence_sprites[fence_nw - 1] + _fence_mod_by_tileh_nw[ti->tileh];
|
SpriteID sprite = _clear_land_fence_sprites[fence_nw - 1] + _fence_mod_by_tileh_nw[ti->tileh];
|
||||||
AddSortableSpriteToDraw(sprite, PAL_NONE, ti->x, ti->y - 16, 16, 32, maxz - z + 4, ti->z + z, false, 0, 16, -z);
|
AddSortableSpriteToDraw(sprite, PAL_NONE, *ti, bounds, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint fence_ne = GetFence(ti->tile, DIAGDIR_NE);
|
uint fence_ne = GetFence(ti->tile, DIAGDIR_NE);
|
||||||
if (fence_ne != 0) {
|
if (fence_ne != 0) {
|
||||||
int z = GetSlopePixelZInCorner(ti->tileh, CORNER_E);
|
bounds.offset.x = -static_cast<int>(TILE_SIZE);
|
||||||
|
bounds.offset.y = 0;
|
||||||
|
bounds.offset.z = GetSlopePixelZInCorner(ti->tileh, CORNER_E);
|
||||||
SpriteID sprite = _clear_land_fence_sprites[fence_ne - 1] + _fence_mod_by_tileh_ne[ti->tileh];
|
SpriteID sprite = _clear_land_fence_sprites[fence_ne - 1] + _fence_mod_by_tileh_ne[ti->tileh];
|
||||||
AddSortableSpriteToDraw(sprite, PAL_NONE, ti->x - 16, ti->y, 32, 16, maxz - z + 4, ti->z + z, false, 16, 0, -z);
|
AddSortableSpriteToDraw(sprite, PAL_NONE, *ti, bounds, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint fence_sw = GetFence(ti->tile, DIAGDIR_SW);
|
uint fence_sw = GetFence(ti->tile, DIAGDIR_SW);
|
||||||
uint fence_se = GetFence(ti->tile, DIAGDIR_SE);
|
uint fence_se = GetFence(ti->tile, DIAGDIR_SE);
|
||||||
|
|
||||||
if (fence_sw != 0 || fence_se != 0) {
|
if (fence_sw != 0 || fence_se != 0) {
|
||||||
int z = GetSlopePixelZInCorner(ti->tileh, CORNER_S);
|
bounds.offset.x = 0;
|
||||||
|
bounds.offset.y = 0;
|
||||||
|
bounds.offset.z = GetSlopePixelZInCorner(ti->tileh, CORNER_S);
|
||||||
|
|
||||||
if (fence_sw != 0) {
|
if (fence_sw != 0) {
|
||||||
SpriteID sprite = _clear_land_fence_sprites[fence_sw - 1] + _fence_mod_by_tileh_sw[ti->tileh];
|
SpriteID sprite = _clear_land_fence_sprites[fence_sw - 1] + _fence_mod_by_tileh_sw[ti->tileh];
|
||||||
AddSortableSpriteToDraw(sprite, PAL_NONE, ti->x, ti->y, 16, 16, maxz - z + 4, ti->z + z, false, 0, 0, -z);
|
AddSortableSpriteToDraw(sprite, PAL_NONE, *ti, bounds, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fence_se != 0) {
|
if (fence_se != 0) {
|
||||||
SpriteID sprite = _clear_land_fence_sprites[fence_se - 1] + _fence_mod_by_tileh_se[ti->tileh];
|
SpriteID sprite = _clear_land_fence_sprites[fence_se - 1] + _fence_mod_by_tileh_se[ti->tileh];
|
||||||
AddSortableSpriteToDraw(sprite, PAL_NONE, ti->x, ti->y, 16, 16, maxz - z + 4, ti->z + z, false, 0, 0, -z);
|
AddSortableSpriteToDraw(sprite, PAL_NONE, *ti, bounds, false);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EndSpriteCombine();
|
EndSpriteCombine();
|
||||||
|
|
|
@ -28,15 +28,30 @@ inline int CentreBounds(int min, int max, int size)
|
||||||
return (min + max - size + 1) / 2;
|
return (min + max - size + 1) / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Coordinates of a point in 2D */
|
/** Coordinates of a point in 2D. */
|
||||||
struct Point {
|
template <typename T>
|
||||||
int x;
|
struct PointXy {
|
||||||
int y;
|
T x = 0; ///< X coordinate of point.
|
||||||
|
T y = 0; ///< Y coordinate of point.
|
||||||
|
|
||||||
constexpr Point() : x(0), y(0) {}
|
constexpr PointXy() = default;
|
||||||
constexpr Point(int x, int y) : x(x), y(y) {}
|
constexpr PointXy(T x, T y) : x(x), y(y) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Coordinates of a point in 3D. */
|
||||||
|
template <typename T>
|
||||||
|
struct PointXyz {
|
||||||
|
T x = 0; ///< X coordinate of point.
|
||||||
|
T y = 0; ///< Y coordinate of point.
|
||||||
|
T z = 0; ///< Z coordinate of point.
|
||||||
|
|
||||||
|
constexpr PointXyz() = default;
|
||||||
|
constexpr PointXyz(T x, T y, T z) : x(x), y(y), z(z) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Coordinates of a point in 2D */
|
||||||
|
using Point = PointXy<int>;
|
||||||
|
|
||||||
/** Dimensions (a width and height) of a rectangle in 2D */
|
/** Dimensions (a width and height) of a rectangle in 2D */
|
||||||
struct Dimension {
|
struct Dimension {
|
||||||
uint width;
|
uint width;
|
||||||
|
|
|
@ -992,9 +992,5 @@ void ReleaseDisasterVehicle(VehicleID vehicle)
|
||||||
|
|
||||||
void DisasterVehicle::UpdateDeltaXY()
|
void DisasterVehicle::UpdateDeltaXY()
|
||||||
{
|
{
|
||||||
this->x_offs = -1;
|
this->bounds = {{-1, -1, 0}, {2, 2, 5}, {}};
|
||||||
this->y_offs = -1;
|
|
||||||
this->x_extent = 2;
|
|
||||||
this->y_extent = 2;
|
|
||||||
this->z_extent = 5;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -619,11 +619,7 @@ bool EffectVehicle::Tick()
|
||||||
|
|
||||||
void EffectVehicle::UpdateDeltaXY()
|
void EffectVehicle::UpdateDeltaXY()
|
||||||
{
|
{
|
||||||
this->x_offs = 0;
|
this->bounds = {{}, {1, 1, 1}, {}};
|
||||||
this->y_offs = 0;
|
|
||||||
this->x_extent = 1;
|
|
||||||
this->y_extent = 1;
|
|
||||||
this->z_extent = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -248,27 +248,12 @@ static int GetPCPElevation(TileIndex tile, DiagDirection pcp_pos)
|
||||||
*/
|
*/
|
||||||
void DrawRailCatenaryOnTunnel(const TileInfo *ti)
|
void DrawRailCatenaryOnTunnel(const TileInfo *ti)
|
||||||
{
|
{
|
||||||
/* xmin, ymin, xmax + 1, ymax + 1 of BB */
|
|
||||||
static const int tunnel_wire_bb[4][4] = {
|
|
||||||
{ 0, 1, 16, 15 }, // NE
|
|
||||||
{ 1, 0, 15, 16 }, // SE
|
|
||||||
{ 0, 1, 16, 15 }, // SW
|
|
||||||
{ 1, 0, 15, 16 }, // NW
|
|
||||||
};
|
|
||||||
|
|
||||||
DiagDirection dir = GetTunnelBridgeDirection(ti->tile);
|
DiagDirection dir = GetTunnelBridgeDirection(ti->tile);
|
||||||
|
|
||||||
SpriteID wire_base = GetWireBase(ti->tile);
|
SpriteID wire_base = GetWireBase(ti->tile);
|
||||||
|
|
||||||
const SortableSpriteStruct *sss = &_rail_catenary_sprite_data_tunnel[dir];
|
const SortableSpriteStruct &sss = _rail_catenary_sprite_data_tunnel[dir];
|
||||||
const int *bb_data = tunnel_wire_bb[dir];
|
AddSortableSpriteToDraw(wire_base + sss.image_offset, PAL_NONE, ti->x, ti->y, GetTilePixelZ(ti->tile), sss, IsTransparencySet(TO_CATENARY));
|
||||||
AddSortableSpriteToDraw(
|
|
||||||
wire_base + sss->image_offset, PAL_NONE, ti->x + sss->x_offset, ti->y + sss->y_offset,
|
|
||||||
bb_data[2] - sss->x_offset, bb_data[3] - sss->y_offset, BB_Z_SEPARATOR - sss->z_offset + 1,
|
|
||||||
GetTilePixelZ(ti->tile) + sss->z_offset,
|
|
||||||
IsTransparencySet(TO_CATENARY),
|
|
||||||
bb_data[0] - sss->x_offset, bb_data[1] - sss->y_offset, BB_Z_SEPARATOR - sss->z_offset
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -440,8 +425,8 @@ static void DrawRailCatenaryRailway(const TileInfo *ti)
|
||||||
continue; // No neighbour, go looking for a better position
|
continue; // No neighbour, go looking for a better position
|
||||||
}
|
}
|
||||||
|
|
||||||
AddSortableSpriteToDraw(pylon_base + _pylon_sprites[temp], PAL_NONE, x, y, 1, 1, BB_HEIGHT_UNDER_BRIDGE,
|
AddSortableSpriteToDraw(pylon_base + _pylon_sprites[temp], PAL_NONE, x, y, elevation,
|
||||||
elevation, IsTransparencySet(TO_CATENARY), -1, -1);
|
{{-1, -1, 0}, {1, 1, BB_HEIGHT_UNDER_BRIDGE}, {1, 1, 0}}, IsTransparencySet(TO_CATENARY));
|
||||||
|
|
||||||
break; // We already have drawn a pylon, bail out
|
break; // We already have drawn a pylon, bail out
|
||||||
}
|
}
|
||||||
|
@ -482,7 +467,7 @@ static void DrawRailCatenaryRailway(const TileInfo *ti)
|
||||||
|
|
||||||
assert(pcp_config != 0); // We have a pylon on neither end of the wire, that doesn't work (since we have no sprites for that)
|
assert(pcp_config != 0); // We have a pylon on neither end of the wire, that doesn't work (since we have no sprites for that)
|
||||||
assert(!IsSteepSlope(tileh[TS_HOME]));
|
assert(!IsSteepSlope(tileh[TS_HOME]));
|
||||||
const SortableSpriteStruct *sss = &_rail_catenary_sprite_data[_rail_wires[tileh_selector][t][pcp_config]];
|
const SortableSpriteStruct &sss = _rail_catenary_sprite_data[_rail_wires[tileh_selector][t][pcp_config]];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The "wire"-sprite position is inside the tile, i.e. 0 <= sss->?_offset < TILE_SIZE.
|
* The "wire"-sprite position is inside the tile, i.e. 0 <= sss->?_offset < TILE_SIZE.
|
||||||
|
@ -490,9 +475,8 @@ static void DrawRailCatenaryRailway(const TileInfo *ti)
|
||||||
* Also note that the result of GetSlopePixelZ() is very special for bridge-ramps, so we round the result up or
|
* Also note that the result of GetSlopePixelZ() is very special for bridge-ramps, so we round the result up or
|
||||||
* down to the nearest full height change.
|
* down to the nearest full height change.
|
||||||
*/
|
*/
|
||||||
AddSortableSpriteToDraw(wire_base + sss->image_offset, PAL_NONE, ti->x + sss->x_offset, ti->y + sss->y_offset,
|
int z = (GetSlopePixelZ(ti->x + sss.origin.x, ti->y + sss.origin.y, true) + 4) / 8 * 8;
|
||||||
sss->x_size, sss->y_size, sss->z_size, (GetSlopePixelZ(ti->x + sss->x_offset, ti->y + sss->y_offset, true) + 4) / 8 * 8 + sss->z_offset,
|
AddSortableSpriteToDraw(wire_base + sss.image_offset, PAL_NONE, ti->x, ti->y, z, sss, IsTransparencySet(TO_CATENARY));
|
||||||
IsTransparencySet(TO_CATENARY));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -530,13 +514,12 @@ void DrawRailCatenaryOnBridge(const TileInfo *ti)
|
||||||
|
|
||||||
SpriteID wire_base = GetWireBase(end, TCX_ON_BRIDGE);
|
SpriteID wire_base = GetWireBase(end, TCX_ON_BRIDGE);
|
||||||
|
|
||||||
AddSortableSpriteToDraw(wire_base + sss->image_offset, PAL_NONE, ti->x + sss->x_offset, ti->y + sss->y_offset,
|
AddSortableSpriteToDraw(wire_base + sss->image_offset, PAL_NONE, ti->x, ti->y, height, *sss, IsTransparencySet(TO_CATENARY));
|
||||||
sss->x_size, sss->y_size, sss->z_size, height + sss->z_offset,
|
|
||||||
IsTransparencySet(TO_CATENARY)
|
|
||||||
);
|
|
||||||
|
|
||||||
SpriteID pylon_base = GetPylonBase(end, TCX_ON_BRIDGE);
|
SpriteID pylon_base = GetPylonBase(end, TCX_ON_BRIDGE);
|
||||||
|
|
||||||
|
static constexpr SpriteBounds pylon_bounds{{-1, -1, 0}, {1, 1, BB_HEIGHT_UNDER_BRIDGE}, {1, 1, 0}};
|
||||||
|
|
||||||
/* Finished with wires, draw pylons
|
/* Finished with wires, draw pylons
|
||||||
* every other tile needs a pylon on the northern end */
|
* every other tile needs a pylon on the northern end */
|
||||||
if (num % 2) {
|
if (num % 2) {
|
||||||
|
@ -545,7 +528,7 @@ void DrawRailCatenaryOnBridge(const TileInfo *ti)
|
||||||
if (HasBit(tlg, (axis == AXIS_X ? 0 : 1))) ppp_pos = ReverseDir(ppp_pos);
|
if (HasBit(tlg, (axis == AXIS_X ? 0 : 1))) ppp_pos = ReverseDir(ppp_pos);
|
||||||
uint x = ti->x + _x_pcp_offsets[pcp_pos] + _x_ppp_offsets[ppp_pos];
|
uint x = ti->x + _x_pcp_offsets[pcp_pos] + _x_ppp_offsets[ppp_pos];
|
||||||
uint y = ti->y + _y_pcp_offsets[pcp_pos] + _y_ppp_offsets[ppp_pos];
|
uint y = ti->y + _y_pcp_offsets[pcp_pos] + _y_ppp_offsets[ppp_pos];
|
||||||
AddSortableSpriteToDraw(pylon_base + _pylon_sprites[ppp_pos], PAL_NONE, x, y, 1, 1, BB_HEIGHT_UNDER_BRIDGE, height, IsTransparencySet(TO_CATENARY), -1, -1);
|
AddSortableSpriteToDraw(pylon_base + _pylon_sprites[ppp_pos], PAL_NONE, x, y, height, pylon_bounds, IsTransparencySet(TO_CATENARY));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* need a pylon on the southern end of the bridge */
|
/* need a pylon on the southern end of the bridge */
|
||||||
|
@ -555,7 +538,7 @@ void DrawRailCatenaryOnBridge(const TileInfo *ti)
|
||||||
if (HasBit(tlg, (axis == AXIS_X ? 0 : 1))) ppp_pos = ReverseDir(ppp_pos);
|
if (HasBit(tlg, (axis == AXIS_X ? 0 : 1))) ppp_pos = ReverseDir(ppp_pos);
|
||||||
uint x = ti->x + _x_pcp_offsets[pcp_pos] + _x_ppp_offsets[ppp_pos];
|
uint x = ti->x + _x_pcp_offsets[pcp_pos] + _x_ppp_offsets[ppp_pos];
|
||||||
uint y = ti->y + _y_pcp_offsets[pcp_pos] + _y_ppp_offsets[ppp_pos];
|
uint y = ti->y + _y_pcp_offsets[pcp_pos] + _y_ppp_offsets[ppp_pos];
|
||||||
AddSortableSpriteToDraw(pylon_base + _pylon_sprites[ppp_pos], PAL_NONE, x, y, 1, 1, BB_HEIGHT_UNDER_BRIDGE, height, IsTransparencySet(TO_CATENARY), -1, -1);
|
AddSortableSpriteToDraw(pylon_base + _pylon_sprites[ppp_pos], PAL_NONE, x, y, height, pylon_bounds, IsTransparencySet(TO_CATENARY));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -569,17 +552,12 @@ void DrawRailCatenary(const TileInfo *ti)
|
||||||
switch (GetTileType(ti->tile)) {
|
switch (GetTileType(ti->tile)) {
|
||||||
case MP_RAILWAY:
|
case MP_RAILWAY:
|
||||||
if (IsRailDepot(ti->tile)) {
|
if (IsRailDepot(ti->tile)) {
|
||||||
const SortableSpriteStruct *sss = &_rail_catenary_sprite_data_depot[GetRailDepotDirection(ti->tile)];
|
const SortableSpriteStruct &sss = _rail_catenary_sprite_data_depot[GetRailDepotDirection(ti->tile)];
|
||||||
|
|
||||||
SpriteID wire_base = GetWireBase(ti->tile);
|
SpriteID wire_base = GetWireBase(ti->tile);
|
||||||
|
|
||||||
/* This wire is not visible with the default depot sprites */
|
/* This wire is not visible with the default depot sprites */
|
||||||
AddSortableSpriteToDraw(
|
AddSortableSpriteToDraw(wire_base + sss.image_offset, PAL_NONE, ti->x, ti->y, GetTileMaxPixelZ(ti->tile), sss, IsTransparencySet(TO_CATENARY));
|
||||||
wire_base + sss->image_offset, PAL_NONE, ti->x + sss->x_offset, ti->y + sss->y_offset,
|
|
||||||
sss->x_size, sss->y_size, sss->z_size,
|
|
||||||
GetTileMaxPixelZ(ti->tile) + sss->z_offset,
|
|
||||||
IsTransparencySet(TO_CATENARY)
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -374,13 +374,7 @@ static void DrawTile_Industry(TileInfo *ti)
|
||||||
image = dits->building.sprite;
|
image = dits->building.sprite;
|
||||||
if (image != 0) {
|
if (image != 0) {
|
||||||
AddSortableSpriteToDraw(image, SpriteLayoutPaletteTransform(image, dits->building.pal, GetColourPalette(ind->random_colour)),
|
AddSortableSpriteToDraw(image, SpriteLayoutPaletteTransform(image, dits->building.pal, GetColourPalette(ind->random_colour)),
|
||||||
ti->x + dits->subtile_x,
|
*ti, *dits, IsTransparencySet(TO_INDUSTRIES));
|
||||||
ti->y + dits->subtile_y,
|
|
||||||
dits->width,
|
|
||||||
dits->height,
|
|
||||||
dits->dz,
|
|
||||||
ti->z,
|
|
||||||
IsTransparencySet(TO_INDUSTRIES));
|
|
||||||
|
|
||||||
if (IsTransparencySet(TO_INDUSTRIES)) return;
|
if (IsTransparencySet(TO_INDUSTRIES)) return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -450,9 +450,8 @@ void DrawFoundation(TileInfo *ti, Foundation f)
|
||||||
if (IsSteepSlope(ti->tileh)) {
|
if (IsSteepSlope(ti->tileh)) {
|
||||||
if (!IsNonContinuousFoundation(f)) {
|
if (!IsNonContinuousFoundation(f)) {
|
||||||
/* Lower part of foundation */
|
/* Lower part of foundation */
|
||||||
AddSortableSpriteToDraw(
|
static constexpr SpriteBounds bounds{{}, {TILE_SIZE, TILE_SIZE, TILE_HEIGHT - 1}, {}};
|
||||||
leveled_base + (ti->tileh & ~SLOPE_STEEP), PAL_NONE, ti->x, ti->y, TILE_SIZE, TILE_SIZE, TILE_HEIGHT - 1, ti->z
|
AddSortableSpriteToDraw(leveled_base + (ti->tileh & ~SLOPE_STEEP), PAL_NONE, *ti, bounds);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Corner highest_corner = GetHighestSlopeCorner(ti->tileh);
|
Corner highest_corner = GetHighestSlopeCorner(ti->tileh);
|
||||||
|
@ -462,24 +461,25 @@ void DrawFoundation(TileInfo *ti, Foundation f)
|
||||||
/* inclined foundation */
|
/* inclined foundation */
|
||||||
uint8_t inclined = highest_corner * 2 + (f == FOUNDATION_INCLINED_Y ? 1 : 0);
|
uint8_t inclined = highest_corner * 2 + (f == FOUNDATION_INCLINED_Y ? 1 : 0);
|
||||||
|
|
||||||
AddSortableSpriteToDraw(inclined_base + inclined, PAL_NONE, ti->x, ti->y,
|
SpriteBounds bounds{{}, {1, 1, TILE_HEIGHT}, {}};
|
||||||
f == FOUNDATION_INCLINED_X ? TILE_SIZE : 1,
|
if (f == FOUNDATION_INCLINED_X) bounds.extent.x = TILE_SIZE;
|
||||||
f == FOUNDATION_INCLINED_Y ? TILE_SIZE : 1,
|
if (f == FOUNDATION_INCLINED_Y) bounds.extent.y = TILE_SIZE;
|
||||||
TILE_HEIGHT, ti->z
|
AddSortableSpriteToDraw(inclined_base + inclined, PAL_NONE, *ti, bounds);
|
||||||
);
|
|
||||||
OffsetGroundSprite(0, 0);
|
OffsetGroundSprite(0, 0);
|
||||||
} else if (IsLeveledFoundation(f)) {
|
} else if (IsLeveledFoundation(f)) {
|
||||||
AddSortableSpriteToDraw(leveled_base + SlopeWithOneCornerRaised(highest_corner), PAL_NONE, ti->x, ti->y, TILE_SIZE, TILE_SIZE, TILE_HEIGHT - 1, ti->z - TILE_HEIGHT);
|
static constexpr SpriteBounds bounds{{0, 0, -(int)TILE_HEIGHT}, {TILE_SIZE, TILE_SIZE, TILE_HEIGHT - 1}, {}};
|
||||||
|
AddSortableSpriteToDraw(leveled_base + SlopeWithOneCornerRaised(highest_corner), PAL_NONE, *ti, bounds);
|
||||||
OffsetGroundSprite(0, -(int)TILE_HEIGHT);
|
OffsetGroundSprite(0, -(int)TILE_HEIGHT);
|
||||||
} else if (f == FOUNDATION_STEEP_LOWER) {
|
} else if (f == FOUNDATION_STEEP_LOWER) {
|
||||||
/* one corner raised */
|
/* one corner raised */
|
||||||
OffsetGroundSprite(0, -(int)TILE_HEIGHT);
|
OffsetGroundSprite(0, -(int)TILE_HEIGHT);
|
||||||
} else {
|
} else {
|
||||||
/* halftile foundation */
|
/* halftile foundation */
|
||||||
int x_bb = (((highest_corner == CORNER_W) || (highest_corner == CORNER_S)) ? TILE_SIZE / 2 : 0);
|
int8_t x_bb = (((highest_corner == CORNER_W) || (highest_corner == CORNER_S)) ? TILE_SIZE / 2 : 0);
|
||||||
int y_bb = (((highest_corner == CORNER_S) || (highest_corner == CORNER_E)) ? TILE_SIZE / 2 : 0);
|
int8_t y_bb = (((highest_corner == CORNER_S) || (highest_corner == CORNER_E)) ? TILE_SIZE / 2 : 0);
|
||||||
|
|
||||||
AddSortableSpriteToDraw(halftile_base + highest_corner, PAL_NONE, ti->x + x_bb, ti->y + y_bb, TILE_SIZE / 2, TILE_SIZE / 2, TILE_HEIGHT - 1, ti->z + TILE_HEIGHT);
|
SpriteBounds bounds{{x_bb, y_bb, TILE_HEIGHT}, {TILE_SIZE / 2, TILE_SIZE / 2, TILE_HEIGHT - 1}, {}};
|
||||||
|
AddSortableSpriteToDraw(halftile_base + highest_corner, PAL_NONE, *ti, bounds);
|
||||||
/* Reposition ground sprite back to original position after bounding box change above. This is similar to
|
/* Reposition ground sprite back to original position after bounding box change above. This is similar to
|
||||||
* RemapCoords() but without zoom scaling. */
|
* RemapCoords() but without zoom scaling. */
|
||||||
Point pt = {(y_bb - x_bb) * 2, y_bb + x_bb};
|
Point pt = {(y_bb - x_bb) * 2, y_bb + x_bb};
|
||||||
|
@ -488,15 +488,17 @@ void DrawFoundation(TileInfo *ti, Foundation f)
|
||||||
} else {
|
} else {
|
||||||
if (IsLeveledFoundation(f)) {
|
if (IsLeveledFoundation(f)) {
|
||||||
/* leveled foundation */
|
/* leveled foundation */
|
||||||
AddSortableSpriteToDraw(leveled_base + ti->tileh, PAL_NONE, ti->x, ti->y, TILE_SIZE, TILE_SIZE, TILE_HEIGHT - 1, ti->z);
|
static constexpr SpriteBounds bounds{{}, {TILE_SIZE, TILE_SIZE, TILE_HEIGHT - 1}, {}};
|
||||||
|
AddSortableSpriteToDraw(leveled_base + ti->tileh, PAL_NONE, *ti, bounds);
|
||||||
OffsetGroundSprite(0, -(int)TILE_HEIGHT);
|
OffsetGroundSprite(0, -(int)TILE_HEIGHT);
|
||||||
} else if (IsNonContinuousFoundation(f)) {
|
} else if (IsNonContinuousFoundation(f)) {
|
||||||
/* halftile foundation */
|
/* halftile foundation */
|
||||||
Corner halftile_corner = GetHalftileFoundationCorner(f);
|
Corner halftile_corner = GetHalftileFoundationCorner(f);
|
||||||
int x_bb = (((halftile_corner == CORNER_W) || (halftile_corner == CORNER_S)) ? TILE_SIZE / 2 : 0);
|
int8_t x_bb = (((halftile_corner == CORNER_W) || (halftile_corner == CORNER_S)) ? TILE_SIZE / 2 : 0);
|
||||||
int y_bb = (((halftile_corner == CORNER_S) || (halftile_corner == CORNER_E)) ? TILE_SIZE / 2 : 0);
|
int8_t y_bb = (((halftile_corner == CORNER_S) || (halftile_corner == CORNER_E)) ? TILE_SIZE / 2 : 0);
|
||||||
|
|
||||||
AddSortableSpriteToDraw(halftile_base + halftile_corner, PAL_NONE, ti->x + x_bb, ti->y + y_bb, TILE_SIZE / 2, TILE_SIZE / 2, TILE_HEIGHT - 1, ti->z);
|
SpriteBounds bounds{{x_bb, y_bb, 0}, {TILE_SIZE / 2, TILE_SIZE / 2, TILE_HEIGHT - 1}, {}};
|
||||||
|
AddSortableSpriteToDraw(halftile_base + halftile_corner, PAL_NONE, *ti, bounds);
|
||||||
/* Reposition ground sprite back to original position after bounding box change above. This is similar to
|
/* Reposition ground sprite back to original position after bounding box change above. This is similar to
|
||||||
* RemapCoords() but without zoom scaling. */
|
* RemapCoords() but without zoom scaling. */
|
||||||
Point pt = {(y_bb - x_bb) * 2, y_bb + x_bb};
|
Point pt = {(y_bb - x_bb) * 2, y_bb + x_bb};
|
||||||
|
@ -511,17 +513,17 @@ void DrawFoundation(TileInfo *ti, Foundation f)
|
||||||
/* tile-slope = sloped along X/Y, foundation-slope = three corners raised */
|
/* tile-slope = sloped along X/Y, foundation-slope = three corners raised */
|
||||||
spr = inclined_base + 2 * GetRailFoundationCorner(f) + ((ti->tileh == SLOPE_SW || ti->tileh == SLOPE_NE) ? 1 : 0);
|
spr = inclined_base + 2 * GetRailFoundationCorner(f) + ((ti->tileh == SLOPE_SW || ti->tileh == SLOPE_NE) ? 1 : 0);
|
||||||
}
|
}
|
||||||
AddSortableSpriteToDraw(spr, PAL_NONE, ti->x, ti->y, TILE_SIZE, TILE_SIZE, TILE_HEIGHT - 1, ti->z);
|
static constexpr SpriteBounds bounds{{}, {TILE_SIZE, TILE_SIZE, TILE_HEIGHT - 1}, {}};
|
||||||
|
AddSortableSpriteToDraw(spr, PAL_NONE, *ti, bounds);
|
||||||
OffsetGroundSprite(0, 0);
|
OffsetGroundSprite(0, 0);
|
||||||
} else {
|
} else {
|
||||||
/* inclined foundation */
|
/* inclined foundation */
|
||||||
uint8_t inclined = GetHighestSlopeCorner(ti->tileh) * 2 + (f == FOUNDATION_INCLINED_Y ? 1 : 0);
|
uint8_t inclined = GetHighestSlopeCorner(ti->tileh) * 2 + (f == FOUNDATION_INCLINED_Y ? 1 : 0);
|
||||||
|
|
||||||
AddSortableSpriteToDraw(inclined_base + inclined, PAL_NONE, ti->x, ti->y,
|
SpriteBounds bounds{{}, {1, 1, TILE_HEIGHT}, {}};
|
||||||
f == FOUNDATION_INCLINED_X ? TILE_SIZE : 1,
|
if (f == FOUNDATION_INCLINED_X) bounds.extent.x = TILE_SIZE;
|
||||||
f == FOUNDATION_INCLINED_Y ? TILE_SIZE : 1,
|
if (f == FOUNDATION_INCLINED_Y) bounds.extent.y = TILE_SIZE;
|
||||||
TILE_HEIGHT, ti->z
|
AddSortableSpriteToDraw(inclined_base + inclined, PAL_NONE, *ti, bounds);
|
||||||
);
|
|
||||||
OffsetGroundSprite(0, 0);
|
OffsetGroundSprite(0, 0);
|
||||||
}
|
}
|
||||||
ti->z += ApplyPixelFoundationToSlope(f, ti->tileh);
|
ti->z += ApplyPixelFoundationToSlope(f, ti->tileh);
|
||||||
|
|
|
@ -5002,6 +5002,7 @@ STR_ERROR_FLAT_LAND_REQUIRED :{WHITE}O terren
|
||||||
STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Terreno inclinado na direção errada
|
STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Terreno inclinado na direção errada
|
||||||
STR_ERROR_CAN_T_DO_THIS :{WHITE}Não é possível fazer isto...
|
STR_ERROR_CAN_T_DO_THIS :{WHITE}Não é possível fazer isto...
|
||||||
STR_ERROR_BUILDING_MUST_BE_DEMOLISHED :{WHITE}A construção precisa ser demolida primeiro
|
STR_ERROR_BUILDING_MUST_BE_DEMOLISHED :{WHITE}A construção precisa ser demolida primeiro
|
||||||
|
STR_ERROR_BUILDING_IS_PROTECTED :{WHITE}... construção é protegida
|
||||||
STR_ERROR_CAN_T_CLEAR_THIS_AREA :{WHITE}Não é possível limpar esta área...
|
STR_ERROR_CAN_T_CLEAR_THIS_AREA :{WHITE}Não é possível limpar esta área...
|
||||||
STR_ERROR_SITE_UNSUITABLE :{WHITE}... local não adequado
|
STR_ERROR_SITE_UNSUITABLE :{WHITE}... local não adequado
|
||||||
STR_ERROR_ALREADY_BUILT :{WHITE}... já construído
|
STR_ERROR_ALREADY_BUILT :{WHITE}... já construído
|
||||||
|
|
|
@ -268,6 +268,7 @@ STR_UNITS_YEARS :{NUM}{NBSP}any{
|
||||||
STR_UNITS_PERIODS :{NUM}{NBSP}període{P "" s}
|
STR_UNITS_PERIODS :{NUM}{NBSP}període{P "" s}
|
||||||
|
|
||||||
STR_LIST_SEPARATOR :,{SPACE}
|
STR_LIST_SEPARATOR :,{SPACE}
|
||||||
|
STR_TRUNCATION_ELLIPSIS :...
|
||||||
|
|
||||||
# Common window strings
|
# Common window strings
|
||||||
STR_LIST_FILTER_TITLE :{BLACK}Filtre:
|
STR_LIST_FILTER_TITLE :{BLACK}Filtre:
|
||||||
|
@ -286,7 +287,7 @@ STR_TOOLTIP_CLOSE_WINDOW :{BLACK}Tanca la
|
||||||
STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS :{BLACK}Títol de la finestra: arrossegueu el títol per desplaçar la finestra.
|
STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS :{BLACK}Títol de la finestra: arrossegueu el títol per desplaçar la finestra.
|
||||||
STR_TOOLTIP_SHADE :{BLACK}Ombra de la finestra: mostra només la barra de títol.
|
STR_TOOLTIP_SHADE :{BLACK}Ombra de la finestra: mostra només la barra de títol.
|
||||||
STR_TOOLTIP_DEBUG :{BLACK}Mostra la informació de depuració NewGRF
|
STR_TOOLTIP_DEBUG :{BLACK}Mostra la informació de depuració NewGRF
|
||||||
STR_TOOLTIP_DEFSIZE :{BLACK}Redimensiona la finestra a la mida predeterminada. Ctrl+Clic desa la mida actual com a predeterminada.
|
STR_TOOLTIP_DEFSIZE :{BLACK}Redimensiona la finestra a la mida predeterminada. Amb Ctrl+Clic, es desa la mida actual com a predeterminada. Amb Ctrl+doble clic, es restableix als valors per defecte.
|
||||||
STR_TOOLTIP_STICKY :{BLACK}Marca aquesta finestra com a no eliminable per la tecla «Tanca totes les finestres». Ctrl+Clic per desar també l'estat predeterminat.
|
STR_TOOLTIP_STICKY :{BLACK}Marca aquesta finestra com a no eliminable per la tecla «Tanca totes les finestres». Ctrl+Clic per desar també l'estat predeterminat.
|
||||||
STR_TOOLTIP_RESIZE :{BLACK}Clica i arrossega per redimensionar aquesta finestra
|
STR_TOOLTIP_RESIZE :{BLACK}Clica i arrossega per redimensionar aquesta finestra
|
||||||
STR_TOOLTIP_TOGGLE_LARGE_SMALL_WINDOW :{BLACK}Commuta entre la mida gran i petita de la finestra
|
STR_TOOLTIP_TOGGLE_LARGE_SMALL_WINDOW :{BLACK}Commuta entre la mida gran i petita de la finestra
|
||||||
|
@ -1108,7 +1109,7 @@ STR_GAME_OPTIONS_BASE_MUSIC_DESCRIPTION_TOOLTIP :Informació add
|
||||||
STR_GAME_OPTIONS_ONLINE_CONTENT :Descarrega contingut
|
STR_GAME_OPTIONS_ONLINE_CONTENT :Descarrega contingut
|
||||||
STR_GAME_OPTIONS_ONLINE_CONTENT_TOOLTIP :Comprova si hi ha continguts nous o actualitzats per a descarregar.
|
STR_GAME_OPTIONS_ONLINE_CONTENT_TOOLTIP :Comprova si hi ha continguts nous o actualitzats per a descarregar.
|
||||||
|
|
||||||
STR_GAME_OPTIONS_SOCIAL_PLUGINS_NONE :{LTBLUE}(no s'han instal·lat complements per a interactuar amb plataformes socials)
|
STR_GAME_OPTIONS_SOCIAL_PLUGINS_NONE :(no s'han instal·lat complements per a interactuar amb plataformes socials)
|
||||||
|
|
||||||
STR_GAME_OPTIONS_SOCIAL_PLUGIN_TITLE :{STRING} ({STRING})
|
STR_GAME_OPTIONS_SOCIAL_PLUGIN_TITLE :{STRING} ({STRING})
|
||||||
STR_GAME_OPTIONS_SOCIAL_PLUGIN_PLATFORM :Plataforma:
|
STR_GAME_OPTIONS_SOCIAL_PLUGIN_PLATFORM :Plataforma:
|
||||||
|
@ -1226,7 +1227,7 @@ STR_CITY_APPROVAL_PERMISSIVE :Permissiva (les
|
||||||
STR_WARNING_NO_SUITABLE_AI :{WHITE}No hi ha cap IA disponible...{}Podeu descarregar-ne a través del «Contingut en línia».
|
STR_WARNING_NO_SUITABLE_AI :{WHITE}No hi ha cap IA disponible...{}Podeu descarregar-ne a través del «Contingut en línia».
|
||||||
|
|
||||||
# Settings tree in the Game Options window
|
# Settings tree in the Game Options window
|
||||||
STR_CONFIG_SETTING_FILTER_TITLE :{G=Masculin}{BLACK}Filtre:
|
STR_CONFIG_SETTING_FILTER_TITLE :{G=Masculin}Filtre:
|
||||||
STR_CONFIG_SETTING_EXPAND_ALL :Desplega-ho tot
|
STR_CONFIG_SETTING_EXPAND_ALL :Desplega-ho tot
|
||||||
STR_CONFIG_SETTING_COLLAPSE_ALL :Plega-ho tot
|
STR_CONFIG_SETTING_COLLAPSE_ALL :Plega-ho tot
|
||||||
STR_CONFIG_SETTING_RESET_ALL :Restableix tots els valors
|
STR_CONFIG_SETTING_RESET_ALL :Restableix tots els valors
|
||||||
|
@ -1302,6 +1303,9 @@ STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :Tipus d'interè
|
||||||
STR_CONFIG_SETTING_RUNNING_COSTS :Costos d'utilització: {STRING}
|
STR_CONFIG_SETTING_RUNNING_COSTS :Costos d'utilització: {STRING}
|
||||||
STR_CONFIG_SETTING_RUNNING_COSTS_HELPTEXT :Fixa el nivell de manteniment i els costos d'utilització dels vehicles i infraestructures
|
STR_CONFIG_SETTING_RUNNING_COSTS_HELPTEXT :Fixa el nivell de manteniment i els costos d'utilització dels vehicles i infraestructures
|
||||||
###length 3
|
###length 3
|
||||||
|
STR_CONFIG_SETTING_RUNNING_COSTS_LOW :Baix
|
||||||
|
STR_CONFIG_SETTING_RUNNING_COSTS_MEDIUM :Mitjà
|
||||||
|
STR_CONFIG_SETTING_RUNNING_COSTS_HIGH :Alt
|
||||||
|
|
||||||
STR_CONFIG_SETTING_CONSTRUCTION_SPEED :Ritme de construcció: {STRING}
|
STR_CONFIG_SETTING_CONSTRUCTION_SPEED :Ritme de construcció: {STRING}
|
||||||
STR_CONFIG_SETTING_CONSTRUCTION_SPEED_HELPTEXT :Limita la quantitat d'accions de construcció per part de les IA
|
STR_CONFIG_SETTING_CONSTRUCTION_SPEED_HELPTEXT :Limita la quantitat d'accions de construcció per part de les IA
|
||||||
|
@ -1324,6 +1328,9 @@ STR_CONFIG_SETTING_SUBSIDY_DURATION_DISABLED :Sense subsidis
|
||||||
STR_CONFIG_SETTING_CONSTRUCTION_COSTS :Costos de construcció: {STRING}
|
STR_CONFIG_SETTING_CONSTRUCTION_COSTS :Costos de construcció: {STRING}
|
||||||
STR_CONFIG_SETTING_CONSTRUCTION_COSTS_HELPTEXT :Fixa el nivell de construcció i els preus de compra
|
STR_CONFIG_SETTING_CONSTRUCTION_COSTS_HELPTEXT :Fixa el nivell de construcció i els preus de compra
|
||||||
###length 3
|
###length 3
|
||||||
|
STR_CONFIG_SETTING_CONSTRUCTION_COSTS_LOW :Baix
|
||||||
|
STR_CONFIG_SETTING_CONSTRUCTION_COSTS_MEDIUM :Mitjà
|
||||||
|
STR_CONFIG_SETTING_CONSTRUCTION_COSTS_HIGH :Alt
|
||||||
|
|
||||||
STR_CONFIG_SETTING_RECESSIONS :Recessions: {STRING}
|
STR_CONFIG_SETTING_RECESSIONS :Recessions: {STRING}
|
||||||
STR_CONFIG_SETTING_RECESSIONS_HELPTEXT :Si està activat, poden haver recessions periòdicament. Durant una recessió, tota la producció és significativament més baixa, tornant al nivell previ quan s'acabi el període de recessió.
|
STR_CONFIG_SETTING_RECESSIONS_HELPTEXT :Si està activat, poden haver recessions periòdicament. Durant una recessió, tota la producció és significativament més baixa, tornant al nivell previ quan s'acabi el període de recessió.
|
||||||
|
@ -2079,9 +2086,9 @@ STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :La classe de c
|
||||||
STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT :Mode de distribució per altres classes de càrrega: {STRING}
|
STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT :Mode de distribució per altres classes de càrrega: {STRING}
|
||||||
STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :"Asimètric" vol dir que quantitats arbitràries de càrrega poden ser enviades en qualsevol sentit. "Manual" significa que no s'aplicarà cap distribució automàtica a aquestes càrregues.
|
STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :"Asimètric" vol dir que quantitats arbitràries de càrrega poden ser enviades en qualsevol sentit. "Manual" significa que no s'aplicarà cap distribució automàtica a aquestes càrregues.
|
||||||
###length 3
|
###length 3
|
||||||
STR_CONFIG_SETTING_DISTRIBUTION_MANUAL :manual
|
STR_CONFIG_SETTING_DISTRIBUTION_MANUAL :Manual
|
||||||
STR_CONFIG_SETTING_DISTRIBUTION_ASYMMETRIC :asimètric
|
STR_CONFIG_SETTING_DISTRIBUTION_ASYMMETRIC :Asimètric
|
||||||
STR_CONFIG_SETTING_DISTRIBUTION_SYMMETRIC :simètric
|
STR_CONFIG_SETTING_DISTRIBUTION_SYMMETRIC :Simètric
|
||||||
|
|
||||||
STR_CONFIG_SETTING_LINKGRAPH_ACCURACY :Precisió de la distribució: {STRING}
|
STR_CONFIG_SETTING_LINKGRAPH_ACCURACY :Precisió de la distribució: {STRING}
|
||||||
STR_CONFIG_SETTING_LINKGRAPH_ACCURACY_HELPTEXT :Com més alt el valor indicat, més temps de processador requerirà el càlcul del graf de distribució. Si requereix massa temps podeu notar ralentització. Si indiqueu un valor baix, però, la distribució serà poc acurada, i us podeu trobar que la càrrega no és enviada als llocs que espereu.
|
STR_CONFIG_SETTING_LINKGRAPH_ACCURACY_HELPTEXT :Com més alt el valor indicat, més temps de processador requerirà el càlcul del graf de distribució. Si requereix massa temps podeu notar ralentització. Si indiqueu un valor baix, però, la distribució serà poc acurada, i us podeu trobar que la càrrega no és enviada als llocs que espereu.
|
||||||
|
@ -2331,16 +2338,19 @@ STR_FACE_SIMPLE_TOOLTIP :{BLACK}Selecci
|
||||||
STR_FACE_LOAD :{BLACK}Carrega
|
STR_FACE_LOAD :{BLACK}Carrega
|
||||||
STR_FACE_LOAD_TOOLTIP :{BLACK}Carrega la cara preferida
|
STR_FACE_LOAD_TOOLTIP :{BLACK}Carrega la cara preferida
|
||||||
STR_FACE_LOAD_DONE :{WHITE}S'ha carregat la cara personalitzada des de l'arxiu de configuració de l'OpenTTD.
|
STR_FACE_LOAD_DONE :{WHITE}S'ha carregat la cara personalitzada des de l'arxiu de configuració de l'OpenTTD.
|
||||||
STR_FACE_FACECODE :{BLACK}Número de la cara
|
STR_FACE_FACECODE :{BLACK}Codi de la cara
|
||||||
STR_FACE_FACECODE_TOOLTIP :{BLACK}Veure i/o assigna el número de la cara del president
|
STR_FACE_FACECODE_TOOLTIP :{BLACK}Veure i/o assigna el codi de la cara del president
|
||||||
STR_FACE_FACECODE_CAPTION :{WHITE}Veure i/o assigna el número de la cara del president
|
STR_FACE_FACECODE_CAPTION :{WHITE}Veure i/o assigna el codi de la cara del president
|
||||||
STR_FACE_FACECODE_SET :{WHITE}El número de la nova cara ha estat assignat
|
STR_FACE_FACECODE_SET :{WHITE}S'ha assignat el codi de la nova cara del president.
|
||||||
STR_FACE_FACECODE_ERR :{WHITE}No s'ha pogut assignar el número de cara del president - ha de ser un nombre entre 0 i 4,294,967,295!
|
STR_FACE_FACECODE_ERR :{WHITE}No s'ha pogut assignar el codi de cara del president - ha de ser una etiqueta i nombre vàlids.
|
||||||
STR_FACE_SAVE :{BLACK}Desa
|
STR_FACE_SAVE :{BLACK}Desa
|
||||||
STR_FACE_SAVE_TOOLTIP :{BLACK}Desa la cara preferida
|
STR_FACE_SAVE_TOOLTIP :{BLACK}Desa la cara preferida
|
||||||
STR_FACE_SAVE_DONE :{WHITE}Es desarà aquesta cara personalitzada a l'arxiu de configuració de l'OpenTTD.
|
STR_FACE_SAVE_DONE :{WHITE}Es desarà aquesta cara personalitzada a l'arxiu de configuració de l'OpenTTD.
|
||||||
|
STR_FACE_SETTING_TOGGLE :{STRING} {ORANGE}{STRING}
|
||||||
|
STR_FACE_SETTING_NUMERIC :{STRING} {ORANGE}{NUM} / {NUM}
|
||||||
STR_FACE_YES :Sí
|
STR_FACE_YES :Sí
|
||||||
STR_FACE_NO :No
|
STR_FACE_NO :No
|
||||||
|
STR_FACE_STYLE :Estil:
|
||||||
STR_FACE_HAIR :Cabell:
|
STR_FACE_HAIR :Cabell:
|
||||||
STR_FACE_EYEBROWS :Celles:
|
STR_FACE_EYEBROWS :Celles:
|
||||||
STR_FACE_EYECOLOUR :Color dels ulls:
|
STR_FACE_EYECOLOUR :Color dels ulls:
|
||||||
|
@ -2813,6 +2823,10 @@ STR_PICKER_MODE_USED_TOOLTIP :Commuta entre m
|
||||||
STR_PICKER_MODE_SAVED :Desats
|
STR_PICKER_MODE_SAVED :Desats
|
||||||
STR_PICKER_MODE_SAVED_TOOLTIP :Commuta entre mostrar tots o bé només els elements desats.
|
STR_PICKER_MODE_SAVED_TOOLTIP :Commuta entre mostrar tots o bé només els elements desats.
|
||||||
|
|
||||||
|
STR_PICKER_PREVIEW_SHRINK :‒
|
||||||
|
STR_PICKER_PREVIEW_SHRINK_TOOLTIP :Redueix l'alçària de les vistes prèvies. Amb Ctrl+clic, es redueix fins al mínim.
|
||||||
|
STR_PICKER_PREVIEW_EXPAND :+
|
||||||
|
STR_PICKER_PREVIEW_EXPAND_TOOLTIP :Augmenta l'alçària de les vistes prèvies. Amb Ctrl+clic, s'augmenta fins al màxim.
|
||||||
|
|
||||||
STR_PICKER_STATION_CLASS_TOOLTIP :Trieu quina classe d'estació voleu veure.
|
STR_PICKER_STATION_CLASS_TOOLTIP :Trieu quina classe d'estació voleu veure.
|
||||||
STR_PICKER_STATION_TYPE_TOOLTIP :Trieu quin tipus d'estació voleu construir. Amb Ctrl+clic, s'afegeix o es trau l'element de la llista de desats.
|
STR_PICKER_STATION_TYPE_TOOLTIP :Trieu quin tipus d'estació voleu construir. Amb Ctrl+clic, s'afegeix o es trau l'element de la llista de desats.
|
||||||
|
@ -3053,6 +3067,11 @@ STR_FOUND_TOWN_INITIAL_SIZE_TOOLTIP :{BLACK}Seleccio
|
||||||
STR_FOUND_TOWN_CITY :{BLACK}Ciutat
|
STR_FOUND_TOWN_CITY :{BLACK}Ciutat
|
||||||
STR_FOUND_TOWN_CITY_TOOLTIP :{BLACK}Les ciutats creixen més ràpid que els pobles{}Depenent de la configuració, són més grans quan es funden
|
STR_FOUND_TOWN_CITY_TOOLTIP :{BLACK}Les ciutats creixen més ràpid que els pobles{}Depenent de la configuració, són més grans quan es funden
|
||||||
|
|
||||||
|
STR_FOUND_TOWN_EXPAND_MODE :{YELLOW}Expansió de la població:
|
||||||
|
STR_FOUND_TOWN_EXPAND_BUILDINGS :Edificis
|
||||||
|
STR_FOUND_TOWN_EXPAND_BUILDINGS_TOOLTIP :Augmenta el nombre d'edificis de les poblacions.
|
||||||
|
STR_FOUND_TOWN_EXPAND_ROADS :Carreteres
|
||||||
|
STR_FOUND_TOWN_EXPAND_ROADS_TOOLTIP :Augmenta el nombre de carreteres de la població.
|
||||||
|
|
||||||
STR_FOUND_TOWN_ROAD_LAYOUT :{YELLOW}Disposició de les carreteres de la població:
|
STR_FOUND_TOWN_ROAD_LAYOUT :{YELLOW}Disposició de les carreteres de la població:
|
||||||
STR_FOUND_TOWN_SELECT_LAYOUT_TOOLTIP :{BLACK}Selecciona la disposició de les carreteres utilitzades per a aquesta població
|
STR_FOUND_TOWN_SELECT_LAYOUT_TOOLTIP :{BLACK}Selecciona la disposició de les carreteres utilitzades per a aquesta població
|
||||||
|
@ -3677,6 +3696,10 @@ STR_TOWN_VIEW_RENAME_TOOLTIP :{BLACK}Canvia e
|
||||||
|
|
||||||
STR_TOWN_VIEW_EXPAND_BUTTON :{BLACK}Eixampla
|
STR_TOWN_VIEW_EXPAND_BUTTON :{BLACK}Eixampla
|
||||||
STR_TOWN_VIEW_EXPAND_TOOLTIP :{BLACK}Incrementa la mida de la població
|
STR_TOWN_VIEW_EXPAND_TOOLTIP :{BLACK}Incrementa la mida de la població
|
||||||
|
STR_TOWN_VIEW_EXPAND_BUILDINGS_BUTTON :{BLACK}Expandeix els edificis
|
||||||
|
STR_TOWN_VIEW_EXPAND_BUILDINGS_TOOLTIP :{BLACK}Augmenta el nombre d'edificis de la població.
|
||||||
|
STR_TOWN_VIEW_EXPAND_ROADS_BUTTON :{BLACK}Expandeix les carreteres
|
||||||
|
STR_TOWN_VIEW_EXPAND_ROADS_TOOLTIP :{BLACK}Augmenta el nombre de carreteres de la població.
|
||||||
STR_TOWN_VIEW_DELETE_BUTTON :{BLACK}Esborra
|
STR_TOWN_VIEW_DELETE_BUTTON :{BLACK}Esborra
|
||||||
STR_TOWN_VIEW_DELETE_TOOLTIP :{BLACK}Esborra totalment aquesta població
|
STR_TOWN_VIEW_DELETE_TOOLTIP :{BLACK}Esborra totalment aquesta població
|
||||||
|
|
||||||
|
@ -4415,10 +4438,10 @@ STR_VEHICLE_VIEW_SHIP_ORDERS_TOOLTIP :{BLACK}Mostra l
|
||||||
STR_VEHICLE_VIEW_AIRCRAFT_ORDERS_TOOLTIP :{BLACK}Mostra les ordres de l'avió. Ctrl+Clic per mostrar l'horari de l'avió
|
STR_VEHICLE_VIEW_AIRCRAFT_ORDERS_TOOLTIP :{BLACK}Mostra les ordres de l'avió. Ctrl+Clic per mostrar l'horari de l'avió
|
||||||
|
|
||||||
###length VEHICLE_TYPES
|
###length VEHICLE_TYPES
|
||||||
STR_VEHICLE_VIEW_TRAIN_SHOW_DETAILS_TOOLTIP :{BLACK}Mostra els detalls del tren
|
STR_VEHICLE_VIEW_TRAIN_SHOW_DETAILS_TOOLTIP :{BLACK}Mostra els detalls del tren. Amb Ctrl+clic, es mostra el grup del tren.
|
||||||
STR_VEHICLE_VIEW_ROAD_VEHICLE_SHOW_DETAILS_TOOLTIP :{BLACK}Mostra els detalls del vehicle
|
STR_VEHICLE_VIEW_ROAD_VEHICLE_SHOW_DETAILS_TOOLTIP :{BLACK}Mostra els detalls del vehicle. Amb Ctrl+clic, es mostra el grup del vehicle.
|
||||||
STR_VEHICLE_VIEW_SHIP_SHOW_DETAILS_TOOLTIP :{BLACK}Mostra els detalls del vaixell
|
STR_VEHICLE_VIEW_SHIP_SHOW_DETAILS_TOOLTIP :{BLACK}Mostra els detalls del vaixell. Amb Ctrl+clic, es mostra el grup del vaixell.
|
||||||
STR_VEHICLE_VIEW_AIRCRAFT_SHOW_DETAILS_TOOLTIP :{BLACK}Mostra els detalls de l'avió
|
STR_VEHICLE_VIEW_AIRCRAFT_SHOW_DETAILS_TOOLTIP :{BLACK}Mostra els detalls de l'aeronau. Amb Ctrl+clic, es mostra el grup de l'aeronau.
|
||||||
|
|
||||||
###length VEHICLE_TYPES
|
###length VEHICLE_TYPES
|
||||||
STR_VEHICLE_VIEW_TRAIN_STATUS_START_STOP_TOOLTIP :{BLACK}Acció actual del tren - Feu clic per parar-lo o engegar-lo.
|
STR_VEHICLE_VIEW_TRAIN_STATUS_START_STOP_TOOLTIP :{BLACK}Acció actual del tren - Feu clic per parar-lo o engegar-lo.
|
||||||
|
@ -4742,14 +4765,15 @@ STR_TIMETABLE_TOOLTIP :{BLACK}Horari -
|
||||||
STR_TIMETABLE_NO_TRAVEL :Sense viatge
|
STR_TIMETABLE_NO_TRAVEL :Sense viatge
|
||||||
STR_TIMETABLE_NOT_TIMETABLEABLE :Viatge (automàtic; programat per la següent ordre manual)
|
STR_TIMETABLE_NOT_TIMETABLEABLE :Viatge (automàtic; programat per la següent ordre manual)
|
||||||
STR_TIMETABLE_TRAVEL_NOT_TIMETABLED :Viatge (fora d'horari)
|
STR_TIMETABLE_TRAVEL_NOT_TIMETABLED :Viatge (fora d'horari)
|
||||||
|
STR_TIMETABLE_TRAVEL_NOT_TIMETABLED_SPEED :Viatja (sense horari) com a molt a {VELOCITY}
|
||||||
STR_TIMETABLE_TRAVEL_FOR :Viatge a {STRING}
|
STR_TIMETABLE_TRAVEL_FOR :Viatge a {STRING}
|
||||||
STR_TIMETABLE_TRAVEL_FOR_SPEED :Viatja durant {STRING} com a molt a {VELOCITY}
|
STR_TIMETABLE_TRAVEL_FOR_SPEED :Viatja durant {STRING} com a molt a {VELOCITY}
|
||||||
STR_TIMETABLE_TRAVEL_FOR_ESTIMATED :Viatja (durant {STRING}, sense horari)
|
STR_TIMETABLE_TRAVEL_FOR_ESTIMATED :Viatja (durant {STRING}, sense horari)
|
||||||
STR_TIMETABLE_TRAVEL_FOR_SPEED_ESTIMATED :Viatja (durant {STRING}, sense horari) com a molt a {VELOCITY}
|
STR_TIMETABLE_TRAVEL_FOR_SPEED_ESTIMATED :Viatja (durant {STRING}, sense horari) com a molt a {VELOCITY}
|
||||||
STR_TIMETABLE_STAY_FOR_ESTIMATED :{SPACE}(quedar-s'hi durant {STRING}, sense horari)
|
STR_TIMETABLE_STAY_FOR_ESTIMATED :{SPACE}(quedar-s'hi durant {STRING}, sense horari)
|
||||||
STR_TIMETABLE_AND_TRAVEL_FOR_ESTIMATED :{SPACE}(viatja durant {STRING}, sense horari)
|
STR_TIMETABLE_AND_TRAVEL_FOR_ESTIMATED :{SPACE}(viatja durant {STRING}, sense horari)
|
||||||
STR_TIMETABLE_STAY_FOR :i estigues {STRING}
|
STR_TIMETABLE_STAY_FOR :{SPACE}i estigues {STRING}
|
||||||
STR_TIMETABLE_AND_TRAVEL_FOR :i viatge per {STRING}
|
STR_TIMETABLE_AND_TRAVEL_FOR :{SPACE}i viatja durant {STRING}
|
||||||
|
|
||||||
STR_TIMETABLE_APPROX_TIME :{BLACK}L'horari trigara aproximadament {STRING} a completar-se.
|
STR_TIMETABLE_APPROX_TIME :{BLACK}L'horari trigara aproximadament {STRING} a completar-se.
|
||||||
STR_TIMETABLE_TOTAL_TIME :{BLACK}L'horari tardarà {STRING} a complir-se
|
STR_TIMETABLE_TOTAL_TIME :{BLACK}L'horari tardarà {STRING} a complir-se
|
||||||
|
@ -5897,3 +5921,11 @@ STR_SHIP :{BLACK}{SHIP}
|
||||||
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
|
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
|
||||||
|
|
||||||
STR_BADGE_NAME_LIST :{STRING}: {GOLD}{STRING}
|
STR_BADGE_NAME_LIST :{STRING}: {GOLD}{STRING}
|
||||||
|
STR_BADGE_CONFIG_MENU_TOOLTIP :Obre la configuració d'insígnies
|
||||||
|
STR_BADGE_CONFIG_RESET :Restableix
|
||||||
|
STR_BADGE_CONFIG_ICONS :{WHITE}Icones d'insígnies
|
||||||
|
STR_BADGE_CONFIG_FILTERS :{WHITE}Filtres d'insígnies
|
||||||
|
STR_BADGE_CONFIG_PREVIEW :Imatge de previsualització
|
||||||
|
STR_BADGE_CONFIG_NAME :Nom
|
||||||
|
STR_BADGE_FILTER_ANY_LABEL :Qualsevol {STRING}
|
||||||
|
STR_BADGE_FILTER_IS_LABEL :{STRING} és {STRING}
|
||||||
|
|
|
@ -5001,6 +5001,7 @@ STR_ERROR_FLAT_LAND_REQUIRED :{WHITE}Tarvitaa
|
||||||
STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Maa viettää väärään suuntaan.
|
STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Maa viettää väärään suuntaan.
|
||||||
STR_ERROR_CAN_T_DO_THIS :{WHITE}Ei onnistu...
|
STR_ERROR_CAN_T_DO_THIS :{WHITE}Ei onnistu...
|
||||||
STR_ERROR_BUILDING_MUST_BE_DEMOLISHED :{WHITE}Rakennus täytyy purkaa ensin.
|
STR_ERROR_BUILDING_MUST_BE_DEMOLISHED :{WHITE}Rakennus täytyy purkaa ensin.
|
||||||
|
STR_ERROR_BUILDING_IS_PROTECTED :{WHITE}… rakennus on suojattu
|
||||||
STR_ERROR_CAN_T_CLEAR_THIS_AREA :{WHITE}Aluetta ei voi tyhjentää...
|
STR_ERROR_CAN_T_CLEAR_THIS_AREA :{WHITE}Aluetta ei voi tyhjentää...
|
||||||
STR_ERROR_SITE_UNSUITABLE :{WHITE}... maasto on sopimaton
|
STR_ERROR_SITE_UNSUITABLE :{WHITE}... maasto on sopimaton
|
||||||
STR_ERROR_ALREADY_BUILT :{WHITE}... se on jo rakennettu
|
STR_ERROR_ALREADY_BUILT :{WHITE}... se on jo rakennettu
|
||||||
|
|
|
@ -5102,6 +5102,7 @@ STR_ERROR_FLAT_LAND_REQUIRED :{WHITE}Απαι
|
||||||
STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Το έδαφος έχει λάθος κλίση
|
STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Το έδαφος έχει λάθος κλίση
|
||||||
STR_ERROR_CAN_T_DO_THIS :{WHITE}Αυτό δεν γίνεται...
|
STR_ERROR_CAN_T_DO_THIS :{WHITE}Αυτό δεν γίνεται...
|
||||||
STR_ERROR_BUILDING_MUST_BE_DEMOLISHED :{WHITE}Το κτίριο πρέπει πρώτα να κατεδαφιστεί
|
STR_ERROR_BUILDING_MUST_BE_DEMOLISHED :{WHITE}Το κτίριο πρέπει πρώτα να κατεδαφιστεί
|
||||||
|
STR_ERROR_BUILDING_IS_PROTECTED :{WHITE}... το κτίριο προστατεύεται
|
||||||
STR_ERROR_CAN_T_CLEAR_THIS_AREA :{WHITE}Είναι αδύνατο να καθαριστεί αυτή η περιοχή...
|
STR_ERROR_CAN_T_CLEAR_THIS_AREA :{WHITE}Είναι αδύνατο να καθαριστεί αυτή η περιοχή...
|
||||||
STR_ERROR_SITE_UNSUITABLE :{WHITE}... ακατάλληλη περιοχή
|
STR_ERROR_SITE_UNSUITABLE :{WHITE}... ακατάλληλη περιοχή
|
||||||
STR_ERROR_ALREADY_BUILT :{WHITE}... ήδη κατασκευασμένο
|
STR_ERROR_ALREADY_BUILT :{WHITE}... ήδη κατασκευασμένο
|
||||||
|
|
|
@ -330,6 +330,7 @@ STR_UNITS_YEARS :{NUM}{NBSP}év
|
||||||
STR_UNITS_PERIODS :{NUM}{NBSP}időszak
|
STR_UNITS_PERIODS :{NUM}{NBSP}időszak
|
||||||
|
|
||||||
STR_LIST_SEPARATOR :,{SPACE}
|
STR_LIST_SEPARATOR :,{SPACE}
|
||||||
|
STR_TRUNCATION_ELLIPSIS :...
|
||||||
|
|
||||||
# Common window strings
|
# Common window strings
|
||||||
STR_LIST_FILTER_TITLE :{BLACK}Szűrő kifejezés:
|
STR_LIST_FILTER_TITLE :{BLACK}Szűrő kifejezés:
|
||||||
|
|
|
@ -5387,6 +5387,7 @@ STR_ERROR_FLAT_LAND_REQUIRED :{WHITE}Wymagany
|
||||||
STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Teren pochylony w złym kierunku
|
STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Teren pochylony w złym kierunku
|
||||||
STR_ERROR_CAN_T_DO_THIS :{WHITE}Nie można tego zrobić...
|
STR_ERROR_CAN_T_DO_THIS :{WHITE}Nie można tego zrobić...
|
||||||
STR_ERROR_BUILDING_MUST_BE_DEMOLISHED :{WHITE}Należy najpierw zburzyć budynek
|
STR_ERROR_BUILDING_MUST_BE_DEMOLISHED :{WHITE}Należy najpierw zburzyć budynek
|
||||||
|
STR_ERROR_BUILDING_IS_PROTECTED :{WHITE}... budynek jest chroniony
|
||||||
STR_ERROR_CAN_T_CLEAR_THIS_AREA :{WHITE}Nie można wyczyścić terenu...
|
STR_ERROR_CAN_T_CLEAR_THIS_AREA :{WHITE}Nie można wyczyścić terenu...
|
||||||
STR_ERROR_SITE_UNSUITABLE :{WHITE}... nieodpowiednie miejsce
|
STR_ERROR_SITE_UNSUITABLE :{WHITE}... nieodpowiednie miejsce
|
||||||
STR_ERROR_ALREADY_BUILT :{WHITE}... już zbudowano
|
STR_ERROR_ALREADY_BUILT :{WHITE}... już zbudowano
|
||||||
|
|
|
@ -647,7 +647,7 @@ STR_GRAPH_KEY_COMPANY_SELECTION_TOOLTIP :{BLACK}Alternar
|
||||||
|
|
||||||
# Company league window
|
# Company league window
|
||||||
STR_COMPANY_LEAGUE_TABLE_CAPTION :{WHITE}Classificação de Empresas
|
STR_COMPANY_LEAGUE_TABLE_CAPTION :{WHITE}Classificação de Empresas
|
||||||
STR_COMPANY_LEAGUE_COMPANY_NAME :{ORANGE}{COMPANY} {BLACK}{COMPANY_NUM} '{STRING}'
|
STR_COMPANY_LEAGUE_COMPANY_NAME :{ORANGE}{COMPANY} {BLACK}{COMPANY_NUM} "{STRING}"
|
||||||
STR_COMPANY_LEAGUE_COMPANY_RANK :{YELLOW}#{NUM}
|
STR_COMPANY_LEAGUE_COMPANY_RANK :{YELLOW}#{NUM}
|
||||||
STR_COMPANY_LEAGUE_PERFORMANCE_TITLE_ENGINEER :Engenheiro
|
STR_COMPANY_LEAGUE_PERFORMANCE_TITLE_ENGINEER :Engenheiro
|
||||||
STR_COMPANY_LEAGUE_PERFORMANCE_TITLE_TRAFFIC_MANAGER :Gestor de Tráfego
|
STR_COMPANY_LEAGUE_PERFORMANCE_TITLE_TRAFFIC_MANAGER :Gestor de Tráfego
|
||||||
|
@ -5002,6 +5002,7 @@ STR_ERROR_FLAT_LAND_REQUIRED :{WHITE}É neces
|
||||||
STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Terreno inclinado na direcção incorrecta
|
STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Terreno inclinado na direcção incorrecta
|
||||||
STR_ERROR_CAN_T_DO_THIS :{WHITE}Não é possível fazer isto...
|
STR_ERROR_CAN_T_DO_THIS :{WHITE}Não é possível fazer isto...
|
||||||
STR_ERROR_BUILDING_MUST_BE_DEMOLISHED :{WHITE}O edifício deve ser demolido primeiro
|
STR_ERROR_BUILDING_MUST_BE_DEMOLISHED :{WHITE}O edifício deve ser demolido primeiro
|
||||||
|
STR_ERROR_BUILDING_IS_PROTECTED :{WHITE}... o edifício está protegido
|
||||||
STR_ERROR_CAN_T_CLEAR_THIS_AREA :{WHITE}Não é possível limpar esta área...
|
STR_ERROR_CAN_T_CLEAR_THIS_AREA :{WHITE}Não é possível limpar esta área...
|
||||||
STR_ERROR_SITE_UNSUITABLE :{WHITE}... sítio inadequado
|
STR_ERROR_SITE_UNSUITABLE :{WHITE}... sítio inadequado
|
||||||
STR_ERROR_ALREADY_BUILT :{WHITE}... já está construído
|
STR_ERROR_ALREADY_BUILT :{WHITE}... já está construído
|
||||||
|
|
|
@ -5188,6 +5188,7 @@ STR_ERROR_FLAT_LAND_REQUIRED :{WHITE}Необ
|
||||||
STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Неверный уклон земли
|
STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Неверный уклон земли
|
||||||
STR_ERROR_CAN_T_DO_THIS :{WHITE}Это невозможно...
|
STR_ERROR_CAN_T_DO_THIS :{WHITE}Это невозможно...
|
||||||
STR_ERROR_BUILDING_MUST_BE_DEMOLISHED :{WHITE}Сначала снесите здания
|
STR_ERROR_BUILDING_MUST_BE_DEMOLISHED :{WHITE}Сначала снесите здания
|
||||||
|
STR_ERROR_BUILDING_IS_PROTECTED :{WHITE}... это здание защищено от изменений
|
||||||
STR_ERROR_CAN_T_CLEAR_THIS_AREA :{WHITE}Невозможно расчистить данный участок...
|
STR_ERROR_CAN_T_CLEAR_THIS_AREA :{WHITE}Невозможно расчистить данный участок...
|
||||||
STR_ERROR_SITE_UNSUITABLE :{WHITE}... неподходящее место
|
STR_ERROR_SITE_UNSUITABLE :{WHITE}... неподходящее место
|
||||||
STR_ERROR_ALREADY_BUILT :{WHITE}... уже построено
|
STR_ERROR_ALREADY_BUILT :{WHITE}... уже построено
|
||||||
|
|
|
@ -5001,6 +5001,7 @@ STR_ERROR_FLAT_LAND_REQUIRED :{WHITE}需要
|
||||||
STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}地面斜坡方向不對
|
STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}地面斜坡方向不對
|
||||||
STR_ERROR_CAN_T_DO_THIS :{WHITE}不能執行以下動作...
|
STR_ERROR_CAN_T_DO_THIS :{WHITE}不能執行以下動作...
|
||||||
STR_ERROR_BUILDING_MUST_BE_DEMOLISHED :{WHITE}必須先摧毀建築物
|
STR_ERROR_BUILDING_MUST_BE_DEMOLISHED :{WHITE}必須先摧毀建築物
|
||||||
|
STR_ERROR_BUILDING_IS_PROTECTED :{WHITE}……建築物受到保護
|
||||||
STR_ERROR_CAN_T_CLEAR_THIS_AREA :{WHITE}不能清除這個地段...
|
STR_ERROR_CAN_T_CLEAR_THIS_AREA :{WHITE}不能清除這個地段...
|
||||||
STR_ERROR_SITE_UNSUITABLE :{WHITE}... 地點不適合
|
STR_ERROR_SITE_UNSUITABLE :{WHITE}... 地點不適合
|
||||||
STR_ERROR_ALREADY_BUILT :{WHITE}……經已建成
|
STR_ERROR_ALREADY_BUILT :{WHITE}……經已建成
|
||||||
|
|
|
@ -90,12 +90,12 @@ static ChangeInfoResult StationChangeInfo(uint first, uint last, int prop, ByteR
|
||||||
|
|
||||||
/* no relative bounding box support */
|
/* no relative bounding box support */
|
||||||
DrawTileSeqStruct &dtss = tmp_layout.emplace_back();
|
DrawTileSeqStruct &dtss = tmp_layout.emplace_back();
|
||||||
dtss.delta_x = delta_x;
|
dtss.origin.x = delta_x;
|
||||||
dtss.delta_y = buf.ReadByte();
|
dtss.origin.y = buf.ReadByte();
|
||||||
dtss.delta_z = buf.ReadByte();
|
dtss.origin.z = buf.ReadByte();
|
||||||
dtss.size_x = buf.ReadByte();
|
dtss.extent.x = buf.ReadByte();
|
||||||
dtss.size_y = buf.ReadByte();
|
dtss.extent.y = buf.ReadByte();
|
||||||
dtss.size_z = buf.ReadByte();
|
dtss.extent.z = buf.ReadByte();
|
||||||
|
|
||||||
ReadSpriteLayoutSprite(buf, false, true, false, GSF_STATIONS, &dtss.image);
|
ReadSpriteLayoutSprite(buf, false, true, false, GSF_STATIONS, &dtss.image);
|
||||||
/* On error, bail out immediately. Temporary GRF data was already freed */
|
/* On error, bail out immediately. Temporary GRF data was already freed */
|
||||||
|
|
|
@ -207,15 +207,15 @@ bool ReadSpriteLayout(ByteReader &buf, uint num_building_sprites, bool use_cur_s
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
seq->delta_x = buf.ReadByte();
|
seq->origin.x = buf.ReadByte();
|
||||||
seq->delta_y = buf.ReadByte();
|
seq->origin.y = buf.ReadByte();
|
||||||
|
|
||||||
if (!no_z_position) seq->delta_z = buf.ReadByte();
|
if (!no_z_position) seq->origin.z = buf.ReadByte();
|
||||||
|
|
||||||
if (seq->IsParentSprite()) {
|
if (seq->IsParentSprite()) {
|
||||||
seq->size_x = buf.ReadByte();
|
seq->extent.x = buf.ReadByte();
|
||||||
seq->size_y = buf.ReadByte();
|
seq->extent.y = buf.ReadByte();
|
||||||
seq->size_z = buf.ReadByte();
|
seq->extent.z = buf.ReadByte();
|
||||||
}
|
}
|
||||||
|
|
||||||
ReadSpriteLayoutRegisters(buf, flags, seq->IsParentSprite(), dts, i + 1);
|
ReadSpriteLayoutRegisters(buf, flags, seq->IsParentSprite(), dts, i + 1);
|
||||||
|
|
|
@ -609,7 +609,7 @@ SpriteLayoutProcessor::SpriteLayoutProcessor(const NewGRFSpriteLayout &raw_layou
|
||||||
* Also include the groundsprite into the sequence for easier processing. */
|
* Also include the groundsprite into the sequence for easier processing. */
|
||||||
DrawTileSeqStruct © = this->result_seq.emplace_back();
|
DrawTileSeqStruct © = this->result_seq.emplace_back();
|
||||||
copy.image = this->raw_layout->ground;
|
copy.image = this->raw_layout->ground;
|
||||||
copy.delta_z = static_cast<int8_t>(0x80);
|
copy.origin.z = static_cast<int8_t>(0x80);
|
||||||
|
|
||||||
this->result_seq.insert(this->result_seq.end(), this->raw_layout->seq.begin(), this->raw_layout->seq.end());
|
this->result_seq.insert(this->result_seq.end(), this->raw_layout->seq.begin(), this->raw_layout->seq.end());
|
||||||
|
|
||||||
|
@ -692,13 +692,13 @@ void SpriteLayoutProcessor::ProcessRegisters(const ResolverObject &object, uint8
|
||||||
|
|
||||||
if (result.IsParentSprite()) {
|
if (result.IsParentSprite()) {
|
||||||
if (flags & TLF_BB_XY_OFFSET) {
|
if (flags & TLF_BB_XY_OFFSET) {
|
||||||
result.delta_x += object.GetRegister(regs->delta.parent[0]);
|
result.origin.x += object.GetRegister(regs->delta.parent[0]);
|
||||||
result.delta_y += object.GetRegister(regs->delta.parent[1]);
|
result.origin.y += object.GetRegister(regs->delta.parent[1]);
|
||||||
}
|
}
|
||||||
if (flags & TLF_BB_Z_OFFSET) result.delta_z += object.GetRegister(regs->delta.parent[2]);
|
if (flags & TLF_BB_Z_OFFSET) result.origin.z += object.GetRegister(regs->delta.parent[2]);
|
||||||
} else {
|
} else {
|
||||||
if (flags & TLF_CHILD_X_OFFSET) result.delta_x += object.GetRegister(regs->delta.child[0]);
|
if (flags & TLF_CHILD_X_OFFSET) result.origin.x += object.GetRegister(regs->delta.child[0]);
|
||||||
if (flags & TLF_CHILD_Y_OFFSET) result.delta_y += object.GetRegister(regs->delta.child[1]);
|
if (flags & TLF_CHILD_Y_OFFSET) result.origin.y += object.GetRegister(regs->delta.child[1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -476,13 +476,7 @@ static void DrawTile_Object(TileInfo *ti)
|
||||||
|
|
||||||
if (!IsInvisibilitySet(TO_STRUCTURES)) {
|
if (!IsInvisibilitySet(TO_STRUCTURES)) {
|
||||||
for (const DrawTileSeqStruct &dtss : dts->GetSequence()) {
|
for (const DrawTileSeqStruct &dtss : dts->GetSequence()) {
|
||||||
AddSortableSpriteToDraw(
|
AddSortableSpriteToDraw(dtss.image.sprite, palette, *ti, dtss, IsTransparencySet(TO_STRUCTURES));
|
||||||
dtss.image.sprite, palette,
|
|
||||||
ti->x + dtss.delta_x, ti->y + dtss.delta_y,
|
|
||||||
dtss.size_x, dtss.size_y,
|
|
||||||
dtss.size_z, ti->z + dtss.delta_z,
|
|
||||||
IsTransparencySet(TO_STRUCTURES)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1899,7 +1899,7 @@ static void DrawSingleSignal(TileIndex tile, const RailTypeInfo *rti, Track trac
|
||||||
sprite += type * 16 + variant * 64 + image * 2 + condition + (type > SIGTYPE_LAST_NOPBS ? 64 : 0);
|
sprite += type * 16 + variant * 64 + image * 2 + condition + (type > SIGTYPE_LAST_NOPBS ? 64 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
AddSortableSpriteToDraw(sprite, PAL_NONE, x, y, 1, 1, BB_HEIGHT_UNDER_BRIDGE, GetSaveSlopeZ(x, y, track));
|
AddSortableSpriteToDraw(sprite, PAL_NONE, x, y, GetSaveSlopeZ(x, y, track), {{}, {1, 1, BB_HEIGHT_UNDER_BRIDGE}, {}});
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t _drawtile_track_palette;
|
static uint32_t _drawtile_track_palette;
|
||||||
|
@ -1907,12 +1907,11 @@ static uint32_t _drawtile_track_palette;
|
||||||
|
|
||||||
|
|
||||||
/** Offsets for drawing fences */
|
/** Offsets for drawing fences */
|
||||||
struct FenceOffset {
|
struct FenceOffset : SpriteBounds {
|
||||||
Corner height_ref; //!< Corner to use height offset from.
|
Corner height_ref; ///< Corner to use height offset from.
|
||||||
int x_offs; //!< Bounding box X offset.
|
|
||||||
int y_offs; //!< Bounding box Y offset.
|
constexpr FenceOffset(Corner height_ref, int8_t origin_x, int8_t origin_y, uint8_t extent_x, uint8_t extent_y) :
|
||||||
int x_size; //!< Bounding box X size.
|
SpriteBounds({origin_x, origin_y, 0}, {extent_x, extent_y, 4}, {}), height_ref(height_ref) {}
|
||||||
int y_size; //!< Bounding box Y size.
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Offsets for drawing fences */
|
/** Offsets for drawing fences */
|
||||||
|
@ -1948,12 +1947,7 @@ static void DrawTrackFence(const TileInfo *ti, SpriteID base_image, uint num_spr
|
||||||
if (_fence_offsets[rfo].height_ref != CORNER_INVALID) {
|
if (_fence_offsets[rfo].height_ref != CORNER_INVALID) {
|
||||||
z += GetSlopePixelZInCorner(RemoveHalftileSlope(ti->tileh), _fence_offsets[rfo].height_ref);
|
z += GetSlopePixelZInCorner(RemoveHalftileSlope(ti->tileh), _fence_offsets[rfo].height_ref);
|
||||||
}
|
}
|
||||||
AddSortableSpriteToDraw(base_image + (rfo % num_sprites), _drawtile_track_palette,
|
AddSortableSpriteToDraw(base_image + (rfo % num_sprites), _drawtile_track_palette, ti->x, ti->y, z, _fence_offsets[rfo]);
|
||||||
ti->x + _fence_offsets[rfo].x_offs,
|
|
||||||
ti->y + _fence_offsets[rfo].y_offs,
|
|
||||||
_fence_offsets[rfo].x_size,
|
|
||||||
_fence_offsets[rfo].y_size,
|
|
||||||
4, z);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1418,7 +1418,7 @@ void DrawRoadTypeCatenary(const TileInfo *ti, RoadType rt, RoadBits rb)
|
||||||
* For tiles with OWNER_TOWN or OWNER_NONE, recolour CC to grey as a neutral colour. */
|
* For tiles with OWNER_TOWN or OWNER_NONE, recolour CC to grey as a neutral colour. */
|
||||||
Owner owner = GetRoadOwner(ti->tile, GetRoadTramType(rt));
|
Owner owner = GetRoadOwner(ti->tile, GetRoadTramType(rt));
|
||||||
PaletteID pal = (owner == OWNER_NONE || owner == OWNER_TOWN ? GetColourPalette(COLOUR_GREY) : GetCompanyPalette(owner));
|
PaletteID pal = (owner == OWNER_NONE || owner == OWNER_TOWN ? GetColourPalette(COLOUR_GREY) : GetCompanyPalette(owner));
|
||||||
int z_wires = (ti->tileh == SLOPE_FLAT ? 0 : TILE_HEIGHT) + BB_HEIGHT_UNDER_BRIDGE;
|
uint8_t z_wires = (ti->tileh == SLOPE_FLAT ? 0 : TILE_HEIGHT) + BB_HEIGHT_UNDER_BRIDGE;
|
||||||
if (back != 0) {
|
if (back != 0) {
|
||||||
/* The "back" sprite contains the west, north and east pillars.
|
/* The "back" sprite contains the west, north and east pillars.
|
||||||
* We cut the sprite at 3/8 of the west/east edges to create 3 sprites.
|
* We cut the sprite at 3/8 of the west/east edges to create 3 sprites.
|
||||||
|
@ -1427,13 +1427,16 @@ void DrawRoadTypeCatenary(const TileInfo *ti, RoadType rt, RoadBits rb)
|
||||||
static const SubSprite west = { -INF, -INF, -12, INF };
|
static const SubSprite west = { -INF, -INF, -12, INF };
|
||||||
static const SubSprite north = { -12, -INF, 12, INF };
|
static const SubSprite north = { -12, -INF, 12, INF };
|
||||||
static const SubSprite east = { 12, -INF, INF, INF };
|
static const SubSprite east = { 12, -INF, INF, INF };
|
||||||
AddSortableSpriteToDraw(back, pal, ti->x, ti->y, 16, 1, z_wires, ti->z, IsTransparencySet(TO_CATENARY), 15, 0, GetSlopePixelZInCorner(ti->tileh, CORNER_W), &west);
|
int8_t west_z = GetSlopePixelZInCorner(ti->tileh, CORNER_W);
|
||||||
AddSortableSpriteToDraw(back, pal, ti->x, ti->y, 1, 1, z_wires, ti->z, IsTransparencySet(TO_CATENARY), 0, 0, GetSlopePixelZInCorner(ti->tileh, CORNER_N), &north);
|
int8_t north_z = GetSlopePixelZInCorner(ti->tileh, CORNER_N);
|
||||||
AddSortableSpriteToDraw(back, pal, ti->x, ti->y, 1, 16, z_wires, ti->z, IsTransparencySet(TO_CATENARY), 0, 15, GetSlopePixelZInCorner(ti->tileh, CORNER_E), &east);
|
int8_t east_z = GetSlopePixelZInCorner(ti->tileh, CORNER_E);
|
||||||
|
AddSortableSpriteToDraw(back, pal, *ti, {{15, 0, west_z}, {1, 1, z_wires}, {-15, 0, static_cast<int8_t>(-west_z)}}, IsTransparencySet(TO_CATENARY), &west);
|
||||||
|
AddSortableSpriteToDraw(back, pal, *ti, {{0, 0, north_z}, {1, 1, z_wires}, {0, 0, static_cast<int8_t>(-north_z)}}, IsTransparencySet(TO_CATENARY), &north);
|
||||||
|
AddSortableSpriteToDraw(back, pal, *ti, {{0, 15, east_z}, {1, 1, z_wires}, {0, -15, static_cast<int8_t>(-east_z)}}, IsTransparencySet(TO_CATENARY), &east);
|
||||||
}
|
}
|
||||||
if (front != 0) {
|
if (front != 0) {
|
||||||
/* Draw the "front" sprite (containing south pillar and wires) at a Z height that is both above the vehicles and above the "back" pillars. */
|
/* Draw the "front" sprite (containing south pillar and wires) at a Z height that is both above the vehicles and above the "back" pillars. */
|
||||||
AddSortableSpriteToDraw(front, pal, ti->x, ti->y, 16, 16, z_wires + 1, ti->z, IsTransparencySet(TO_CATENARY), 0, 0, z_wires);
|
AddSortableSpriteToDraw(front, pal, *ti, {{0, 0, static_cast<int8_t>(z_wires)}, {TILE_SIZE, TILE_SIZE, 1}, {0, 0, static_cast<int8_t>(-z_wires)}}, IsTransparencySet(TO_CATENARY));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1487,13 +1490,13 @@ void DrawRoadCatenary(const TileInfo *ti)
|
||||||
* @param h the height of the sprite to draw
|
* @param h the height of the sprite to draw
|
||||||
* @param transparent whether the sprite should be transparent (used for roadside trees)
|
* @param transparent whether the sprite should be transparent (used for roadside trees)
|
||||||
*/
|
*/
|
||||||
static void DrawRoadDetail(SpriteID img, const TileInfo *ti, int dx, int dy, int h, bool transparent)
|
static void DrawRoadDetail(SpriteID img, const TileInfo *ti, int8_t dx, int8_t dy, uint8_t h, bool transparent)
|
||||||
{
|
{
|
||||||
int x = ti->x | dx;
|
int x = ti->x | dx;
|
||||||
int y = ti->y | dy;
|
int y = ti->y | dy;
|
||||||
int z = ti->z;
|
int z = ti->z;
|
||||||
if (ti->tileh != SLOPE_FLAT) z = GetSlopePixelZ(x, y);
|
if (ti->tileh != SLOPE_FLAT) z = GetSlopePixelZ(x, y);
|
||||||
AddSortableSpriteToDraw(img, PAL_NONE, x, y, 2, 2, h, z, transparent);
|
AddSortableSpriteToDraw(img, PAL_NONE, ti->x, ti->y, z, {{dx, dy, 0}, {2, 2, h}, {}}, transparent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -405,29 +405,56 @@ void RoadVehicle::MarkDirty()
|
||||||
|
|
||||||
void RoadVehicle::UpdateDeltaXY()
|
void RoadVehicle::UpdateDeltaXY()
|
||||||
{
|
{
|
||||||
static const int8_t _delta_xy_table[8][10] = {
|
/* Set common defaults. */
|
||||||
/* y_extent, x_extent, y_offs, x_offs, y_bb_offs, x_bb_offs, y_extent_shorten, x_extent_shorten, y_bb_offs_shorten, x_bb_offs_shorten */
|
this->bounds = {{-1, -1, 0}, {3, 3, 6}, {}};
|
||||||
{3, 3, -1, -1, 0, 0, -1, -1, -1, -1}, // N
|
|
||||||
{3, 7, -1, -3, 0, -1, 0, -1, 0, 0}, // NE
|
if (!IsDiagonalDirection(this->direction)) {
|
||||||
{3, 3, -1, -1, 0, 0, 1, -1, 1, -1}, // E
|
static const Point _sign_table[] = {
|
||||||
{7, 3, -3, -1, -1, 0, 0, 0, 1, 0}, // SE
|
/* x, y */
|
||||||
{3, 3, -1, -1, 0, 0, 1, 1, 1, 1}, // S
|
{-1, -1}, // DIR_N
|
||||||
{3, 7, -1, -3, 0, -1, 0, 0, 0, 1}, // SW
|
{-1, 1}, // DIR_E
|
||||||
{3, 3, -1, -1, 0, 0, -1, 1, -1, 1}, // W
|
{ 1, 1}, // DIR_S
|
||||||
{7, 3, -3, -1, -1, 0, -1, 0, 0, 0}, // NW
|
{ 1, -1}, // DIR_W
|
||||||
};
|
};
|
||||||
|
|
||||||
int shorten = VEHICLE_LENGTH - this->gcache.cached_veh_length;
|
int half_shorten = (VEHICLE_LENGTH - this->gcache.cached_veh_length) / 2;
|
||||||
if (!IsDiagonalDirection(this->direction)) shorten >>= 1;
|
|
||||||
|
|
||||||
const int8_t *bb = _delta_xy_table[this->direction];
|
/* For all straight directions, move the bound box to the centre of the vehicle, but keep the size. */
|
||||||
this->x_bb_offs = bb[5] + bb[9] * shorten;
|
this->bounds.offset.x -= half_shorten * _sign_table[DirToDiagDir(this->direction)].x;
|
||||||
this->y_bb_offs = bb[4] + bb[8] * shorten;;
|
this->bounds.offset.y -= half_shorten * _sign_table[DirToDiagDir(this->direction)].y;
|
||||||
this->x_offs = bb[3];
|
} else {
|
||||||
this->y_offs = bb[2];
|
/* Unlike trains, road vehicles do not have their offsets moved to the centre. */
|
||||||
this->x_extent = bb[1] + bb[7] * shorten;
|
switch (this->direction) {
|
||||||
this->y_extent = bb[0] + bb[6] * shorten;
|
/* Shorten southern corner of the bounding box according the vehicle length. */
|
||||||
this->z_extent = 6;
|
case DIR_NE:
|
||||||
|
this->bounds.origin.x = -3;
|
||||||
|
this->bounds.extent.x = this->gcache.cached_veh_length;
|
||||||
|
this->bounds.offset.x = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DIR_NW:
|
||||||
|
this->bounds.origin.y = -3;
|
||||||
|
this->bounds.extent.y = this->gcache.cached_veh_length;
|
||||||
|
this->bounds.offset.y = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Move northern corner of the bounding box down according to vehicle length. */
|
||||||
|
case DIR_SW:
|
||||||
|
this->bounds.origin.x = -3 + (VEHICLE_LENGTH - this->gcache.cached_veh_length);
|
||||||
|
this->bounds.extent.x = this->gcache.cached_veh_length;
|
||||||
|
this->bounds.offset.x = 1 - (VEHICLE_LENGTH - this->gcache.cached_veh_length);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DIR_SE:
|
||||||
|
this->bounds.origin.y = -3 + (VEHICLE_LENGTH - this->gcache.cached_veh_length);
|
||||||
|
this->bounds.extent.y = this->gcache.cached_veh_length;
|
||||||
|
this->bounds.offset.y = 1 - (VEHICLE_LENGTH - this->gcache.cached_veh_length);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
NOT_REACHED();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -330,32 +330,26 @@ TileIndex Ship::GetOrderStationLocation(StationID station)
|
||||||
|
|
||||||
void Ship::UpdateDeltaXY()
|
void Ship::UpdateDeltaXY()
|
||||||
{
|
{
|
||||||
static const int8_t _delta_xy_table[8][4] = {
|
static constexpr SpriteBounds ship_bounds[DIR_END] = {
|
||||||
/* y_extent, x_extent, y_offs, x_offs */
|
{{ -3, -3, 0}, { 6, 6, 6}, {}}, // N
|
||||||
{ 6, 6, -3, -3}, // N
|
{{-16, -3, 0}, {32, 6, 6}, {}}, // NE
|
||||||
{ 6, 32, -3, -16}, // NE
|
{{ -3, -3, 0}, { 6, 6, 6}, {}}, // E
|
||||||
{ 6, 6, -3, -3}, // E
|
{{ -3, -16, 0}, { 6, 32, 6}, {}}, // SE
|
||||||
{32, 6, -16, -3}, // SE
|
{{ -3, -3, 0}, { 6, 6, 6}, {}}, // S
|
||||||
{ 6, 6, -3, -3}, // S
|
{{-16, -3, 0}, {32, 6, 6}, {}}, // SW
|
||||||
{ 6, 32, -3, -16}, // SW
|
{{ -3, -3, 0}, { 6, 6, 6}, {}}, // W
|
||||||
{ 6, 6, -3, -3}, // W
|
{{ -3, -16, 0}, { 6, 32, 6}, {}}, // NW
|
||||||
{32, 6, -16, -3}, // NW
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const int8_t *bb = _delta_xy_table[this->rotation];
|
this->bounds = ship_bounds[this->rotation];
|
||||||
this->x_offs = bb[3];
|
|
||||||
this->y_offs = bb[2];
|
|
||||||
this->x_extent = bb[1];
|
|
||||||
this->y_extent = bb[0];
|
|
||||||
this->z_extent = 6;
|
|
||||||
|
|
||||||
if (this->direction != this->rotation) {
|
if (this->direction != this->rotation) {
|
||||||
/* If we are rotating, then it is possible the ship was moved to its next position. In that
|
/* If we are rotating, then it is possible the ship was moved to its next position. In that
|
||||||
* case, because we are still showing the old direction, the ship will appear to glitch sideways
|
* case, because we are still showing the old direction, the ship will appear to glitch sideways
|
||||||
* slightly. We can work around this by applying an additional offset to make the ship appear
|
* slightly. We can work around this by applying an additional offset to make the ship appear
|
||||||
* where it was before it moved. */
|
* where it was before it moved. */
|
||||||
this->x_offs -= this->x_pos - this->rotation_x_pos;
|
this->bounds.origin.x -= this->x_pos - this->rotation_x_pos;
|
||||||
this->y_offs -= this->y_pos - this->rotation_y_pos;
|
this->bounds.origin.y -= this->y_pos - this->rotation_y_pos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,16 +54,11 @@ void DrawCommonTileSeq(const TileInfo *ti, const DrawTileSprites *dts, Transpare
|
||||||
|
|
||||||
if (dtss.IsParentSprite()) {
|
if (dtss.IsParentSprite()) {
|
||||||
parent_sprite_encountered = true;
|
parent_sprite_encountered = true;
|
||||||
AddSortableSpriteToDraw(
|
AddSortableSpriteToDraw(image, pal, *ti, dtss, !HasBit(image, SPRITE_MODIFIER_OPAQUE) && IsTransparencySet(to)
|
||||||
image, pal,
|
|
||||||
ti->x + dtss.delta_x, ti->y + dtss.delta_y,
|
|
||||||
dtss.size_x, dtss.size_y,
|
|
||||||
dtss.size_z, ti->z + dtss.delta_z,
|
|
||||||
!HasBit(image, SPRITE_MODIFIER_OPAQUE) && IsTransparencySet(to)
|
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
int offs_x = child_offset_is_unsigned ? static_cast<uint8_t>(dtss.delta_x) : dtss.delta_x;
|
int offs_x = child_offset_is_unsigned ? static_cast<uint8_t>(dtss.origin.x) : dtss.origin.x;
|
||||||
int offs_y = child_offset_is_unsigned ? static_cast<uint8_t>(dtss.delta_y) : dtss.delta_y;
|
int offs_y = child_offset_is_unsigned ? static_cast<uint8_t>(dtss.origin.y) : dtss.origin.y;
|
||||||
bool transparent = !HasBit(image, SPRITE_MODIFIER_OPAQUE) && IsTransparencySet(to);
|
bool transparent = !HasBit(image, SPRITE_MODIFIER_OPAQUE) && IsTransparencySet(to);
|
||||||
if (parent_sprite_encountered) {
|
if (parent_sprite_encountered) {
|
||||||
AddChildSpriteScreen(image, pal, offs_x, offs_y, transparent);
|
AddChildSpriteScreen(image, pal, offs_x, offs_y, transparent);
|
||||||
|
@ -114,15 +109,15 @@ void DrawCommonTileSeqInGUI(int x, int y, const DrawTileSprites *dts, int32_t or
|
||||||
pal = SpriteLayoutPaletteTransform(image, pal, default_palette);
|
pal = SpriteLayoutPaletteTransform(image, pal, default_palette);
|
||||||
|
|
||||||
if (dtss.IsParentSprite()) {
|
if (dtss.IsParentSprite()) {
|
||||||
Point pt = RemapCoords(dtss.delta_x, dtss.delta_y, dtss.delta_z);
|
Point pt = RemapCoords(dtss.origin.x, dtss.origin.y, dtss.origin.z);
|
||||||
DrawSprite(image, pal, x + UnScaleGUI(pt.x), y + UnScaleGUI(pt.y));
|
DrawSprite(image, pal, x + UnScaleGUI(pt.x), y + UnScaleGUI(pt.y));
|
||||||
|
|
||||||
const Sprite *spr = GetSprite(image & SPRITE_MASK, SpriteType::Normal);
|
const Sprite *spr = GetSprite(image & SPRITE_MASK, SpriteType::Normal);
|
||||||
child_offset.x = UnScaleGUI(pt.x + spr->x_offs);
|
child_offset.x = UnScaleGUI(pt.x + spr->x_offs);
|
||||||
child_offset.y = UnScaleGUI(pt.y + spr->y_offs);
|
child_offset.y = UnScaleGUI(pt.y + spr->y_offs);
|
||||||
} else {
|
} else {
|
||||||
int offs_x = child_offset_is_unsigned ? static_cast<uint8_t>(dtss.delta_x) : dtss.delta_x;
|
int offs_x = child_offset_is_unsigned ? static_cast<uint8_t>(dtss.origin.x) : dtss.origin.x;
|
||||||
int offs_y = child_offset_is_unsigned ? static_cast<uint8_t>(dtss.delta_y) : dtss.delta_y;
|
int offs_y = child_offset_is_unsigned ? static_cast<uint8_t>(dtss.origin.y) : dtss.origin.y;
|
||||||
DrawSprite(image, pal, x + child_offset.x + ScaleSpriteTrad(offs_x), y + child_offset.y + ScaleSpriteTrad(offs_y));
|
DrawSprite(image, pal, x + child_offset.x + ScaleSpriteTrad(offs_x), y + child_offset.y + ScaleSpriteTrad(offs_y));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
32
src/sprite.h
32
src/sprite.h
|
@ -10,28 +10,33 @@
|
||||||
#ifndef SPRITE_H
|
#ifndef SPRITE_H
|
||||||
#define SPRITE_H
|
#define SPRITE_H
|
||||||
|
|
||||||
|
#include "core/geometry_type.hpp"
|
||||||
#include "transparency.h"
|
#include "transparency.h"
|
||||||
|
|
||||||
#include "table/sprites.h"
|
#include "table/sprites.h"
|
||||||
|
|
||||||
|
struct SpriteBounds {
|
||||||
|
PointXyz<int8_t> origin; ///< Position of northern corner within tile.
|
||||||
|
PointXyz<uint8_t> extent; ///< Size of bounding box.
|
||||||
|
PointXyz<int8_t> offset; ///< Relative position of sprite from bounding box.
|
||||||
|
};
|
||||||
|
|
||||||
/* The following describes bunch of sprites to be drawn together in a single 3D
|
/* The following describes bunch of sprites to be drawn together in a single 3D
|
||||||
* bounding box. Used especially for various multi-sprite buildings (like
|
* bounding box. Used especially for various multi-sprite buildings (like
|
||||||
* depots or stations): */
|
* depots or stations): */
|
||||||
|
|
||||||
/** A tile child sprite and palette to draw for stations etc, with 3D bounding box */
|
/** A tile child sprite and palette to draw for stations etc, with 3D bounding box */
|
||||||
struct DrawTileSeqStruct {
|
struct DrawTileSeqStruct : SpriteBounds {
|
||||||
int8_t delta_x = 0;
|
PalSpriteID image;
|
||||||
int8_t delta_y = 0;
|
|
||||||
int8_t delta_z = 0; ///< \c 0x80 identifies child sprites
|
constexpr DrawTileSeqStruct() = default;
|
||||||
uint8_t size_x = 0;
|
constexpr DrawTileSeqStruct(int8_t origin_x, int8_t origin_y, int8_t origin_z, uint8_t extent_x, uint8_t extent_y, uint8_t extent_z, PalSpriteID image) :
|
||||||
uint8_t size_y = 0;
|
SpriteBounds({origin_x, origin_y, origin_z}, {extent_x, extent_y, extent_z}, {}), image(image) {}
|
||||||
uint8_t size_z = 0;
|
|
||||||
PalSpriteID image{};
|
|
||||||
|
|
||||||
/** Check whether this is a parent sprite with a boundingbox. */
|
/** Check whether this is a parent sprite with a boundingbox. */
|
||||||
bool IsParentSprite() const
|
inline bool IsParentSprite() const
|
||||||
{
|
{
|
||||||
return (uint8_t)this->delta_z != 0x80;
|
return static_cast<uint8_t>(this->origin.z) != 0x80;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -69,14 +74,9 @@ struct DrawTileSpriteSpan : DrawTileSprites {
|
||||||
* This structure is the same for both Industries and Houses.
|
* This structure is the same for both Industries and Houses.
|
||||||
* Buildings here reference a general type of construction
|
* Buildings here reference a general type of construction
|
||||||
*/
|
*/
|
||||||
struct DrawBuildingsTileStruct {
|
struct DrawBuildingsTileStruct : SpriteBounds {
|
||||||
PalSpriteID ground;
|
PalSpriteID ground;
|
||||||
PalSpriteID building;
|
PalSpriteID building;
|
||||||
uint8_t subtile_x;
|
|
||||||
uint8_t subtile_y;
|
|
||||||
uint8_t width;
|
|
||||||
uint8_t height;
|
|
||||||
uint8_t dz;
|
|
||||||
uint8_t draw_proc; // this allows to specify a special drawing procedure.
|
uint8_t draw_proc; // this allows to specify a special drawing procedure.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -3184,7 +3184,7 @@ static void DrawTile_Station(TileInfo *ti)
|
||||||
7, 8, 9 // SLOPE_NE, SLOPE_ENW, SLOPE_SEN
|
7, 8, 9 // SLOPE_NE, SLOPE_ENW, SLOPE_SEN
|
||||||
};
|
};
|
||||||
|
|
||||||
AddSortableSpriteToDraw(image + foundation_parts[ti->tileh], PAL_NONE, ti->x, ti->y, 16, 16, 7, ti->z);
|
AddSortableSpriteToDraw(image + foundation_parts[ti->tileh], PAL_NONE, *ti, {{}, {TILE_SIZE, TILE_SIZE, 7}, {}});
|
||||||
} else {
|
} else {
|
||||||
/* Draw simple foundations, built up from 8 possible foundation sprites. */
|
/* Draw simple foundations, built up from 8 possible foundation sprites. */
|
||||||
|
|
||||||
|
@ -3218,7 +3218,7 @@ static void DrawTile_Station(TileInfo *ti)
|
||||||
StartSpriteCombine();
|
StartSpriteCombine();
|
||||||
for (int i = 0; i < 8; i++) {
|
for (int i = 0; i < 8; i++) {
|
||||||
if (HasBit(parts, i)) {
|
if (HasBit(parts, i)) {
|
||||||
AddSortableSpriteToDraw(image + i, PAL_NONE, ti->x, ti->y, 16, 16, 7, ti->z);
|
AddSortableSpriteToDraw(image + i, PAL_NONE, *ti, {{}, {TILE_SIZE, TILE_SIZE, 7}, {}});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EndSpriteCombine();
|
EndSpriteCombine();
|
||||||
|
|
|
@ -313,14 +313,12 @@ enum WireSpriteOffset : uint8_t {
|
||||||
WSO_ENTRANCE_SE,
|
WSO_ENTRANCE_SE,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SortableSpriteStruct {
|
struct SortableSpriteStruct : SpriteBounds {
|
||||||
uint8_t image_offset;
|
uint8_t image_offset;
|
||||||
int8_t x_offset;
|
|
||||||
int8_t y_offset;
|
constexpr SortableSpriteStruct(uint8_t image_offset, const SpriteBounds &bounds) : SpriteBounds(bounds), image_offset(image_offset) {}
|
||||||
int8_t x_size;
|
constexpr SortableSpriteStruct(uint8_t image_offset, int8_t x_offset, int8_t y_offset, uint8_t x_size, uint8_t y_size, uint8_t z_size, int8_t z_offset) :
|
||||||
int8_t y_size;
|
SpriteBounds({x_offset, y_offset, z_offset}, {x_size, y_size, z_size}, {}), image_offset(image_offset) {}
|
||||||
int8_t z_size;
|
|
||||||
int8_t z_offset;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Distance between wire and rail */
|
/** Distance between wire and rail */
|
||||||
|
@ -398,11 +396,17 @@ static const SortableSpriteStruct _rail_catenary_sprite_data_depot[] = {
|
||||||
{ WSO_ENTRANCE_NW, 7, 0, 1, 15, 1, ELRAIL_ELEVATION } //! Wire for NW depot exit
|
{ WSO_ENTRANCE_NW, 7, 0, 1, 15, 1, ELRAIL_ELEVATION } //! Wire for NW depot exit
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In tunnelheads, the bounding box for wires covers nearly the full tile, and is lowered a bit.
|
||||||
|
* ELRAIL_TUNNEL_OFFSET is the difference between visual position and bounding box.
|
||||||
|
*/
|
||||||
|
static const int8_t ELRAIL_TUNNEL_OFFSET = ELRAIL_ELEVATION - BB_Z_SEPARATOR;
|
||||||
|
|
||||||
static const SortableSpriteStruct _rail_catenary_sprite_data_tunnel[] = {
|
static const SortableSpriteStruct _rail_catenary_sprite_data_tunnel[] = {
|
||||||
{ WSO_ENTRANCE_SW, 0, 7, 15, 1, 1, ELRAIL_ELEVATION }, //! Wire for NE tunnel (SW facing exit)
|
{ WSO_ENTRANCE_SW, {{0, 0, BB_Z_SEPARATOR}, {16, 15, 1}, {0, 7, ELRAIL_TUNNEL_OFFSET}} }, //! Wire for NE tunnel (SW facing exit)
|
||||||
{ WSO_ENTRANCE_NW, 7, 0, 1, 15, 1, ELRAIL_ELEVATION }, //! Wire for SE tunnel (NW facing exit)
|
{ WSO_ENTRANCE_NW, {{0, 0, BB_Z_SEPARATOR}, {15, 16, 1}, {7, 0, ELRAIL_TUNNEL_OFFSET}} }, //! Wire for SE tunnel (NW facing exit)
|
||||||
{ WSO_ENTRANCE_NE, 0, 7, 15, 1, 1, ELRAIL_ELEVATION }, //! Wire for SW tunnel (NE facing exit)
|
{ WSO_ENTRANCE_NE, {{0, 0, BB_Z_SEPARATOR}, {16, 15, 1}, {0, 7, ELRAIL_TUNNEL_OFFSET}} }, //! Wire for SW tunnel (NE facing exit)
|
||||||
{ WSO_ENTRANCE_SE, 7, 0, 1, 15, 1, ELRAIL_ELEVATION } //! Wire for NW tunnel (SE facing exit)
|
{ WSO_ENTRANCE_SE, {{0, 0, BB_Z_SEPARATOR}, {15, 16, 1}, {7, 0, ELRAIL_TUNNEL_OFFSET}} } //! Wire for NW tunnel (SE facing exit)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -37,15 +37,15 @@ struct DrawIndustryCoordinates {
|
||||||
* @param p1 palette ID of ground sprite
|
* @param p1 palette ID of ground sprite
|
||||||
* @param s2 sprite ID of building sprite
|
* @param s2 sprite ID of building sprite
|
||||||
* @param p2 palette ID of building sprite
|
* @param p2 palette ID of building sprite
|
||||||
* @param sx coordinate x of the sprite
|
* @param dx The x-position of the sprite within the tile.
|
||||||
* @param sy coordinate y of the sprite
|
* @param dy the y-position of the sprite within the tile.
|
||||||
* @param w width of the sprite
|
* @param sx the x-extent of the sprite.
|
||||||
* @param h height of the sprite
|
* @param sy the y-extent of the sprite.
|
||||||
* @param dz virtual height of the sprite
|
* @param sz the z-extent of the sprite.
|
||||||
* @param p this allows to specify a special drawing procedure.
|
* @param p this allows to specify a special drawing procedure.
|
||||||
* @see DrawBuildingsTileStruct
|
* @see DrawBuildingsTileStruct
|
||||||
*/
|
*/
|
||||||
#define M(s1, p1, s2, p2, sx, sy, w, h, dz, p) { { s1, p1 }, { s2, p2 }, sx, sy, w, h, dz, p }
|
#define M(s1, p1, s2, p2, dx, dy, sx, sy, sz, p) { {{dx, dy, 0}, {sx, sy, sz}, {}}, { s1, p1 }, { s2, p2 }, p}
|
||||||
|
|
||||||
/** Structure for industry tiles drawing */
|
/** Structure for industry tiles drawing */
|
||||||
static const DrawBuildingsTileStruct _industry_draw_tile_data[NEW_INDUSTRYTILEOFFSET * 4] = {
|
static const DrawBuildingsTileStruct _industry_draw_tile_data[NEW_INDUSTRYTILEOFFSET * 4] = {
|
||||||
|
|
|
@ -13,15 +13,15 @@
|
||||||
* @param p1 The first sprite's palette of the building, mostly the ground sprite
|
* @param p1 The first sprite's palette of the building, mostly the ground sprite
|
||||||
* @param s2 The second sprite of the building.
|
* @param s2 The second sprite of the building.
|
||||||
* @param p2 The second sprite's palette of the building.
|
* @param p2 The second sprite's palette of the building.
|
||||||
* @param sx The x-position of the sprite within the tile
|
* @param dx The x-position of the sprite within the tile.
|
||||||
* @param sy the y-position of the sprite within the tile
|
* @param dy the y-position of the sprite within the tile.
|
||||||
* @param w the width of the sprite
|
* @param sx the x-extent of the sprite.
|
||||||
* @param h the height of the sprite
|
* @param sy the y-extent of the sprite.
|
||||||
* @param dz the virtual height of the sprite
|
* @param sz the z-extent of the sprite.
|
||||||
* @param p set to 1 if a lift is present ()
|
* @param p set to 1 if a lift is present ()
|
||||||
* @see DrawBuildingsTileStruct
|
* @see DrawBuildingsTileStruct
|
||||||
*/
|
*/
|
||||||
#define M(s1, p1, s2, p2, sx, sy, w, h, dz, p) { { s1, p1 }, { s2, p2 }, sx, sy, w, h, dz, p}
|
#define M(s1, p1, s2, p2, dx, dy, sx, sy, sz, p) { {{dx, dy, 0}, {sx, sy, sz}, {}}, { s1, p1 }, { s2, p2 }, p}
|
||||||
|
|
||||||
/** structure of houses graphics*/
|
/** structure of houses graphics*/
|
||||||
static const DrawBuildingsTileStruct _town_draw_tile_data[] = {
|
static const DrawBuildingsTileStruct _town_draw_tile_data[] = {
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#ifndef TILE_CMD_H
|
#ifndef TILE_CMD_H
|
||||||
#define TILE_CMD_H
|
#define TILE_CMD_H
|
||||||
|
|
||||||
|
#include "core/geometry_type.hpp"
|
||||||
#include "command_type.h"
|
#include "command_type.h"
|
||||||
#include "vehicle_type.h"
|
#include "vehicle_type.h"
|
||||||
#include "cargo_type.h"
|
#include "cargo_type.h"
|
||||||
|
@ -26,12 +27,9 @@ enum class VehicleEnterTileState : uint8_t {
|
||||||
using VehicleEnterTileStates = EnumBitSet<VehicleEnterTileState, uint8_t>;
|
using VehicleEnterTileStates = EnumBitSet<VehicleEnterTileState, uint8_t>;
|
||||||
|
|
||||||
/** Tile information, used while rendering the tile */
|
/** Tile information, used while rendering the tile */
|
||||||
struct TileInfo {
|
struct TileInfo : PointXyz<int> {
|
||||||
int x; ///< X position of the tile in unit coordinates
|
|
||||||
int y; ///< Y position of the tile in unit coordinates
|
|
||||||
Slope tileh; ///< Slope of the tile
|
Slope tileh; ///< Slope of the tile
|
||||||
TileIndex tile; ///< Tile index
|
TileIndex tile; ///< Tile index
|
||||||
int z; ///< Height
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Tile description for the 'land area information' tool */
|
/** Tile description for the 'land area information' tool */
|
||||||
|
|
|
@ -12,29 +12,29 @@
|
||||||
|
|
||||||
#include "core/strong_typedef_type.hpp"
|
#include "core/strong_typedef_type.hpp"
|
||||||
|
|
||||||
static const uint TILE_SIZE = 16; ///< Tile size in world coordinates.
|
static constexpr uint TILE_SIZE = 16; ///< Tile size in world coordinates.
|
||||||
static const uint TILE_UNIT_MASK = TILE_SIZE - 1; ///< For masking in/out the inner-tile world coordinate units.
|
static constexpr uint TILE_UNIT_MASK = TILE_SIZE - 1; ///< For masking in/out the inner-tile world coordinate units.
|
||||||
static const uint TILE_PIXELS = 32; ///< Pixel distance between tile columns/rows in #ZOOM_BASE.
|
static constexpr uint TILE_PIXELS = 32; ///< Pixel distance between tile columns/rows in #ZOOM_BASE.
|
||||||
static const uint TILE_HEIGHT = 8; ///< Height of a height level in world coordinate AND in pixels in #ZOOM_BASE.
|
static constexpr uint TILE_HEIGHT = 8; ///< Height of a height level in world coordinate AND in pixels in #ZOOM_BASE.
|
||||||
|
|
||||||
static const uint MAX_BUILDING_PIXELS = 200; ///< Maximum height of a building in pixels in #ZOOM_BASE. (Also applies to "bridge buildings" on the bridge floor.)
|
static constexpr uint MAX_BUILDING_PIXELS = 200; ///< Maximum height of a building in pixels in #ZOOM_BASE. (Also applies to "bridge buildings" on the bridge floor.)
|
||||||
static const int MAX_VEHICLE_PIXEL_X = 192; ///< Maximum width of a vehicle in pixels in #ZOOM_BASE.
|
static constexpr int MAX_VEHICLE_PIXEL_X = 192; ///< Maximum width of a vehicle in pixels in #ZOOM_BASE.
|
||||||
static const int MAX_VEHICLE_PIXEL_Y = 96; ///< Maximum height of a vehicle in pixels in #ZOOM_BASE.
|
static constexpr int MAX_VEHICLE_PIXEL_Y = 96; ///< Maximum height of a vehicle in pixels in #ZOOM_BASE.
|
||||||
|
|
||||||
static const uint MAX_TILE_HEIGHT = 255; ///< Maximum allowed tile height
|
static constexpr uint MAX_TILE_HEIGHT = 255; ///< Maximum allowed tile height
|
||||||
|
|
||||||
static const uint MIN_HEIGHTMAP_HEIGHT = 1; ///< Lowest possible peak value for heightmap creation
|
static constexpr uint MIN_HEIGHTMAP_HEIGHT = 1; ///< Lowest possible peak value for heightmap creation
|
||||||
static const uint MIN_CUSTOM_TERRAIN_TYPE = 1; ///< Lowest possible peak value for world generation
|
static constexpr uint MIN_CUSTOM_TERRAIN_TYPE = 1; ///< Lowest possible peak value for world generation
|
||||||
|
|
||||||
static const uint MIN_MAP_HEIGHT_LIMIT = 15; ///< Lower bound of maximum allowed heightlevel (in the construction settings)
|
static constexpr uint MIN_MAP_HEIGHT_LIMIT = 15; ///< Lower bound of maximum allowed heightlevel (in the construction settings)
|
||||||
static const uint MAX_MAP_HEIGHT_LIMIT = MAX_TILE_HEIGHT; ///< Upper bound of maximum allowed heightlevel (in the construction settings)
|
static constexpr uint MAX_MAP_HEIGHT_LIMIT = MAX_TILE_HEIGHT; ///< Upper bound of maximum allowed heightlevel (in the construction settings)
|
||||||
|
|
||||||
static const uint MIN_SNOWLINE_HEIGHT = 2; ///< Minimum snowline height
|
static constexpr uint MIN_SNOWLINE_HEIGHT = 2; ///< Minimum snowline height
|
||||||
static const uint DEF_SNOWLINE_HEIGHT = 10; ///< Default snowline height
|
static constexpr uint DEF_SNOWLINE_HEIGHT = 10; ///< Default snowline height
|
||||||
static const uint MAX_SNOWLINE_HEIGHT = (MAX_TILE_HEIGHT - 2); ///< Maximum allowed snowline height
|
static constexpr uint MAX_SNOWLINE_HEIGHT = (MAX_TILE_HEIGHT - 2); ///< Maximum allowed snowline height
|
||||||
|
|
||||||
static const uint DEF_SNOW_COVERAGE = 40; ///< Default snow coverage.
|
static constexpr uint DEF_SNOW_COVERAGE = 40; ///< Default snow coverage.
|
||||||
static const uint DEF_DESERT_COVERAGE = 50; ///< Default desert coverage.
|
static constexpr uint DEF_DESERT_COVERAGE = 50; ///< Default desert coverage.
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -284,15 +284,7 @@ static void DrawTile_Town(TileInfo *ti)
|
||||||
/* Add a house on top of the ground? */
|
/* Add a house on top of the ground? */
|
||||||
SpriteID image = dcts->building.sprite;
|
SpriteID image = dcts->building.sprite;
|
||||||
if (image != 0) {
|
if (image != 0) {
|
||||||
AddSortableSpriteToDraw(image, dcts->building.pal,
|
AddSortableSpriteToDraw(image, dcts->building.pal, *ti, *dcts, IsTransparencySet(TO_HOUSES));
|
||||||
ti->x + dcts->subtile_x,
|
|
||||||
ti->y + dcts->subtile_y,
|
|
||||||
dcts->width,
|
|
||||||
dcts->height,
|
|
||||||
dcts->dz,
|
|
||||||
ti->z,
|
|
||||||
IsTransparencySet(TO_HOUSES)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (IsTransparencySet(TO_HOUSES)) return;
|
if (IsTransparencySet(TO_HOUSES)) return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1376,7 +1376,7 @@ void DrawHouseInGUI(int x, int y, HouseID house_id, int view)
|
||||||
|
|
||||||
/* Add a house on top of the ground? */
|
/* Add a house on top of the ground? */
|
||||||
if (dcts.building.sprite != 0) {
|
if (dcts.building.sprite != 0) {
|
||||||
Point pt = RemapCoords(dcts.subtile_x, dcts.subtile_y, 0);
|
Point pt = RemapCoords(dcts.origin.x, dcts.origin.y, dcts.origin.z);
|
||||||
DrawSprite(dcts.building.sprite, dcts.building.pal, x + UnScaleGUI(pt.x), y + UnScaleGUI(pt.y));
|
DrawSprite(dcts.building.sprite, dcts.building.pal, x + UnScaleGUI(pt.x), y + UnScaleGUI(pt.y));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1491,13 +1491,7 @@ CommandCost CmdSellRailWagon(DoCommandFlags flags, Vehicle *t, bool sell_chain,
|
||||||
void Train::UpdateDeltaXY()
|
void Train::UpdateDeltaXY()
|
||||||
{
|
{
|
||||||
/* Set common defaults. */
|
/* Set common defaults. */
|
||||||
this->x_offs = -1;
|
this->bounds = {{-1, -1, 0}, {3, 3, 6}, {}};
|
||||||
this->y_offs = -1;
|
|
||||||
this->x_extent = 3;
|
|
||||||
this->y_extent = 3;
|
|
||||||
this->z_extent = 6;
|
|
||||||
this->x_bb_offs = 0;
|
|
||||||
this->y_bb_offs = 0;
|
|
||||||
|
|
||||||
/* Set if flipped and engine is NOT flagged with custom flip handling. */
|
/* Set if flipped and engine is NOT flagged with custom flip handling. */
|
||||||
int flipped = this->flags.Test(VehicleRailFlag::Flipped) && !EngInfo(this->engine_type)->misc_flags.Test(EngineMiscFlag::RailFlips);
|
int flipped = this->flags.Test(VehicleRailFlag::Flipped) && !EngInfo(this->engine_type)->misc_flags.Test(EngineMiscFlag::RailFlips);
|
||||||
|
@ -1508,50 +1502,47 @@ void Train::UpdateDeltaXY()
|
||||||
if (flipped) dir = ReverseDir(dir);
|
if (flipped) dir = ReverseDir(dir);
|
||||||
|
|
||||||
if (!IsDiagonalDirection(dir)) {
|
if (!IsDiagonalDirection(dir)) {
|
||||||
static const int _sign_table[] =
|
static const Point _sign_table[] = {
|
||||||
{
|
|
||||||
/* x, y */
|
/* x, y */
|
||||||
-1, -1, // DIR_N
|
{-1, -1}, // DIR_N
|
||||||
-1, 1, // DIR_E
|
{-1, 1}, // DIR_E
|
||||||
1, 1, // DIR_S
|
{ 1, 1}, // DIR_S
|
||||||
1, -1, // DIR_W
|
{ 1, -1}, // DIR_W
|
||||||
};
|
};
|
||||||
|
|
||||||
int half_shorten = (VEHICLE_LENGTH - this->gcache.cached_veh_length + flipped) / 2;
|
int half_shorten = (VEHICLE_LENGTH - this->gcache.cached_veh_length + flipped) / 2;
|
||||||
|
|
||||||
/* For all straight directions, move the bound box to the centre of the vehicle, but keep the size. */
|
/* For all straight directions, move the bound box to the centre of the vehicle, but keep the size. */
|
||||||
this->x_offs -= half_shorten * _sign_table[dir];
|
this->bounds.offset.x -= half_shorten * _sign_table[DirToDiagDir(dir)].x;
|
||||||
this->y_offs -= half_shorten * _sign_table[dir + 1];
|
this->bounds.offset.y -= half_shorten * _sign_table[DirToDiagDir(dir)].y;
|
||||||
this->x_extent += this->x_bb_offs = half_shorten * _sign_table[dir];
|
|
||||||
this->y_extent += this->y_bb_offs = half_shorten * _sign_table[dir + 1];
|
|
||||||
} else {
|
} else {
|
||||||
switch (dir) {
|
switch (dir) {
|
||||||
/* Shorten southern corner of the bounding box according the vehicle length
|
/* Shorten southern corner of the bounding box according the vehicle length
|
||||||
* and center the bounding box on the vehicle. */
|
* and center the bounding box on the vehicle. */
|
||||||
case DIR_NE:
|
case DIR_NE:
|
||||||
this->x_offs = 1 - (this->gcache.cached_veh_length + 1) / 2 + flip_offs;
|
this->bounds.origin.x = -(this->gcache.cached_veh_length + 1) / 2 + flip_offs;
|
||||||
this->x_extent = this->gcache.cached_veh_length - 1;
|
this->bounds.extent.x = this->gcache.cached_veh_length;
|
||||||
this->x_bb_offs = -1;
|
this->bounds.offset.x = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DIR_NW:
|
case DIR_NW:
|
||||||
this->y_offs = 1 - (this->gcache.cached_veh_length + 1) / 2 + flip_offs;
|
this->bounds.origin.y = -(this->gcache.cached_veh_length + 1) / 2 + flip_offs;
|
||||||
this->y_extent = this->gcache.cached_veh_length - 1;
|
this->bounds.extent.y = this->gcache.cached_veh_length;
|
||||||
this->y_bb_offs = -1;
|
this->bounds.offset.y = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Move northern corner of the bounding box down according to vehicle length
|
/* Move northern corner of the bounding box down according to vehicle length
|
||||||
* and center the bounding box on the vehicle. */
|
* and center the bounding box on the vehicle. */
|
||||||
case DIR_SW:
|
case DIR_SW:
|
||||||
this->x_offs = 1 + (this->gcache.cached_veh_length + 1) / 2 - VEHICLE_LENGTH - flip_offs;
|
this->bounds.origin.x = -(this->gcache.cached_veh_length) / 2 - flip_offs;
|
||||||
this->x_extent = VEHICLE_LENGTH - 1;
|
this->bounds.extent.x = this->gcache.cached_veh_length;
|
||||||
this->x_bb_offs = VEHICLE_LENGTH - this->gcache.cached_veh_length - 1;
|
this->bounds.offset.x = 1 - (VEHICLE_LENGTH - this->gcache.cached_veh_length);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DIR_SE:
|
case DIR_SE:
|
||||||
this->y_offs = 1 + (this->gcache.cached_veh_length + 1) / 2 - VEHICLE_LENGTH - flip_offs;
|
this->bounds.origin.y = -(this->gcache.cached_veh_length) / 2 - flip_offs;
|
||||||
this->y_extent = VEHICLE_LENGTH - 1;
|
this->bounds.extent.y = this->gcache.cached_veh_length;
|
||||||
this->y_bb_offs = VEHICLE_LENGTH - this->gcache.cached_veh_length - 1;
|
this->bounds.offset.y = 1 - (VEHICLE_LENGTH - this->gcache.cached_veh_length);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -635,7 +635,7 @@ CommandCost CmdPlantTree(DoCommandFlags flags, TileIndex tile, TileIndex start_t
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TreeListEnt : PalSpriteID {
|
struct TreeListEnt : PalSpriteID {
|
||||||
uint8_t x, y;
|
int8_t x, y;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void DrawTile_Trees(TileInfo *ti)
|
static void DrawTile_Trees(TileInfo *ti)
|
||||||
|
@ -699,7 +699,8 @@ static void DrawTile_Trees(TileInfo *ti)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AddSortableSpriteToDraw(te[mi].sprite, te[mi].pal, ti->x + te[mi].x, ti->y + te[mi].y, 16 - te[mi].x, 16 - te[mi].y, 0x30, z, IsTransparencySet(TO_TREES), -te[mi].x, -te[mi].y);
|
SpriteBounds bounds{{}, {TILE_SIZE, TILE_SIZE, 48}, {te[mi].x, te[mi].y, 0}};
|
||||||
|
AddSortableSpriteToDraw(te[mi].sprite, te[mi].pal, ti->x, ti->y, z, bounds, IsTransparencySet(TO_TREES));
|
||||||
|
|
||||||
/* replace the removed one with the last one */
|
/* replace the removed one with the last one */
|
||||||
te[mi] = te[trees - 1];
|
te[mi] = te[trees - 1];
|
||||||
|
|
|
@ -1017,10 +1017,10 @@ static CommandCost ClearTile_TunnelBridge(TileIndex tile, DoCommandFlags flags)
|
||||||
* @param h Bounding box size in Y direction
|
* @param h Bounding box size in Y direction
|
||||||
* @param subsprite Optional subsprite for drawing halfpillars
|
* @param subsprite Optional subsprite for drawing halfpillars
|
||||||
*/
|
*/
|
||||||
static inline void DrawPillar(const PalSpriteID *psid, int x, int y, int z, int w, int h, const SubSprite *subsprite)
|
static inline void DrawPillar(const PalSpriteID *psid, int x, int y, int z, uint8_t w, uint8_t h, const SubSprite *subsprite)
|
||||||
{
|
{
|
||||||
static const int PILLAR_Z_OFFSET = TILE_HEIGHT - BRIDGE_Z_START; ///< Start offset of pillar wrt. bridge (downwards)
|
static const int PILLAR_Z_OFFSET = TILE_HEIGHT - BRIDGE_Z_START; ///< Start offset of pillar wrt. bridge (downwards)
|
||||||
AddSortableSpriteToDraw(psid->sprite, psid->pal, x, y, w, h, BB_HEIGHT_UNDER_BRIDGE - PILLAR_Z_OFFSET, z, IsTransparencySet(TO_BRIDGES), 0, 0, -PILLAR_Z_OFFSET, subsprite);
|
AddSortableSpriteToDraw(psid->sprite, psid->pal, x, y, z, {{0, 0, -PILLAR_Z_OFFSET}, {w, h, BB_HEIGHT_UNDER_BRIDGE}, {0, 0, PILLAR_Z_OFFSET}}, IsTransparencySet(TO_BRIDGES), subsprite);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1194,18 +1194,20 @@ static void DrawBridgeRoadBits(TileIndex head_tile, int x, int y, int z, int off
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const uint size_x[6] = { 1, 16, 16, 1, 16, 1 };
|
static constexpr SpriteBounds back_bounds[6] = {
|
||||||
static const uint size_y[6] = { 16, 1, 1, 16, 1, 16 };
|
{{}, {0, TILE_SIZE, 40}, {}},
|
||||||
static const uint front_bb_offset_x[6] = { 15, 0, 0, 15, 0, 15 };
|
{{}, {TILE_SIZE, 0, 40}, {}},
|
||||||
static const uint front_bb_offset_y[6] = { 0, 15, 15, 0, 15, 0 };
|
{{}, {TILE_SIZE, 0, 40}, {}},
|
||||||
|
{{}, {0, TILE_SIZE, 40}, {}},
|
||||||
|
{{}, {TILE_SIZE, 0, 40}, {}},
|
||||||
|
{{}, {0, TILE_SIZE, 40}, {}},
|
||||||
|
};
|
||||||
|
|
||||||
/* The sprites under the vehicles are drawn as SpriteCombine. StartSpriteCombine() has already been called
|
/* The sprites under the vehicles are drawn as SpriteCombine. StartSpriteCombine() has already been called
|
||||||
* The bounding boxes here are the same as for bridge front/roof */
|
* The bounding boxes here are the same as for bridge front/roof */
|
||||||
for (uint i = 0; i < lengthof(seq_back); ++i) {
|
for (uint i = 0; i < lengthof(seq_back); ++i) {
|
||||||
if (seq_back[i] != 0) {
|
if (seq_back[i] != 0) {
|
||||||
AddSortableSpriteToDraw(seq_back[i], PAL_NONE,
|
AddSortableSpriteToDraw(seq_back[i], PAL_NONE, x, y, z, back_bounds[offset], trans_back[i]);
|
||||||
x, y, size_x[offset], size_y[offset], 0x28, z,
|
|
||||||
trans_back[i]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1213,12 +1215,18 @@ static void DrawBridgeRoadBits(TileIndex head_tile, int x, int y, int z, int off
|
||||||
EndSpriteCombine();
|
EndSpriteCombine();
|
||||||
StartSpriteCombine();
|
StartSpriteCombine();
|
||||||
|
|
||||||
|
static constexpr SpriteBounds front_bounds[6] = {
|
||||||
|
{{15, 0, 0}, {0, TILE_SIZE, 40}, {-15, 0, 0}},
|
||||||
|
{{0, 15, 0}, {TILE_SIZE, 0, 40}, {0, -15, 0}},
|
||||||
|
{{0, 15, 0}, {TILE_SIZE, 0, 40}, {0, -15, 0}},
|
||||||
|
{{15, 0, 0}, {0, TILE_SIZE, 40}, {-15, 0, 0}},
|
||||||
|
{{0, 15, 0}, {TILE_SIZE, 0, 40}, {0, -15, 0}},
|
||||||
|
{{15, 0, 0}, {0, TILE_SIZE, 40}, {-15, 0, 0}},
|
||||||
|
};
|
||||||
|
|
||||||
for (uint i = 0; i < lengthof(seq_front); ++i) {
|
for (uint i = 0; i < lengthof(seq_front); ++i) {
|
||||||
if (seq_front[i] != 0) {
|
if (seq_front[i] != 0) {
|
||||||
AddSortableSpriteToDraw(seq_front[i], PAL_NONE,
|
AddSortableSpriteToDraw(seq_front[i], PAL_NONE, x, y, z, front_bounds[offset], trans_front[i]);
|
||||||
x, y, size_x[offset] + front_bb_offset_x[offset], size_y[offset] + front_bb_offset_y[offset], 0x28, z,
|
|
||||||
trans_front[i],
|
|
||||||
front_bb_offset_x[offset], front_bb_offset_y[offset]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1251,15 +1259,35 @@ static void DrawTile_TunnelBridge(TileInfo *ti)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static const int _tunnel_BB[4][12] = {
|
/* Tunnel sprites are positioned at 15,15, but the bounding box covers most of the tile. */
|
||||||
/* tunnnel-roof | Z-separator | tram-catenary
|
static constexpr SpriteBounds roof_bounds[DIAGDIR_END] = {
|
||||||
* w h bb_x bb_y| x y w h |bb_x bb_y w h */
|
{{0, 1, BB_Z_SEPARATOR}, {TILE_SIZE, TILE_SIZE - 1, 1}, {TILE_SIZE - 1, TILE_SIZE - 2, -BB_Z_SEPARATOR}}, // NE
|
||||||
{ 1, 0, -15, -14, 0, 15, 16, 1, 0, 1, 16, 15 }, // NE
|
{{1, 0, BB_Z_SEPARATOR}, {TILE_SIZE - 1, TILE_SIZE, 1}, {TILE_SIZE - 2, TILE_SIZE - 1, -BB_Z_SEPARATOR}}, // SE
|
||||||
{ 0, 1, -14, -15, 15, 0, 1, 16, 1, 0, 15, 16 }, // SE
|
{{0, 1, BB_Z_SEPARATOR}, {TILE_SIZE, TILE_SIZE - 1, 1}, {TILE_SIZE - 1, TILE_SIZE - 2, -BB_Z_SEPARATOR}}, // SW
|
||||||
{ 1, 0, -15, -14, 0, 15, 16, 1, 0, 1, 16, 15 }, // SW
|
{{1, 0, BB_Z_SEPARATOR}, {TILE_SIZE - 1, TILE_SIZE, 1}, {TILE_SIZE - 2, TILE_SIZE - 1, -BB_Z_SEPARATOR}}, // NW
|
||||||
{ 0, 1, -14, -15, 15, 0, 1, 16, 1, 0, 15, 16 }, // NW
|
};
|
||||||
|
|
||||||
|
/* Catenary sprites are positioned at 0,0, with the same bounding box as above. */
|
||||||
|
static constexpr SpriteBounds catenary_bounds[DIAGDIR_END] = {
|
||||||
|
{{0, 1, BB_Z_SEPARATOR}, {TILE_SIZE, TILE_SIZE - 1, 1}, {0, -1, -BB_Z_SEPARATOR}}, // NE
|
||||||
|
{{1, 0, BB_Z_SEPARATOR}, {TILE_SIZE - 1, TILE_SIZE, 1}, {-1, 0, -BB_Z_SEPARATOR}}, // SE
|
||||||
|
{{0, 1, BB_Z_SEPARATOR}, {TILE_SIZE, TILE_SIZE - 1, 1}, {0, -1, -BB_Z_SEPARATOR}}, // SW
|
||||||
|
{{1, 0, BB_Z_SEPARATOR}, {TILE_SIZE - 1, TILE_SIZE, 1}, {-1, 0, -BB_Z_SEPARATOR}}, // NW
|
||||||
|
};
|
||||||
|
|
||||||
|
static constexpr SpriteBounds rear_sep[DIAGDIR_END] = {
|
||||||
|
{{}, {TILE_SIZE, 1, TILE_HEIGHT}, {}}, // NE
|
||||||
|
{{}, {1, TILE_SIZE, TILE_HEIGHT}, {}}, // SE
|
||||||
|
{{}, {TILE_SIZE, 1, TILE_HEIGHT}, {}}, // SW
|
||||||
|
{{}, {1, TILE_SIZE, TILE_HEIGHT}, {}}, // NW
|
||||||
|
};
|
||||||
|
|
||||||
|
static constexpr SpriteBounds front_sep[DIAGDIR_END] = {
|
||||||
|
{{0, TILE_SIZE - 1, 0}, {TILE_SIZE, 1, TILE_HEIGHT}, {}}, // NE
|
||||||
|
{{TILE_SIZE - 1, 0, 0}, {1, TILE_SIZE, TILE_HEIGHT}, {}}, // SE
|
||||||
|
{{0, TILE_SIZE - 1, 0}, {TILE_SIZE, 1, TILE_HEIGHT}, {}}, // SW
|
||||||
|
{{TILE_SIZE - 1, 0, 0}, {1, TILE_SIZE, TILE_HEIGHT}, {}}, // NW
|
||||||
};
|
};
|
||||||
const int *BB_data = _tunnel_BB[tunnelbridge_direction];
|
|
||||||
|
|
||||||
bool catenary = false;
|
bool catenary = false;
|
||||||
|
|
||||||
|
@ -1332,7 +1360,7 @@ static void DrawTile_TunnelBridge(TileInfo *ti)
|
||||||
if (catenary_sprite_base != 0) {
|
if (catenary_sprite_base != 0) {
|
||||||
catenary = true;
|
catenary = true;
|
||||||
StartSpriteCombine();
|
StartSpriteCombine();
|
||||||
AddSortableSpriteToDraw(catenary_sprite_base + tunnelbridge_direction, PAL_NONE, ti->x, ti->y, BB_data[10], BB_data[11], TILE_HEIGHT, ti->z, IsTransparencySet(TO_CATENARY), BB_data[8], BB_data[9], BB_Z_SEPARATOR);
|
AddSortableSpriteToDraw(catenary_sprite_base + tunnelbridge_direction, PAL_NONE, *ti, catenary_bounds[tunnelbridge_direction], IsTransparencySet(TO_CATENARY));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const RailTypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile));
|
const RailTypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile));
|
||||||
|
@ -1364,15 +1392,15 @@ static void DrawTile_TunnelBridge(TileInfo *ti)
|
||||||
|
|
||||||
if (railtype_overlay != 0 && !catenary) StartSpriteCombine();
|
if (railtype_overlay != 0 && !catenary) StartSpriteCombine();
|
||||||
|
|
||||||
AddSortableSpriteToDraw(image + 1, PAL_NONE, ti->x + TILE_SIZE - 1, ti->y + TILE_SIZE - 1, BB_data[0], BB_data[1], TILE_HEIGHT, ti->z, false, BB_data[2], BB_data[3], BB_Z_SEPARATOR);
|
AddSortableSpriteToDraw(image + 1, PAL_NONE, *ti, roof_bounds[tunnelbridge_direction], false);
|
||||||
/* Draw railtype tunnel portal overlay if defined. */
|
/* Draw railtype tunnel portal overlay if defined. */
|
||||||
if (railtype_overlay != 0) AddSortableSpriteToDraw(railtype_overlay + tunnelbridge_direction, PAL_NONE, ti->x + TILE_SIZE - 1, ti->y + TILE_SIZE - 1, BB_data[0], BB_data[1], TILE_HEIGHT, ti->z, false, BB_data[2], BB_data[3], BB_Z_SEPARATOR);
|
if (railtype_overlay != 0) AddSortableSpriteToDraw(railtype_overlay + tunnelbridge_direction, PAL_NONE, *ti, roof_bounds[tunnelbridge_direction], false);
|
||||||
|
|
||||||
if (catenary || railtype_overlay != 0) EndSpriteCombine();
|
if (catenary || railtype_overlay != 0) EndSpriteCombine();
|
||||||
|
|
||||||
/* Add helper BB for sprite sorting that separates the tunnel from things beside of it. */
|
/* Add helper BB for sprite sorting that separates the tunnel from things beside of it. */
|
||||||
AddSortableSpriteToDraw(SPR_EMPTY_BOUNDING_BOX, PAL_NONE, ti->x, ti->y, BB_data[6], BB_data[7], TILE_HEIGHT, ti->z);
|
AddSortableSpriteToDraw(SPR_EMPTY_BOUNDING_BOX, PAL_NONE, *ti, rear_sep[tunnelbridge_direction]);
|
||||||
AddSortableSpriteToDraw(SPR_EMPTY_BOUNDING_BOX, PAL_NONE, ti->x + BB_data[4], ti->y + BB_data[5], BB_data[6], BB_data[7], TILE_HEIGHT, ti->z);
|
AddSortableSpriteToDraw(SPR_EMPTY_BOUNDING_BOX, PAL_NONE, *ti, front_sep[tunnelbridge_direction]);
|
||||||
|
|
||||||
DrawBridgeMiddle(ti);
|
DrawBridgeMiddle(ti);
|
||||||
} else { // IsBridge(ti->tile)
|
} else { // IsBridge(ti->tile)
|
||||||
|
@ -1423,7 +1451,7 @@ static void DrawTile_TunnelBridge(TileInfo *ti)
|
||||||
* it doesn't disappear behind it
|
* it doesn't disappear behind it
|
||||||
*/
|
*/
|
||||||
/* Bridge heads are drawn solid no matter how invisibility/transparency is set */
|
/* Bridge heads are drawn solid no matter how invisibility/transparency is set */
|
||||||
AddSortableSpriteToDraw(psid->sprite, psid->pal, ti->x, ti->y, 16, 16, ti->tileh == SLOPE_FLAT ? 0 : 8, ti->z);
|
AddSortableSpriteToDraw(psid->sprite, psid->pal, *ti, {{}, {TILE_SIZE, TILE_SIZE, static_cast<uint8_t>(ti->tileh == SLOPE_FLAT ? 0 : TILE_HEIGHT)}, {}});
|
||||||
|
|
||||||
if (transport_type == TRANSPORT_ROAD) {
|
if (transport_type == TRANSPORT_ROAD) {
|
||||||
uint offset = tunnelbridge_direction;
|
uint offset = tunnelbridge_direction;
|
||||||
|
@ -1445,9 +1473,9 @@ static void DrawTile_TunnelBridge(TileInfo *ti)
|
||||||
SpriteID surface = GetCustomRailSprite(rti, ti->tile, RTSG_BRIDGE);
|
SpriteID surface = GetCustomRailSprite(rti, ti->tile, RTSG_BRIDGE);
|
||||||
if (surface != 0) {
|
if (surface != 0) {
|
||||||
if (HasBridgeFlatRamp(ti->tileh, DiagDirToAxis(tunnelbridge_direction))) {
|
if (HasBridgeFlatRamp(ti->tileh, DiagDirToAxis(tunnelbridge_direction))) {
|
||||||
AddSortableSpriteToDraw(surface + ((DiagDirToAxis(tunnelbridge_direction) == AXIS_X) ? RTBO_X : RTBO_Y), PAL_NONE, ti->x, ti->y, 16, 16, 0, ti->z + 8);
|
AddSortableSpriteToDraw(surface + ((DiagDirToAxis(tunnelbridge_direction) == AXIS_X) ? RTBO_X : RTBO_Y), PAL_NONE, *ti, {{0, 0, TILE_HEIGHT}, {TILE_SIZE, TILE_SIZE, 0}, {}});
|
||||||
} else {
|
} else {
|
||||||
AddSortableSpriteToDraw(surface + RTBO_SLOPE + tunnelbridge_direction, PAL_NONE, ti->x, ti->y, 16, 16, 8, ti->z);
|
AddSortableSpriteToDraw(surface + RTBO_SLOPE + tunnelbridge_direction, PAL_NONE, *ti, {{}, {TILE_SIZE, TILE_SIZE, TILE_HEIGHT}, {}});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Don't fallback to non-overlay sprite -- the spec states that
|
/* Don't fallback to non-overlay sprite -- the spec states that
|
||||||
|
@ -1460,15 +1488,15 @@ static void DrawTile_TunnelBridge(TileInfo *ti)
|
||||||
if (rti->UsesOverlay()) {
|
if (rti->UsesOverlay()) {
|
||||||
SpriteID overlay = GetCustomRailSprite(rti, ti->tile, RTSG_OVERLAY);
|
SpriteID overlay = GetCustomRailSprite(rti, ti->tile, RTSG_OVERLAY);
|
||||||
if (HasBridgeFlatRamp(ti->tileh, DiagDirToAxis(tunnelbridge_direction))) {
|
if (HasBridgeFlatRamp(ti->tileh, DiagDirToAxis(tunnelbridge_direction))) {
|
||||||
AddSortableSpriteToDraw(overlay + RTO_X + DiagDirToAxis(tunnelbridge_direction), PALETTE_CRASH, ti->x, ti->y, 16, 16, 0, ti->z + 8);
|
AddSortableSpriteToDraw(overlay + RTO_X + DiagDirToAxis(tunnelbridge_direction), PALETTE_CRASH, *ti, {{0, 0, TILE_HEIGHT}, {TILE_SIZE, TILE_SIZE, 0}, {}});
|
||||||
} else {
|
} else {
|
||||||
AddSortableSpriteToDraw(overlay + RTO_SLOPE_NE + tunnelbridge_direction, PALETTE_CRASH, ti->x, ti->y, 16, 16, 8, ti->z);
|
AddSortableSpriteToDraw(overlay + RTO_SLOPE_NE + tunnelbridge_direction, PALETTE_CRASH, *ti, {{}, {TILE_SIZE, TILE_SIZE, TILE_HEIGHT}, {}});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (HasBridgeFlatRamp(ti->tileh, DiagDirToAxis(tunnelbridge_direction))) {
|
if (HasBridgeFlatRamp(ti->tileh, DiagDirToAxis(tunnelbridge_direction))) {
|
||||||
AddSortableSpriteToDraw(DiagDirToAxis(tunnelbridge_direction) == AXIS_X ? rti->base_sprites.single_x : rti->base_sprites.single_y, PALETTE_CRASH, ti->x, ti->y, 16, 16, 0, ti->z + 8);
|
AddSortableSpriteToDraw(DiagDirToAxis(tunnelbridge_direction) == AXIS_X ? rti->base_sprites.single_x : rti->base_sprites.single_y, PALETTE_CRASH, *ti, {{0, 0, TILE_HEIGHT}, {TILE_SIZE, TILE_SIZE, 0}, {}});
|
||||||
} else {
|
} else {
|
||||||
AddSortableSpriteToDraw(rti->base_sprites.single_sloped + tunnelbridge_direction, PALETTE_CRASH, ti->x, ti->y, 16, 16, 8, ti->z);
|
AddSortableSpriteToDraw(rti->base_sprites.single_sloped + tunnelbridge_direction, PALETTE_CRASH, *ti, {{}, {TILE_SIZE, TILE_SIZE, TILE_HEIGHT}, {}});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1578,7 +1606,7 @@ void DrawBridgeMiddle(const TileInfo *ti)
|
||||||
int z = bridge_z - BRIDGE_Z_START;
|
int z = bridge_z - BRIDGE_Z_START;
|
||||||
|
|
||||||
/* Add a bounding box that separates the bridge from things below it. */
|
/* Add a bounding box that separates the bridge from things below it. */
|
||||||
AddSortableSpriteToDraw(SPR_EMPTY_BOUNDING_BOX, PAL_NONE, x, y, 16, 16, 1, bridge_z - TILE_HEIGHT + BB_Z_SEPARATOR);
|
AddSortableSpriteToDraw(SPR_EMPTY_BOUNDING_BOX, PAL_NONE, x, y, bridge_z - TILE_HEIGHT + BB_Z_SEPARATOR, {{}, {TILE_SIZE, TILE_SIZE, 1}, {}});
|
||||||
|
|
||||||
/* Draw Trambits as SpriteCombine */
|
/* Draw Trambits as SpriteCombine */
|
||||||
if (transport_type == TRANSPORT_ROAD || transport_type == TRANSPORT_RAIL) StartSpriteCombine();
|
if (transport_type == TRANSPORT_ROAD || transport_type == TRANSPORT_RAIL) StartSpriteCombine();
|
||||||
|
@ -1586,9 +1614,9 @@ void DrawBridgeMiddle(const TileInfo *ti)
|
||||||
/* Draw floor and far part of bridge*/
|
/* Draw floor and far part of bridge*/
|
||||||
if (!IsInvisibilitySet(TO_BRIDGES)) {
|
if (!IsInvisibilitySet(TO_BRIDGES)) {
|
||||||
if (axis == AXIS_X) {
|
if (axis == AXIS_X) {
|
||||||
AddSortableSpriteToDraw(psid->sprite, psid->pal, x, y, 16, 1, 0x28, z, IsTransparencySet(TO_BRIDGES), 0, 0, BRIDGE_Z_START);
|
AddSortableSpriteToDraw(psid->sprite, psid->pal, x, y, z, {{0, 0, BRIDGE_Z_START}, {TILE_SIZE, 1, 40}, {0, 0, -BRIDGE_Z_START}}, IsTransparencySet(TO_BRIDGES));
|
||||||
} else {
|
} else {
|
||||||
AddSortableSpriteToDraw(psid->sprite, psid->pal, x, y, 1, 16, 0x28, z, IsTransparencySet(TO_BRIDGES), 0, 0, BRIDGE_Z_START);
|
AddSortableSpriteToDraw(psid->sprite, psid->pal, x, y, z, {{0, 0, BRIDGE_Z_START}, {1, TILE_SIZE, 40}, {0, 0, -BRIDGE_Z_START}}, IsTransparencySet(TO_BRIDGES));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1602,16 +1630,16 @@ void DrawBridgeMiddle(const TileInfo *ti)
|
||||||
if (rti->UsesOverlay() && !IsInvisibilitySet(TO_BRIDGES)) {
|
if (rti->UsesOverlay() && !IsInvisibilitySet(TO_BRIDGES)) {
|
||||||
SpriteID surface = GetCustomRailSprite(rti, rampsouth, RTSG_BRIDGE, TCX_ON_BRIDGE);
|
SpriteID surface = GetCustomRailSprite(rti, rampsouth, RTSG_BRIDGE, TCX_ON_BRIDGE);
|
||||||
if (surface != 0) {
|
if (surface != 0) {
|
||||||
AddSortableSpriteToDraw(surface + axis, PAL_NONE, x, y, 16, 16, 0, bridge_z, IsTransparencySet(TO_BRIDGES));
|
AddSortableSpriteToDraw(surface + axis, PAL_NONE, x, y, bridge_z, {{}, {TILE_SIZE, TILE_SIZE, 0}, {}}, IsTransparencySet(TO_BRIDGES));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_game_mode != GM_MENU && _settings_client.gui.show_track_reservation && !IsInvisibilitySet(TO_BRIDGES) && HasTunnelBridgeReservation(rampnorth)) {
|
if (_game_mode != GM_MENU && _settings_client.gui.show_track_reservation && !IsInvisibilitySet(TO_BRIDGES) && HasTunnelBridgeReservation(rampnorth)) {
|
||||||
if (rti->UsesOverlay()) {
|
if (rti->UsesOverlay()) {
|
||||||
SpriteID overlay = GetCustomRailSprite(rti, ti->tile, RTSG_OVERLAY);
|
SpriteID overlay = GetCustomRailSprite(rti, ti->tile, RTSG_OVERLAY);
|
||||||
AddSortableSpriteToDraw(overlay + RTO_X + axis, PALETTE_CRASH, ti->x, ti->y, 16, 16, 0, bridge_z, IsTransparencySet(TO_BRIDGES));
|
AddSortableSpriteToDraw(overlay + RTO_X + axis, PALETTE_CRASH, ti->x, ti->y, bridge_z, {{}, {TILE_SIZE, TILE_SIZE, 0}, {}}, IsTransparencySet(TO_BRIDGES));
|
||||||
} else {
|
} else {
|
||||||
AddSortableSpriteToDraw(axis == AXIS_X ? rti->base_sprites.single_x : rti->base_sprites.single_y, PALETTE_CRASH, ti->x, ti->y, 16, 16, 0, bridge_z, IsTransparencySet(TO_BRIDGES));
|
AddSortableSpriteToDraw(axis == AXIS_X ? rti->base_sprites.single_x : rti->base_sprites.single_y, PALETTE_CRASH, ti->x, ti->y, bridge_z, {{}, {TILE_SIZE, TILE_SIZE, 0}, {}}, IsTransparencySet(TO_BRIDGES));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1626,10 +1654,10 @@ void DrawBridgeMiddle(const TileInfo *ti)
|
||||||
if (!IsInvisibilitySet(TO_BRIDGES)) {
|
if (!IsInvisibilitySet(TO_BRIDGES)) {
|
||||||
if (axis == AXIS_X) {
|
if (axis == AXIS_X) {
|
||||||
y += 12;
|
y += 12;
|
||||||
if (psid->sprite & SPRITE_MASK) AddSortableSpriteToDraw(psid->sprite, psid->pal, x, y, 16, 4, 0x28, z, IsTransparencySet(TO_BRIDGES), 0, 3, BRIDGE_Z_START);
|
if (psid->sprite & SPRITE_MASK) AddSortableSpriteToDraw(psid->sprite, psid->pal, x, y, z, {{0, 3, BRIDGE_Z_START}, {TILE_SIZE, 1, 40}, {0, -3, -BRIDGE_Z_START}}, IsTransparencySet(TO_BRIDGES));
|
||||||
} else {
|
} else {
|
||||||
x += 12;
|
x += 12;
|
||||||
if (psid->sprite & SPRITE_MASK) AddSortableSpriteToDraw(psid->sprite, psid->pal, x, y, 4, 16, 0x28, z, IsTransparencySet(TO_BRIDGES), 3, 0, BRIDGE_Z_START);
|
if (psid->sprite & SPRITE_MASK) AddSortableSpriteToDraw(psid->sprite, psid->pal, x, y, z, {{3, 0, BRIDGE_Z_START}, {1, TILE_SIZE, 40}, {-3, 0, -BRIDGE_Z_START}}, IsTransparencySet(TO_BRIDGES));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1109,8 +1109,7 @@ static void DoDrawVehicle(const Vehicle *v)
|
||||||
for (uint i = 0; i < v->sprite_cache.sprite_seq.count; ++i) {
|
for (uint i = 0; i < v->sprite_cache.sprite_seq.count; ++i) {
|
||||||
PaletteID pal2 = v->sprite_cache.sprite_seq.seq[i].pal;
|
PaletteID pal2 = v->sprite_cache.sprite_seq.seq[i].pal;
|
||||||
if (!pal2 || v->vehstatus.Test(VehState::Crashed)) pal2 = pal;
|
if (!pal2 || v->vehstatus.Test(VehState::Crashed)) pal2 = pal;
|
||||||
AddSortableSpriteToDraw(v->sprite_cache.sprite_seq.seq[i].sprite, pal2, v->x_pos + v->x_offs, v->y_pos + v->y_offs,
|
AddSortableSpriteToDraw(v->sprite_cache.sprite_seq.seq[i].sprite, pal2, v->x_pos, v->y_pos, v->z_pos, v->bounds, shadowed);
|
||||||
v->x_extent, v->y_extent, v->z_extent, v->z_pos, shadowed, v->x_bb_offs, v->y_bb_offs);
|
|
||||||
}
|
}
|
||||||
EndSpriteCombine();
|
EndSpriteCombine();
|
||||||
}
|
}
|
||||||
|
@ -1674,12 +1673,24 @@ void Vehicle::UpdateBoundingBoxCoordinates(bool update_cache) const
|
||||||
Rect new_coord;
|
Rect new_coord;
|
||||||
this->sprite_cache.sprite_seq.GetBounds(&new_coord);
|
this->sprite_cache.sprite_seq.GetBounds(&new_coord);
|
||||||
|
|
||||||
Point pt = RemapCoords(this->x_pos + this->x_offs, this->y_pos + this->y_offs, this->z_pos);
|
/* z-bounds are not used. */
|
||||||
|
Point pt = RemapCoords(this->x_pos + this->bounds.origin.x + this->bounds.offset.x, this->y_pos + this->bounds.origin.y + this->bounds.offset.y, this->z_pos);
|
||||||
new_coord.left += pt.x;
|
new_coord.left += pt.x;
|
||||||
new_coord.top += pt.y;
|
new_coord.top += pt.y;
|
||||||
new_coord.right += pt.x + 2 * ZOOM_BASE;
|
new_coord.right += pt.x + 2 * ZOOM_BASE;
|
||||||
new_coord.bottom += pt.y + 2 * ZOOM_BASE;
|
new_coord.bottom += pt.y + 2 * ZOOM_BASE;
|
||||||
|
|
||||||
|
extern bool _draw_bounding_boxes;
|
||||||
|
if (_draw_bounding_boxes) {
|
||||||
|
int x = this->x_pos + this->bounds.origin.x;
|
||||||
|
int y = this->y_pos + this->bounds.origin.y;
|
||||||
|
int z = this->z_pos + this->bounds.origin.z;
|
||||||
|
new_coord.left = std::min(new_coord.left, RemapCoords(x + bounds.extent.x, y, z).x);
|
||||||
|
new_coord.right = std::max(new_coord.right, RemapCoords(x, y + bounds.extent.y, z).x + 1);
|
||||||
|
new_coord.top = std::min(new_coord.top, RemapCoords(x, y, z + bounds.extent.z).y);
|
||||||
|
new_coord.bottom = std::max(new_coord.bottom, RemapCoords(x + bounds.extent.x, y + bounds.extent.y, z).y + 1);
|
||||||
|
}
|
||||||
|
|
||||||
if (update_cache) {
|
if (update_cache) {
|
||||||
/*
|
/*
|
||||||
* If the old coordinates are invalid, set the cache to the new coordinates for correct
|
* If the old coordinates are invalid, set the cache to the new coordinates for correct
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#ifndef VEHICLE_BASE_H
|
#ifndef VEHICLE_BASE_H
|
||||||
#define VEHICLE_BASE_H
|
#define VEHICLE_BASE_H
|
||||||
|
|
||||||
|
#include "sprite.h"
|
||||||
#include "track_type.h"
|
#include "track_type.h"
|
||||||
#include "command_type.h"
|
#include "command_type.h"
|
||||||
#include "order_base.h"
|
#include "order_base.h"
|
||||||
|
@ -293,13 +294,7 @@ public:
|
||||||
* 0xff == reserved for another custom sprite
|
* 0xff == reserved for another custom sprite
|
||||||
*/
|
*/
|
||||||
uint8_t spritenum = 0;
|
uint8_t spritenum = 0;
|
||||||
uint8_t x_extent = 0; ///< x-extent of vehicle bounding box
|
SpriteBounds bounds{}; ///< Bounding box of vehicle.
|
||||||
uint8_t y_extent = 0; ///< y-extent of vehicle bounding box
|
|
||||||
uint8_t z_extent = 0; ///< z-extent of vehicle bounding box
|
|
||||||
int8_t x_bb_offs = 0; ///< x offset of vehicle bounding box
|
|
||||||
int8_t y_bb_offs = 0; ///< y offset of vehicle bounding box
|
|
||||||
int8_t x_offs = 0; ///< x offset for vehicle sprite
|
|
||||||
int8_t y_offs = 0; ///< y offset for vehicle sprite
|
|
||||||
EngineID engine_type = EngineID::Invalid(); ///< The type of engine used for this vehicle.
|
EngineID engine_type = EngineID::Invalid(); ///< The type of engine used for this vehicle.
|
||||||
|
|
||||||
TextEffectID fill_percent_te_id = INVALID_TE_ID; ///< a text-effect id to a loading indicator object
|
TextEffectID fill_percent_te_id = INVALID_TE_ID; ///< a text-effect id to a loading indicator object
|
||||||
|
|
|
@ -660,12 +660,17 @@ static void AddCombinedSprite(SpriteID image, PaletteID pal, int x, int y, int z
|
||||||
* @param bb_offset_z bounding box extent towards negative Z (world)
|
* @param bb_offset_z bounding box extent towards negative Z (world)
|
||||||
* @param sub Only draw a part of the sprite.
|
* @param sub Only draw a part of the sprite.
|
||||||
*/
|
*/
|
||||||
void AddSortableSpriteToDraw(SpriteID image, PaletteID pal, int x, int y, int w, int h, int dz, int z, bool transparent, int bb_offset_x, int bb_offset_y, int bb_offset_z, const SubSprite *sub)
|
void AddSortableSpriteToDraw(SpriteID image, PaletteID pal, int x, int y, int z, const SpriteBounds &bounds, bool transparent, const SubSprite *sub)
|
||||||
{
|
{
|
||||||
int32_t left, right, top, bottom;
|
int32_t left, right, top, bottom;
|
||||||
|
|
||||||
assert((image & SPRITE_MASK) < MAX_SPRITES);
|
assert((image & SPRITE_MASK) < MAX_SPRITES);
|
||||||
|
|
||||||
|
/* Move to bounding box. */
|
||||||
|
x += bounds.origin.x;
|
||||||
|
y += bounds.origin.y;
|
||||||
|
z += bounds.origin.z;
|
||||||
|
|
||||||
/* make the sprites transparent with the right palette */
|
/* make the sprites transparent with the right palette */
|
||||||
if (transparent) {
|
if (transparent) {
|
||||||
SetBit(image, PALETTE_MODIFIER_TRANSPARENT);
|
SetBit(image, PALETTE_MODIFIER_TRANSPARENT);
|
||||||
|
@ -673,21 +678,21 @@ void AddSortableSpriteToDraw(SpriteID image, PaletteID pal, int x, int y, int w,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_vd.combine_sprites == SPRITE_COMBINE_ACTIVE) {
|
if (_vd.combine_sprites == SPRITE_COMBINE_ACTIVE) {
|
||||||
AddCombinedSprite(image, pal, x, y, z, sub);
|
AddCombinedSprite(image, pal, x + bounds.offset.x, y + bounds.offset.y, z + bounds.offset.z, sub);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_vd.last_child = LAST_CHILD_NONE;
|
_vd.last_child = LAST_CHILD_NONE;
|
||||||
|
|
||||||
Point pt = RemapCoords(x, y, z);
|
Point pt = RemapCoords(x + bounds.offset.x, y + bounds.offset.y, z + bounds.offset.z);
|
||||||
int tmp_left, tmp_top, tmp_x = pt.x, tmp_y = pt.y;
|
int tmp_left, tmp_top, tmp_x = pt.x, tmp_y = pt.y;
|
||||||
|
|
||||||
/* Compute screen extents of sprite */
|
/* Compute screen extents of sprite */
|
||||||
if (image == SPR_EMPTY_BOUNDING_BOX) {
|
if (image == SPR_EMPTY_BOUNDING_BOX) {
|
||||||
left = tmp_left = RemapCoords(x + w , y + bb_offset_y, z + bb_offset_z).x;
|
left = tmp_left = RemapCoords(x + bounds.extent.x, y, z).x;
|
||||||
right = RemapCoords(x + bb_offset_x, y + h , z + bb_offset_z).x + 1;
|
right = RemapCoords(x, y + bounds.extent.y, z).x + 1;
|
||||||
top = tmp_top = RemapCoords(x + bb_offset_x, y + bb_offset_y, z + dz ).y;
|
top = tmp_top = RemapCoords(x, y, z + bounds.extent.z).y;
|
||||||
bottom = RemapCoords(x + w , y + h , z + bb_offset_z).y + 1;
|
bottom = RemapCoords(x + bounds.extent.x, y + bounds.extent.y, z).y + 1;
|
||||||
} else {
|
} else {
|
||||||
const Sprite *spr = GetSprite(image & SPRITE_MASK, SpriteType::Normal);
|
const Sprite *spr = GetSprite(image & SPRITE_MASK, SpriteType::Normal);
|
||||||
left = tmp_left = (pt.x += spr->x_offs);
|
left = tmp_left = (pt.x += spr->x_offs);
|
||||||
|
@ -698,10 +703,10 @@ void AddSortableSpriteToDraw(SpriteID image, PaletteID pal, int x, int y, int w,
|
||||||
|
|
||||||
if (_draw_bounding_boxes && (image != SPR_EMPTY_BOUNDING_BOX)) {
|
if (_draw_bounding_boxes && (image != SPR_EMPTY_BOUNDING_BOX)) {
|
||||||
/* Compute maximal extents of sprite and its bounding box */
|
/* Compute maximal extents of sprite and its bounding box */
|
||||||
left = std::min(left , RemapCoords(x + w , y + bb_offset_y, z + bb_offset_z).x);
|
left = std::min(left , RemapCoords(x + bounds.extent.x, y, z).x);
|
||||||
right = std::max(right , RemapCoords(x + bb_offset_x, y + h , z + bb_offset_z).x + 1);
|
right = std::max(right , RemapCoords(x, y + bounds.extent.y, z).x + 1);
|
||||||
top = std::min(top , RemapCoords(x + bb_offset_x, y + bb_offset_y, z + dz ).y);
|
top = std::min(top , RemapCoords(x, y, z + bounds.extent.z).y);
|
||||||
bottom = std::max(bottom, RemapCoords(x + w , y + h , z + bb_offset_z).y + 1);
|
bottom = std::max(bottom, RemapCoords(x + bounds.extent.x, y + bounds.extent.y, z).y + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Do not add the sprite to the viewport, if it is outside */
|
/* Do not add the sprite to the viewport, if it is outside */
|
||||||
|
@ -722,14 +727,14 @@ void AddSortableSpriteToDraw(SpriteID image, PaletteID pal, int x, int y, int w,
|
||||||
ps.image = image;
|
ps.image = image;
|
||||||
ps.pal = pal;
|
ps.pal = pal;
|
||||||
ps.sub = sub;
|
ps.sub = sub;
|
||||||
ps.xmin = x + bb_offset_x;
|
ps.xmin = x;
|
||||||
ps.xmax = x + std::max(bb_offset_x, w) - 1;
|
ps.xmax = x + bounds.extent.x - 1;
|
||||||
|
|
||||||
ps.ymin = y + bb_offset_y;
|
ps.ymin = y;
|
||||||
ps.ymax = y + std::max(bb_offset_y, h) - 1;
|
ps.ymax = y + bounds.extent.y - 1;
|
||||||
|
|
||||||
ps.zmin = z + bb_offset_z;
|
ps.zmin = z;
|
||||||
ps.zmax = z + std::max(bb_offset_z, dz) - 1;
|
ps.zmax = z + bounds.extent.z - 1;
|
||||||
|
|
||||||
ps.first_child = LAST_CHILD_NONE;
|
ps.first_child = LAST_CHILD_NONE;
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#define VIEWPORT_FUNC_H
|
#define VIEWPORT_FUNC_H
|
||||||
|
|
||||||
#include "gfx_type.h"
|
#include "gfx_type.h"
|
||||||
|
#include "sprite.h"
|
||||||
#include "viewport_type.h"
|
#include "viewport_type.h"
|
||||||
#include "window_type.h"
|
#include "window_type.h"
|
||||||
#include "tile_map.h"
|
#include "tile_map.h"
|
||||||
|
@ -51,10 +52,14 @@ void OffsetGroundSprite(int x, int y);
|
||||||
|
|
||||||
void DrawGroundSprite(SpriteID image, PaletteID pal, const SubSprite *sub = nullptr, int extra_offs_x = 0, int extra_offs_y = 0);
|
void DrawGroundSprite(SpriteID image, PaletteID pal, const SubSprite *sub = nullptr, int extra_offs_x = 0, int extra_offs_y = 0);
|
||||||
void DrawGroundSpriteAt(SpriteID image, PaletteID pal, int32_t x, int32_t y, int z, const SubSprite *sub = nullptr, int extra_offs_x = 0, int extra_offs_y = 0);
|
void DrawGroundSpriteAt(SpriteID image, PaletteID pal, int32_t x, int32_t y, int z, const SubSprite *sub = nullptr, int extra_offs_x = 0, int extra_offs_y = 0);
|
||||||
void AddSortableSpriteToDraw(SpriteID image, PaletteID pal, int x, int y, int w, int h, int dz, int z, bool transparent = false, int bb_offset_x = 0, int bb_offset_y = 0, int bb_offset_z = 0, const SubSprite *sub = nullptr);
|
void AddSortableSpriteToDraw(SpriteID image, PaletteID pal, int x, int y, int z, const SpriteBounds &bounds, bool transparent = false, const SubSprite *sub = nullptr);
|
||||||
void AddChildSpriteScreen(SpriteID image, PaletteID pal, int x, int y, bool transparent = false, const SubSprite *sub = nullptr, bool scale = true, bool relative = true);
|
void AddChildSpriteScreen(SpriteID image, PaletteID pal, int x, int y, bool transparent = false, const SubSprite *sub = nullptr, bool scale = true, bool relative = true);
|
||||||
std::string *ViewportAddString(const DrawPixelInfo *dpi, const ViewportSign *sign, ViewportStringFlags flags, Colours colour);
|
std::string *ViewportAddString(const DrawPixelInfo *dpi, const ViewportSign *sign, ViewportStringFlags flags, Colours colour);
|
||||||
|
|
||||||
|
inline void AddSortableSpriteToDraw(SpriteID image, PaletteID pal, const PointXyz<int32_t> &world, const SpriteBounds &bounds, bool transparent = false, const SubSprite *sub = nullptr)
|
||||||
|
{
|
||||||
|
AddSortableSpriteToDraw(image, pal, world.x, world.y, world.z, bounds, transparent, sub);
|
||||||
|
}
|
||||||
|
|
||||||
void StartSpriteCombine();
|
void StartSpriteCombine();
|
||||||
void EndSpriteCombine();
|
void EndSpriteCombine();
|
||||||
|
|
|
@ -89,8 +89,8 @@ enum ZoomStateChange : uint8_t {
|
||||||
* z=6 reserved, currently unused.
|
* z=6 reserved, currently unused.
|
||||||
* z=7 Z separator between bridge/tunnel and the things under/above it.
|
* z=7 Z separator between bridge/tunnel and the things under/above it.
|
||||||
*/
|
*/
|
||||||
static const uint BB_HEIGHT_UNDER_BRIDGE = 6; ///< Everything that can be built under low bridges, must not exceed this Z height.
|
static constexpr int BB_HEIGHT_UNDER_BRIDGE = 6; ///< Everything that can be built under low bridges, must not exceed this Z height.
|
||||||
static const uint BB_Z_SEPARATOR = 7; ///< Separates the bridge/tunnel from the things under/above it.
|
static constexpr int BB_Z_SEPARATOR = 7; ///< Separates the bridge/tunnel from the things under/above it.
|
||||||
|
|
||||||
/** Viewport place method (type of highlighted area and placed objects) */
|
/** Viewport place method (type of highlighted area and placed objects) */
|
||||||
enum ViewportPlaceMethod : uint8_t {
|
enum ViewportPlaceMethod : uint8_t {
|
||||||
|
|
|
@ -806,11 +806,7 @@ static void DrawWaterTileStruct(const TileInfo *ti, std::span<const DrawTileSeqS
|
||||||
for (const DrawTileSeqStruct &dtss : seq) {
|
for (const DrawTileSeqStruct &dtss : seq) {
|
||||||
uint tile_offs = offset + dtss.image.sprite;
|
uint tile_offs = offset + dtss.image.sprite;
|
||||||
if (feature < CF_END) tile_offs = GetCanalSpriteOffset(feature, ti->tile, tile_offs);
|
if (feature < CF_END) tile_offs = GetCanalSpriteOffset(feature, ti->tile, tile_offs);
|
||||||
AddSortableSpriteToDraw(base + tile_offs, palette,
|
AddSortableSpriteToDraw(base + tile_offs, palette, *ti, dtss, IsTransparencySet(TO_BUILDINGS));
|
||||||
ti->x + dtss.delta_x, ti->y + dtss.delta_y,
|
|
||||||
dtss.size_x, dtss.size_y,
|
|
||||||
dtss.size_z, ti->z + dtss.delta_z,
|
|
||||||
IsTransparencySet(TO_BUILDINGS));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue