OpenTTD Source  20241121-master-g67a0fccfad
newgrf_roadtype.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of OpenTTD.
3  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
6  */
7 
10 #include "stdafx.h"
11 #include "core/container_func.hpp"
12 #include "debug.h"
13 #include "newgrf_roadtype.h"
15 #include "depot_base.h"
16 #include "town.h"
17 
18 #include "safeguards.h"
19 
20 /* virtual */ uint32_t RoadTypeScopeResolver::GetRandomBits() const
21 {
22  uint tmp = CountBits(this->tile.base() + (TileX(this->tile) + TileY(this->tile)) * TILE_SIZE);
23  return GB(tmp, 0, 2);
24 }
25 
26 /* virtual */ uint32_t RoadTypeScopeResolver::GetVariable(uint8_t variable, [[maybe_unused]] uint32_t parameter, bool &available) const
27 {
28  if (this->tile == INVALID_TILE) {
29  switch (variable) {
30  case 0x40: return 0;
31  case 0x41: return 0;
32  case 0x42: return 0;
33  case 0x43: return TimerGameCalendar::date.base();
34  case 0x44: return HZB_TOWN_EDGE;
35  }
36  }
37 
38  switch (variable) {
39  case 0x40: return GetTerrainType(this->tile, this->context);
40  case 0x41: return 0;
41  case 0x42: return IsLevelCrossingTile(this->tile) && IsCrossingBarred(this->tile);
42  case 0x43:
43  if (IsRoadDepotTile(this->tile)) return Depot::GetByTile(this->tile)->build_date.base();
44  return TimerGameCalendar::date.base();
45  case 0x44: {
46  const Town *t = nullptr;
47  if (IsRoadDepotTile(this->tile)) {
48  t = Depot::GetByTile(this->tile)->town;
49  } else {
50  t = ClosestTownFromTile(this->tile, UINT_MAX);
51  }
52  return t != nullptr ? GetTownRadiusGroup(t, this->tile) : HZB_TOWN_EDGE;
53  }
54  }
55 
56  Debug(grf, 1, "Unhandled road type tile variable 0x{:X}", variable);
57 
58  available = false;
59  return UINT_MAX;
60 }
61 
63 {
64  RoadType rt = GetRoadTypeByLabel(this->roadtype_scope.rti->label, false);
65  switch (GetRoadTramType(rt)) {
66  case RTT_ROAD: return GSF_ROADTYPES;
67  case RTT_TRAM: return GSF_TRAMTYPES;
68  default: return GSF_INVALID;
69  }
70 }
71 
73 {
74  return this->roadtype_scope.rti->label;
75 }
76 
86 RoadTypeResolverObject::RoadTypeResolverObject(const RoadTypeInfo *rti, TileIndex tile, TileContext context, RoadTypeSpriteGroup rtsg, uint32_t param1, uint32_t param2)
87  : ResolverObject(rti != nullptr ? rti->grffile[rtsg] : nullptr, CBID_NO_CALLBACK, param1, param2), roadtype_scope(*this, rti, tile, context)
88 {
89  this->root_spritegroup = rti != nullptr ? rti->group[rtsg] : nullptr;
90 }
91 
101 SpriteID GetCustomRoadSprite(const RoadTypeInfo *rti, TileIndex tile, RoadTypeSpriteGroup rtsg, TileContext context, uint *num_results)
102 {
103  assert(rtsg < ROTSG_END);
104 
105  if (rti->group[rtsg] == nullptr) return 0;
106 
107  RoadTypeResolverObject object(rti, tile, context, rtsg);
108  const SpriteGroup *group = object.Resolve();
109  if (group == nullptr || group->GetNumResults() == 0) return 0;
110 
111  if (num_results) *num_results = group->GetNumResults();
112 
113  return group->GetResult();
114 }
115 
123 RoadType GetRoadTypeTranslation(RoadTramType rtt, uint8_t tracktype, const GRFFile *grffile)
124 {
125  /* Because OpenTTD mixes RoadTypes and TramTypes into the same type,
126  * the mapping of the original road- and tramtypes does not match the default GRF-local mapping.
127  * So, this function cannot provide any similar behavior to GetCargoTranslation() and GetRailTypeTranslation()
128  * when the GRF defines no translation table.
129  * But since there is only one default road/tram-type, this makes little sense anyway.
130  * So for GRF without translation table, we always return INVALID_ROADTYPE.
131  */
132 
133  if (grffile == nullptr) return INVALID_ROADTYPE;
134 
135  const auto &list = rtt == RTT_TRAM ? grffile->tramtype_list : grffile->roadtype_list;
136  if (tracktype >= list.size()) return INVALID_ROADTYPE;
137 
138  /* Look up roadtype including alternate labels. */
139  RoadType result = GetRoadTypeByLabel(list[tracktype]);
140 
141  /* Check whether the result is actually the wanted road/tram-type */
142  if (result != INVALID_ROADTYPE && GetRoadTramType(result) != rtt) return INVALID_ROADTYPE;
143 
144  return result;
145 }
146 
153 uint8_t GetReverseRoadTypeTranslation(RoadType roadtype, const GRFFile *grffile)
154 {
155  /* No road type table present, return road type as-is */
156  if (grffile == nullptr) return roadtype;
157 
158  const std::vector<RoadTypeLabel> *list = RoadTypeIsRoad(roadtype) ? &grffile->roadtype_list : &grffile->tramtype_list;
159  if (list->empty()) return roadtype;
160 
161  /* Look for a matching road type label in the table */
162  RoadTypeLabel label = GetRoadTypeInfo(roadtype)->label;
163 
164  int index = find_index(*list, label);
165  if (index >= 0) return index;
166 
167  /* If not found, return as invalid */
168  return 0xFF;
169 }
constexpr uint CountBits(T value)
Counts the number of set bits in a variable.
constexpr static debug_inline uint GB(const T x, const uint8_t s, const uint8_t n)
Fetch n bits from x, started at bit s.
RoadTypeLabel label
Unique 32 bit road type identifier.
Definition: road.h:147
const SpriteGroup * group[ROTSG_END]
Sprite groups for resolving sprites.
Definition: road.h:192
static Date date
Current date in days (day counter).
Some simple functions to help with accessing containers.
int find_index(Container const &container, typename Container::const_reference item)
Helper function to get the index of an item Consider using std::set, std::unordered_set or std::flat_...
Functions related to debugging.
#define Debug(category, level, format_string,...)
Ouptut a line of debugging information.
Definition: debug.h:37
Base for all depots (except hangars)
uint32_t SpriteID
The number of a sprite, without mapping bits and colourtables.
Definition: gfx_type.h:18
static debug_inline uint TileY(TileIndex tile)
Get the Y component of a tile.
Definition: map_func.h:425
static debug_inline uint TileX(TileIndex tile)
Get the X component of a tile.
Definition: map_func.h:415
GrfSpecFeature
Definition: newgrf.h:67
@ GSF_INVALID
An invalid spec feature.
Definition: newgrf.h:94
@ CBID_NO_CALLBACK
Set when using the callback resolve system, but not to resolve a callback.
uint32_t GetTerrainType(TileIndex tile, TileContext context)
Function used by houses (and soon industries) to get information on type of "terrain" the tile it is ...
TileContext
Context for tile accesses.
SpriteID GetCustomRoadSprite(const RoadTypeInfo *rti, TileIndex tile, RoadTypeSpriteGroup rtsg, TileContext context, uint *num_results)
Get the sprite to draw for the given tile.
uint8_t GetReverseRoadTypeTranslation(RoadType roadtype, const GRFFile *grffile)
Perform a reverse roadtype lookup to get the GRF internal ID.
RoadType GetRoadTypeTranslation(RoadTramType rtt, uint8_t tracktype, const GRFFile *grffile)
Translate an index to the GRF-local road/tramtype-translation table into a RoadType.
NewGRF handling of road types.
RoadType GetRoadTypeByLabel(RoadTypeLabel label, bool allow_alternate_labels)
Get the road type for a given label.
Definition: road.cpp:254
const RoadTypeInfo * GetRoadTypeInfo(RoadType roadtype)
Returns a pointer to the Roadtype information for a given roadtype.
Definition: road.h:227
RoadTypeSpriteGroup
Sprite groups for a roadtype.
Definition: road.h:59
bool IsLevelCrossingTile(Tile t)
Return whether a tile is a level crossing tile.
Definition: road_map.h:95
static debug_inline bool IsRoadDepotTile(Tile t)
Return whether a tile is a road depot tile.
Definition: road_map.h:116
bool IsCrossingBarred(Tile t)
Check if the level crossing is barred.
Definition: road_map.h:416
RoadType
The different roadtypes we support.
Definition: road_type.h:25
@ INVALID_ROADTYPE
flag for invalid roadtype
Definition: road_type.h:30
A number of safeguards to prevent using unsafe methods.
Definition of base types and functions in a cross-platform compatible way.
TimerGameCalendar::Date build_date
Date of construction.
Definition: depot_base.h:26
Dynamic data of a loaded NewGRF.
Definition: newgrf.h:108
std::vector< RoadTypeLabel > roadtype_list
Roadtype translation table (road)
Definition: newgrf.h:136
std::vector< RoadTypeLabel > tramtype_list
Roadtype translation table (tram)
Definition: newgrf.h:139
Interface for SpriteGroup-s to access the gamestate.
const SpriteGroup * root_spritegroup
Root SpriteGroup to use for resolving.
Resolver object for road types.
RoadTypeScopeResolver roadtype_scope
Resolver for the roadtype scope.
RoadTypeResolverObject(const RoadTypeInfo *rti, TileIndex tile, TileContext context, RoadTypeSpriteGroup rtsg, uint32_t param1=0, uint32_t param2=0)
Resolver object for road types.
uint32_t GetDebugID() const override
Get an identifier for the item being resolved.
GrfSpecFeature GetFeature() const override
Get the feature number being resolved for.
uint32_t GetVariable(uint8_t variable, [[maybe_unused]] uint32_t parameter, bool &available) const override
Get a variable value.
TileContext context
Are we resolving sprites for the upper halftile, or on a bridge?
uint32_t GetRandomBits() const override
Get a few random bits.
TileIndex tile
Tracktile. For track on a bridge this is the southern bridgehead.
virtual const SpriteGroup * Resolve([[maybe_unused]] ResolverObject &object) const
Base sprite group resolver.
Town data structure.
Definition: town.h:54
static const uint TILE_SIZE
Tile size in world coordinates.
Definition: tile_type.h:15
constexpr TileIndex INVALID_TILE
The very nice invalid tile marker.
Definition: tile_type.h:95
Definition of the game-calendar-timer.
Base of the town class.
HouseZonesBits GetTownRadiusGroup(const Town *t, TileIndex tile)
Returns the bit corresponding to the town zone of the specified tile.
Definition: town_cmd.cpp:2447
Town * ClosestTownFromTile(TileIndex tile, uint threshold)
Return the town closest (in distance or ownership) to a given tile, within a given threshold.
Definition: town_cmd.cpp:3870