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

OpenTTD Source 15.3

newgrf_act0_cargo.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 "../newgrf_cargo.h"
13#include "newgrf_bytereader.h"
14#include "newgrf_internal.h"
15#include "newgrf_stringmapping.h"
16
17#include "../safeguards.h"
18
26 static void MaybeInstallFallbackCargoLabel(uint id, uint last, CargoLabel label)
27{
28 if (_cur_gps.grffile->cargo_list.empty()) {
29 /* Cargo translation table isn't configured yet, assume it won't be and configure the cargo list as a fallback list. */
30 auto default_cargo_list = GetCargoTranslationTable(*_cur_gps.grffile);
31 _cur_gps.grffile->cargo_list.assign(default_cargo_list.begin(), default_cargo_list.end());
32 _cur_gps.grffile->cargo_list_is_fallback = true;
33 }
34
35 if (_cur_gps.grffile->cargo_list_is_fallback) {
36 /* Automatically fill fallback cargo list with the defined label, resizing as needed. */
37 if (_cur_gps.grffile->cargo_list.size() < last) _cur_gps.grffile->cargo_list.resize(last, CT_INVALID);
38 _cur_gps.grffile->cargo_list[id] = label;
39 }
40}
41
50 static ChangeInfoResult CargoReserveInfo(uint first, uint last, int prop, ByteReader &buf)
51{
52 ChangeInfoResult ret = CIR_SUCCESS;
53
54 if (last > NUM_CARGO) {
55 GrfMsg(2, "CargoChangeInfo: Cargo type {} out of range (max {})", last, NUM_CARGO - 1);
56 return CIR_INVALID_ID;
57 }
58
59 for (uint id = first; id < last; ++id) {
60 CargoSpec *cs = CargoSpec::Get(id);
61
62 switch (prop) {
63 case 0x08: // Bit number of cargo
64 cs->bitnum = buf.ReadByte();
65 if (cs->IsValid()) {
66 cs->grffile = _cur_gps.grffile;
67 SetBit(_cargo_mask, id);
68 } else {
69 ClrBit(_cargo_mask, id);
70 }
71 BuildCargoLabelMap();
72 break;
73
74 case 0x09: // String ID for cargo type name
75 AddStringForMapping(GRFStringID{buf.ReadWord()}, &cs->name);
76 break;
77
78 case 0x0A: // String for 1 unit of cargo
79 AddStringForMapping(GRFStringID{buf.ReadWord()}, &cs->name_single);
80 break;
81
82 case 0x0B: // String for singular quantity of cargo (e.g. 1 tonne of coal)
83 case 0x1B: // String for cargo units
84 /* String for units of cargo. This is different in OpenTTD
85 * (e.g. tonnes) to TTDPatch (e.g. {COMMA} tonne of coal).
86 * Property 1B is used to set OpenTTD's behaviour. */
87 AddStringForMapping(GRFStringID{buf.ReadWord()}, &cs->units_volume);
88 break;
89
90 case 0x0C: // String for plural quantity of cargo (e.g. 10 tonnes of coal)
91 case 0x1C: // String for any amount of cargo
92 /* Strings for an amount of cargo. This is different in OpenTTD
93 * (e.g. {WEIGHT} of coal) to TTDPatch (e.g. {COMMA} tonnes of coal).
94 * Property 1C is used to set OpenTTD's behaviour. */
95 AddStringForMapping(GRFStringID{buf.ReadWord()}, &cs->quantifier);
96 break;
97
98 case 0x0D: // String for two letter cargo abbreviation
99 AddStringForMapping(GRFStringID{buf.ReadWord()}, &cs->abbrev);
100 break;
101
102 case 0x0E: // Sprite ID for cargo icon
103 cs->sprite = buf.ReadWord();
104 break;
105
106 case 0x0F: // Weight of one unit of cargo
107 cs->weight = buf.ReadByte();
108 break;
109
110 case 0x10: // Used for payment calculation
111 cs->transit_periods[0] = buf.ReadByte();
112 break;
113
114 case 0x11: // Used for payment calculation
115 cs->transit_periods[1] = buf.ReadByte();
116 break;
117
118 case 0x12: // Base cargo price
119 cs->initial_payment = buf.ReadDWord();
120 break;
121
122 case 0x13: // Colour for station rating bars
123 cs->rating_colour = PixelColour{buf.ReadByte()};
124 break;
125
126 case 0x14: // Colour for cargo graph
127 cs->legend_colour = PixelColour{buf.ReadByte()};
128 break;
129
130 case 0x15: // Freight status
131 cs->is_freight = (buf.ReadByte() != 0);
132 break;
133
134 case 0x16: // Cargo classes
135 cs->classes = CargoClasses{buf.ReadWord()};
136 break;
137
138 case 0x17: // Cargo label
139 cs->label = CargoLabel{std::byteswap(buf.ReadDWord())};
140 BuildCargoLabelMap();
141 MaybeInstallFallbackCargoLabel(id, last, cs->label);
142 break;
143
144 case 0x18: { // Town growth substitute type
145 uint8_t substitute_type = buf.ReadByte();
146
147 switch (substitute_type) {
148 case 0x00: cs->town_acceptance_effect = TAE_PASSENGERS; break;
149 case 0x02: cs->town_acceptance_effect = TAE_MAIL; break;
150 case 0x05: cs->town_acceptance_effect = TAE_GOODS; break;
151 case 0x09: cs->town_acceptance_effect = TAE_WATER; break;
152 case 0x0B: cs->town_acceptance_effect = TAE_FOOD; break;
153 default:
154 GrfMsg(1, "CargoChangeInfo: Unknown town growth substitute value {}, setting to none.", substitute_type);
155 [[fallthrough]];
156 case 0xFF: cs->town_acceptance_effect = TAE_NONE; break;
157 }
158 break;
159 }
160
161 case 0x19: // Town growth coefficient
162 buf.ReadWord();
163 break;
164
165 case 0x1A: // Bitmask of callbacks to use
166 cs->callback_mask = static_cast<CargoCallbackMasks>(buf.ReadByte());
167 break;
168
169 case 0x1D: // Vehicle capacity multiplier
170 cs->multiplier = std::max<uint16_t>(1u, buf.ReadWord());
171 break;
172
173 case 0x1E: { // Town production substitute type
174 uint8_t substitute_type = buf.ReadByte();
175
176 switch (substitute_type) {
177 case 0x00: cs->town_production_effect = TPE_PASSENGERS; break;
178 case 0x02: cs->town_production_effect = TPE_MAIL; break;
179 default:
180 GrfMsg(1, "CargoChangeInfo: Unknown town production substitute value {}, setting to none.", substitute_type);
181 [[fallthrough]];
182 case 0xFF: cs->town_production_effect = TPE_NONE; break;
183 }
184 break;
185 }
186
187 case 0x1F: // Town production multiplier
188 cs->town_production_multiplier = std::max<uint16_t>(1U, buf.ReadWord());
189 break;
190
191 default:
192 ret = CIR_UNKNOWN;
193 break;
194 }
195 }
196
197 return ret;
198}
199
200template <> ChangeInfoResult GrfChangeInfoHandler<GSF_CARGOES>::Reserve(uint first, uint last, int prop, ByteReader &buf) { return CargoReserveInfo(first, last, prop, buf); }
201template <> ChangeInfoResult GrfChangeInfoHandler<GSF_CARGOES>::Activation(uint, uint, int, ByteReader &) { return CIR_UNHANDLED; }
SetBit
constexpr T SetBit(T &x, const uint8_t y)
Set a bit in a variable.
Definition bitmath_func.hpp:121
ClrBit
constexpr T ClrBit(T &x, const uint8_t y)
Clears a bit in a variable.
Definition bitmath_func.hpp:139
CT_INVALID
static constexpr CargoLabel CT_INVALID
Invalid cargo type.
Definition cargo_type.h:70
NUM_CARGO
static const CargoType NUM_CARGO
Maximum number of cargo types in a game.
Definition cargo_type.h:73
BuildCargoLabelMap
void BuildCargoLabelMap()
Build cargo label map.
Definition cargotype.cpp:132
_cargo_mask
CargoTypes _cargo_mask
Bitmask of cargo types available.
Definition cargotype.cpp:31
TPE_NONE
@ TPE_NONE
Town will not produce this cargo type.
Definition cargotype.h:36
TPE_PASSENGERS
@ TPE_PASSENGERS
Cargo behaves passenger-like for production.
Definition cargotype.h:37
TPE_MAIL
@ TPE_MAIL
Cargo behaves mail-like for production.
Definition cargotype.h:38
TAE_GOODS
@ TAE_GOODS
Cargo behaves goods/candy-like.
Definition cargotype.h:27
TAE_NONE
@ TAE_NONE
Cargo has no effect.
Definition cargotype.h:24
TAE_PASSENGERS
@ TAE_PASSENGERS
Cargo behaves passenger-like.
Definition cargotype.h:25
TAE_MAIL
@ TAE_MAIL
Cargo behaves mail-like.
Definition cargotype.h:26
TAE_FOOD
@ TAE_FOOD
Cargo behaves food/fizzy-drinks-like.
Definition cargotype.h:29
TAE_WATER
@ TAE_WATER
Cargo behaves water-like.
Definition cargotype.h:28
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< CargoClass, uint16_t >
GetCargoTranslationTable
std::span< const CargoLabel > GetCargoTranslationTable(const GRFFile &grffile)
Get the cargo translation table to use for the given GRF file.
Definition newgrf.cpp:521
CargoReserveInfo
static ChangeInfoResult CargoReserveInfo(uint first, uint last, int prop, ByteReader &buf)
Define properties for cargoes.
Definition newgrf_act0_cargo.cpp:50
MaybeInstallFallbackCargoLabel
static void MaybeInstallFallbackCargoLabel(uint id, uint last, CargoLabel label)
Install cargo label in a fallback cargo list, if a NewGRF-defined cargo list is not present.
Definition newgrf_act0_cargo.cpp:26
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_UNHANDLED
@ CIR_UNHANDLED
Variable was parsed but unread.
Definition newgrf_internal.h:23
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.
CargoSpec
Specification of a cargo type.
Definition cargotype.h:74
CargoSpec::initial_payment
int32_t initial_payment
Initial payment rate before inflation is applied.
Definition cargotype.h:82
CargoSpec::classes
CargoClasses classes
Classes of this cargo type.
Definition cargotype.h:81
CargoSpec::multiplier
uint16_t multiplier
Capacity multiplier for vehicles. (8 fractional bits)
Definition cargotype.h:80
CargoSpec::units_volume
StringID units_volume
Name of a single unit of cargo of this type.
Definition cargotype.h:93
CargoSpec::Get
static CargoSpec * Get(size_t index)
Retrieve cargo details for the given cargo type.
Definition cargotype.h:137
CargoSpec::abbrev
StringID abbrev
Two letter abbreviation for this cargo type.
Definition cargotype.h:95
CargoSpec::bitnum
uint8_t bitnum
Cargo bit number, is INVALID_CARGO_BITNUM for a non-used spec.
Definition cargotype.h:76
CargoSpec::quantifier
StringID quantifier
Text for multiple units of cargo of this type.
Definition cargotype.h:94
CargoSpec::sprite
SpriteID sprite
Icon to display this cargo type, may be 0xFFF (which means to resolve an action123 chain).
Definition cargotype.h:97
CargoSpec::is_freight
bool is_freight
Cargo type is considered to be freight (affects train freight multiplier).
Definition cargotype.h:85
CargoSpec::weight
uint8_t weight
Weight of a single unit of this cargo type in 1/16 ton (62.5 kg).
Definition cargotype.h:79
CargoSpec::label
CargoLabel label
Unique label of the cargo type.
Definition cargotype.h:75
CargoSpec::grffile
const struct GRFFile * grffile
NewGRF where group belongs to.
Definition cargotype.h:99
CargoSpec::name
StringID name
Name of this type of cargo.
Definition cargotype.h:91
CargoSpec::town_production_effect
TownProductionEffect town_production_effect
The effect on town cargo production.
Definition cargotype.h:87
CargoSpec::town_acceptance_effect
TownAcceptanceEffect town_acceptance_effect
The effect that delivering this cargo type has on towns. Also affects destination of subsidies.
Definition cargotype.h:86
CargoSpec::callback_mask
CargoCallbackMasks callback_mask
Bitmask of cargo callbacks that have to be called.
Definition cargotype.h:89
CargoSpec::town_production_multiplier
uint16_t town_production_multiplier
Town production multiplier, if commanded by TownProductionEffect.
Definition cargotype.h:88
CargoSpec::IsValid
bool IsValid() const
Tests for validity of this cargospec.
Definition cargotype.h:118
CargoSpec::name_single
StringID name_single
Name of a single entity of this type of cargo.
Definition cargotype.h:92
GRFFile::cargo_list_is_fallback
bool cargo_list_is_fallback
Set if cargo types have been created but a cargo list has not been installed.
Definition newgrf.h:156
GRFFile::cargo_list
std::vector< CargoLabel > cargo_list
Cargo translation table (local ID -> label)
Definition newgrf.h:135
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 CargoLabelTag, StrongType::Compare >