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

OpenTTD Source 15.0-RC2

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 <https://www.gnu.org/licenses/old-licenses/gpl-2.0>.
6 */
7
10#include "../stdafx.h"
11#include "../debug.h"
12#include "../road.h"
13#include "newgrf_bytereader.h"
14#include "newgrf_internal.h"
15#include "newgrf_stringmapping.h"
16
17#include "../safeguards.h"
18
28 static ChangeInfoResult RoadTypeChangeInfo(uint first, uint last, int prop, ByteReader &buf, RoadTramType rtt)
29{
30 ChangeInfoResult ret = CIR_SUCCESS;
31
32 extern RoadTypeInfo _roadtypes[ROADTYPE_END];
33 const auto &type_map = (rtt == RTT_TRAM) ? _cur_gps.grffile->tramtype_map : _cur_gps.grffile->roadtype_map;
34
35 if (last > std::size(type_map)) {
36 GrfMsg(1, "RoadTypeChangeInfo: Road type {} is invalid, max {}, ignoring", last, std::size(type_map));
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
53 AddStringForMapping(GRFStringID{buf.ReadWord()}, &rti->strings.toolbar_caption);
54 break;
55
56 case 0x0A: // Menu text of roadtype
57 AddStringForMapping(GRFStringID{buf.ReadWord()}, &rti->strings.menu_text);
58 break;
59
60 case 0x0B: // Build window caption
61 AddStringForMapping(GRFStringID{buf.ReadWord()}, &rti->strings.build_caption);
62 break;
63
64 case 0x0C: // Autoreplace text
65 AddStringForMapping(GRFStringID{buf.ReadWord()}, &rti->strings.replace_text);
66 break;
67
68 case 0x0D: // New engine text
69 AddStringForMapping(GRFStringID{buf.ReadWord()}, &rti->strings.new_engine);
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 = PixelColour{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
124 AddStringForMapping(GRFStringID{buf.ReadWord()}, &rti->strings.name);
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{
151 ChangeInfoResult ret = CIR_SUCCESS;
152
153 extern RoadTypeInfo _roadtypes[ROADTYPE_END];
154 auto &type_map = (rtt == RTT_TRAM) ? _cur_gps.grffile->tramtype_map : _cur_gps.grffile->roadtype_map;
155
156 if (last > std::size(type_map)) {
157 GrfMsg(1, "RoadTypeReserveInfo: Road type {} is invalid, max {}, ignoring", last, std::size(type_map));
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.insert(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); }
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< RoadTypeFlag, 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
RoadTypeInfo
Definition road.h:52
RoadTypeInfo::strings
struct RoadTypeInfo::@25 strings
Strings associated with the rail type.
RoadTypeInfo::menu_text
StringID menu_text
Name of this rail type in the main toolbar dropdown.
Definition road.h:79
RoadTypeInfo::replace_text
StringID replace_text
Text used in the autoreplace GUI.
Definition road.h:81
RoadTypeInfo::powered_roadtypes
RoadTypes powered_roadtypes
bitmask to the OTHER roadtypes on which a vehicle of THIS roadtype generates power
Definition road.h:96
RoadTypeInfo::introduces_roadtypes
RoadTypes introduces_roadtypes
Bitmask of which other roadtypes are introduced when this roadtype is introduced.
Definition road.h:151
RoadTypeInfo::introduction_date
TimerGameCalendar::Date introduction_date
Introduction date.
Definition road.h:140
RoadTypeInfo::sorting_order
uint8_t sorting_order
The sorting order of this roadtype for the toolbar dropdown.
Definition road.h:156
RoadTypeInfo::maintenance_multiplier
uint16_t maintenance_multiplier
Cost multiplier for maintenance of this road type.
Definition road.h:111
RoadTypeInfo::flags
RoadTypeFlags flags
Bit mask of road type flags.
Definition road.h:101
RoadTypeInfo::alternate_labels
FlatSet< RoadTypeLabel > alternate_labels
Road type labels this type provides in addition to the main label.
Definition road.h:126
RoadTypeInfo::max_speed
uint16_t max_speed
Maximum speed for vehicles travelling on this road type.
Definition road.h:116
RoadTypeInfo::name
StringID name
Name of this rail type.
Definition road.h:77
RoadTypeInfo::toolbar_caption
StringID toolbar_caption
Caption in the construction toolbar GUI for this rail type.
Definition road.h:78
RoadTypeInfo::new_engine
StringID new_engine
Name of an engine for this type of road in the engine preview GUI.
Definition road.h:82
RoadTypeInfo::introduction_required_roadtypes
RoadTypes introduction_required_roadtypes
Bitmask of roadtypes that are required for this roadtype to be introduced at a given introduction_dat...
Definition road.h:146
RoadTypeInfo::cost_multiplier
uint16_t cost_multiplier
Cost multiplier for building this road type.
Definition road.h:106
RoadTypeInfo::map_colour
PixelColour map_colour
Colour on mini-map.
Definition road.h:131
RoadTypeInfo::build_caption
StringID build_caption
Caption of the build vehicle GUI for this rail type.
Definition road.h:80
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
RoadTypeChangeInfo
static ChangeInfoResult RoadTypeChangeInfo(uint first, uint last, int prop, ByteReader &buf, RoadTramType rtt)
Define properties for roadtypes.
Definition newgrf_act0_roadtypes.cpp:28
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.
GetRoadTypeByLabel
RoadType GetRoadTypeByLabel(RoadTypeLabel label, bool allow_alternate_labels)
Get the road type for a given label.
Definition road.cpp:265
AllocateRoadType
RoadType AllocateRoadType(RoadTypeLabel label, RoadTramType rtt)
Allocate a new road type label.
Definition road_cmd.cpp:129
RoadTramType
RoadTramType
The different types of road type.
Definition road_type.h:37
RTT_ROAD
@ RTT_ROAD
Road road type.
Definition road_type.h:38
RTT_TRAM
@ RTT_TRAM
Tram road type.
Definition road_type.h:39
RoadType
RoadType
The different roadtypes we support.
Definition road_type.h:23
INVALID_ROADTYPE
@ INVALID_ROADTYPE
flag for invalid roadtype
Definition road_type.h:28
ROADTYPE_END
@ ROADTYPE_END
Used for iterations.
Definition road_type.h:27
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 >