GRF: Initial support for > 255 road stop specs per GRF
Add new variable for road stop info of nearby tiles Bump roadstops version
This commit is contained in:
@@ -43,7 +43,10 @@
|
|||||||
|
|
||||||
<h3 id="roadstop_ids">Road Stop IDs</h3>
|
<h3 id="roadstop_ids">Road Stop IDs</h3>
|
||||||
<p>
|
<p>
|
||||||
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.<br />
|
||||||
|
Road stop IDs are NewGRF-local and can be freely chosen in the 0..63999 range, as of version 7 of the <span class="code">road_stops</span> feature.<br />
|
||||||
|
When loaded into a version of OpenTTD with versions 1 to 6 of the <span class="code">road_stops</span> feature, IDs are limited to the range: 0..254.
|
||||||
|
Any road stops with IDs outside this range will be skipped.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h3 id="roadstop_properties">Road Stop Properties</h3>
|
<h3 id="roadstop_properties">Road Stop Properties</h3>
|
||||||
@@ -172,6 +175,7 @@
|
|||||||
<tr><td>nearby_tile_road_piece</td><td>x, y offset (-8..7)</td><td>0..18 | 0xFF</td><td>Present road piece and slope in <a href="https://newgrf-specs.tt-wiki.net/wiki/Action3/Roadtypes#Road_underlay_.2802.29">sprite order</a>, or 0xFF if none</td></tr>
|
<tr><td>nearby_tile_road_piece</td><td>x, y offset (-8..7)</td><td>0..18 | 0xFF</td><td>Present road piece and slope in <a href="https://newgrf-specs.tt-wiki.net/wiki/Action3/Roadtypes#Road_underlay_.2802.29">sprite order</a>, or 0xFF if none</td></tr>
|
||||||
<tr><td>nearby_tile_tram_piece</td><td>x, y offset (-8..7)</td><td>0..18 | 0xFF</td><td>Present tram piece and slope in <a href="https://newgrf-specs.tt-wiki.net/wiki/Action3/Roadtypes#Road_underlay_.2802.29">sprite order</a>, or 0xFF if none</td></tr>
|
<tr><td>nearby_tile_tram_piece</td><td>x, y offset (-8..7)</td><td>0..18 | 0xFF</td><td>Present tram piece and slope in <a href="https://newgrf-specs.tt-wiki.net/wiki/Action3/Roadtypes#Road_underlay_.2802.29">sprite order</a>, or 0xFF if none</td></tr>
|
||||||
<tr><td>nearby_tile_road_stop_info</td><td>x, y offset (-8..7)</td><td></td><td>Above nearby road tile variables in one variable (all of variable 0x6B)</td></tr>
|
<tr><td>nearby_tile_road_stop_info</td><td>x, y offset (-8..7)</td><td></td><td>Above nearby road tile variables in one variable (all of variable 0x6B)</td></tr>
|
||||||
|
<tr><td>nearby_tile_road_stop_info_v2</td><td>x, y offset (-8..7)</td><td></td><td>Above nearby road tile variables in one variable (all of variable roadstop_road_stop_info_nearby_tiles_v2)</td></tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<h3 id="roadstop_callbacks">Road Stop Callbacks</h3>
|
<h3 id="roadstop_callbacks">Road Stop Callbacks</h3>
|
||||||
|
@@ -323,7 +323,10 @@
|
|||||||
|
|
||||||
<table>
|
<table>
|
||||||
<tr><th>Bits</th><th>Meaning</th></tr>
|
<tr><th>Bits</th><th>Meaning</th></tr>
|
||||||
<tr><td>0 - 7</td><td>If the tile is defined in the current GRF, this is the setID used in the definition. Otherwise, the content is undefined. </td></tr>
|
<tr><td>0 - 7</td><td>
|
||||||
|
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.<br />
|
||||||
|
Note that if this GRF has any road stop setIDs greater than 255, bits 24 - 31 need to be used as well.
|
||||||
|
</td></tr>
|
||||||
<tr><td>8 - 9</td><td>
|
<tr><td>8 - 9</td><td>
|
||||||
0 - The tile uses original TTD graphics<br />
|
0 - The tile uses original TTD graphics<br />
|
||||||
1 - The tile is defined in the current GRF<br />
|
1 - The tile is defined in the current GRF<br />
|
||||||
@@ -344,6 +347,43 @@
|
|||||||
1 - North-bound only<br />
|
1 - North-bound only<br />
|
||||||
2 - South-bound only<br />
|
2 - South-bound only<br />
|
||||||
3 - No entry
|
3 - No entry
|
||||||
|
</td></tr>
|
||||||
|
<tr><td>24 - 31</td><td>
|
||||||
|
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.<br />
|
||||||
|
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).<br />
|
||||||
|
This requires <font face="monospace">road_stops</font>, version 7.
|
||||||
|
</td></tr>
|
||||||
|
</table>
|
||||||
|
<br />
|
||||||
|
The remaining bits are reserved for future use and should be masked.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h4 id="roadstop_road_stop_info_nearby_tiles">Road stop of nearby tile v2 (mappable variable: roadstop_road_stop_info_nearby_tiles_v2)</h4>
|
||||||
|
<p>This has a similar value to <a href="#roadstop_road_stop_info_nearby_tiles">68</a>/<a href="#roadstop_road_stop_info_nearby_tiles">roadstop_road_stop_info_nearby_tiles</a>, above.<br />
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<tr><th>Bits</th><th>Meaning</th></tr>
|
||||||
|
<tr><td>0 - 15</td><td>If the tile is defined in the current GRF, this is the setID used in the definition. Otherwise, the content is undefined. </td></tr>
|
||||||
|
<tr><td>16 - 17</td><td>
|
||||||
|
0 - The tile uses original TTD graphics<br />
|
||||||
|
1 - The tile is defined in the current GRF<br />
|
||||||
|
2 - The tile is defined in another GRF
|
||||||
|
</td></tr>
|
||||||
|
<tr><td>18</td><td>Set if the selected tile belongs to the current station, clear otherwise</td></tr>
|
||||||
|
<tr><td>19</td><td>Clear if the selected tile has the same view/rotation, set if a different view/rotation</td></tr>
|
||||||
|
<tr><td>20 - 23</td><td>View/rotation of the selected tile</td></tr>
|
||||||
|
<tr><td>24 - 27</td><td>
|
||||||
|
0 - Passenger/bus stop<br />
|
||||||
|
1 - Freight/lorry stop<br />
|
||||||
|
2 - Road waypoint
|
||||||
|
</td></tr>
|
||||||
|
<tr><td>28</td><td>Set if the stop type (passenger/bus, freight/lorry or road waypoint) is the same as the current tile</td></tr>
|
||||||
|
<tr><td>29 - 30</td><td>
|
||||||
|
One-way road information of the selected tile:<br />
|
||||||
|
0 - Two-way traffic<br />
|
||||||
|
1 - North-bound only<br />
|
||||||
|
2 - South-bound only<br />
|
||||||
|
3 - No entry
|
||||||
</table>
|
</table>
|
||||||
<br />
|
<br />
|
||||||
The remaining bits are reserved for future use and should be masked.
|
The remaining bits are reserved for future use and should be masked.
|
||||||
@@ -415,6 +455,10 @@
|
|||||||
|
|
||||||
<p>Road stops have the same Action 3 cargo-type values as feature 4 (station).</p>
|
<p>Road stops have the same Action 3 cargo-type values as feature 4 (station).</p>
|
||||||
|
|
||||||
|
<p>In feature name <font face="monospace">road_stops</font> version 7 and later, the Action 3 ID field is an extended byte; GRFs may define more than 255 road stop types.<br />
|
||||||
|
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.</p>
|
||||||
|
<br />
|
||||||
|
|
||||||
<h3 id="erata">Erata</h3>
|
<h3 id="erata">Erata</h3>
|
||||||
|
|
||||||
<p>In feature name <font face="monospace">road_stops</font> versions 1 to 5 (inclusive), mapped Action 0 properties which are unknown and should be ignored, instead generate an error on use.</p>
|
<p>In feature name <font face="monospace">road_stops</font> versions 1 to 5 (inclusive), mapped Action 0 properties which are unknown and should be ignored, instead generate an error on use.</p>
|
||||||
|
@@ -30,7 +30,7 @@ struct StationSpecList {
|
|||||||
struct RoadStopSpecList {
|
struct RoadStopSpecList {
|
||||||
const RoadStopSpec *spec;
|
const RoadStopSpec *spec;
|
||||||
uint32 grfid; ///< GRF ID of this custom road stop
|
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 {
|
struct RoadStopTileData {
|
||||||
|
@@ -5056,12 +5056,14 @@ static ChangeInfoResult RoadStopChangeInfo(uint id, int numinfo, int prop, const
|
|||||||
{
|
{
|
||||||
ChangeInfoResult ret = CIR_SUCCESS;
|
ChangeInfoResult ret = CIR_SUCCESS;
|
||||||
|
|
||||||
if (id + numinfo > 255) {
|
if (id + numinfo > NUM_ROADSTOPS_PER_GRF) {
|
||||||
grfmsg(1, "RoadStopChangeInfo: RoadStop %u is invalid, max %u, ignoring", id + numinfo, 255);
|
grfmsg(1, "RoadStopChangeInfo: RoadStop %u is invalid, max %u, ignoring", id + numinfo, NUM_ROADSTOPS_PER_GRF);
|
||||||
return CIR_INVALID_ID;
|
return CIR_INVALID_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_cur.grffile->roadstops == nullptr) _cur.grffile->roadstops = CallocT<RoadStopSpec*>(255);
|
if (id + numinfo > _cur.grffile->roadstops.size()) {
|
||||||
|
_cur.grffile->roadstops.resize(id + numinfo);
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < numinfo; i++) {
|
for (int i = 0; i < numinfo; i++) {
|
||||||
RoadStopSpec *rs = _cur.grffile->roadstops[id + 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)
|
static void RoadStopMapSpriteGroup(ByteReader *buf, uint8 idcount)
|
||||||
{
|
{
|
||||||
uint8 *roadstops = AllocaM(uint8, idcount);
|
uint16 *roadstops = AllocaM(uint16, idcount);
|
||||||
for (uint i = 0; i < idcount; i++) {
|
for (uint i = 0; i < idcount; i++) {
|
||||||
roadstops[i] = buf->ReadByte();
|
roadstops[i] = buf->ReadExtendedByte();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 cidcount = buf->ReadByte();
|
uint8 cidcount = buf->ReadByte();
|
||||||
@@ -6716,7 +6718,7 @@ static void RoadStopMapSpriteGroup(ByteReader *buf, uint8 idcount)
|
|||||||
if (ctype == CT_INVALID) continue;
|
if (ctype == CT_INVALID) continue;
|
||||||
|
|
||||||
for (uint i = 0; i < idcount; i++) {
|
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) {
|
if (roadstopspec == nullptr) {
|
||||||
grfmsg(1, "RoadStopMapSpriteGroup: Road stop with ID 0x%02X does not exist, skipping", roadstops[i]);
|
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();
|
uint16 groupid = buf->ReadWord();
|
||||||
if (!IsValidGroupID(groupid, "RoadStopMapSpriteGroup")) return;
|
if (!IsValidGroupID(groupid, "RoadStopMapSpriteGroup")) return;
|
||||||
|
|
||||||
if (_cur.grffile->roadstops == nullptr) {
|
if (_cur.grffile->roadstops.empty()) {
|
||||||
grfmsg(0, "RoadStopMapSpriteGroup: No roadstops defined, skipping.");
|
grfmsg(0, "RoadStopMapSpriteGroup: No roadstops defined, skipping.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint i = 0; i < idcount; i++) {
|
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) {
|
if (roadstopspec == nullptr) {
|
||||||
grfmsg(1, "RoadStopMapSpriteGroup: Road stop with ID 0x%02X does not exist, skipping.", roadstops[i]);
|
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()
|
static void ResetCustomRoadStops()
|
||||||
{
|
{
|
||||||
for (auto file : _grf_files) {
|
for (auto file : _grf_files) {
|
||||||
RoadStopSpec **&roadstopspec = file->roadstops;
|
std::vector<RoadStopSpec *> &roadstops = file->roadstops;
|
||||||
if (roadstopspec == nullptr) continue;
|
for (RoadStopSpec *spec : roadstops) {
|
||||||
for (uint i = 0; i < NUM_ROADSTOPS_PER_GRF; i++) {
|
free(spec);
|
||||||
free(roadstopspec[i]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
free(roadstopspec);
|
roadstops.clear();
|
||||||
roadstopspec = nullptr;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -320,7 +320,7 @@ struct GRFFile : ZeroedMemoryAllocator {
|
|||||||
std::vector<struct ObjectSpec *> objectspec;
|
std::vector<struct ObjectSpec *> objectspec;
|
||||||
struct AirportSpec **airportspec;
|
struct AirportSpec **airportspec;
|
||||||
struct AirportTileSpec **airtspec;
|
struct AirportTileSpec **airtspec;
|
||||||
struct RoadStopSpec **roadstops;
|
std::vector<struct RoadStopSpec *> roadstops;
|
||||||
|
|
||||||
GRFFeatureMapRemapSet feature_id_remaps;
|
GRFFeatureMapRemapSet feature_id_remaps;
|
||||||
GRFFilePropertyRemapSet action0_property_remaps[GSF_END];
|
GRFFilePropertyRemapSet action0_property_remaps[GSF_END];
|
||||||
|
@@ -63,7 +63,7 @@ public:
|
|||||||
static bool IsClassIDValid(Tid cls_id);
|
static bool IsClassIDValid(Tid cls_id);
|
||||||
static NewGRFClass *Get(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 */
|
#endif /* NEWGRF_CLASS_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.
|
* @param index Pointer to return the index of the spec in its class. If nullptr then not used.
|
||||||
* @return The spec.
|
* @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;
|
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 const Tspec *name::GetSpec(uint index) const; \
|
||||||
template int name::GetUIFromIndex(int index) const; \
|
template int name::GetUIFromIndex(int index) const; \
|
||||||
template int name::GetIndexFromUI(int ui_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);
|
||||||
|
@@ -55,7 +55,7 @@ extern const GRFFeatureInfo _grf_feature_list[] = {
|
|||||||
GRFFeatureInfo("action0_object_edge_foundation_mode", 2),
|
GRFFeatureInfo("action0_object_edge_foundation_mode", 2),
|
||||||
GRFFeatureInfo("action0_object_flood_resistant", 1),
|
GRFFeatureInfo("action0_object_flood_resistant", 1),
|
||||||
GRFFeatureInfo("action0_object_viewport_map_tile_type", 1),
|
GRFFeatureInfo("action0_object_viewport_map_tile_type", 1),
|
||||||
GRFFeatureInfo("road_stops", 6),
|
GRFFeatureInfo("road_stops", 7),
|
||||||
GRFFeatureInfo("new_landscape", 2),
|
GRFFeatureInfo("new_landscape", 2),
|
||||||
GRFFeatureInfo("more_objects_per_grf", 1),
|
GRFFeatureInfo("more_objects_per_grf", 1),
|
||||||
GRFFeatureInfo(),
|
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, 0x68, "roadstop_road_stop_info_nearby_tiles"),
|
||||||
GRFVariableMapDefinition(GSF_ROADSTOPS, 0x6A, "roadstop_road_stop_grfid_nearby_tiles"),
|
GRFVariableMapDefinition(GSF_ROADSTOPS, 0x6A, "roadstop_road_stop_grfid_nearby_tiles"),
|
||||||
GRFVariableMapDefinition(GSF_ROADSTOPS, 0x6B, "roadstop_road_info_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_RESTRICTION_INFO, "railtype_signal_restriction_info"),
|
||||||
GRFVariableMapDefinition(GSF_RAILTYPES, A2VRI_RAILTYPE_SIGNAL_CONTEXT, "railtype_signal_context"),
|
GRFVariableMapDefinition(GSF_RAILTYPES, A2VRI_RAILTYPE_SIGNAL_CONTEXT, "railtype_signal_context"),
|
||||||
GRFVariableMapDefinition(GSF_SIGNALS, A2VRI_SIGNALS_SIGNAL_RESTRICTION_INFO, "signals_signal_restriction_info"),
|
GRFVariableMapDefinition(GSF_SIGNALS, A2VRI_SIGNALS_SIGNAL_RESTRICTION_INFO, "signals_signal_restriction_info"),
|
||||||
|
@@ -77,6 +77,7 @@ enum Action2VariableRemapIds {
|
|||||||
A2VRI_OBJECT_FOUNDATION_SLOPE = 0x100,
|
A2VRI_OBJECT_FOUNDATION_SLOPE = 0x100,
|
||||||
A2VRI_OBJECT_FOUNDATION_SLOPE_CHANGE,
|
A2VRI_OBJECT_FOUNDATION_SLOPE_CHANGE,
|
||||||
A2VRI_VEHICLE_CURRENT_SPEED_SCALED,
|
A2VRI_VEHICLE_CURRENT_SPEED_SCALED,
|
||||||
|
A2VRI_ROADSTOP_INFO_NEARBY_TILES_V2,
|
||||||
A2VRI_RAILTYPE_SIGNAL_RESTRICTION_INFO,
|
A2VRI_RAILTYPE_SIGNAL_RESTRICTION_INFO,
|
||||||
A2VRI_RAILTYPE_SIGNAL_CONTEXT,
|
A2VRI_RAILTYPE_SIGNAL_CONTEXT,
|
||||||
A2VRI_SIGNALS_SIGNAL_RESTRICTION_INFO,
|
A2VRI_SIGNALS_SIGNAL_RESTRICTION_INFO,
|
||||||
|
@@ -24,6 +24,7 @@
|
|||||||
#include "viewport_func.h"
|
#include "viewport_func.h"
|
||||||
#include "newgrf_animation_base.h"
|
#include "newgrf_animation_base.h"
|
||||||
#include "newgrf_sound.h"
|
#include "newgrf_sound.h"
|
||||||
|
#include "newgrf_extension.h"
|
||||||
|
|
||||||
#include "safeguards.h"
|
#include "safeguards.h"
|
||||||
|
|
||||||
@@ -66,6 +67,39 @@ uint32 RoadStopScopeResolver::GetTriggers() const
|
|||||||
return this->st == nullptr ? 0 : this->st->waiting_triggers;
|
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
|
uint32 RoadStopScopeResolver::GetVariable(uint16 variable, uint32 parameter, GetVariableExtra *extra) const
|
||||||
{
|
{
|
||||||
auto get_road_type_variable = [&](RoadTramType rtt) -> uint32 {
|
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 */
|
/* Road stop info of nearby tiles */
|
||||||
case 0x68: {
|
case 0x68: {
|
||||||
if (this->tile == INVALID_TILE) return 0xFFFFFFFF;
|
return this->GetNearbyRoadStopsInfo(parameter, false);
|
||||||
TileIndex nearby_tile = GetNearbyTile(parameter, this->tile);
|
}
|
||||||
|
|
||||||
if (!IsAnyRoadStopTile(nearby_tile)) return 0xFFFFFFFF;
|
/* Road stop info of nearby tiles: v2 */
|
||||||
|
case A2VRI_ROADSTOP_INFO_NEARBY_TILES_V2: {
|
||||||
uint32 grfid = this->st->roadstop_speclist[GetCustomRoadStopSpecIndex(this->tile)].grfid;
|
return this->GetNearbyRoadStopsInfo(parameter, true);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* GRFID of nearby road stop tiles */
|
/* GRFID of nearby road stop tiles */
|
||||||
|
@@ -20,7 +20,7 @@
|
|||||||
#include "road.h"
|
#include "road.h"
|
||||||
|
|
||||||
/** The maximum amount of roadstops a single GRF is allowed to add */
|
/** 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 {
|
enum RoadStopClassID : byte {
|
||||||
ROADSTOP_CLASS_BEGIN = 0, ///< The lowest valid value
|
ROADSTOP_CLASS_BEGIN = 0, ///< The lowest valid value
|
||||||
@@ -98,6 +98,9 @@ struct RoadStopScopeResolver : public ScopeResolver {
|
|||||||
uint32 GetTriggers() const override;
|
uint32 GetTriggers() const override;
|
||||||
|
|
||||||
uint32 GetVariable(uint16 variable, uint32 parameter, GetVariableExtra *extra) const override;
|
uint32 GetVariable(uint16 variable, uint32 parameter, GetVariableExtra *extra) const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint32 GetNearbyRoadStopsInfo(uint32 parameter, bool v2) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Road stop resolver. */
|
/** Road stop resolver. */
|
||||||
|
@@ -62,8 +62,8 @@ struct RoadStopGUISettings {
|
|||||||
DiagDirection orientation; // This replaces _road_station_picker_orientation
|
DiagDirection orientation; // This replaces _road_station_picker_orientation
|
||||||
|
|
||||||
RoadStopClassID roadstop_class;
|
RoadStopClassID roadstop_class;
|
||||||
byte roadstop_type;
|
uint16 roadstop_type;
|
||||||
byte roadstop_count;
|
uint16 roadstop_count;
|
||||||
};
|
};
|
||||||
static RoadStopGUISettings _roadstop_gui_settings;
|
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;
|
bool connect_to_road = true;
|
||||||
|
|
||||||
RoadStopClassID spec_class = Extract<RoadStopClassID, 0, 8>(p3);
|
RoadStopClassID spec_class = Extract<RoadStopClassID, 0, 8>(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()) {
|
if ((uint)spec_class < RoadStopClass::GetClassCount() && spec_index < RoadStopClass::Get(spec_class)->GetSpecCount()) {
|
||||||
const RoadStopSpec *roadstopspec = RoadStopClass::Get(spec_class)->GetSpec(spec_index);
|
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;
|
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);
|
TileArea ta(start_tile, end_tile);
|
||||||
CommandContainer cmdcont = NewCommandContainerBasic(ta.tile, (uint32)(ta.w | ta.h << 8), p2, cmd, CcRoadStop);
|
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);
|
ShowSelectStationIfNeeded(cmdcont, ta);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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, 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_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 },
|
||||||
|
@@ -243,6 +243,12 @@ static const SaveLoad _station_speclist_desc[] = {
|
|||||||
SLE_CONDVAR(StationSpecList, localidx, SLE_UINT8, SLV_27, SL_MAX_VERSION),
|
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;
|
CargoPacketList _packets;
|
||||||
uint32 _num_dests;
|
uint32 _num_dests;
|
||||||
|
|
||||||
@@ -504,6 +510,7 @@ std::vector<SaveLoad> _filtered_station_desc;
|
|||||||
std::vector<SaveLoad> _filtered_waypoint_desc;
|
std::vector<SaveLoad> _filtered_waypoint_desc;
|
||||||
std::vector<SaveLoad> _filtered_goods_desc;
|
std::vector<SaveLoad> _filtered_goods_desc;
|
||||||
std::vector<SaveLoad> _filtered_station_speclist_desc;
|
std::vector<SaveLoad> _filtered_station_speclist_desc;
|
||||||
|
std::vector<SaveLoad> _filtered_roadstop_speclist_desc;
|
||||||
|
|
||||||
static void SetupDescs_STNN()
|
static void SetupDescs_STNN()
|
||||||
{
|
{
|
||||||
@@ -511,6 +518,7 @@ static void SetupDescs_STNN()
|
|||||||
_filtered_waypoint_desc = SlFilterObject(_waypoint_desc);
|
_filtered_waypoint_desc = SlFilterObject(_waypoint_desc);
|
||||||
_filtered_goods_desc = SlFilterObject(GetGoodsDesc());
|
_filtered_goods_desc = SlFilterObject(GetGoodsDesc());
|
||||||
_filtered_station_speclist_desc = SlFilterObject(_station_speclist_desc);
|
_filtered_station_speclist_desc = SlFilterObject(_station_speclist_desc);
|
||||||
|
_filtered_roadstop_speclist_desc = SlFilterObject(_roadstop_speclist_desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<SaveLoad> _filtered_roadstop_desc;
|
std::vector<SaveLoad> _filtered_roadstop_desc;
|
||||||
@@ -584,7 +592,7 @@ 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_roadstop_speclist_desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint i = 0; i < bst->custom_roadstop_tile_data.size(); i++) {
|
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 */
|
/* Allocate speclist memory when loading a game */
|
||||||
bst->roadstop_speclist.resize(_num_roadstop_specs);
|
bst->roadstop_speclist.resize(_num_roadstop_specs);
|
||||||
for (uint i = 0; i < bst->roadstop_speclist.size(); i++) {
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -2083,7 +2083,7 @@ static CommandCost FindJoiningRoadStop(StationID existing_stop, StationID statio
|
|||||||
* bit 5..10: The roadtype.
|
* bit 5..10: The roadtype.
|
||||||
* bit 16..31: Station ID to join (NEW_STATION if build new one).
|
* bit 16..31: Station ID to join (NEW_STATION if build new one).
|
||||||
* @param p3 bit 0..7: Roadstop class.
|
* @param p3 bit 0..7: Roadstop class.
|
||||||
* bit 8..15: Roadstopspec index.
|
* bit 16..31: Roadstopspec index.
|
||||||
* @param text Unused.
|
* @param text Unused.
|
||||||
* @return The cost of this operation or an error.
|
* @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);
|
uint8 length = (uint8)GB(p1, 8, 8);
|
||||||
|
|
||||||
RoadStopClassID spec_class = Extract<RoadStopClassID, 0, 8>(p3);
|
RoadStopClassID spec_class = Extract<RoadStopClassID, 0, 8>(p3);
|
||||||
byte spec_index = GB(p3, 8, 8);
|
uint16 spec_index = GB(p3, 16, 16);
|
||||||
|
|
||||||
/* Check if the given station class is valid */
|
/* Check if the given station class is valid */
|
||||||
if ((uint)spec_class >= RoadStopClass::GetClassCount() || spec_class == ROADSTOP_CLASS_WAYP) return CMD_ERROR;
|
if ((uint)spec_class >= RoadStopClass::GetClassCount() || spec_class == ROADSTOP_CLASS_WAYP) return CMD_ERROR;
|
||||||
|
@@ -1846,6 +1846,7 @@ static const NIVariable _nif_roadstops[] = {
|
|||||||
NIV(0x69, "information about cargo accepted in the past"),
|
NIV(0x69, "information about cargo accepted in the past"),
|
||||||
NIV(0x6A, "GRFID of nearby road stop tiles"),
|
NIV(0x6A, "GRFID of nearby road stop tiles"),
|
||||||
NIV(0x6B, "Road info of nearby plain road 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(),
|
NIV_END(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user