Road stops: Use a struct for road stop tile data
This commit is contained in:
@@ -33,6 +33,11 @@ struct RoadStopSpecList {
|
|||||||
uint8 localidx; ///< Station ID within GRF of road stop
|
uint8 localidx; ///< Station ID within GRF of road stop
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct RoadStopTileData {
|
||||||
|
TileIndex tile;
|
||||||
|
uint8 random_bits;
|
||||||
|
uint8 animation_frame;
|
||||||
|
};
|
||||||
|
|
||||||
/** StationRect - used to track station spread out rectangle - cheaper than scanning whole map */
|
/** StationRect - used to track station spread out rectangle - cheaper than scanning whole map */
|
||||||
struct StationRect : public Rect {
|
struct StationRect : public Rect {
|
||||||
@@ -86,8 +91,7 @@ struct BaseStation : StationPool::PoolItem<&_station_pool> {
|
|||||||
TileArea train_station; ///< Tile area the train 'station' part covers
|
TileArea train_station; ///< Tile area the train 'station' part covers
|
||||||
StationRect rect; ///< NOSAVE: Station spread out rectangle maintained by StationRect::xxx() functions
|
StationRect rect; ///< NOSAVE: Station spread out rectangle maintained by StationRect::xxx() functions
|
||||||
|
|
||||||
std::vector<TileIndex> custom_road_stop_tiles; ///< List of custom road stop tiles
|
std::vector<RoadStopTileData> custom_roadstop_tile_data; ///< List of custom road stop tile data
|
||||||
std::vector<uint16> custom_road_stop_data; ///< Custom road stop random bits (low) and animation byte (high) in same order as custom_road_stop_tiles
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the base station.
|
* Initialize the base station.
|
||||||
@@ -192,30 +196,28 @@ struct BaseStation : StationPool::PoolItem<&_station_pool> {
|
|||||||
return (this->facilities & facilities) != 0;
|
return (this->facilities & facilities) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline uint GetRoadStopData(TileIndex tile) const
|
inline byte GetRoadStopRandomBits(TileIndex tile) const
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < this->custom_road_stop_tiles.size(); i++) {
|
for (const RoadStopTileData &tile_data : this->custom_roadstop_tile_data) {
|
||||||
if (this->custom_road_stop_tiles[i] == tile) return this->custom_road_stop_data[i];
|
if (tile_data.tile == tile) return tile_data.random_bits;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline byte GetRoadStopRandomBits(TileIndex tile) const
|
|
||||||
{
|
|
||||||
return GB(this->GetRoadStopData(tile), 0, 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline byte GetRoadStopAnimationFrame(TileIndex tile) const
|
inline byte GetRoadStopAnimationFrame(TileIndex tile) const
|
||||||
{
|
{
|
||||||
return GB(this->GetRoadStopData(tile), 8, 8);
|
for (const RoadStopTileData &tile_data : this->custom_roadstop_tile_data) {
|
||||||
|
if (tile_data.tile == tile) return tile_data.animation_frame;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool SetRoadStopTileData(TileIndex tile, byte data, byte offset);
|
bool SetRoadStopTileData(TileIndex tile, byte data, bool animation);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
inline void SetRoadStopRandomBits(TileIndex tile, byte random_bits) { this->SetRoadStopTileData(tile, random_bits, 0); }
|
inline void SetRoadStopRandomBits(TileIndex tile, byte random_bits) { this->SetRoadStopTileData(tile, random_bits, false); }
|
||||||
inline bool SetRoadStopAnimationFrame(TileIndex tile, byte frame) { return this->SetRoadStopTileData(tile, frame, 8); }
|
inline bool SetRoadStopAnimationFrame(TileIndex tile, byte frame) { return this->SetRoadStopTileData(tile, frame, true); }
|
||||||
void RemoveRoadStopTileData(TileIndex tile);
|
void RemoveRoadStopTileData(TileIndex tile);
|
||||||
|
|
||||||
static void PostDestructor(size_t index);
|
static void PostDestructor(size_t index);
|
||||||
|
@@ -402,8 +402,8 @@ void TriggerRoadStopAnimation(BaseStation *st, TileIndex trigger_tile, StationAn
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (trigger == SAT_NEW_CARGO || trigger == SAT_CARGO_TAKEN || trigger == SAT_250_TICKS) {
|
if (trigger == SAT_NEW_CARGO || trigger == SAT_CARGO_TAKEN || trigger == SAT_250_TICKS) {
|
||||||
for (TileIndex cur_tile : st->custom_road_stop_tiles) {
|
for (const RoadStopTileData &tile_data : st->custom_roadstop_tile_data) {
|
||||||
process_tile(cur_tile);
|
process_tile(tile_data.tile);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
process_tile(trigger_tile);
|
process_tile(trigger_tile);
|
||||||
@@ -477,8 +477,8 @@ void TriggerRoadStopRandomisation(Station *st, TileIndex tile, RoadStopRandomTri
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
if (trigger == RSRT_NEW_CARGO || trigger == RSRT_CARGO_TAKEN) {
|
if (trigger == RSRT_NEW_CARGO || trigger == RSRT_CARGO_TAKEN) {
|
||||||
for (TileIndex cur_tile : st->custom_road_stop_tiles) {
|
for (const RoadStopTileData &tile_data : st->custom_roadstop_tile_data) {
|
||||||
process_tile(cur_tile);
|
process_tile(tile_data.tile);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
process_tile(tile);
|
process_tile(tile);
|
||||||
@@ -597,8 +597,8 @@ void DeallocateRoadStopSpecFromStation(BaseStation *st, byte specindex)
|
|||||||
if (specindex == 0) return;
|
if (specindex == 0) return;
|
||||||
|
|
||||||
/* Check custom road stop tiles if the specindex is still in use */
|
/* Check custom road stop tiles if the specindex is still in use */
|
||||||
for (TileIndex tile : st->custom_road_stop_tiles) {
|
for (const RoadStopTileData &tile_data : st->custom_roadstop_tile_data) {
|
||||||
if (GetCustomRoadStopSpecIndex(tile) == specindex) {
|
if (GetCustomRoadStopSpecIndex(tile_data.tile) == specindex) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -171,7 +171,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = {
|
|||||||
{ XSLFI_ROAD_WAYPOINTS, XSCF_NULL, 1, 1, "road_waypoints", nullptr, nullptr, nullptr },
|
{ XSLFI_ROAD_WAYPOINTS, XSCF_NULL, 1, 1, "road_waypoints", nullptr, nullptr, nullptr },
|
||||||
{ XSLFI_MORE_STATION_TYPES, XSCF_NULL, 1, 1, "more_station_types", nullptr, nullptr, nullptr },
|
{ XSLFI_MORE_STATION_TYPES, XSCF_NULL, 1, 1, "more_station_types", nullptr, nullptr, nullptr },
|
||||||
{ XSLFI_RV_ORDER_EXTRA_FLAGS, XSCF_IGNORABLE_UNKNOWN, 1, 1, "rv_order_extra_flags", nullptr, nullptr, nullptr },
|
{ XSLFI_RV_ORDER_EXTRA_FLAGS, XSCF_IGNORABLE_UNKNOWN, 1, 1, "rv_order_extra_flags", nullptr, nullptr, nullptr },
|
||||||
{ XSLFI_GRF_ROADSTOPS, XSCF_NULL, 1, 1, "grf_road_stops", nullptr, nullptr, nullptr },
|
{ XSLFI_GRF_ROADSTOPS, XSCF_NULL, 2, 2, "grf_road_stops", nullptr, nullptr, nullptr },
|
||||||
{ XSLFI_INDUSTRY_ANIM_MASK, XSCF_IGNORABLE_ALL, 1, 1, "industry_anim_mask", nullptr, nullptr, nullptr },
|
{ XSLFI_INDUSTRY_ANIM_MASK, XSCF_IGNORABLE_ALL, 1, 1, "industry_anim_mask", nullptr, nullptr, nullptr },
|
||||||
{ XSLFI_NEW_SIGNAL_STYLES, XSCF_NULL, 2, 2, "new_signal_styles", nullptr, nullptr, "XBST,NSID" },
|
{ XSLFI_NEW_SIGNAL_STYLES, XSCF_NULL, 2, 2, "new_signal_styles", nullptr, nullptr, "XBST,NSID" },
|
||||||
{ XSLFI_NO_TREE_COUNTER, XSCF_IGNORABLE_ALL, 1, 1, "no_tree_counter", nullptr, nullptr, nullptr },
|
{ XSLFI_NO_TREE_COUNTER, XSCF_IGNORABLE_ALL, 1, 1, "no_tree_counter", nullptr, nullptr, nullptr },
|
||||||
|
@@ -25,6 +25,9 @@
|
|||||||
static byte _old_last_vehicle_type;
|
static byte _old_last_vehicle_type;
|
||||||
static uint8 _num_specs;
|
static uint8 _num_specs;
|
||||||
static uint8 _num_roadstop_specs;
|
static uint8 _num_roadstop_specs;
|
||||||
|
static uint32 _num_roadstop_custom_tiles;
|
||||||
|
static std::vector<TileIndex> _custom_road_stop_tiles;
|
||||||
|
static std::vector<uint16> _custom_road_stop_data;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the buoy orders to be waypoint orders.
|
* Update the buoy orders to be waypoint orders.
|
||||||
@@ -414,8 +417,9 @@ static const SaveLoad _base_station_desc[] = {
|
|||||||
SLE_VAR(BaseStation, waiting_triggers, SLE_UINT8),
|
SLE_VAR(BaseStation, waiting_triggers, SLE_UINT8),
|
||||||
SLEG_VAR(_num_specs, SLE_UINT8),
|
SLEG_VAR(_num_specs, SLE_UINT8),
|
||||||
SLEG_CONDVAR_X(_num_roadstop_specs, SLE_UINT8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_GRF_ROADSTOPS)),
|
SLEG_CONDVAR_X(_num_roadstop_specs, SLE_UINT8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_GRF_ROADSTOPS)),
|
||||||
SLE_CONDVARVEC_X(BaseStation, custom_road_stop_tiles, SLE_UINT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_GRF_ROADSTOPS)),
|
SLEG_CONDVARVEC_X(_custom_road_stop_tiles, SLE_UINT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_GRF_ROADSTOPS, 1, 1)),
|
||||||
SLE_CONDVARVEC_X(BaseStation, custom_road_stop_data, SLE_UINT16, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_GRF_ROADSTOPS)),
|
SLEG_CONDVARVEC_X(_custom_road_stop_data, SLE_UINT16, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_GRF_ROADSTOPS, 1, 1)),
|
||||||
|
SLEG_CONDVAR_X(_num_roadstop_custom_tiles, SLE_UINT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_GRF_ROADSTOPS, 2)),
|
||||||
};
|
};
|
||||||
|
|
||||||
static OldPersistentStorage _old_st_persistent_storage;
|
static OldPersistentStorage _old_st_persistent_storage;
|
||||||
@@ -481,6 +485,12 @@ static const SaveLoad _waypoint_desc[] = {
|
|||||||
SLE_CONDVAR_X(Waypoint, road_waypoint_area.h, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_ROAD_WAYPOINTS)),
|
SLE_CONDVAR_X(Waypoint, road_waypoint_area.h, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_ROAD_WAYPOINTS)),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const SaveLoad _custom_roadstop_tile_data_desc[] = {
|
||||||
|
SLE_VAR(RoadStopTileData, tile, SLE_UINT32),
|
||||||
|
SLE_VAR(RoadStopTileData, random_bits, SLE_UINT8),
|
||||||
|
SLE_VAR(RoadStopTileData, animation_frame, SLE_UINT8),
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the base station description to be used for SL_ST_INCLUDE
|
* Get the base station description to be used for SL_ST_INCLUDE
|
||||||
* @return the base station description.
|
* @return the base station description.
|
||||||
@@ -515,6 +525,7 @@ static void RealSave_STNN(BaseStation *bst)
|
|||||||
{
|
{
|
||||||
_num_specs = (uint8)bst->speclist.size();
|
_num_specs = (uint8)bst->speclist.size();
|
||||||
_num_roadstop_specs = (uint8)bst->roadstop_speclist.size();
|
_num_roadstop_specs = (uint8)bst->roadstop_speclist.size();
|
||||||
|
_num_roadstop_custom_tiles = (uint32)bst->custom_roadstop_tile_data.size();
|
||||||
|
|
||||||
bool waypoint = (bst->facilities & FACIL_WAYPOINT) != 0;
|
bool waypoint = (bst->facilities & FACIL_WAYPOINT) != 0;
|
||||||
SlObjectSaveFiltered(bst, waypoint ? SaveLoadTable(_filtered_waypoint_desc) : SaveLoadTable(_filtered_station_desc));
|
SlObjectSaveFiltered(bst, waypoint ? SaveLoadTable(_filtered_waypoint_desc) : SaveLoadTable(_filtered_station_desc));
|
||||||
@@ -575,6 +586,10 @@ static void RealSave_STNN(BaseStation *bst)
|
|||||||
for (uint i = 0; i < bst->roadstop_speclist.size(); i++) {
|
for (uint i = 0; i < bst->roadstop_speclist.size(); i++) {
|
||||||
SlObjectSaveFiltered(&bst->roadstop_speclist[i], _filtered_station_speclist_desc);
|
SlObjectSaveFiltered(&bst->roadstop_speclist[i], _filtered_station_speclist_desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (uint i = 0; i < bst->custom_roadstop_tile_data.size(); i++) {
|
||||||
|
SlObjectSaveFiltered(&bst->custom_roadstop_tile_data[i], _custom_roadstop_tile_data_desc); // _custom_roadstop_tile_data_desc has no conditionals
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Save_STNN()
|
static void Save_STNN()
|
||||||
@@ -595,6 +610,7 @@ static void Load_STNN()
|
|||||||
_num_flows = 0;
|
_num_flows = 0;
|
||||||
_num_specs = 0;
|
_num_specs = 0;
|
||||||
_num_roadstop_specs = 0;
|
_num_roadstop_specs = 0;
|
||||||
|
_num_roadstop_custom_tiles = 0;
|
||||||
|
|
||||||
const uint num_cargo = IsSavegameVersionBefore(SLV_EXTEND_CARGOTYPES) ? 32 : NUM_CARGO;
|
const uint num_cargo = IsSavegameVersionBefore(SLV_EXTEND_CARGOTYPES) ? 32 : NUM_CARGO;
|
||||||
ReadBuffer *buffer = ReadBuffer::GetCurrent();
|
ReadBuffer *buffer = ReadBuffer::GetCurrent();
|
||||||
@@ -714,6 +730,22 @@ static void Load_STNN()
|
|||||||
SlObjectLoadFiltered(&bst->roadstop_speclist[i], _filtered_station_speclist_desc);
|
SlObjectLoadFiltered(&bst->roadstop_speclist[i], _filtered_station_speclist_desc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_num_roadstop_custom_tiles != 0) {
|
||||||
|
/* Allocate custom road stop tile data memory when loading a game */
|
||||||
|
bst->custom_roadstop_tile_data.resize(_num_roadstop_custom_tiles);
|
||||||
|
for (uint i = 0; i < bst->custom_roadstop_tile_data.size(); i++) {
|
||||||
|
SlObjectLoadFiltered(&bst->custom_roadstop_tile_data[i], _custom_roadstop_tile_data_desc); // _custom_roadstop_tile_data_desc has no conditionals
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SlXvIsFeaturePresent(XSLFI_GRF_ROADSTOPS, 1, 1)) {
|
||||||
|
for (size_t i = 0; i < _custom_road_stop_tiles.size(); i++) {
|
||||||
|
bst->custom_roadstop_tile_data.push_back({ _custom_road_stop_tiles[i], (uint8)GB(_custom_road_stop_data[i], 0, 8), (uint8)GB(_custom_road_stop_data[i], 8, 8) });
|
||||||
|
}
|
||||||
|
_custom_road_stop_tiles.clear();
|
||||||
|
_custom_road_stop_data.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -183,28 +183,30 @@ void BaseStation::PostDestructor(size_t index)
|
|||||||
InvalidateWindowData(WC_SELECT_STATION, 0, 0);
|
InvalidateWindowData(WC_SELECT_STATION, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BaseStation::SetRoadStopTileData(TileIndex tile, byte data, byte offset)
|
bool BaseStation::SetRoadStopTileData(TileIndex tile, byte data, bool animation)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < this->custom_road_stop_tiles.size(); i++) {
|
for (RoadStopTileData &tile_data : this->custom_roadstop_tile_data) {
|
||||||
if (this->custom_road_stop_tiles[i] == tile) {
|
if (tile_data.tile == tile) {
|
||||||
if (GB(this->custom_road_stop_data[i], offset, 8) == data) return false;
|
uint8 &value = animation ? tile_data.animation_frame : tile_data.random_bits;
|
||||||
SB(this->custom_road_stop_data[i], offset, 8, data);
|
if (value == data) return false;
|
||||||
|
value = data;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this->custom_road_stop_tiles.push_back(tile);
|
RoadStopTileData tile_data;
|
||||||
this->custom_road_stop_data.push_back(((uint)data) << offset);
|
tile_data.tile = tile;
|
||||||
|
tile_data.animation_frame = animation ? data : 0;
|
||||||
|
tile_data.random_bits = animation ? 0 : data;
|
||||||
|
this->custom_roadstop_tile_data.push_back(tile_data);
|
||||||
return data != 0;
|
return data != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseStation::RemoveRoadStopTileData(TileIndex tile)
|
void BaseStation::RemoveRoadStopTileData(TileIndex tile)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < this->custom_road_stop_tiles.size(); i++) {
|
for (RoadStopTileData &tile_data : this->custom_roadstop_tile_data) {
|
||||||
if (this->custom_road_stop_tiles[i] == tile) {
|
if (tile_data.tile == tile) {
|
||||||
this->custom_road_stop_tiles[i] = this->custom_road_stop_tiles.back();
|
tile_data = this->custom_roadstop_tile_data.back();
|
||||||
this->custom_road_stop_data[i] = this->custom_road_stop_data.back();
|
this->custom_roadstop_tile_data.pop_back();
|
||||||
this->custom_road_stop_tiles.pop_back();
|
|
||||||
this->custom_road_stop_data.pop_back();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user