diff --git a/docs/newgrf-roadstops-nml.html b/docs/newgrf-roadstops-nml.html index 63bebb82e1..269005cace 100644 --- a/docs/newgrf-roadstops-nml.html +++ b/docs/newgrf-roadstops-nml.html @@ -43,7 +43,10 @@

Road Stop IDs

- Road stop IDs are NewGRF-local and can therefore freely be chosen in the 0..255 range. A road stop is allocated by setting the 'class'-property, which should therefore be set first. + A road stop is allocated by setting the 'class'-property, which should therefore be set first.
+ Road stop IDs are NewGRF-local and can be freely chosen in the 0..63999 range, as of version 7 of the road_stops feature.
+ When loaded into a version of OpenTTD with versions 1 to 6 of the road_stops feature, IDs are limited to the range: 0..254. + Any road stops with IDs outside this range will be skipped.

Road Stop Properties

@@ -172,6 +175,7 @@ nearby_tile_road_piecex, y offset (-8..7)0..18 | 0xFFPresent road piece and slope in sprite order, or 0xFF if none nearby_tile_tram_piecex, y offset (-8..7)0..18 | 0xFFPresent tram piece and slope in sprite order, or 0xFF if none nearby_tile_road_stop_infox, y offset (-8..7)Above nearby road tile variables in one variable (all of variable 0x6B) + nearby_tile_road_stop_info_v2x, y offset (-8..7)Above nearby road tile variables in one variable (all of variable roadstop_road_stop_info_nearby_tiles_v2)

Road Stop Callbacks

diff --git a/docs/newgrf-roadstops.html b/docs/newgrf-roadstops.html index b166186c2e..55f25a1ca3 100644 --- a/docs/newgrf-roadstops.html +++ b/docs/newgrf-roadstops.html @@ -323,7 +323,10 @@ - + + +
BitsMeaning
0 - 7If the tile is defined in the current GRF, this is the setID used in the definition. Otherwise, the content is undefined.
0 - 7 + If the tile is defined in the current GRF, this is the lower 8 bits of the setID used in the definition. Otherwise, the content is undefined.
+ Note that if this GRF has any road stop setIDs greater than 255, bits 24 - 31 need to be used as well. +
8 - 9 0 - The tile uses original TTD graphics
1 - The tile is defined in the current GRF
@@ -344,6 +347,43 @@ 1 - North-bound only
2 - South-bound only
3 - No entry +
24 - 31 + If the tile is defined in the current GRF, this is the upper 8 bits of the setID used in the definition. Otherwise, the content is undefined.
+ This can be ignored if this GRF does not have any road stop setIDs greater than 255 (does not define more than 256 road stop types).
+ This requires road_stops, version 7. +
+
+ The remaining bits are reserved for future use and should be masked. +

+ +

Road stop of nearby tile v2 (mappable variable: roadstop_road_stop_info_nearby_tiles_v2)

+

This has a similar value to 68/roadstop_road_stop_info_nearby_tiles, above.
+ + + + + + + + + + +
BitsMeaning
0 - 15If the tile is defined in the current GRF, this is the setID used in the definition. Otherwise, the content is undefined.
16 - 17 + 0 - The tile uses original TTD graphics
+ 1 - The tile is defined in the current GRF
+ 2 - The tile is defined in another GRF +
18Set if the selected tile belongs to the current station, clear otherwise
19Clear if the selected tile has the same view/rotation, set if a different view/rotation
20 - 23View/rotation of the selected tile
24 - 27 + 0 - Passenger/bus stop
+ 1 - Freight/lorry stop
+ 2 - Road waypoint +
28Set if the stop type (passenger/bus, freight/lorry or road waypoint) is the same as the current tile
29 - 30 + One-way road information of the selected tile:
+ 0 - Two-way traffic
+ 1 - North-bound only
+ 2 - South-bound only
+ 3 - No entry

The remaining bits are reserved for future use and should be masked. @@ -415,6 +455,10 @@

Road stops have the same Action 3 cargo-type values as feature 4 (station).

+

In feature name road_stops version 7 and later, the Action 3 ID field is an extended byte; GRFs may define more than 255 road stop types.
+ In versions 1 to 6 (inclusive), only 255 road stop types may be defined per GRF, and the extended byte format may not be used.

+
+

Erata

In feature name road_stops versions 1 to 5 (inclusive), mapped Action 0 properties which are unknown and should be ignored, instead generate an error on use.

