OpenTTD Source: src/newgrf/newgrf_act0_railtypes.cpp Source File

OpenTTD Source 15.3

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
10#include "../stdafx.h"
11#include "../debug.h"
12#include "../rail.h"
13#include "newgrf_bytereader.h"
14#include "newgrf_internal.h"
15#include "newgrf_stringmapping.h"
16
17#include "../safeguards.h"
18
27 static ChangeInfoResult RailTypeChangeInfo(uint first, uint last, int prop, ByteReader &buf)
28{
29 ChangeInfoResult ret = CIR_SUCCESS;
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));
36 return CIR_INVALID_ID;
37 }
38
39 for (uint id = first; id < last; ++id) {
40 RailType rt = type_map[id];
41 if (rt == INVALID_RAILTYPE) return CIR_INVALID_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()};
53 AddStringForMapping(str, &rti->strings.toolbar_caption);
54 if (_cur_gps.grffile->grf_version < 8) {
55 AddStringForMapping(str, &rti->strings.name);
56 }
57 break;
58 }
59
60 case 0x0A: // Menu text of railtype
61 AddStringForMapping(GRFStringID{buf.ReadWord()}, &rti->strings.menu_text);
62 break;
63
64 case 0x0B: // Build window caption
65 AddStringForMapping(GRFStringID{buf.ReadWord()}, &rti->strings.build_caption);
66 break;
67
68 case 0x0C: // Autoreplace text
69 AddStringForMapping(GRFStringID{buf.ReadWord()}, &rti->strings.replace_text);
70 break;
71
72 case 0x0D: // New locomotive text
73 AddStringForMapping(GRFStringID{buf.ReadWord()}, &rti->strings.new_loco);
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 RailTypeLabel label = buf.ReadDWord();
87 RailType resolved_rt = GetRailTypeByLabel(std::byteswap(label), false);
88 if (resolved_rt != INVALID_RAILTYPE) {
89 switch (prop) {
90 case 0x0F: rti->powered_railtypes.Set(resolved_rt); [[fallthrough]]; // Powered implies compatible.
91 case 0x0E: rti->compatible_railtypes.Set(resolved_rt); break;
92 case 0x18: rti->introduction_required_railtypes.Set(resolved_rt); break;
93 case 0x19: rti->introduces_railtypes.Set(resolved_rt); break;
94 }
95 }
96 }
97 break;
98 }
99
100 case 0x10: // Rail Type flags
101 rti->flags = static_cast<RailTypeFlags>(buf.ReadByte());
102 break;
103
104 case 0x11: // Curve speed advantage
105 rti->curve_speed = buf.ReadByte();
106 break;
107
108 case 0x12: // Station graphic
109 rti->fallback_railtype = Clamp(buf.ReadByte(), 0, 2);
110 break;
111
112 case 0x13: // Construction cost factor
113 rti->cost_multiplier = buf.ReadWord();
114 break;
115
116 case 0x14: // Speed limit
117 rti->max_speed = buf.ReadWord();
118 break;
119
120 case 0x15: // Acceleration model
121 rti->acceleration_type = static_cast<VehicleAccelerationModel>(Clamp(buf.ReadByte(), 0, 2));
122 break;
123
124 case 0x16: // Map colour
125 rti->map_colour = PixelColour{buf.ReadByte()};
126 break;
127
128 case 0x17: // Introduction date
129 rti->introduction_date = TimerGameCalendar::Date(buf.ReadDWord());
130 break;
131
132 case 0x1A: // Sort order
133 rti->sorting_order = buf.ReadByte();
134 break;
135
136 case 0x1B: // Name of railtype (overridden by prop 09 for grf ver < 8)
137 AddStringForMapping(GRFStringID{buf.ReadWord()}, &rti->strings.name);
138 break;
139
140 case 0x1C: // Maintenance cost factor
141 rti->maintenance_multiplier = buf.ReadWord();
142 break;
143
144 case 0x1D: // Alternate rail type label list
145 /* Skipped here as this is loaded during reservation stage. */
146 for (int j = buf.ReadByte(); j != 0; j--) buf.ReadDWord();
147 break;
148
149 case 0x1E: // Badge list
150 rti->badges = ReadBadgeList(buf, GSF_RAILTYPES);
151 break;
152
153 default:
154 ret = CIR_UNKNOWN;
155 break;
156 }
157 }
158
159 return ret;
160}
161
162static ChangeInfoResult RailTypeReserveInfo(uint first, uint last, int prop, ByteReader &buf)
163{
164 ChangeInfoResult ret = CIR_SUCCESS;
165
166 extern RailTypeInfo _railtypes[RAILTYPE_END];
167 auto &type_map = _cur_gps.grffile->railtype_map;
168
169 if (last > std::size(type_map)) {
170 GrfMsg(1, "RailTypeReserveInfo: Rail type {} is invalid, max {}, ignoring", last, std::size(type_map));
171 return CIR_INVALID_ID;
172 }
173
174 for (uint id = first; id < last; ++id) {
175 switch (prop) {
176 case 0x08: // Label of rail type
177 {
178 RailTypeLabel rtl = buf.ReadDWord();
179 rtl = std::byteswap(rtl);
180
181 RailType rt = GetRailTypeByLabel(rtl, false);
182 if (rt == INVALID_RAILTYPE) {
183 /* Set up new rail type */
184 rt = AllocateRailType(rtl);
185 }
186
187 type_map[id] = rt;
188 break;
189 }
190
191 case 0x09: // Toolbar caption of railtype
192 case 0x0A: // Menu text
193 case 0x0B: // Build window caption
194 case 0x0C: // Autoreplace text
195 case 0x0D: // New loco
196 case 0x13: // Construction cost
197 case 0x14: // Speed limit
198 case 0x1B: // Name of railtype
199 case 0x1C: // Maintenance cost factor
200 buf.ReadWord();
201 break;
202
203 case 0x1D: // Alternate rail type label list
204 if (type_map[id] != INVALID_RAILTYPE) {
205 int n = buf.ReadByte();
206 for (int j = 0; j != n; j++) {
207 _railtypes[type_map[id]].alternate_labels.insert(std::byteswap(buf.ReadDWord()));
208 }
209 break;
210 }
211 GrfMsg(1, "RailTypeReserveInfo: Ignoring property 1D for rail type {} because no label was set", id);
212 [[fallthrough]];
213
214 case 0x0E: // Compatible railtype list
215 case 0x0F: // Powered railtype list
216 case 0x18: // Railtype list required for date introduction
217 case 0x19: // Introduced railtype list
218 for (int j = buf.ReadByte(); j != 0; j--) buf.ReadDWord();
219 break;
220
221 case 0x10: // Rail Type flags
222 case 0x11: // Curve speed advantage
223 case 0x12: // Station graphic
224 case 0x15: // Acceleration model
225 case 0x16: // Map colour
226 case 0x1A: // Sort order
227 buf.ReadByte();
228 break;
229
230 case 0x17: // Introduction date
231 buf.ReadDWord();
232 break;
233
234 case 0x1E: // Badge list
235 SkipBadgeList(buf);
236 break;
237
238 default:
239 ret = CIR_UNKNOWN;
240 break;
241 }
242 }
243
244 return ret;
245}
246
247template <> ChangeInfoResult GrfChangeInfoHandler<GSF_RAILTYPES>::Reserve(uint first, uint last, int prop, ByteReader &buf) { return RailTypeReserveInfo(first, last, prop, buf); }
248template <> ChangeInfoResult GrfChangeInfoHandler<GSF_RAILTYPES>::Activation(uint first, uint last, int prop, ByteReader &buf) { return RailTypeChangeInfo(first, last, prop, buf); }
std::byteswap
constexpr enable_if_t< is_integral_v< T >, T > byteswap(T x) noexcept
Custom implementation of std::byteswap; remove once we build with C++23.
Definition bitmath_func.hpp:330
BaseBitSet::Set
constexpr Timpl & Set()
Set all bits.
Definition base_bitset_type.hpp:40
ByteReader
Class to read from a NewGRF file.
Definition newgrf_bytereader.h:18
ByteReader::ReadDWord
uint32_t ReadDWord()
Read a single DWord (32 bits).
Definition newgrf_bytereader.h:66
ByteReader::ReadWord
uint16_t ReadWord()
Read a single Word (16 bits).
Definition newgrf_bytereader.h:45
ByteReader::ReadByte
uint8_t ReadByte()
Read a single byte (8 bits).
Definition newgrf_bytereader.h:34
EnumBitSet< RailTypeFlag, uint8_t >
FlatSet::insert
std::pair< const_iterator, bool > insert(const Tkey &key)
Insert a key into the set, if it does not already exist.
Definition flatset_type.hpp:31
RailTypeInfo
This struct contains all the info that is needed to draw and construct tracks.
Definition rail.h:115
RailTypeInfo::max_speed
uint16_t max_speed
Maximum speed for vehicles travelling on this rail type.
Definition rail.h:220
RailTypeInfo::introduction_date
TimerGameCalendar::Date introduction_date
Introduction date.
Definition rail.h:244
RailTypeInfo::map_colour
PixelColour map_colour
Colour on mini-map.
Definition rail.h:235
RailTypeInfo::powered_railtypes
RailTypes powered_railtypes
bitmask to the OTHER railtypes on which an engine of THIS railtype generates power
Definition rail.h:177
RailTypeInfo::introduces_railtypes
RailTypes introduces_railtypes
Bitmask of which other railtypes are introduced when this railtype is introduced.
Definition rail.h:255
RailTypeInfo::introduction_required_railtypes
RailTypes introduction_required_railtypes
Bitmask of railtypes that are required for this railtype to be introduced at a given introduction_dat...
Definition rail.h:250
RailTypeInfo::sorting_order
uint8_t sorting_order
The sorting order of this railtype for the toolbar dropdown.
Definition rail.h:260
RailTypeInfo::acceleration_type
VehicleAccelerationModel acceleration_type
Acceleration type of this rail type.
Definition rail.h:215
RailTypeInfo::maintenance_multiplier
uint16_t maintenance_multiplier
Cost multiplier for maintenance of this rail type.
Definition rail.h:210
RailTypeInfo::menu_text
StringID menu_text
Name of this rail type in the main toolbar dropdown.
Definition rail.h:167
RailTypeInfo::name
StringID name
Name of this rail type.
Definition rail.h:165
RailTypeInfo::compatible_railtypes
RailTypes compatible_railtypes
bitmask to the OTHER railtypes on which an engine of THIS railtype can physically travel
Definition rail.h:180
RailTypeInfo::fallback_railtype
uint8_t fallback_railtype
Original railtype number to use when drawing non-newgrf railtypes, or when drawing stations.
Definition rail.h:190
RailTypeInfo::toolbar_caption
StringID toolbar_caption
Caption in the construction toolbar GUI for this rail type.
Definition rail.h:166
RailTypeInfo::flags
RailTypeFlags flags
Bit mask of rail type flags.
Definition rail.h:200
RailTypeInfo::curve_speed
uint8_t curve_speed
Multiplier for curve maximum speed advantage.
Definition rail.h:195
RailTypeInfo::alternate_labels
FlatSet< RailTypeLabel > alternate_labels
Rail type labels this type provides in addition to the main label.
Definition rail.h:230
RailTypeInfo::strings
struct RailTypeInfo::@22 strings
Strings associated with the rail type.
RailTypeInfo::cost_multiplier
uint16_t cost_multiplier
Cost multiplier for building this rail type.
Definition rail.h:205
RailTypeInfo::replace_text
StringID replace_text
Text used in the autoreplace GUI.
Definition rail.h:169
RailTypeInfo::build_caption
StringID build_caption
Caption of the build vehicle GUI for this rail type.
Definition rail.h:168
RailTypeInfo::new_loco
StringID new_loco
Name of an engine for this type of rail in the engine preview GUI.
Definition rail.h:170
VehicleAccelerationModel
VehicleAccelerationModel
Acceleration model of a vehicle.
Definition engine_type.h:47
Clamp
constexpr T Clamp(const T a, const T min, const T max)
Clamp a value between an interval.
Definition math_func.hpp:79
ReadBadgeList
std::vector< BadgeID > ReadBadgeList(ByteReader &buf, GrfSpecFeature feature)
Read a list of badges.
Definition newgrf_act0.cpp:86
SkipBadgeList
void SkipBadgeList(ByteReader &buf)
Skip a list of badges.
Definition newgrf_act0.cpp:72
RailTypeChangeInfo
static ChangeInfoResult RailTypeChangeInfo(uint first, uint last, int prop, ByteReader &buf)
Define properties for railtypes.
Definition newgrf_act0_railtypes.cpp:27
newgrf_bytereader.h
NewGRF buffer reader definition.
newgrf_internal.h
NewGRF internal processing state.
ChangeInfoResult
ChangeInfoResult
Possible return values for the GrfChangeInfoHandler functions.
Definition newgrf_internal.h:20
CIR_INVALID_ID
@ CIR_INVALID_ID
Attempt to modify an invalid ID.
Definition newgrf_internal.h:25
CIR_UNKNOWN
@ CIR_UNKNOWN
Variable is unknown.
Definition newgrf_internal.h:24
CIR_SUCCESS
@ CIR_SUCCESS
Variable was parsed and read.
Definition newgrf_internal.h:21
AddStringForMapping
void AddStringForMapping(GRFStringID source, std::function< void(StringID)> &&func)
Record a static StringID for getting translated later.
Definition newgrf_stringmapping.cpp:42
newgrf_stringmapping.h
NewGRF string mapping definition.
GetRailTypeByLabel
RailType GetRailTypeByLabel(RailTypeLabel label, bool allow_alternate_labels)
Get the rail type for a given label.
Definition rail.cpp:195
AllocateRailType
RailType AllocateRailType(RailTypeLabel label)
Allocate a new rail type label.
Definition rail_cmd.cpp:148
RailType
RailType
Enumeration for all possible railtypes.
Definition rail_type.h:25
RAILTYPE_END
@ RAILTYPE_END
Used for iterations.
Definition rail_type.h:31
INVALID_RAILTYPE
@ INVALID_RAILTYPE
Flag for invalid railtype.
Definition rail_type.h:32
GrfChangeInfoHandler
GRF feature handler.
Definition newgrf_internal.h:30
GrfProcessingState::grffile
GRFFile * grffile
Currently processed GRF file.
Definition newgrf_internal.h:67
PixelColour
Colour for pixel/line drawing.
Definition gfx_type.h:405
StrongType::Typedef< uint32_t, struct GRFStringIDTag, StrongType::Compare, StrongType::Integer >