OpenTTD Source 20250328-master-gc3457cd4c0
newgrf_act0_aircraft.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 "../newgrf_cargo.h"
13#include "../newgrf_engine.h"
14#include "../newgrf_sound.h"
15#include "newgrf_bytereader.h"
17#include "newgrf_internal.h"
18
19#include "../safeguards.h"
20
29static ChangeInfoResult AircraftVehicleChangeInfo(uint first, uint last, int prop, ByteReader &buf)
30{
32
33 for (uint id = first; id < last; ++id) {
35 if (e == nullptr) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles
36
37 EngineInfo *ei = &e->info;
38 AircraftVehicleInfo *avi = &e->u.air;
39
40 switch (prop) {
41 case 0x08: { // Sprite ID
42 uint8_t spriteid = buf.ReadByte();
43 uint8_t orig_spriteid = spriteid;
44
45 /* aircraft have different custom id in the GRF file */
46 if (spriteid == 0xFF) spriteid = 0xFD;
47
48 if (spriteid < 0xFD) spriteid >>= 1;
49
50 if (IsValidNewGRFImageIndex<VEH_AIRCRAFT>(spriteid)) {
51 avi->image_index = spriteid;
52 } else {
53 GrfMsg(1, "AircraftVehicleChangeInfo: Invalid Sprite {} specified, ignoring", orig_spriteid);
54 avi->image_index = 0;
55 }
56 break;
57 }
58
59 case 0x09: // Helicopter
60 if (buf.ReadByte() == 0) {
61 avi->subtype = AIR_HELI;
62 } else {
63 SB(avi->subtype, 0, 1, 1); // AIR_CTOL
64 }
65 break;
66
67 case 0x0A: // Large
68 AssignBit(avi->subtype, 1, buf.ReadByte() != 0); // AIR_FAST
69 break;
70
71 case PROP_AIRCRAFT_COST_FACTOR: // 0x0B Cost factor
72 avi->cost_factor = buf.ReadByte();
73 break;
74
75 case PROP_AIRCRAFT_SPEED: // 0x0C Speed (1 unit is 8 mph, we translate to 1 unit is 1 km-ish/h)
76 avi->max_speed = (buf.ReadByte() * 128) / 10;
77 break;
78
79 case 0x0D: // Acceleration
80 avi->acceleration = buf.ReadByte();
81 break;
82
83 case PROP_AIRCRAFT_RUNNING_COST_FACTOR: // 0x0E Running cost factor
84 avi->running_cost = buf.ReadByte();
85 break;
86
87 case PROP_AIRCRAFT_PASSENGER_CAPACITY: // 0x0F Passenger capacity
88 avi->passenger_capacity = buf.ReadWord();
89 break;
90
91 case PROP_AIRCRAFT_MAIL_CAPACITY: // 0x11 Mail capacity
92 avi->mail_capacity = buf.ReadByte();
93 break;
94
95 case 0x12: // SFX
96 avi->sfx = GetNewGRFSoundID(_cur.grffile, buf.ReadByte());
97 break;
98
99 case 0x13: { // Cargoes available for refitting
100 uint32_t mask = buf.ReadDWord();
101 _gted[e->index].UpdateRefittability(mask != 0);
102 ei->refit_mask = TranslateRefitMask(mask);
103 _gted[e->index].defaultcargo_grf = _cur.grffile;
104 break;
105 }
106
107 case 0x14: { // Callback mask
108 auto mask = ei->callback_mask.base();
109 SB(mask, 0, 8, buf.ReadByte());
111 break;
112 }
113
114 case 0x15: // Refit cost
115 ei->refit_cost = buf.ReadByte();
116 break;
117
118 case 0x16: // Retire vehicle early
119 ei->retire_early = buf.ReadByte();
120 break;
121
122 case 0x17: // Miscellaneous flags
123 ei->misc_flags = static_cast<EngineMiscFlags>(buf.ReadByte());
125 break;
126
127 case 0x18: // Cargo classes allowed
128 _gted[e->index].cargo_allowed = CargoClasses{buf.ReadWord()};
129 _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed.Any());
130 _gted[e->index].defaultcargo_grf = _cur.grffile;
131 break;
132
133 case 0x19: // Cargo classes disallowed
134 _gted[e->index].cargo_disallowed = CargoClasses{buf.ReadWord()};
135 _gted[e->index].UpdateRefittability(false);
136 break;
137
138 case 0x1A: // Long format introduction date (days since year 0)
139 ei->base_intro = TimerGameCalendar::Date(buf.ReadDWord());
140 break;
141
142 case 0x1B: // Alter purchase list sort order
144 break;
145
146 case PROP_AIRCRAFT_CARGO_AGE_PERIOD: // 0x1C Cargo aging period
147 ei->cargo_age_period = buf.ReadWord();
148 break;
149
150 case 0x1D: // CTT refit include list
151 case 0x1E: { // CTT refit exclude list
152 uint8_t count = buf.ReadByte();
153 _gted[e->index].UpdateRefittability(prop == 0x1D && count != 0);
154 if (prop == 0x1D) _gted[e->index].defaultcargo_grf = _cur.grffile;
155 CargoTypes &ctt = prop == 0x1D ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
156 ctt = 0;
157 while (count--) {
158 CargoType ctype = GetCargoTranslation(buf.ReadByte(), _cur.grffile);
159 if (IsValidCargoType(ctype)) SetBit(ctt, ctype);
160 }
161 break;
162 }
163
164 case PROP_AIRCRAFT_RANGE: // 0x1F Max aircraft range
165 avi->max_range = buf.ReadWord();
166 break;
167
168 case 0x20: // Engine variant
169 ei->variant_id = static_cast<EngineID>(buf.ReadWord());
170 break;
171
172 case 0x21: // Extra miscellaneous flags
173 ei->extra_flags = static_cast<ExtraEngineFlags>(buf.ReadDWord());
174 break;
175
176 case 0x22: { // Callback additional mask
177 auto mask = ei->callback_mask.base();
178 SB(mask, 8, 8, buf.ReadByte());
180 break;
181 }
182
183 case 0x23: // Cargo classes required for a refit.
184 _gted[e->index].cargo_allowed_required = CargoClasses{buf.ReadWord()};
185 break;
186
187 case 0x24: // Badge list
188 e->badges = ReadBadgeList(buf, GSF_AIRCRAFT);
189 break;
190
191 default:
192 ret = CommonVehicleChangeInfo(ei, prop, buf);
193 break;
194 }
195 }
196
197 return ret;
198}
199
201template <> ChangeInfoResult GrfChangeInfoHandler<GSF_AIRCRAFT>::Activation(uint first, uint last, int prop, ByteReader &buf) { return AircraftVehicleChangeInfo(first, last, prop, buf); }
constexpr T AssignBit(T &x, const uint8_t y, bool value)
Assigns a bit in a variable.
constexpr T SB(T &x, const uint8_t s, const uint8_t n, const U d)
Set n bits in x starting at bit s to d.
constexpr T SetBit(T &x, const uint8_t y)
Set a bit in a variable.
uint8_t CargoType
Cargo slots to indicate a cargo type within a game.
Definition cargo_type.h:23
bool IsValidCargoType(CargoType cargo)
Test whether cargo type is not INVALID_CARGO.
Definition cargo_type.h:106
constexpr bool Test(Tvalue_type value) const
Test if the value-th bit is set.
constexpr Tstorage base() const noexcept
Retrieve the raw value behind this bit set.
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).
@ Uses2CC
Vehicle uses two company colours.
Engine * GetNewEngine(const GRFFile *file, VehicleType type, uint16_t internal_id, bool static_access)
Returns the engine associated to a certain internal_id, resp.
Definition newgrf.cpp:207
ReferenceThroughBaseContainer< std::vector< GRFTempEngineData > > _gted
Temporary engine data used during NewGRF loading.
Definition newgrf.cpp:76
GRFLoadedFeatures _loaded_newgrf_features
Indicates which are the newgrf features currently loaded ingame.
Definition newgrf.cpp:72
CargoTypes TranslateRefitMask(uint32_t refit_mask)
Translate the refit mask.
Definition newgrf.cpp:307
ChangeInfoResult CommonVehicleChangeInfo(EngineInfo *ei, int prop, ByteReader &buf)
Define properties common to all vehicles.
std::vector< BadgeID > ReadBadgeList(ByteReader &buf, GrfSpecFeature feature)
Read a list of badges.
static ChangeInfoResult AircraftVehicleChangeInfo(uint first, uint last, int prop, ByteReader &buf)
Define properties for aircraft.
NewGRF buffer reader definition.
CargoType GetCargoTranslation(uint8_t cargo, const GRFFile *grffile, bool usebit)
Translate a GRF-local cargo slot/bitnum into a CargoType.
void AlterVehicleListOrder(EngineID engine, uint16_t target)
Record a vehicle ListOrderChange.
NewGRF internal processing state.
ChangeInfoResult
Possible return values for the GrfChangeInfoHandler functions.
@ CIR_INVALID_ID
Attempt to modify an invalid ID.
@ CIR_UNHANDLED
Variable was parsed but unread.
@ CIR_SUCCESS
Variable was parsed and read.
NewGRF internal processing state for vehicles.
@ PROP_AIRCRAFT_PASSENGER_CAPACITY
Passenger Capacity.
@ PROP_AIRCRAFT_RANGE
Aircraft range.
@ PROP_AIRCRAFT_RUNNING_COST_FACTOR
Yearly runningcost.
@ PROP_AIRCRAFT_SPEED
Max. speed: 1 unit = 8 mph = 12.8 km-ish/h.
@ PROP_AIRCRAFT_MAIL_CAPACITY
Mail Capacity.
@ PROP_AIRCRAFT_COST_FACTOR
Purchase cost.
@ PROP_AIRCRAFT_CARGO_AGE_PERIOD
Number of ticks before carried cargo is aged.
SoundID GetNewGRFSoundID(const GRFFile *file, SoundID sound_id)
Resolve NewGRF sound ID.
Information about a aircraft vehicle.
uint16_t max_speed
Maximum speed (1 unit = 8 mph = 12.8 km-ish/h)
uint8_t mail_capacity
Mail capacity (bags).
uint8_t subtype
Type of aircraft.
uint16_t passenger_capacity
Passenger capacity (persons).
uint16_t max_range
Maximum range of this aircraft.
Information about a vehicle.
uint16_t cargo_age_period
Number of ticks before carried cargo is aged.
EngineMiscFlags misc_flags
Miscellaneous flags.
EngineID variant_id
Engine variant ID. If set, will be treated specially in purchase lists.
VehicleCallbackMasks callback_mask
Bitmask of vehicle callbacks that have to be called.
TimerGameCalendar::Date base_intro
Basic date of engine introduction (without random parts).
int8_t retire_early
Number of years early to retire vehicle.
bool has_2CC
Set if any vehicle is loaded which uses 2cc (two company colours).
Definition newgrf.h:184
GRF feature handler.
GRFFile * grffile
Currently processed GRF file.
Tindex index
Index of this pool item.
@ VEH_AIRCRAFT
Aircraft vehicle type.