diff --git a/src/base_station_base.h b/src/base_station_base.h index a34b3dd839..4fd319d6c9 100644 --- a/src/base_station_base.h +++ b/src/base_station_base.h @@ -30,7 +30,7 @@ struct StationSpecList { struct RoadStopSpecList { const RoadStopSpec *spec; uint32 grfid; ///< GRF ID of this custom road stop - uint8 localidx; ///< Station ID within GRF of road stop + uint16 localidx; ///< Station ID within GRF of road stop }; struct RoadStopTileData { diff --git a/src/newgrf.cpp b/src/newgrf.cpp index 5f81b16d12..13783435e1 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -5056,12 +5056,14 @@ static ChangeInfoResult RoadStopChangeInfo(uint id, int numinfo, int prop, const { ChangeInfoResult ret = CIR_SUCCESS; - if (id + numinfo > 255) { - grfmsg(1, "RoadStopChangeInfo: RoadStop %u is invalid, max %u, ignoring", id + numinfo, 255); + if (id + numinfo > NUM_ROADSTOPS_PER_GRF) { + grfmsg(1, "RoadStopChangeInfo: RoadStop %u is invalid, max %u, ignoring", id + numinfo, NUM_ROADSTOPS_PER_GRF); return CIR_INVALID_ID; } - if (_cur.grffile->roadstops == nullptr) _cur.grffile->roadstops = CallocT(255); + if (id + numinfo > _cur.grffile->roadstops.size()) { + _cur.grffile->roadstops.resize(id + numinfo); + } for (int i = 0; i < numinfo; i++) { RoadStopSpec *rs = _cur.grffile->roadstops[id + i]; @@ -6701,9 +6703,9 @@ static void AirportTileMapSpriteGroup(ByteReader *buf, uint8 idcount) static void RoadStopMapSpriteGroup(ByteReader *buf, uint8 idcount) { - uint8 *roadstops = AllocaM(uint8, idcount); + uint16 *roadstops = AllocaM(uint16, idcount); for (uint i = 0; i < idcount; i++) { - roadstops[i] = buf->ReadByte(); + roadstops[i] = buf->ReadExtendedByte(); } uint8 cidcount = buf->ReadByte(); @@ -6716,7 +6718,7 @@ static void RoadStopMapSpriteGroup(ByteReader *buf, uint8 idcount) if (ctype == CT_INVALID) continue; for (uint i = 0; i < idcount; i++) { - RoadStopSpec *roadstopspec = _cur.grffile->roadstops == nullptr ? nullptr : _cur.grffile->roadstops[roadstops[i]]; + RoadStopSpec *roadstopspec = (roadstops[i] >= _cur.grffile->roadstops.size()) ? nullptr : _cur.grffile->roadstops[roadstops[i]]; if (roadstopspec == nullptr) { grfmsg(1, "RoadStopMapSpriteGroup: Road stop with ID 0x%02X does not exist, skipping", roadstops[i]); @@ -6730,13 +6732,13 @@ static void RoadStopMapSpriteGroup(ByteReader *buf, uint8 idcount) uint16 groupid = buf->ReadWord(); if (!IsValidGroupID(groupid, "RoadStopMapSpriteGroup")) return; - if (_cur.grffile->roadstops == nullptr) { + if (_cur.grffile->roadstops.empty()) { grfmsg(0, "RoadStopMapSpriteGroup: No roadstops defined, skipping."); return; } for (uint i = 0; i < idcount; i++) { - RoadStopSpec *roadstopspec = _cur.grffile->roadstops == nullptr ? nullptr : _cur.grffile->roadstops[roadstops[i]]; + RoadStopSpec *roadstopspec = (roadstops[i] >= _cur.grffile->roadstops.size()) ? nullptr : _cur.grffile->roadstops[roadstops[i]]; if (roadstopspec == nullptr) { grfmsg(1, "RoadStopMapSpriteGroup: Road stop with ID 0x%02X does not exist, skipping.", roadstops[i]); @@ -10147,14 +10149,12 @@ static void ResetCustomObjects() static void ResetCustomRoadStops() { for (auto file : _grf_files) { - RoadStopSpec **&roadstopspec = file->roadstops; - if (roadstopspec == nullptr) continue; - for (uint i = 0; i < NUM_ROADSTOPS_PER_GRF; i++) { - free(roadstopspec[i]); + std::vector &roadstops = file->roadstops; + for (RoadStopSpec *spec : roadstops) { + free(spec); } - free(roadstopspec); - roadstopspec = nullptr; + roadstops.clear(); } } diff --git a/src/newgrf.h b/src/newgrf.h index 0454e95233..2765bca309 100644 --- a/src/newgrf.h +++ b/src/newgrf.h @@ -320,7 +320,7 @@ struct GRFFile : ZeroedMemoryAllocator { std::vector objectspec; struct AirportSpec **airportspec; struct AirportTileSpec **airtspec; - struct RoadStopSpec **roadstops; + std::vector roadstops; GRFFeatureMapRemapSet feature_id_remaps; GRFFilePropertyRemapSet action0_property_remaps[GSF_END]; diff --git a/src/newgrf_class.h b/src/newgrf_class.h index 02d1487a5b..fa14d352e2 100644 --- a/src/newgrf_class.h +++ b/src/newgrf_class.h @@ -63,7 +63,7 @@ public: static bool IsClassIDValid(Tid cls_id); static NewGRFClass *Get(Tid cls_id); - static const Tspec *GetByGrf(uint32 grfid, byte local_id, int *index); + static const Tspec *GetByGrf(uint32 grfid, uint16 local_id, int *index); }; #endif /* NEWGRF_CLASS_H */ diff --git a/src/newgrf_class_func.h b/src/newgrf_class_func.h index da5fa44d05..5b391baee1 100644 --- a/src/newgrf_class_func.h +++ b/src/newgrf_class_func.h @@ -209,7 +209,7 @@ DEFINE_NEWGRF_CLASS_METHOD(int)::GetUIFromIndex(int index) const * @param index Pointer to return the index of the spec in its class. If nullptr then not used. * @return The spec. */ -DEFINE_NEWGRF_CLASS_METHOD(const Tspec *)::GetByGrf(uint32 grfid, byte local_id, int *index) +DEFINE_NEWGRF_CLASS_METHOD(const Tspec *)::GetByGrf(uint32 grfid, uint16 local_id, int *index) { uint j; @@ -246,4 +246,4 @@ DEFINE_NEWGRF_CLASS_METHOD(const Tspec *)::GetByGrf(uint32 grfid, byte local_id, template const Tspec *name::GetSpec(uint index) const; \ template int name::GetUIFromIndex(int index) const; \ template int name::GetIndexFromUI(int ui_index) const; \ - template const Tspec *name::GetByGrf(uint32 grfid, byte localidx, int *index); + template const Tspec *name::GetByGrf(uint32 grfid, uint16 localidx, int *index); diff --git a/src/newgrf_extension.cpp b/src/newgrf_extension.cpp index 42395d9ecb..3e9c557f92 100644 --- a/src/newgrf_extension.cpp +++ b/src/newgrf_extension.cpp @@ -55,7 +55,7 @@ extern const GRFFeatureInfo _grf_feature_list[] = { GRFFeatureInfo("action0_object_edge_foundation_mode", 2), GRFFeatureInfo("action0_object_flood_resistant", 1), GRFFeatureInfo("action0_object_viewport_map_tile_type", 1), - GRFFeatureInfo("road_stops", 6), + GRFFeatureInfo("road_stops", 7), GRFFeatureInfo("new_landscape", 2), GRFFeatureInfo("more_objects_per_grf", 1), GRFFeatureInfo(), @@ -150,6 +150,7 @@ extern const GRFVariableMapDefinition _grf_action2_remappable_variables[] = { GRFVariableMapDefinition(GSF_ROADSTOPS, 0x68, "roadstop_road_stop_info_nearby_tiles"), GRFVariableMapDefinition(GSF_ROADSTOPS, 0x6A, "roadstop_road_stop_grfid_nearby_tiles"), GRFVariableMapDefinition(GSF_ROADSTOPS, 0x6B, "roadstop_road_info_nearby_tiles"), + GRFVariableMapDefinition(GSF_ROADSTOPS, A2VRI_ROADSTOP_INFO_NEARBY_TILES_V2, "roadstop_road_stop_info_nearby_tiles_v2"), GRFVariableMapDefinition(GSF_RAILTYPES, A2VRI_RAILTYPE_SIGNAL_RESTRICTION_INFO, "railtype_signal_restriction_info"), GRFVariableMapDefinition(GSF_RAILTYPES, A2VRI_RAILTYPE_SIGNAL_CONTEXT, "railtype_signal_context"), GRFVariableMapDefinition(GSF_SIGNALS, A2VRI_SIGNALS_SIGNAL_RESTRICTION_INFO, "signals_signal_restriction_info"), diff --git a/src/newgrf_extension.h b/src/newgrf_extension.h index aa13d5a7d7..348103369c 100644 --- a/src/newgrf_extension.h +++ b/src/newgrf_extension.h @@ -77,6 +77,7 @@ enum Action2VariableRemapIds { A2VRI_OBJECT_FOUNDATION_SLOPE = 0x100, A2VRI_OBJECT_FOUNDATION_SLOPE_CHANGE, A2VRI_VEHICLE_CURRENT_SPEED_SCALED, + A2VRI_ROADSTOP_INFO_NEARBY_TILES_V2, A2VRI_RAILTYPE_SIGNAL_RESTRICTION_INFO, A2VRI_RAILTYPE_SIGNAL_CONTEXT, A2VRI_SIGNALS_SIGNAL_RESTRICTION_INFO, diff --git a/src/newgrf_roadstop.cpp b/src/newgrf_roadstop.cpp index ed79ecdf1d..8ad2870ff0 100644 --- a/src/newgrf_roadstop.cpp +++ b/src/newgrf_roadstop.cpp @@ -24,6 +24,7 @@ #include "viewport_func.h" #include "newgrf_animation_base.h" #include "newgrf_sound.h" +#include "newgrf_extension.h" #include "safeguards.h" @@ -66,6 +67,39 @@ uint32 RoadStopScopeResolver::GetTriggers() const return this->st == nullptr ? 0 : this->st->waiting_triggers; } +uint32 RoadStopScopeResolver::GetNearbyRoadStopsInfo(uint32 parameter, bool v2) const +{ + if (this->tile == INVALID_TILE) return 0xFFFFFFFF; + TileIndex nearby_tile = GetNearbyTile(parameter, this->tile); + + if (!IsAnyRoadStopTile(nearby_tile)) return 0xFFFFFFFF; + + uint32 grfid = this->st->roadstop_speclist[GetCustomRoadStopSpecIndex(this->tile)].grfid; + bool same_orientation = GetStationGfx(this->tile) == GetStationGfx(nearby_tile); + bool same_station = GetStationIndex(nearby_tile) == this->st->index; + uint32 res = GetStationGfx(nearby_tile) << 12 | !same_orientation << 11 | !!same_station << 10; + StationType type = GetStationType(nearby_tile); + if (type == STATION_TRUCK) res |= (1 << 16); + if (type == STATION_ROADWAYPOINT) res |= (2 << 16); + if (type == this->type) SetBit(res, 20); + + uint16 localidx = 0; + if (IsCustomRoadStopSpecIndex(nearby_tile)) { + const RoadStopSpecList ssl = BaseStation::GetByTile(nearby_tile)->roadstop_speclist[GetCustomRoadStopSpecIndex(nearby_tile)]; + localidx = ssl.localidx; + res |= 1 << (ssl.grfid != grfid ? 9 : 8); + } + if (IsDriveThroughStopTile(nearby_tile)) { + res |= (GetDriveThroughStopDisallowedRoadDirections(nearby_tile) << 21); + } + + if (v2) { + return (res << 8) | localidx; + } else { + return res | (localidx & 0xFF) | ((localidx & 0xFF00) << 16); + } +} + uint32 RoadStopScopeResolver::GetVariable(uint16 variable, uint32 parameter, GetVariableExtra *extra) const { auto get_road_type_variable = [&](RoadTramType rtt) -> uint32 { @@ -151,28 +185,12 @@ uint32 RoadStopScopeResolver::GetVariable(uint16 variable, uint32 parameter, Get /* Road stop info of nearby tiles */ case 0x68: { - if (this->tile == INVALID_TILE) return 0xFFFFFFFF; - TileIndex nearby_tile = GetNearbyTile(parameter, this->tile); + return this->GetNearbyRoadStopsInfo(parameter, false); + } - if (!IsAnyRoadStopTile(nearby_tile)) return 0xFFFFFFFF; - - uint32 grfid = this->st->roadstop_speclist[GetCustomRoadStopSpecIndex(this->tile)].grfid; - bool same_orientation = GetStationGfx(this->tile) == GetStationGfx(nearby_tile); - bool same_station = GetStationIndex(nearby_tile) == this->st->index; - uint32 res = GetStationGfx(nearby_tile) << 12 | !same_orientation << 11 | !!same_station << 10; - StationType type = GetStationType(nearby_tile); - if (type == STATION_TRUCK) res |= (1 << 16); - if (type == STATION_ROADWAYPOINT) res |= (2 << 16); - if (type == this->type) SetBit(res, 20); - - if (IsCustomRoadStopSpecIndex(nearby_tile)) { - const RoadStopSpecList ssl = BaseStation::GetByTile(nearby_tile)->roadstop_speclist[GetCustomRoadStopSpecIndex(nearby_tile)]; - res |= 1 << (ssl.grfid != grfid ? 9 : 8) | ssl.localidx; - } - if (IsDriveThroughStopTile(nearby_tile)) { - res |= (GetDriveThroughStopDisallowedRoadDirections(nearby_tile) << 21); - } - return res; + /* Road stop info of nearby tiles: v2 */ + case A2VRI_ROADSTOP_INFO_NEARBY_TILES_V2: { + return this->GetNearbyRoadStopsInfo(parameter, true); } /* GRFID of nearby road stop tiles */ diff --git a/src/newgrf_roadstop.h b/src/newgrf_roadstop.h index 4a370eccd5..1adc150fd1 100644 --- a/src/newgrf_roadstop.h +++ b/src/newgrf_roadstop.h @@ -20,7 +20,7 @@ #include "road.h" /** The maximum amount of roadstops a single GRF is allowed to add */ -static const int NUM_ROADSTOPS_PER_GRF = 255; +static const int NUM_ROADSTOPS_PER_GRF = 64000; enum RoadStopClassID : byte { ROADSTOP_CLASS_BEGIN = 0, ///< The lowest valid value @@ -98,6 +98,9 @@ struct RoadStopScopeResolver : public ScopeResolver { uint32 GetTriggers() const override; uint32 GetVariable(uint16 variable, uint32 parameter, GetVariableExtra *extra) const override; + +private: + uint32 GetNearbyRoadStopsInfo(uint32 parameter, bool v2) const; }; /** Road stop resolver. */ diff --git a/src/road_gui.cpp b/src/road_gui.cpp index 95b7572a92..a2bb493a71 100644 --- a/src/road_gui.cpp +++ b/src/road_gui.cpp @@ -62,8 +62,8 @@ struct RoadStopGUISettings { DiagDirection orientation; // This replaces _road_station_picker_orientation RoadStopClassID roadstop_class; - byte roadstop_type; - byte roadstop_count; + uint16 roadstop_type; + uint16 roadstop_count; }; static RoadStopGUISettings _roadstop_gui_settings; @@ -217,7 +217,7 @@ void CcRoadStop(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, bool connect_to_road = true; RoadStopClassID spec_class = Extract(p3); - byte spec_index = GB(p3, 8, 8); + uint16 spec_index = GB(p3, 16, 16); if ((uint)spec_class < RoadStopClass::GetClassCount() && spec_index < RoadStopClass::Get(spec_class)->GetSpecCount()) { const RoadStopSpec *roadstopspec = RoadStopClass::Get(spec_class)->GetSpec(spec_index); if (roadstopspec != nullptr && HasBit(roadstopspec->flags, RSF_NO_AUTO_ROAD_CONNECTION)) connect_to_road = false; @@ -256,7 +256,7 @@ static void PlaceRoadStop(TileIndex start_tile, TileIndex end_tile, uint32 p2, u TileArea ta(start_tile, end_tile); CommandContainer cmdcont = NewCommandContainerBasic(ta.tile, (uint32)(ta.w | ta.h << 8), p2, cmd, CcRoadStop); - cmdcont.p3 = (_roadstop_gui_settings.roadstop_type << 8) | _roadstop_gui_settings.roadstop_class; + cmdcont.p3 = (_roadstop_gui_settings.roadstop_type << 16) | _roadstop_gui_settings.roadstop_class; ShowSelectStationIfNeeded(cmdcont, ta); } diff --git a/src/saveload/extended_ver_sl.cpp b/src/saveload/extended_ver_sl.cpp index 8c7c46c60d..6b0a194ecd 100644 --- a/src/saveload/extended_ver_sl.cpp +++ b/src/saveload/extended_ver_sl.cpp @@ -171,7 +171,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = { { 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_RV_ORDER_EXTRA_FLAGS, XSCF_IGNORABLE_UNKNOWN, 1, 1, "rv_order_extra_flags", nullptr, nullptr, nullptr }, - { XSLFI_GRF_ROADSTOPS, XSCF_NULL, 2, 2, "grf_road_stops", nullptr, nullptr, nullptr }, + { XSLFI_GRF_ROADSTOPS, XSCF_NULL, 3, 3, "grf_road_stops", 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_NO_TREE_COUNTER, XSCF_IGNORABLE_ALL, 1, 1, "no_tree_counter", nullptr, nullptr, nullptr }, diff --git a/src/saveload/station_sl.cpp b/src/saveload/station_sl.cpp index 7a2b8393b1..9b40bb336c 100644 --- a/src/saveload/station_sl.cpp +++ b/src/saveload/station_sl.cpp @@ -243,6 +243,12 @@ static const SaveLoad _station_speclist_desc[] = { SLE_CONDVAR(StationSpecList, localidx, SLE_UINT8, SLV_27, SL_MAX_VERSION), }; +static const SaveLoad _roadstop_speclist_desc[] = { + SLE_CONDVAR(RoadStopSpecList, grfid, SLE_UINT32, SL_MIN_VERSION, SL_MAX_VERSION), + SLE_CONDVAR_X(RoadStopSpecList, localidx, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_GRF_ROADSTOPS, 0, 2)), + SLE_CONDVAR_X(RoadStopSpecList, localidx, SLE_UINT16, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_GRF_ROADSTOPS, 3)), +}; + CargoPacketList _packets; uint32 _num_dests; @@ -504,6 +510,7 @@ std::vector _filtered_station_desc; std::vector _filtered_waypoint_desc; std::vector _filtered_goods_desc; std::vector _filtered_station_speclist_desc; +std::vector _filtered_roadstop_speclist_desc; static void SetupDescs_STNN() { @@ -511,6 +518,7 @@ static void SetupDescs_STNN() _filtered_waypoint_desc = SlFilterObject(_waypoint_desc); _filtered_goods_desc = SlFilterObject(GetGoodsDesc()); _filtered_station_speclist_desc = SlFilterObject(_station_speclist_desc); + _filtered_roadstop_speclist_desc = SlFilterObject(_roadstop_speclist_desc); } std::vector _filtered_roadstop_desc; @@ -584,7 +592,7 @@ static void RealSave_STNN(BaseStation *bst) } 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_roadstop_speclist_desc); } for (uint i = 0; i < bst->custom_roadstop_tile_data.size(); i++) { @@ -727,7 +735,7 @@ static void Load_STNN() /* Allocate speclist memory when loading a game */ bst->roadstop_speclist.resize(_num_roadstop_specs); for (uint i = 0; i < bst->roadstop_speclist.size(); i++) { - SlObjectLoadFiltered(&bst->roadstop_speclist[i], _filtered_station_speclist_desc); + SlObjectLoadFiltered(&bst->roadstop_speclist[i], _filtered_roadstop_speclist_desc); } } diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index f5dc4919c2..1bbececcda 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -2083,7 +2083,7 @@ static CommandCost FindJoiningRoadStop(StationID existing_stop, StationID statio * bit 5..10: The roadtype. * bit 16..31: Station ID to join (NEW_STATION if build new one). * @param p3 bit 0..7: Roadstop class. - * bit 8..15: Roadstopspec index. + * bit 16..31: Roadstopspec index. * @param text Unused. * @return The cost of this operation or an error. */ @@ -2102,7 +2102,7 @@ CommandCost CmdBuildRoadStop(TileIndex tile, DoCommandFlag flags, uint32 p1, uin uint8 length = (uint8)GB(p1, 8, 8); RoadStopClassID spec_class = Extract(p3); - byte spec_index = GB(p3, 8, 8); + uint16 spec_index = GB(p3, 16, 16); /* Check if the given station class is valid */ if ((uint)spec_class >= RoadStopClass::GetClassCount() || spec_class == ROADSTOP_CLASS_WAYP) return CMD_ERROR; diff --git a/src/table/newgrf_debug_data.h b/src/table/newgrf_debug_data.h index 8ff42a4dc2..99f978ba6d 100644 --- a/src/table/newgrf_debug_data.h +++ b/src/table/newgrf_debug_data.h @@ -1846,6 +1846,7 @@ static const NIVariable _nif_roadstops[] = { NIV(0x69, "information about cargo accepted in the past"), NIV(0x6A, "GRFID of nearby road stop tiles"), NIV(0x6B, "Road info of nearby plain road tiles"), + NIV(A2VRI_ROADSTOP_INFO_NEARBY_TILES_V2, "road stop info of nearby tiles v2"), NIV_END(), };