OpenTTD Source 20260721-master-g25ec12c62d
newgrf_act0_railtypes.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 <https://www.gnu.org/licenses/old-licenses/gpl-2.0>.
6 */
7
9
10#include "../stdafx.h"
11#include "../debug.h"
12#include "../rail.h"
13#include "newgrf_bytereader.h"
14#include "newgrf_internal.h"
16
17#include "../safeguards.h"
18
27static ChangeInfoResult RailTypeChangeInfo(uint first, uint last, int prop, ByteReader &buf)
28{
30
31 extern RailTypeInfo _railtypes[RAILTYPE_END];
32 const auto &type_map = _cur_gps.grffile->railtype_map;
33
34 if (last > std::size(type_map)) {
35 GrfMsg(1, "RailTypeChangeInfo: Rail type {} is invalid, max {}, ignoring", last, std::size(type_map));
37 }
38
39 for (uint id = first; id < last; ++id) {
40 RailType rt = type_map[id];
42
43 RailTypeInfo *rti = &_railtypes[rt];
44
45 switch (prop) {
46 case 0x08: // Label of rail type
47 /* Skipped here as this is loaded during reservation stage. */
48 buf.ReadDWord();
49 break;
50
51 case 0x09: { // Toolbar caption of railtype (sets name as well for backwards compatibility for grf ver < 8)
52 GRFStringID str{buf.ReadWord()};
54 if (_cur_gps.grffile->grf_version < 8) {
56 }
57 break;
58 }
59
60 case 0x0A: // Menu text of railtype
62 break;
63
64 case 0x0B: // Build window caption
66 break;
67
68 case 0x0C: // Autoreplace text
70 break;
71
72 case 0x0D: // New locomotive text
74 break;
75
76 case 0x0E: // Compatible railtype list
77 case 0x0F: // Powered railtype list
78 case 0x18: // Railtype list required for date introduction
79 case 0x19: // Introduced railtype list
80 {
81 /* Rail type compatibility bits are added to the existing bits
82 * to allow multiple GRFs to modify compatibility with the
83 * default rail types. */
84 int n = buf.ReadByte();
85 for (int j = 0; j != n; j++) {
86 RailType resolved_rt = GetRailTypeByLabel(buf.ReadLabel<RailTypeLabel>(), false);
87 if (resolved_rt != INVALID_RAILTYPE) {
88 switch (prop) {
89 case 0x0F: rti->powered_railtypes.Set(resolved_rt); [[fallthrough]]; // Powered implies compatible.
90 case 0x0E: rti->compatible_railtypes.Set(resolved_rt); break;
91 case 0x18: rti->introduction_required_railtypes.Set(resolved_rt); break;
92 case 0x19: rti->introduces_railtypes.Set(resolved_rt); break;
93 }
94 }
95 }
96 break;
97 }
98
99 case 0x10: // Rail Type flags
100 rti->flags = static_cast<RailTypeFlags>(buf.ReadByte());
101 break;
102
103 case 0x11: // Curve speed advantage
104 rti->curve_speed = buf.ReadByte();
105 break;
106
107 case 0x12: // Station graphic
108 rti->fallback_railtype = Clamp(buf.ReadByte(), 0, 2);
109 break;
110
111 case 0x13: // Construction cost factor
112 rti->cost_multiplier = buf.ReadWord();
113 break;
114
115 case 0x14: // Speed limit
116 rti->max_speed = buf.ReadWord();
117 break;
118
119 case 0x15: // Acceleration model
120 rti->acceleration_type = static_cast<VehicleAccelerationModel>(Clamp(buf.ReadByte(), 0, 2));
121 break;
122
123 case 0x16: // Map colour
124 rti->map_colour = PixelColour{buf.ReadByte()};
125 break;
126
127 case 0x17: // Introduction date
129 break;
130
131 case 0x1A: // Sort order
132 rti->sorting_order = buf.ReadByte();
133 break;
134
135 case 0x1B: // Name of railtype (overridden by prop 09 for grf ver < 8)
137 break;
138
139 case 0x1C: // Maintenance cost factor
140 rti->maintenance_multiplier = buf.ReadWord();
141 break;
142
143 case 0x1D: // Alternate rail type label list
144 /* Skipped here as this is loaded during reservation stage. */
145 for (int j = buf.ReadByte(); j != 0; j--) buf.ReadDWord();
146 break;
147
148 case 0x1E: // Badge list
149 rti->badges = ReadBadgeList(buf, GrfSpecFeature::RailTypes);
150 break;
151
152 default:
154 break;
155 }
156 }
157
158 return ret;
159}
160
161static ChangeInfoResult RailTypeReserveInfo(uint first, uint last, int prop, ByteReader &buf)
162{
164
165 extern RailTypeInfo _railtypes[RAILTYPE_END];
166 auto &type_map = _cur_gps.grffile->railtype_map;
167
168 if (last > std::size(type_map)) {
169 GrfMsg(1, "RailTypeReserveInfo: Rail type {} is invalid, max {}, ignoring", last, std::size(type_map));
171 }
172
173 for (uint id = first; id < last; ++id) {
174 switch (prop) {
175 case 0x08: // Label of rail type
176 {
177 RailTypeLabel rtl = buf.ReadLabel<RailTypeLabel>();
178 RailType rt = GetRailTypeByLabel(rtl, false);
179 if (rt == INVALID_RAILTYPE) {
180 /* Set up new rail type */
181 rt = AllocateRailType(rtl);
182 }
183
184 type_map[id] = rt;
185 break;
186 }
187
188 case 0x09: // Toolbar caption of railtype
189 case 0x0A: // Menu text
190 case 0x0B: // Build window caption
191 case 0x0C: // Autoreplace text
192 case 0x0D: // New loco
193 case 0x13: // Construction cost
194 case 0x14: // Speed limit
195 case 0x1B: // Name of railtype
196 case 0x1C: // Maintenance cost factor
197 buf.ReadWord();
198 break;
199
200 case 0x1D: // Alternate rail type label list
201 if (type_map[id] != INVALID_RAILTYPE) {
202 int n = buf.ReadByte();
203 for (int j = 0; j != n; j++) {
204 _railtypes[type_map[id]].alternate_labels.insert(buf.ReadLabel<RailTypeLabel>());
205 }
206 break;
207 }
208 GrfMsg(1, "RailTypeReserveInfo: Ignoring property 1D for rail type {} because no label was set", id);
209 [[fallthrough]];
210
211 case 0x0E: // Compatible railtype list
212 case 0x0F: // Powered railtype list
213 case 0x18: // Railtype list required for date introduction
214 case 0x19: // Introduced railtype list
215 for (int j = buf.ReadByte(); j != 0; j--) buf.ReadDWord();
216 break;
217
218 case 0x10: // Rail Type flags
219 case 0x11: // Curve speed advantage
220 case 0x12: // Station graphic
221 case 0x15: // Acceleration model
222 case 0x16: // Map colour
223 case 0x1A: // Sort order
224 buf.ReadByte();
225 break;
226
227 case 0x17: // Introduction date
228 buf.ReadDWord();
229 break;
230
231 case 0x1E: // Badge list
232 SkipBadgeList(buf);
233 break;
234
235 default:
237 break;
238 }
239 }
240
241 return ret;
242}
243
245template <> ChangeInfoResult GrfChangeInfoHandler<GrfSpecFeature::RailTypes>::Reserve(uint first, uint last, int prop, ByteReader &buf) { return RailTypeReserveInfo(first, last, prop, buf); }
247template <> ChangeInfoResult GrfChangeInfoHandler<GrfSpecFeature::RailTypes>::Activation(uint first, uint last, int prop, ByteReader &buf) { return RailTypeChangeInfo(first, last, prop, buf); }
constexpr Timpl & Set()
Set all bits.
Class to read from a NewGRF file.
uint32_t ReadDWord()
Read a single DWord (32 bits).
uint16_t ReadWord()
Read a single Word (16 bits).
T ReadLabel()
Read a label.
uint8_t ReadByte()
Read a single byte (8 bits).
This struct contains all the info that is needed to draw and construct tracks.
Definition rail.h:117
uint16_t max_speed
Maximum speed for vehicles travelling on this rail type.
Definition rail.h:222
struct RailTypeInfo::@157247141350136173143103254227157213063052244122 strings
Strings associated with the rail type.
TimerGameCalendar::Date introduction_date
Introduction date.
Definition rail.h:246
PixelColour map_colour
Colour on mini-map.
Definition rail.h:237
RailTypes powered_railtypes
bitmask to the OTHER railtypes on which an engine of THIS railtype generates power
Definition rail.h:179
RailTypes introduces_railtypes
Bitmask of which other railtypes are introduced when this railtype is introduced.
Definition rail.h:257
EnumIndexArray< const GRFFile *, RailSpriteType, RailSpriteType::End > grffile
NewGRF providing the Action3 for the railtype.
Definition rail.h:267
RailTypes introduction_required_railtypes
Bitmask of railtypes that are required for this railtype to be introduced at a given introduction_dat...
Definition rail.h:252
uint8_t sorting_order
The sorting order of this railtype for the toolbar dropdown.
Definition rail.h:262
VehicleAccelerationModel acceleration_type
Acceleration type of this rail type.
Definition rail.h:217
uint16_t maintenance_multiplier
Cost multiplier for maintenance of this rail type.
Definition rail.h:212
StringID menu_text
Name of this rail type in the main toolbar dropdown.
Definition rail.h:169
StringID name
Name of this rail type.
Definition rail.h:167
RailTypes compatible_railtypes
bitmask to the OTHER railtypes on which an engine of THIS railtype can physically travel
Definition rail.h:182
uint8_t fallback_railtype
Original railtype number to use when drawing non-newgrf railtypes, or when drawing stations.
Definition rail.h:192
StringID toolbar_caption
Caption in the construction toolbar GUI for this rail type.
Definition rail.h:168
RailTypeFlags flags
Bit mask of rail type flags.
Definition rail.h:202
uint8_t curve_speed
Multiplier for curve maximum speed advantage.
Definition rail.h:197
uint16_t cost_multiplier
Cost multiplier for building this rail type.
Definition rail.h:207
StringID replace_text
Text used in the autoreplace GUI.
Definition rail.h:171
StringID build_caption
Caption of the build vehicle GUI for this rail type.
Definition rail.h:170
StringID new_loco
Name of an engine for this type of rail in the engine preview GUI.
Definition rail.h:172
StrongType::Typedef< int32_t, DateTag< struct Calendar >, StrongType::Compare, StrongType::Integer > Date
Functions related to debugging.
VehicleAccelerationModel
Acceleration model of a vehicle.
Definition engine_type.h:47
constexpr T Clamp(const T a, const T min, const T max)
Clamp a value between an interval.
Definition math_func.hpp:79
@ RailTypes
Rail types feature.
Definition newgrf.h:95
std::vector< BadgeID > ReadBadgeList(ByteReader &buf, GrfSpecFeature feature)
Read a list of badges.
void SkipBadgeList(ByteReader &buf)
Skip a list of badges.
static ChangeInfoResult RailTypeChangeInfo(uint first, uint last, int prop, ByteReader &buf)
Define properties for railtypes.
NewGRF buffer reader definition.
NewGRF internal processing state.
ChangeInfoResult
Possible return values for the GrfChangeInfoHandler functions.
@ Success
Variable was parsed and read.
@ Unknown
Variable is unknown.
@ InvalidId
Attempt to modify an invalid ID.
void AddStringForMapping(GRFStringID source, std::function< void(StringID)> &&func)
Record a static StringID for getting translated later.
NewGRF string mapping definition.
StrongType::Typedef< uint32_t, struct GRFStringIDTag, StrongType::Compare, StrongType::Integer > GRFStringID
Type for GRF-internal string IDs.
RailType GetRailTypeByLabel(RailTypeLabel label, bool allow_alternate_labels)
Get the rail type for a given label.
Definition rail.cpp:197
Rail specific functions.
RailType AllocateRailType(RailTypeLabel label)
Allocate a new rail type label.
Definition rail_cmd.cpp:150
EnumBitSet< RailTypeFlag, uint8_t > RailTypeFlags
Bitset of RailTypeFlag elements.
Definition rail.h:37
RailType
Enumeration for all possible railtypes.
Definition rail_type.h:26
@ RAILTYPE_END
Used for iterations.
Definition rail_type.h:32
@ INVALID_RAILTYPE
Flag for invalid railtype.
Definition rail_type.h:33
A number of safeguards to prevent using unsafe methods.
Definition of base types and functions in a cross-platform compatible way.
static ChangeInfoResult Reserve(uint first, uint last, int prop, ByteReader &buf)
Implementation of the GrfLoadingStage::Reserve stage of this feature.
static ChangeInfoResult Activation(uint first, uint last, int prop, ByteReader &buf)
Implementation of the GrfLoadingStage::Activation stage of this feature.
Colour for pixel/line drawing.
Definition gfx_type.h:307