Fix #8316: Make sort industries by production and transported with a cargo filter...
[openttd-github.git] / src / cargotype.h
blob5ed9ac90e2ad78ac8b9f65e6f55d04d9bdc3801e
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 */
8 /** @file cargotype.h Types/functions related to cargoes. */
10 #ifndef CARGOTYPE_H
11 #define CARGOTYPE_H
13 #include "economy_type.h"
14 #include "cargo_type.h"
15 #include "gfx_type.h"
16 #include "strings_type.h"
17 #include "landscape_type.h"
18 #include "core/bitmath_func.hpp"
19 #include "core/span_type.hpp"
20 #include <vector>
22 /** Globally unique label of a cargo type. */
23 typedef uint32 CargoLabel;
25 /** Town growth effect when delivering cargo. */
26 enum TownEffect {
27 TE_BEGIN = 0,
28 TE_NONE = TE_BEGIN, ///< Cargo has no effect.
29 TE_PASSENGERS, ///< Cargo behaves passenger-like.
30 TE_MAIL, ///< Cargo behaves mail-like.
31 TE_GOODS, ///< Cargo behaves goods/candy-like.
32 TE_WATER, ///< Cargo behaves water-like.
33 TE_FOOD, ///< Cargo behaves food/fizzy-drinks-like.
34 TE_END, ///< End of town effects.
35 NUM_TE = TE_END, ///< Amount of town effects.
38 /** Cargo classes. */
39 enum CargoClass {
40 CC_NOAVAILABLE = 0, ///< No cargo class has been specified
41 CC_PASSENGERS = 1 << 0, ///< Passengers
42 CC_MAIL = 1 << 1, ///< Mail
43 CC_EXPRESS = 1 << 2, ///< Express cargo (Goods, Food, Candy, but also possible for passengers)
44 CC_ARMOURED = 1 << 3, ///< Armoured cargo (Valuables, Gold, Diamonds)
45 CC_BULK = 1 << 4, ///< Bulk cargo (Coal, Grain etc., Ores, Fruit)
46 CC_PIECE_GOODS = 1 << 5, ///< Piece goods (Livestock, Wood, Steel, Paper)
47 CC_LIQUID = 1 << 6, ///< Liquids (Oil, Water, Rubber)
48 CC_REFRIGERATED = 1 << 7, ///< Refrigerated cargo (Food, Fruit)
49 CC_HAZARDOUS = 1 << 8, ///< Hazardous cargo (Nuclear Fuel, Explosives, etc.)
50 CC_COVERED = 1 << 9, ///< Covered/Sheltered Freight (Transportation in Box Vans, Silo Wagons, etc.)
51 CC_SPECIAL = 1 << 15, ///< Special bit used for livery refit tricks instead of normal cargoes.
54 static const byte INVALID_CARGO = 0xFF; ///< Constant representing invalid cargo
56 /** Specification of a cargo type. */
57 struct CargoSpec {
58 uint8 bitnum; ///< Cargo bit number, is #INVALID_CARGO for a non-used spec.
59 CargoLabel label; ///< Unique label of the cargo type.
60 uint8 legend_colour;
61 uint8 rating_colour;
62 uint8 weight; ///< Weight of a single unit of this cargo type in 1/16 ton (62.5 kg).
63 uint16 multiplier; ///< Capacity multiplier for vehicles. (8 fractional bits)
64 int32 initial_payment; ///< Initial payment rate before inflation is applied.
65 uint8 transit_days[2];
67 bool is_freight; ///< Cargo type is considered to be freight (affects train freight multiplier).
68 TownEffect town_effect; ///< The effect that delivering this cargo type has on towns. Also affects destination of subsidies.
69 uint16 multipliertowngrowth; ///< Size of the effect.
70 uint8 callback_mask; ///< Bitmask of cargo callbacks that have to be called
72 StringID name; ///< Name of this type of cargo.
73 StringID name_single; ///< Name of a single entity of this type of cargo.
74 StringID units_volume; ///< Name of a single unit of cargo of this type.
75 StringID quantifier; ///< Text for multiple units of cargo of this type.
76 StringID abbrev; ///< Two letter abbreviation for this cargo type.
78 SpriteID sprite; ///< Icon to display this cargo type, may be \c 0xFFF (which means to resolve an action123 chain).
80 uint16 classes; ///< Classes of this cargo type. @see CargoClass
81 const struct GRFFile *grffile; ///< NewGRF where #group belongs to.
82 const struct SpriteGroup *group;
84 Money current_payment;
86 /**
87 * Determines index of this cargospec
88 * @return index (in the CargoSpec::array array)
90 inline CargoID Index() const
92 return this - CargoSpec::array;
95 /**
96 * Tests for validity of this cargospec
97 * @return is this cargospec valid?
98 * @note assert(cs->IsValid()) can be triggered when GRF config is modified
100 inline bool IsValid() const
102 return this->bitnum != INVALID_CARGO;
106 * Total number of cargospecs, both valid and invalid
107 * @return length of CargoSpec::array
109 static inline size_t GetArraySize()
111 return lengthof(CargoSpec::array);
115 * Retrieve cargo details for the given cargo ID
116 * @param index ID of cargo
117 * @pre index is a valid cargo ID
119 static inline CargoSpec *Get(size_t index)
121 assert(index < lengthof(CargoSpec::array));
122 return &CargoSpec::array[index];
125 SpriteID GetCargoIcon() const;
128 * Iterator to iterate all valid CargoSpec
130 struct Iterator {
131 typedef CargoSpec value_type;
132 typedef CargoSpec *pointer;
133 typedef CargoSpec &reference;
134 typedef size_t difference_type;
135 typedef std::forward_iterator_tag iterator_category;
137 explicit Iterator(size_t index) : index(index)
139 this->ValidateIndex();
142 bool operator==(const Iterator &other) const { return this->index == other.index; }
143 bool operator!=(const Iterator &other) const { return !(*this == other); }
144 CargoSpec * operator*() const { return CargoSpec::Get(this->index); }
145 Iterator & operator++() { this->index++; this->ValidateIndex(); return *this; }
147 private:
148 size_t index;
149 void ValidateIndex() { while (this->index < CargoSpec::GetArraySize() && !(CargoSpec::Get(this->index)->IsValid())) this->index++; }
153 * Iterable ensemble of all valid CargoSpec
155 struct IterateWrapper {
156 size_t from;
157 IterateWrapper(size_t from = 0) : from(from) {}
158 Iterator begin() { return Iterator(this->from); }
159 Iterator end() { return Iterator(CargoSpec::GetArraySize()); }
160 bool empty() { return this->begin() == this->end(); }
164 * Returns an iterable ensemble of all valid CargoSpec
165 * @param from index of the first CargoSpec to consider
166 * @return an iterable ensemble of all valid CargoSpec
168 static IterateWrapper Iterate(size_t from = 0) { return IterateWrapper(from); }
170 private:
171 static CargoSpec array[NUM_CARGO]; ///< Array holding all CargoSpecs
173 friend void SetupCargoForClimate(LandscapeID l);
176 extern CargoTypes _cargo_mask;
177 extern CargoTypes _standard_cargo_mask;
179 void SetupCargoForClimate(LandscapeID l);
180 CargoID GetCargoIDByLabel(CargoLabel cl);
181 CargoID GetCargoIDByBitnum(uint8 bitnum);
182 CargoID GetDefaultCargoID(LandscapeID l, CargoType ct);
184 void InitializeSortedCargoSpecs();
185 extern std::vector<const CargoSpec *> _sorted_cargo_specs;
186 extern span<const CargoSpec *> _sorted_standard_cargo_specs;
189 * Does cargo \a c have cargo class \a cc?
190 * @param c Cargo type.
191 * @param cc Cargo class.
192 * @return The type fits in the class.
194 static inline bool IsCargoInClass(CargoID c, CargoClass cc)
196 return (CargoSpec::Get(c)->classes & cc) != 0;
199 using SetCargoBitIterator = SetBitIterator<CargoID, CargoTypes>;
201 #endif /* CARGOTYPE_H */