mirror of https://github.com/OpenTTD/OpenTTD.git
Merge 6b8db74afd
into 8308998388
This commit is contained in:
commit
8fb9b219d6
|
@ -2043,11 +2043,11 @@ static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, Byte
|
||||||
const uint8_t *layout = buf->ReadBytes(length * number);
|
const uint8_t *layout = buf->ReadBytes(length * number);
|
||||||
statspec->layouts[length - 1][number - 1].assign(layout, layout + length * number);
|
statspec->layouts[length - 1][number - 1].assign(layout, layout + length * number);
|
||||||
|
|
||||||
/* Validate tile values are only the permitted 00, 02, 04 and 06. */
|
/* Ensure the first bit, axis, is zero. The rest of the value is validated during rendering, as we don't know the range yet. */
|
||||||
for (auto &tile : statspec->layouts[length - 1][number - 1]) {
|
for (auto &tile : statspec->layouts[length - 1][number - 1]) {
|
||||||
if ((tile & 6) != tile) {
|
if ((tile & ~1U) != tile) {
|
||||||
GrfMsg(1, "StationChangeInfo: Invalid tile {} in layout {}x{}", tile, length, number);
|
GrfMsg(1, "StationChangeInfo: Invalid tile {} in layout {}x{}", tile, length, number);
|
||||||
tile &= 6;
|
tile &= ~1U;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2070,9 +2070,18 @@ static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, Byte
|
||||||
statspec->cargo_threshold = buf->ReadWord();
|
statspec->cargo_threshold = buf->ReadWord();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x11: // Pylon placement
|
case 0x11: { // Pylon placement
|
||||||
statspec->pylons = buf->ReadByte();
|
uint8_t pylons = buf->ReadByte();
|
||||||
|
if (statspec->tileflags.size() < 8) statspec->tileflags.resize(8);
|
||||||
|
for (int j = 0; j < 8; ++j) {
|
||||||
|
if (HasBit(pylons, j)) {
|
||||||
|
statspec->tileflags[j] |= StationSpec::TileFlags::Pylons;
|
||||||
|
} else {
|
||||||
|
statspec->tileflags[j] &= ~StationSpec::TileFlags::Pylons;
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case 0x12: // Cargo types for random triggers
|
case 0x12: // Cargo types for random triggers
|
||||||
if (_cur.grffile->grf_version >= 7) {
|
if (_cur.grffile->grf_version >= 7) {
|
||||||
|
@ -2086,13 +2095,31 @@ static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, Byte
|
||||||
statspec->flags = buf->ReadByte();
|
statspec->flags = buf->ReadByte();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x14: // Overhead wire placement
|
case 0x14: { // Overhead wire placement
|
||||||
statspec->wires = buf->ReadByte();
|
uint8_t wires = buf->ReadByte();
|
||||||
|
if (statspec->tileflags.size() < 8) statspec->tileflags.resize(8);
|
||||||
|
for (int j = 0; j < 8; ++j) {
|
||||||
|
if (HasBit(wires, j)) {
|
||||||
|
statspec->tileflags[j] |= StationSpec::TileFlags::NoWires;
|
||||||
|
} else {
|
||||||
|
statspec->tileflags[j] &= ~StationSpec::TileFlags::NoWires;
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case 0x15: // Blocked tiles
|
case 0x15: { // Blocked tiles
|
||||||
statspec->blocked = buf->ReadByte();
|
uint8_t blocked = buf->ReadByte();
|
||||||
|
if (statspec->tileflags.size() < 8) statspec->tileflags.resize(8);
|
||||||
|
for (int j = 0; j < 8; ++j) {
|
||||||
|
if (HasBit(blocked, j)) {
|
||||||
|
statspec->tileflags[j] |= StationSpec::TileFlags::Blocked;
|
||||||
|
} else {
|
||||||
|
statspec->tileflags[j] &= ~StationSpec::TileFlags::Blocked;
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case 0x16: // Animation info
|
case 0x16: // Animation info
|
||||||
statspec->animation.frames = buf->ReadByte();
|
statspec->animation.frames = buf->ReadByte();
|
||||||
|
@ -2144,6 +2171,13 @@ static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, Byte
|
||||||
AddStringForMapping(buf->ReadWord(), [statspec](StringID str) { StationClass::Get(statspec->cls_id)->name = str; });
|
AddStringForMapping(buf->ReadWord(), [statspec](StringID str) { StationClass::Get(statspec->cls_id)->name = str; });
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 0x1E: { // Extended tile flags (replaces prop 11, 14 and 15)
|
||||||
|
uint16_t tiles = buf->ReadExtendedByte();
|
||||||
|
auto flags = reinterpret_cast<const StationSpec::TileFlags *>(buf->ReadBytes(tiles));
|
||||||
|
statspec->tileflags.assign(flags, flags + tiles);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ret = CIR_UNKNOWN;
|
ret = CIR_UNKNOWN;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -38,8 +38,8 @@ enum CallbackID {
|
||||||
/** Determine whether a newstation should be made available to build. */
|
/** Determine whether a newstation should be made available to build. */
|
||||||
CBID_STATION_AVAILABILITY = 0x13, // 8 bit callback
|
CBID_STATION_AVAILABILITY = 0x13, // 8 bit callback
|
||||||
|
|
||||||
/** Choose a sprite layout to draw, instead of the standard 0-7 range. */
|
/** Choose a tile layout to draw, instead of the standard range. */
|
||||||
CBID_STATION_SPRITE_LAYOUT = 0x14,
|
CBID_STATION_DRAW_TILE_LAYOUT = 0x14,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Refit capacity, the passed vehicle needs to have its ->cargo_type set to
|
* Refit capacity, the passed vehicle needs to have its ->cargo_type set to
|
||||||
|
@ -93,7 +93,7 @@ enum CallbackID {
|
||||||
CBID_VEHICLE_ADDITIONAL_TEXT = 0x23,
|
CBID_VEHICLE_ADDITIONAL_TEXT = 0x23,
|
||||||
|
|
||||||
/** Called when building a station to customize the tile layout */
|
/** Called when building a station to customize the tile layout */
|
||||||
CBID_STATION_TILE_LAYOUT = 0x24, // 15 bit callback
|
CBID_STATION_BUILD_TILE_LAYOUT = 0x24, // 15 bit callback
|
||||||
|
|
||||||
/** Called for periodically starting or stopping the animation. */
|
/** Called for periodically starting or stopping the animation. */
|
||||||
CBID_INDTILE_ANIM_START_STOP = 0x25, // 15 bit callback
|
CBID_INDTILE_ANIM_START_STOP = 0x25, // 15 bit callback
|
||||||
|
@ -308,7 +308,7 @@ enum VehicleCallbackMask {
|
||||||
*/
|
*/
|
||||||
enum StationCallbackMask {
|
enum StationCallbackMask {
|
||||||
CBM_STATION_AVAIL = 0, ///< Availability of station in construction window
|
CBM_STATION_AVAIL = 0, ///< Availability of station in construction window
|
||||||
CBM_STATION_SPRITE_LAYOUT = 1, ///< Use callback to select a sprite layout to use
|
CBM_STATION_DRAW_TILE_LAYOUT = 1, ///< Use callback to select a tile layout to use when drawing.
|
||||||
CBM_STATION_ANIMATION_NEXT_FRAME = 2, ///< Use a custom next frame callback
|
CBM_STATION_ANIMATION_NEXT_FRAME = 2, ///< Use a custom next frame callback
|
||||||
CBM_STATION_ANIMATION_SPEED = 3, ///< Customize the animation speed of the station
|
CBM_STATION_ANIMATION_SPEED = 3, ///< Customize the animation speed of the station
|
||||||
CBM_STATION_SLOPE_CHECK = 4, ///< Check slope of new station tiles
|
CBM_STATION_SLOPE_CHECK = 4, ///< Check slope of new station tiles
|
||||||
|
|
|
@ -782,8 +782,8 @@ bool DrawStationTile(int x, int y, RailType railtype, Axis axis, StationClassID
|
||||||
const StationSpec *statspec = StationClass::Get(sclass)->GetSpec(station);
|
const StationSpec *statspec = StationClass::Get(sclass)->GetSpec(station);
|
||||||
if (statspec == nullptr) return false;
|
if (statspec == nullptr) return false;
|
||||||
|
|
||||||
if (HasBit(statspec->callback_mask, CBM_STATION_SPRITE_LAYOUT)) {
|
if (HasBit(statspec->callback_mask, CBM_STATION_DRAW_TILE_LAYOUT)) {
|
||||||
uint16_t callback = GetStationCallback(CBID_STATION_SPRITE_LAYOUT, 0, 0, statspec, nullptr, INVALID_TILE);
|
uint16_t callback = GetStationCallback(CBID_STATION_DRAW_TILE_LAYOUT, 0, 0, statspec, nullptr, INVALID_TILE);
|
||||||
if (callback != CALLBACK_FAILED) tile = callback & ~1;
|
if (callback != CALLBACK_FAILED) tile = callback & ~1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#ifndef NEWGRF_STATION_H
|
#ifndef NEWGRF_STATION_H
|
||||||
#define NEWGRF_STATION_H
|
#define NEWGRF_STATION_H
|
||||||
|
|
||||||
|
#include "core/enum_type.hpp"
|
||||||
#include "newgrf_animation_type.h"
|
#include "newgrf_animation_type.h"
|
||||||
#include "newgrf_callbacks.h"
|
#include "newgrf_callbacks.h"
|
||||||
#include "newgrf_class.h"
|
#include "newgrf_class.h"
|
||||||
|
@ -112,7 +113,7 @@ struct StationSpec {
|
||||||
StationSpec() : cls_id(STAT_CLASS_DFLT), name(0),
|
StationSpec() : cls_id(STAT_CLASS_DFLT), name(0),
|
||||||
disallowed_platforms(0), disallowed_lengths(0),
|
disallowed_platforms(0), disallowed_lengths(0),
|
||||||
cargo_threshold(0), cargo_triggers(0),
|
cargo_threshold(0), cargo_triggers(0),
|
||||||
callback_mask(0), flags(0), pylons(0), wires(0), blocked(0),
|
callback_mask(0), flags(0),
|
||||||
animation({0, 0, 0, 0}) {}
|
animation({0, 0, 0, 0}) {}
|
||||||
/**
|
/**
|
||||||
* Properties related the the grf file.
|
* Properties related the the grf file.
|
||||||
|
@ -157,9 +158,13 @@ struct StationSpec {
|
||||||
|
|
||||||
uint8_t flags; ///< Bitmask of flags, bit 0: use different sprite set; bit 1: divide cargo about by station size
|
uint8_t flags; ///< Bitmask of flags, bit 0: use different sprite set; bit 1: divide cargo about by station size
|
||||||
|
|
||||||
uint8_t pylons; ///< Bitmask of base tiles (0 - 7) which should contain elrail pylons
|
enum class TileFlags : uint8_t {
|
||||||
uint8_t wires; ///< Bitmask of base tiles (0 - 7) which should contain elrail wires
|
None = 0,
|
||||||
uint8_t blocked; ///< Bitmask of base tiles (0 - 7) which are blocked to trains
|
Pylons = 1U << 0, ///< Tile should contain catenary pylons.
|
||||||
|
NoWires = 1U << 1, ///< Tile should NOT contain catenary wires.
|
||||||
|
Blocked = 1U << 2, ///< Tile is blocked to vehicles.
|
||||||
|
};
|
||||||
|
std::vector<TileFlags> tileflags; ///< List of tile flags.
|
||||||
|
|
||||||
AnimationInfo animation;
|
AnimationInfo animation;
|
||||||
|
|
||||||
|
@ -173,6 +178,7 @@ struct StationSpec {
|
||||||
*/
|
*/
|
||||||
std::vector<std::vector<std::vector<uint8_t>>> layouts;
|
std::vector<std::vector<std::vector<uint8_t>>> layouts;
|
||||||
};
|
};
|
||||||
|
DECLARE_ENUM_AS_BIT_SET(StationSpec::TileFlags);
|
||||||
|
|
||||||
/** Class containing information relating to station classes. */
|
/** Class containing information relating to station classes. */
|
||||||
using StationClass = NewGRFClass<StationSpec, StationClassID, STAT_CLASS_MAX>;
|
using StationClass = NewGRFClass<StationSpec, StationClassID, STAT_CLASS_MAX>;
|
||||||
|
|
|
@ -1294,6 +1294,14 @@ static CommandCost CalculateRailStationCost(TileArea tile_area, DoCommandFlag fl
|
||||||
return cost;
|
return cost;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StationSpec::TileFlags GetStationTileFlags(TileIndex tile, const StationSpec *statspec)
|
||||||
|
{
|
||||||
|
const StationGfx gfx = GetStationGfx(tile);
|
||||||
|
/* Default stations do not draw pylons under roofs (gfx >= 4) */
|
||||||
|
if (statspec == nullptr || gfx >= statspec->tileflags.size()) return gfx < 4 ? StationSpec::TileFlags::Pylons : StationSpec::TileFlags::None;
|
||||||
|
return statspec->tileflags[gfx];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set rail station tile flags for the given tile.
|
* Set rail station tile flags for the given tile.
|
||||||
* @param tile Tile to set flags on.
|
* @param tile Tile to set flags on.
|
||||||
|
@ -1301,15 +1309,10 @@ static CommandCost CalculateRailStationCost(TileArea tile_area, DoCommandFlag fl
|
||||||
*/
|
*/
|
||||||
void SetRailStationTileFlags(TileIndex tile, const StationSpec *statspec)
|
void SetRailStationTileFlags(TileIndex tile, const StationSpec *statspec)
|
||||||
{
|
{
|
||||||
const StationGfx gfx = GetStationGfx(tile);
|
auto flags = GetStationTileFlags(tile, statspec);
|
||||||
bool blocked = statspec != nullptr && HasBit(statspec->blocked, gfx);
|
SetStationTileBlocked(tile, (flags & StationSpec::TileFlags::Blocked) == StationSpec::TileFlags::Blocked);
|
||||||
/* Default stations do not draw pylons under roofs (gfx >= 4) */
|
SetStationTileHavePylons(tile, (flags & StationSpec::TileFlags::Pylons) == StationSpec::TileFlags::Pylons);
|
||||||
bool pylons = statspec != nullptr ? HasBit(statspec->pylons, gfx) : gfx < 4;
|
SetStationTileHaveWires(tile, (flags & StationSpec::TileFlags::NoWires) != StationSpec::TileFlags::NoWires);
|
||||||
bool wires = statspec == nullptr || !HasBit(statspec->wires, gfx);
|
|
||||||
|
|
||||||
SetStationTileBlocked(tile, blocked);
|
|
||||||
SetStationTileHavePylons(tile, pylons);
|
|
||||||
SetStationTileHaveWires(tile, wires);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1461,12 +1464,12 @@ CommandCost CmdBuildRailStation(DoCommandFlag flags, TileIndex tile_org, RailTyp
|
||||||
uint32_t platinfo = GetPlatformInfo(AXIS_X, GetStationGfx(tile), plat_len, numtracks_orig, plat_len - w, numtracks_orig - numtracks, false);
|
uint32_t platinfo = GetPlatformInfo(AXIS_X, GetStationGfx(tile), plat_len, numtracks_orig, plat_len - w, numtracks_orig - numtracks, false);
|
||||||
|
|
||||||
/* As the station is not yet completely finished, the station does not yet exist. */
|
/* As the station is not yet completely finished, the station does not yet exist. */
|
||||||
uint16_t callback = GetStationCallback(CBID_STATION_TILE_LAYOUT, platinfo, 0, statspec, nullptr, tile);
|
uint16_t callback = GetStationCallback(CBID_STATION_BUILD_TILE_LAYOUT, platinfo, 0, statspec, nullptr, tile);
|
||||||
if (callback != CALLBACK_FAILED) {
|
if (callback != CALLBACK_FAILED) {
|
||||||
if (callback < 8) {
|
if (callback <= UINT8_MAX) {
|
||||||
SetStationGfx(tile, (callback & ~1) + axis);
|
SetStationGfx(tile, (callback & ~1) + axis);
|
||||||
} else {
|
} else {
|
||||||
ErrorUnknownCallbackResult(statspec->grf_prop.grffile->grfid, CBID_STATION_TILE_LAYOUT, callback);
|
ErrorUnknownCallbackResult(statspec->grf_prop.grffile->grfid, CBID_STATION_BUILD_TILE_LAYOUT, callback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2885,7 +2888,9 @@ static CommandCost RemoveDock(TileIndex tile, DoCommandFlag flags)
|
||||||
|
|
||||||
const DrawTileSprites *GetStationTileLayout(StationType st, uint8_t gfx)
|
const DrawTileSprites *GetStationTileLayout(StationType st, uint8_t gfx)
|
||||||
{
|
{
|
||||||
return &_station_display_datas[st][gfx];
|
const auto layouts = _station_display_datas[st];
|
||||||
|
if (gfx < layouts.size()) return layouts.data() + gfx;
|
||||||
|
return layouts.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2978,8 +2983,8 @@ static void DrawTile_Station(TileInfo *ti)
|
||||||
if (statspec != nullptr) {
|
if (statspec != nullptr) {
|
||||||
tile_layout = GetStationGfx(ti->tile);
|
tile_layout = GetStationGfx(ti->tile);
|
||||||
|
|
||||||
if (HasBit(statspec->callback_mask, CBM_STATION_SPRITE_LAYOUT)) {
|
if (HasBit(statspec->callback_mask, CBM_STATION_DRAW_TILE_LAYOUT)) {
|
||||||
uint16_t callback = GetStationCallback(CBID_STATION_SPRITE_LAYOUT, 0, 0, statspec, st, ti->tile);
|
uint16_t callback = GetStationCallback(CBID_STATION_DRAW_TILE_LAYOUT, 0, 0, statspec, st, ti->tile);
|
||||||
if (callback != CALLBACK_FAILED) tile_layout = (callback & ~1) + GetRailStationAxis(ti->tile);
|
if (callback != CALLBACK_FAILED) tile_layout = (callback & ~1) + GetRailStationAxis(ti->tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ static const StationID INVALID_STATION = 0xFFFF;
|
||||||
typedef SmallStack<StationID, StationID, INVALID_STATION, 8, 0xFFFD> StationIDStack;
|
typedef SmallStack<StationID, StationID, INVALID_STATION, 8, 0xFFFD> StationIDStack;
|
||||||
|
|
||||||
/** Station types */
|
/** Station types */
|
||||||
enum StationType {
|
enum StationType : uint8_t {
|
||||||
STATION_RAIL,
|
STATION_RAIL,
|
||||||
STATION_AIRPORT,
|
STATION_AIRPORT,
|
||||||
STATION_TRUCK,
|
STATION_TRUCK,
|
||||||
|
@ -37,6 +37,7 @@ enum StationType {
|
||||||
STATION_DOCK,
|
STATION_DOCK,
|
||||||
STATION_BUOY,
|
STATION_BUOY,
|
||||||
STATION_WAYPOINT,
|
STATION_WAYPOINT,
|
||||||
|
STATION_END,
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Types of RoadStops */
|
/** Types of RoadStops */
|
||||||
|
|
|
@ -99,8 +99,8 @@ static const NIFeature _nif_vehicle = {
|
||||||
#define NICS(cb_id, bit) NIC(cb_id, StationSpec, callback_mask, bit)
|
#define NICS(cb_id, bit) NIC(cb_id, StationSpec, callback_mask, bit)
|
||||||
static const NICallback _nic_stations[] = {
|
static const NICallback _nic_stations[] = {
|
||||||
NICS(CBID_STATION_AVAILABILITY, CBM_STATION_AVAIL),
|
NICS(CBID_STATION_AVAILABILITY, CBM_STATION_AVAIL),
|
||||||
NICS(CBID_STATION_SPRITE_LAYOUT, CBM_STATION_SPRITE_LAYOUT),
|
NICS(CBID_STATION_DRAW_TILE_LAYOUT, CBM_STATION_DRAW_TILE_LAYOUT),
|
||||||
NICS(CBID_STATION_TILE_LAYOUT, CBM_NO_BIT),
|
NICS(CBID_STATION_BUILD_TILE_LAYOUT,CBM_NO_BIT),
|
||||||
NICS(CBID_STATION_ANIM_START_STOP, CBM_NO_BIT),
|
NICS(CBID_STATION_ANIM_START_STOP, CBM_NO_BIT),
|
||||||
NICS(CBID_STATION_ANIM_NEXT_FRAME, CBM_STATION_ANIMATION_NEXT_FRAME),
|
NICS(CBID_STATION_ANIM_NEXT_FRAME, CBM_STATION_ANIMATION_NEXT_FRAME),
|
||||||
NICS(CBID_STATION_ANIMATION_SPEED, CBM_STATION_ANIMATION_SPEED),
|
NICS(CBID_STATION_ANIMATION_SPEED, CBM_STATION_ANIMATION_SPEED),
|
||||||
|
|
|
@ -990,7 +990,7 @@ static const DrawTileSprites _station_display_datas_waypoint[] = {
|
||||||
* As these are drawn/build like stations, they may use the same number of layouts. */
|
* As these are drawn/build like stations, they may use the same number of layouts. */
|
||||||
static_assert(lengthof(_station_display_datas_rail) == lengthof(_station_display_datas_waypoint));
|
static_assert(lengthof(_station_display_datas_rail) == lengthof(_station_display_datas_waypoint));
|
||||||
|
|
||||||
static const DrawTileSprites * const _station_display_datas[] = {
|
static const std::array<std::span<const DrawTileSprites>, STATION_END> _station_display_datas = {{
|
||||||
_station_display_datas_rail,
|
_station_display_datas_rail,
|
||||||
_station_display_datas_airport,
|
_station_display_datas_airport,
|
||||||
_station_display_datas_truck,
|
_station_display_datas_truck,
|
||||||
|
@ -999,4 +999,4 @@ static const DrawTileSprites * const _station_display_datas[] = {
|
||||||
_station_display_datas_dock,
|
_station_display_datas_dock,
|
||||||
_station_display_datas_buoy,
|
_station_display_datas_buoy,
|
||||||
_station_display_datas_waypoint,
|
_station_display_datas_waypoint,
|
||||||
};
|
}};
|
||||||
|
|
Loading…
Reference in New Issue