OpenTTD Source 20260206-master-g4d4e37dbf1
newgrf_act0_roadstops.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 "../newgrf_engine.h"
13#include "../newgrf_roadstop.h"
14#include "newgrf_bytereader.h"
15#include "newgrf_internal.h"
17
18#include "../safeguards.h"
19
27{
29
30 switch (prop) {
31 case 0x09:
32 case 0x0C:
33 case 0x0F:
34 case 0x11:
35 buf.ReadByte();
36 break;
37
38 case 0x0A:
39 case 0x0B:
40 case 0x0E:
41 case 0x10:
42 case 0x15:
43 buf.ReadWord();
44 break;
45
46 case 0x08:
47 case 0x0D:
48 case 0x12:
49 buf.ReadDWord();
50 break;
51
52 case 0x13:
53 case 0x14:
54 buf.Skip(buf.ReadExtendedByte());
55 break;
56
57 case 0x16: // Badge list
58 SkipBadgeList(buf);
59 break;
60
61 default:
62 ret = CIR_UNKNOWN;
63 break;
64 }
65
66 return ret;
67}
68
69static ChangeInfoResult RoadStopChangeInfo(uint first, uint last, int prop, ByteReader &buf)
70{
72
73 if (last > NUM_ROADSTOPS_PER_GRF) {
74 GrfMsg(1, "RoadStopChangeInfo: RoadStop {} is invalid, max {}, ignoring", last, NUM_ROADSTOPS_PER_GRF);
75 return CIR_INVALID_ID;
76 }
77
78 if (_cur_gps.grffile->roadstops.size() < last) _cur_gps.grffile->roadstops.resize(last);
79
80 for (uint id = first; id < last; ++id) {
81 auto &rs = _cur_gps.grffile->roadstops[id];
82
83 if (rs == nullptr && prop != 0x08) {
84 GrfMsg(1, "RoadStopChangeInfo: Attempt to modify undefined road stop {}, ignoring", id);
86 if (cir > ret) ret = cir;
87 continue;
88 }
89
90 switch (prop) {
91 case 0x08: { // Road Stop Class ID
92 if (rs == nullptr) {
93 rs = std::make_unique<RoadStopSpec>();
94 }
95
96 uint32_t classid = buf.ReadDWord();
97 rs->class_index = RoadStopClass::Allocate(std::byteswap(classid));
98 break;
99 }
100
101 case 0x09: // Road stop type
102 rs->stop_type = (RoadStopAvailabilityType)buf.ReadByte();
103 break;
104
105 case 0x0A: // Road Stop Name
106 AddStringForMapping(GRFStringID{buf.ReadWord()}, &rs->name);
107 break;
108
109 case 0x0B: // Road Stop Class name
110 AddStringForMapping(GRFStringID{buf.ReadWord()}, [rs = rs.get()](StringID str) { RoadStopClass::Get(rs->class_index)->name = str; });
111 break;
112
113 case 0x0C: // The draw modes
114 rs->draw_mode = static_cast<RoadStopDrawModes>(buf.ReadByte());
115 break;
116
117 case 0x0D: // Cargo types for random triggers
118 rs->cargo_triggers = TranslateRefitMask(buf.ReadDWord());
119 break;
120
121 case 0x0E: // Animation info
122 rs->animation.frames = buf.ReadByte();
123 rs->animation.status = static_cast<AnimationStatus>(buf.ReadByte());
124 break;
125
126 case 0x0F: // Animation speed
127 rs->animation.speed = buf.ReadByte();
128 break;
129
130 case 0x10: // Animation triggers
131 rs->animation.triggers = static_cast<StationAnimationTriggers>(buf.ReadWord());
132 break;
133
134 case 0x11: // Callback mask
135 rs->callback_mask = static_cast<RoadStopCallbackMasks>(buf.ReadByte());
136 break;
137
138 case 0x12: // General flags
139 rs->flags = static_cast<RoadStopSpecFlags>(buf.ReadDWord()); // Future-proofing, size this as 4 bytes, but we only need two byte's worth of flags at present
140 break;
141
142 case 0x13: { // Minimum bridge height for each of the roadstop's tile layouts.
143 uint16_t tiles = buf.ReadExtendedByte();
144 for (uint j = 0; j != tiles; ++j) {
145 if (j < std::size(rs->bridgeable_info)) {
146 rs->bridgeable_info[j].height = buf.ReadByte();
147 } else {
148 buf.ReadByte();
149 }
150 }
151 break;
152 }
153
154 case 0x14: { // Disallowed pillars for each of the roadstop's tile layouts.
155 uint16_t tiles = buf.ReadExtendedByte();
156 for (uint j = 0; j != tiles; ++j) {
157 if (j < std::size(rs->bridgeable_info)) {
158 rs->bridgeable_info[j].disallowed_pillars = BridgePillarFlags{buf.ReadByte()};
159 } else {
160 buf.ReadByte();
161 }
162 }
163 break;
164 }
165
166 case 0x15: // Cost multipliers
167 rs->build_cost_multiplier = buf.ReadByte();
168 rs->clear_cost_multiplier = buf.ReadByte();
169 break;
170
171 case 0x16: // Badge list
172 rs->badges = ReadBadgeList(buf, GSF_ROADSTOPS);
173 break;
174
175 default:
176 ret = CIR_UNKNOWN;
177 break;
178 }
179 }
180
181 return ret;
182}
183
184template <> ChangeInfoResult GrfChangeInfoHandler<GSF_ROADSTOPS>::Reserve(uint, uint, int, ByteReader &) { return CIR_UNHANDLED; }
185template <> ChangeInfoResult GrfChangeInfoHandler<GSF_ROADSTOPS>::Activation(uint first, uint last, int prop, ByteReader &buf) { return RoadStopChangeInfo(first, last, prop, buf); }
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.
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).
uint16_t ReadExtendedByte()
Read a single Extended Byte (8 or 16 bits).
uint8_t ReadByte()
Read a single byte (8 bits).
StringID name
Name of this class.
static NewGRFClass * Get(RoadStopClassID class_index)
static RoadStopClassID Allocate(uint32_t global_id)
Functions related to debugging.
CargoTypes TranslateRefitMask(uint32_t refit_mask)
Translate the refit mask.
Definition newgrf.cpp:316
std::vector< BadgeID > ReadBadgeList(ByteReader &buf, GrfSpecFeature feature)
Read a list of badges.
void SkipBadgeList(ByteReader &buf)
Skip a list of badges.
static ChangeInfoResult IgnoreRoadStopProperty(uint prop, ByteReader &buf)
Ignore properties for roadstops.
AnimationStatus
Statuses of animation within NewGRFs.
NewGRF buffer reader definition.
Functions for NewGRF engines.
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_UNHANDLED
Variable was parsed but unread.
@ CIR_SUCCESS
Variable was parsed and read.
NewGRF definitions and structures for road stops.
RoadStopAvailabilityType
Various different options for availability, restricting the roadstop to be only for busses or for tru...
static const int NUM_ROADSTOPS_PER_GRF
The maximum amount of roadstops a single GRF is allowed to add.
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.
A number of safeguards to prevent using unsafe methods.
Definition of base types and functions in a cross-platform compatible way.
uint32_t StringID
Numeric value that represents a string, independent of the selected language.