OpenTTD Source 20250328-master-gc3457cd4c0
newgrf_act0_roadtypes.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 "../debug.h"
12#include "../road.h"
13#include "newgrf_bytereader.h"
14#include "newgrf_internal.h"
16
17#include "../safeguards.h"
18
28static ChangeInfoResult RoadTypeChangeInfo(uint first, uint last, int prop, ByteReader &buf, RoadTramType rtt)
29{
31
32 extern RoadTypeInfo _roadtypes[ROADTYPE_END];
33 std::array<RoadType, ROADTYPE_END> &type_map = (rtt == RTT_TRAM) ? _cur.grffile->tramtype_map : _cur.grffile->roadtype_map;
34
35 if (last > ROADTYPE_END) {
36 GrfMsg(1, "RoadTypeChangeInfo: Road type {} is invalid, max {}, ignoring", last, ROADTYPE_END);
37 return CIR_INVALID_ID;
38 }
39
40 for (uint id = first; id < last; ++id) {
41 RoadType rt = type_map[id];
42 if (rt == INVALID_ROADTYPE) return CIR_INVALID_ID;
43
44 RoadTypeInfo *rti = &_roadtypes[rt];
45
46 switch (prop) {
47 case 0x08: // Label of road type
48 /* Skipped here as this is loaded during reservation stage. */
49 buf.ReadDWord();
50 break;
51
52 case 0x09: // Toolbar caption of roadtype
54 break;
55
56 case 0x0A: // Menu text of roadtype
58 break;
59
60 case 0x0B: // Build window caption
62 break;
63
64 case 0x0C: // Autoreplace text
66 break;
67
68 case 0x0D: // New engine text
70 break;
71
72 case 0x0F: // Powered roadtype list
73 case 0x18: // Roadtype list required for date introduction
74 case 0x19: { // Introduced roadtype list
75 /* Road type compatibility bits are added to the existing bits
76 * to allow multiple GRFs to modify compatibility with the
77 * default road types. */
78 int n = buf.ReadByte();
79 for (int j = 0; j != n; j++) {
80 RoadTypeLabel label = buf.ReadDWord();
81 RoadType resolved_rt = GetRoadTypeByLabel(std::byteswap(label), false);
82 if (resolved_rt != INVALID_ROADTYPE) {
83 switch (prop) {
84 case 0x0F:
85 if (GetRoadTramType(resolved_rt) == rtt) {
86 rti->powered_roadtypes.Set(resolved_rt);
87 } else {
88 GrfMsg(1, "RoadTypeChangeInfo: Powered road type list: Road type {} road/tram type does not match road type {}, ignoring", resolved_rt, rt);
89 }
90 break;
91 case 0x18: rti->introduction_required_roadtypes.Set(resolved_rt); break;
92 case 0x19: rti->introduces_roadtypes.Set(resolved_rt); break;
93 }
94 }
95 }
96 break;
97 }
98
99 case 0x10: // Road Type flags
100 rti->flags = static_cast<RoadTypeFlags>(buf.ReadByte());
101 break;
102
103 case 0x13: // Construction cost factor
104 rti->cost_multiplier = buf.ReadWord();
105 break;
106
107 case 0x14: // Speed limit
108 rti->max_speed = buf.ReadWord();
109 break;
110
111 case 0x16: // Map colour
112 rti->map_colour = buf.ReadByte();
113 break;
114
115 case 0x17: // Introduction date
116 rti->introduction_date = TimerGameCalendar::Date(buf.ReadDWord());
117 break;
118
119 case 0x1A: // Sort order
120 rti->sorting_order = buf.ReadByte();
121 break;
122
123 case 0x1B: // Name of roadtype
125 break;
126
127 case 0x1C: // Maintenance cost factor
128 rti->maintenance_multiplier = buf.ReadWord();
129 break;
130
131 case 0x1D: // Alternate road type label list
132 /* Skipped here as this is loaded during reservation stage. */
133 for (int j = buf.ReadByte(); j != 0; j--) buf.ReadDWord();
134 break;
135
136 case 0x1E: // Badge list
137 rti->badges = ReadBadgeList(buf, GSF_ROADTYPES);
138 break;
139
140 default:
141 ret = CIR_UNKNOWN;
142 break;
143 }
144 }
145
146 return ret;
147}
148
149static ChangeInfoResult RoadTypeReserveInfo(uint first, uint last, int prop, ByteReader &buf, RoadTramType rtt)
150{
152
153 extern RoadTypeInfo _roadtypes[ROADTYPE_END];
154 std::array<RoadType, ROADTYPE_END> &type_map = (rtt == RTT_TRAM) ? _cur.grffile->tramtype_map : _cur.grffile->roadtype_map;
155
156 if (last > ROADTYPE_END) {
157 GrfMsg(1, "RoadTypeReserveInfo: Road type {} is invalid, max {}, ignoring", last, ROADTYPE_END);
158 return CIR_INVALID_ID;
159 }
160
161 for (uint id = first; id < last; ++id) {
162 switch (prop) {
163 case 0x08: { // Label of road type
164 RoadTypeLabel rtl = buf.ReadDWord();
165 rtl = std::byteswap(rtl);
166
167 RoadType rt = GetRoadTypeByLabel(rtl, false);
168 if (rt == INVALID_ROADTYPE) {
169 /* Set up new road type */
170 rt = AllocateRoadType(rtl, rtt);
171 } else if (GetRoadTramType(rt) != rtt) {
172 GrfMsg(1, "RoadTypeReserveInfo: Road type {} is invalid type (road/tram), ignoring", id);
173 return CIR_INVALID_ID;
174 }
175
176 type_map[id] = rt;
177 break;
178 }
179 case 0x09: // Toolbar caption of roadtype
180 case 0x0A: // Menu text
181 case 0x0B: // Build window caption
182 case 0x0C: // Autoreplace text
183 case 0x0D: // New loco
184 case 0x13: // Construction cost
185 case 0x14: // Speed limit
186 case 0x1B: // Name of roadtype
187 case 0x1C: // Maintenance cost factor
188 buf.ReadWord();
189 break;
190
191 case 0x1D: // Alternate road type label list
192 if (type_map[id] != INVALID_ROADTYPE) {
193 int n = buf.ReadByte();
194 for (int j = 0; j != n; j++) {
195 _roadtypes[type_map[id]].alternate_labels.push_back(std::byteswap(buf.ReadDWord()));
196 }
197 break;
198 }
199 GrfMsg(1, "RoadTypeReserveInfo: Ignoring property 1D for road type {} because no label was set", id);
200 /* FALL THROUGH */
201
202 case 0x0F: // Powered roadtype list
203 case 0x18: // Roadtype list required for date introduction
204 case 0x19: // Introduced roadtype list
205 for (int j = buf.ReadByte(); j != 0; j--) buf.ReadDWord();
206 break;
207
208 case 0x10: // Road Type flags
209 case 0x16: // Map colour
210 case 0x1A: // Sort order
211 buf.ReadByte();
212 break;
213
214 case 0x17: // Introduction date
215 buf.ReadDWord();
216 break;
217
218 case 0x1E: // Badge list
219 SkipBadgeList(buf);
220 break;
221
222 default:
223 ret = CIR_UNKNOWN;
224 break;
225 }
226 }
227
228 return ret;
229}
230
231template <> ChangeInfoResult GrfChangeInfoHandler<GSF_ROADTYPES>::Reserve(uint first, uint last, int prop, ByteReader &buf) { return RoadTypeReserveInfo(first, last, prop, buf, RTT_ROAD); }
232template <> ChangeInfoResult GrfChangeInfoHandler<GSF_ROADTYPES>::Activation(uint first, uint last, int prop, ByteReader &buf) { return RoadTypeChangeInfo(first, last, prop, buf, RTT_ROAD); }
233
234template <> ChangeInfoResult GrfChangeInfoHandler<GSF_TRAMTYPES>::Reserve(uint first, uint last, int prop, ByteReader &buf) { return RoadTypeReserveInfo(first, last, prop, buf, RTT_TRAM); }
235template <> ChangeInfoResult GrfChangeInfoHandler<GSF_TRAMTYPES>::Activation(uint first, uint last, int prop, ByteReader &buf) { return RoadTypeChangeInfo(first, last, prop, buf, RTT_TRAM); }
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.
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).
uint8_t ReadByte()
Read a single byte (8 bits).
StringID menu_text
Name of this rail type in the main toolbar dropdown.
Definition road.h:96
StringID replace_text
Text used in the autoreplace GUI.
Definition road.h:98
RoadTypeLabelList alternate_labels
Road type labels this type provides in addition to the main label.
Definition road.h:143
RoadTypes powered_roadtypes
bitmask to the OTHER roadtypes on which a vehicle of THIS roadtype generates power
Definition road.h:113
RoadTypes introduces_roadtypes
Bitmask of which other roadtypes are introduced when this roadtype is introduced.
Definition road.h:168
TimerGameCalendar::Date introduction_date
Introduction date.
Definition road.h:157
uint8_t sorting_order
The sorting order of this roadtype for the toolbar dropdown.
Definition road.h:173
uint16_t maintenance_multiplier
Cost multiplier for maintenance of this road type.
Definition road.h:128
RoadTypeFlags flags
Bit mask of road type flags.
Definition road.h:118
uint8_t map_colour
Colour on mini-map.
Definition road.h:148
uint16_t max_speed
Maximum speed for vehicles travelling on this road type.
Definition road.h:133
StringID name
Name of this rail type.
Definition road.h:94
StringID toolbar_caption
Caption in the construction toolbar GUI for this rail type.
Definition road.h:95
struct RoadTypeInfo::@27 strings
Strings associated with the rail type.
StringID new_engine
Name of an engine for this type of road in the engine preview GUI.
Definition road.h:99
RoadTypes introduction_required_roadtypes
Bitmask of roadtypes that are required for this roadtype to be introduced at a given introduction_dat...
Definition road.h:163
uint16_t cost_multiplier
Cost multiplier for building this road type.
Definition road.h:123
StringID build_caption
Caption of the build vehicle GUI for this rail type.
Definition road.h:97
std::vector< BadgeID > ReadBadgeList(ByteReader &buf, GrfSpecFeature feature)
Read a list of badges.
void SkipBadgeList(ByteReader &buf)
Skip a list of badges.
static ChangeInfoResult RoadTypeChangeInfo(uint first, uint last, int prop, ByteReader &buf, RoadTramType rtt)
Define properties for roadtypes.
NewGRF buffer reader definition.
NewGRF internal processing state.
ChangeInfoResult
Possible return values for the GrfChangeInfoHandler functions.
@ CIR_INVALID_ID
Attempt to modify an invalid ID.
@ CIR_UNKNOWN
Variable is unknown.
@ CIR_SUCCESS
Variable was parsed and read.
void AddStringForMapping(GRFStringID source, std::function< void(StringID)> &&func)
Record a static StringID for getting translated later.
NewGRF string mapping definition.
RoadType GetRoadTypeByLabel(RoadTypeLabel label, bool allow_alternate_labels)
Get the road type for a given label.
Definition road.cpp:253
RoadType AllocateRoadType(RoadTypeLabel label, RoadTramType rtt)
Allocate a new road type label.
Definition road_cmd.cpp:130
RoadType
The different roadtypes we support.
Definition road_type.h:23
@ INVALID_ROADTYPE
flag for invalid roadtype
Definition road_type.h:28
@ ROADTYPE_END
Used for iterations.
Definition road_type.h:27
GRF feature handler.
GRFFile * grffile
Currently processed GRF file.