OpenTTD Source 20260721-master-g25ec12c62d
newgrf_act0_objects.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_object.h"
13#include "newgrf_bytereader.h"
14#include "newgrf_internal.h"
16
17#include "../safeguards.h"
18
26{
28
29 switch (prop) {
30 case 0x0B:
31 case 0x0C:
32 case 0x0D:
33 case 0x12:
34 case 0x14:
35 case 0x16:
36 case 0x17:
37 case 0x18:
38 buf.ReadByte();
39 break;
40
41 case 0x09:
42 case 0x0A:
43 case 0x10:
44 case 0x11:
45 case 0x13:
46 case 0x15:
47 buf.ReadWord();
48 break;
49
50 case 0x08:
51 case 0x0E:
52 case 0x0F:
53 buf.ReadDWord();
54 break;
55
56 case 0x19: // Badge list
57 SkipBadgeList(buf);
58 break;
59
60 default:
62 break;
63 }
64
65 return ret;
66}
67
76static ChangeInfoResult ObjectChangeInfo(uint first, uint last, int prop, ByteReader &buf)
77{
79
80 if (last > NUM_OBJECTS_PER_GRF) {
81 GrfMsg(1, "ObjectChangeInfo: Too many objects loaded ({}), max ({}). Ignoring.", last, NUM_OBJECTS_PER_GRF);
83 }
84
85 /* Allocate object specs if they haven't been allocated already. */
86 if (_cur_gps.grffile->objectspec.size() < last) _cur_gps.grffile->objectspec.resize(last);
87
88 for (uint id = first; id < last; ++id) {
89 auto &spec = _cur_gps.grffile->objectspec[id];
90
91 if (prop != 0x08 && spec == nullptr) {
92 /* If the object property 08 is not yet set, ignore this property */
94 if (cir > ret) ret = cir;
95 continue;
96 }
97
98 switch (prop) {
99 case 0x08: // Class ID
100 /* Allocate space for this object. */
101 if (spec == nullptr) {
102 spec = std::make_unique<ObjectSpec>();
103 spec->views = 1; // Default for NewGRFs that don't set it.
104 spec->size = OBJECT_SIZE_1X1; // Default for NewGRFs that manage to not set it (1x1)
105 }
106
107 spec->class_index = ObjectClass::Allocate(buf.ReadLabel<ObjectClass::GlobalID>());
108 break;
109
110 case 0x09: // Class name
111 AddStringForMapping(GRFStringID{buf.ReadWord()}, [spec = spec.get()](StringID str) { ObjectClass::Get(spec->class_index)->name = str; });
112 break;
113
114 case 0x0A: // Object name
115 AddStringForMapping(GRFStringID{buf.ReadWord()}, &spec->name);
116 break;
117
118 case 0x0B: // Climate mask
119 spec->climate = LandscapeTypes{buf.ReadByte()};
120 break;
121
122 case 0x0C: // Size
123 spec->size = buf.ReadByte();
124 if (GB(spec->size, 0, 4) == 0 || GB(spec->size, 4, 4) == 0) {
125 GrfMsg(0, "ObjectChangeInfo: Invalid object size requested (0x{:X}) for object id {}. Ignoring.", spec->size, id);
126 spec->size = OBJECT_SIZE_1X1;
127 }
128 break;
129
130 case 0x0D: // Build cost multiplier
131 spec->build_cost_multiplier = buf.ReadByte();
132 spec->clear_cost_multiplier = spec->build_cost_multiplier;
133 break;
134
135 case 0x0E: // Introduction date
136 spec->introduction_date = TimerGameCalendar::Date(buf.ReadDWord());
137 break;
138
139 case 0x0F: // End of life
140 spec->end_of_life_date = TimerGameCalendar::Date(buf.ReadDWord());
141 break;
142
143 case 0x10: // Flags
144 spec->flags = (ObjectFlags)buf.ReadWord();
145 _loaded_newgrf_features.has_2CC |= spec->flags.Test(ObjectFlag::Uses2CC);
146 break;
147
148 case 0x11: // Animation info
149 spec->animation.frames = buf.ReadByte();
150 spec->animation.status = static_cast<AnimationStatus>(buf.ReadByte());
151 break;
152
153 case 0x12: // Animation speed
154 spec->animation.speed = buf.ReadByte();
155 break;
156
157 case 0x13: // Animation triggers
158 spec->animation.triggers = static_cast<ObjectAnimationTriggers>(buf.ReadWord());
159 break;
160
161 case 0x14: // Removal cost multiplier
162 spec->clear_cost_multiplier = buf.ReadByte();
163 break;
164
165 case 0x15: // Callback mask
166 spec->callback_mask = static_cast<ObjectCallbackMasks>(buf.ReadWord());
167 break;
168
169 case 0x16: // Building height
170 spec->height = buf.ReadByte();
171 break;
172
173 case 0x17: // Views
174 spec->views = buf.ReadByte();
175 if (spec->views != 1 && spec->views != 2 && spec->views != 4) {
176 GrfMsg(2, "ObjectChangeInfo: Invalid number of views ({}) for object id {}. Ignoring.", spec->views, id);
177 spec->views = 1;
178 }
179 break;
180
181 case 0x18: // Amount placed on 256^2 map on map creation
182 spec->generate_amount = buf.ReadByte();
183 break;
184
185 case 0x19: // Badge list
186 spec->badges = ReadBadgeList(buf, GrfSpecFeature::Objects);
187 break;
188
189 default:
191 break;
192 }
193 }
194
195 return ret;
196}
197
201template <> ChangeInfoResult GrfChangeInfoHandler<GrfSpecFeature::Objects>::Activation(uint first, uint last, int prop, ByteReader &buf) { return ObjectChangeInfo(first, last, prop, buf); }
static constexpr uint GB(const T x, const uint8_t s, const uint8_t n)
Fetch n bits from x, started at bit s.
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).
static NewGRFClass * Get(ObjectClassID class_index)
StringID name
Name of this class.
Label< NewGRFClass< ObjectSpec, ObjectClassID > > GlobalID
static ObjectClassID Allocate(GlobalID global_id)
StrongType::Typedef< int32_t, DateTag< struct Calendar >, StrongType::Compare, StrongType::Integer > Date
Functions related to debugging.
EnumBitSet< LandscapeType, uint8_t > LandscapeTypes
Bitset of LandscapeType elements.
GRFLoadedFeatures _loaded_newgrf_features
Indicates which are the newgrf features currently loaded ingame.
Definition newgrf.cpp:76
@ Objects
Objects feature.
Definition newgrf.h:94
std::vector< BadgeID > ReadBadgeList(ByteReader &buf, GrfSpecFeature feature)
Read a list of badges.
void SkipBadgeList(ByteReader &buf)
Skip a list of badges.
static ChangeInfoResult ObjectChangeInfo(uint first, uint last, int prop, ByteReader &buf)
Define properties for objects.
static ChangeInfoResult IgnoreObjectProperty(uint prop, ByteReader &buf)
Ignore properties for objects.
AnimationStatus
Statuses of animation within NewGRFs.
NewGRF buffer reader definition.
EnumBitSet< ObjectCallbackMask, uint8_t > ObjectCallbackMasks
Bitset of ObjectCallbackMask elements.
NewGRF internal processing state.
ChangeInfoResult
Possible return values for the GrfChangeInfoHandler functions.
@ Success
Variable was parsed and read.
@ Unhandled
Variable was parsed but unread.
@ Unknown
Variable is unknown.
@ InvalidId
Attempt to modify an invalid ID.
Functions related to NewGRF objects.
static const uint8_t OBJECT_SIZE_1X1
The value of a NewGRF's size property when the object is 1x1 tiles: low nibble for X,...
EnumBitSet< ObjectFlag, uint16_t > ObjectFlags
Bitset of ObjectFlag elements.
@ Uses2CC
Object wants 2CC colour mapping.
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.
EnumBitSet< ObjectAnimationTrigger, uint16_t > ObjectAnimationTriggers
Bitset of ObjectAnimationTrigger elements.
Definition object_type.h:43
static const ObjectType NUM_OBJECTS_PER_GRF
Number of supported objects per NewGRF.
Definition object_type.h:26
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.
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.