summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNiels Martin Hansen <nielsm@indvikleren.dk>2018-07-25 19:20:17 +0200
committerNiels Martin Hansen <nielsm@indvikleren.dk>2018-11-03 21:43:54 +0100
commit8859381d301a60169e167431c97cb084b7730ead (patch)
tree3daf7557f10f114e31cf88a5d463acf28a68be62 /src
parent32b9ee7063b79ae6621762db2a006d6ed267502f (diff)
downloadopenttd-8859381d301a60169e167431c97cb084b7730ead.tar.xz
Add: Industries can produce and accept up to 16 different cargoes
Diffstat (limited to 'src')
-rw-r--r--src/economy.cpp11
-rw-r--r--src/industry.h29
-rw-r--r--src/industry_cmd.cpp52
-rw-r--r--src/industry_gui.cpp17
-rw-r--r--src/industrytype.h62
-rw-r--r--src/newgrf_industries.cpp7
-rw-r--r--src/saveload/afterload.cpp21
-rw-r--r--src/saveload/industry_sl.cpp30
-rw-r--r--src/saveload/saveload.cpp3
-rw-r--r--src/subsidy.cpp31
-rw-r--r--src/table/build_industry.h10
-rw-r--r--src/table/newgrf_debug_data.h8
12 files changed, 165 insertions, 116 deletions
diff --git a/src/economy.cpp b/src/economy.cpp
index 98989971c..b42dc3301 100644
--- a/src/economy.cpp
+++ b/src/economy.cpp
@@ -1147,14 +1147,15 @@ static void TriggerIndustryProduction(Industry *i)
SetWindowDirty(WC_INDUSTRY_VIEW, i->index);
}
} else {
- for (uint cargo_index = 0; cargo_index < lengthof(i->incoming_cargo_waiting); cargo_index++) {
- uint cargo_waiting = i->incoming_cargo_waiting[cargo_index];
+ for (uint ci_in = 0; ci_in < lengthof(i->incoming_cargo_waiting); ci_in++) {
+ uint cargo_waiting = i->incoming_cargo_waiting[ci_in];
if (cargo_waiting == 0) continue;
- i->produced_cargo_waiting[0] = min(i->produced_cargo_waiting[0] + (cargo_waiting * indspec->input_cargo_multiplier[cargo_index][0] / 256), 0xFFFF);
- i->produced_cargo_waiting[1] = min(i->produced_cargo_waiting[1] + (cargo_waiting * indspec->input_cargo_multiplier[cargo_index][1] / 256), 0xFFFF);
+ for (uint ci_out = 0; ci_out < lengthof(i->produced_cargo_waiting), ci_out++) {
+ i->produced_cargo_waiting[ci_out] = min(i->produced_cargo_waiting[ci_out] + (cargo_waiting * indspec->input_cargo_multiplier[ci_in][ci_out] / 256), 0xFFFF);
+ }
- i->incoming_cargo_waiting[cargo_index] = 0;
+ i->incoming_cargo_waiting[ci_in] = 0;
}
}
diff --git a/src/industry.h b/src/industry.h
index 9b185efc4..42cf3aff2 100644
--- a/src/industry.h
+++ b/src/industry.h
@@ -15,6 +15,7 @@
#include "newgrf_storage.h"
#include "subsidy_type.h"
#include "industry_map.h"
+#include "industrytype.h"
#include "tilearea_type.h"
@@ -37,20 +38,20 @@ enum ProductionLevels {
* Defines the internal data of a functional industry.
*/
struct Industry : IndustryPool::PoolItem<&_industry_pool> {
- TileArea location; ///< Location of the industry
- Town *town; ///< Nearest town
- CargoID produced_cargo[2]; ///< 2 production cargo slots
- uint16 produced_cargo_waiting[2]; ///< amount of cargo produced per cargo
- uint16 incoming_cargo_waiting[3]; ///< incoming cargo waiting to be processed
- byte production_rate[2]; ///< production rate for each cargo
- byte prod_level; ///< general production level
- CargoID accepts_cargo[3]; ///< 3 input cargo slots
- uint16 this_month_production[2]; ///< stats of this month's production per cargo
- uint16 this_month_transported[2]; ///< stats of this month's transport per cargo
- byte last_month_pct_transported[2]; ///< percentage transported per cargo in the last full month
- uint16 last_month_production[2]; ///< total units produced per cargo in the last full month
- uint16 last_month_transported[2]; ///< total units transported per cargo in the last full month
- uint16 counter; ///< used for animation and/or production (if available cargo)
+ TileArea location; ///< Location of the industry
+ Town *town; ///< Nearest town
+ CargoID produced_cargo[INDUSTRY_NUM_OUTPUTS]; ///< 16 production cargo slots
+ uint16 produced_cargo_waiting[INDUSTRY_NUM_OUTPUTS]; ///< amount of cargo produced per cargo
+ uint16 incoming_cargo_waiting[INDUSTRY_NUM_INPUTS]; ///< incoming cargo waiting to be processed
+ byte production_rate[INDUSTRY_NUM_OUTPUTS]; ///< production rate for each cargo
+ byte prod_level; ///< general production level
+ CargoID accepts_cargo[INDUSTRY_NUM_INPUTS]; ///< 16 input cargo slots
+ uint16 this_month_production[INDUSTRY_NUM_OUTPUTS]; ///< stats of this month's production per cargo
+ uint16 this_month_transported[INDUSTRY_NUM_OUTPUTS]; ///< stats of this month's transport per cargo
+ byte last_month_pct_transported[INDUSTRY_NUM_OUTPUTS]; ///< percentage transported per cargo in the last full month
+ uint16 last_month_production[INDUSTRY_NUM_OUTPUTS]; ///< total units produced per cargo in the last full month
+ uint16 last_month_transported[INDUSTRY_NUM_OUTPUTS]; ///< total units transported per cargo in the last full month
+ uint16 counter; ///< used for animation and/or production (if available cargo)
IndustryType type; ///< type of industry.
OwnerByte owner; ///< owner of the industry. Which SHOULD always be (imho) OWNER_NONE
diff --git a/src/industry_cmd.cpp b/src/industry_cmd.cpp
index ee55e490b..a30fea6d1 100644
--- a/src/industry_cmd.cpp
+++ b/src/industry_cmd.cpp
@@ -1118,8 +1118,9 @@ static void ProduceIndustryGoods(Industry *i)
if (HasBit(indsp->callback_mask, CBM_IND_PRODUCTION_256_TICKS)) IndustryProductionCallback(i, 1);
IndustryBehaviour indbehav = indsp->behaviour;
- i->produced_cargo_waiting[0] = min(0xffff, i->produced_cargo_waiting[0] + i->production_rate[0]);
- i->produced_cargo_waiting[1] = min(0xffff, i->produced_cargo_waiting[1] + i->production_rate[1]);
+ for (size_t j = 0; j < lengthof(i->produced_cargo_waiting); j++) {
+ i->produced_cargo_waiting[j] = min(0xffff, i->produced_cargo_waiting[j] + i->production_rate[j]);
+ }
if ((indbehav & INDUSTRYBEH_PLANT_FIELDS) != 0) {
uint16 cb_res = CALLBACK_FAILED;
@@ -1648,18 +1649,22 @@ static void DoCreateNewIndustry(Industry *i, TileIndex tile, IndustryType type,
i->type = type;
Industry::IncIndustryTypeCount(type);
- i->produced_cargo[0] = indspec->produced_cargo[0];
- i->produced_cargo[1] = indspec->produced_cargo[1];
- i->accepts_cargo[0] = indspec->accepts_cargo[0];
- i->accepts_cargo[1] = indspec->accepts_cargo[1];
- i->accepts_cargo[2] = indspec->accepts_cargo[2];
- i->production_rate[0] = indspec->production_rate[0];
- i->production_rate[1] = indspec->production_rate[1];
+ MemCpyT(i->produced_cargo, indspec->produced_cargo, lengthof(i->produced_cargo));
+ MemCpyT(i->production_rate, indspec->production_rate, lengthof(i->production_rate));
+ MemCpyT(i->accepts_cargo, indspec->accepts_cargo, lengthof(i->accepts_cargo));
+
+ MemSetT(i->produced_cargo_waiting, 0, lengthof(i->produced_cargo_waiting));
+ MemSetT(i->this_month_production, 0, lengthof(i->this_month_production));
+ MemSetT(i->this_month_transported, 0, lengthof(i->this_month_transported));
+ MemSetT(i->last_month_pct_transported, 0, lengthof(i->last_month_pct_transported));
+ MemSetT(i->last_month_transported, 0, lengthof(i->last_month_transported));
+ MemSetT(i->incoming_cargo_waiting, 0, lengthof(i->incoming_cargo_waiting));
/* don't use smooth economy for industries using production related callbacks */
if (indspec->UsesSmoothEconomy()) {
- i->production_rate[0] = min((RandomRange(256) + 128) * i->production_rate[0] >> 8, 255);
- i->production_rate[1] = min((RandomRange(256) + 128) * i->production_rate[1] >> 8, 255);
+ for (size_t ci = 0; ci < lengthof(i->production_rate); ci++) {
+ i->production_rate[ci] = min((RandomRange(256) + 128) * i->production_rate[ci] >> 8, 255);
+ }
}
i->town = t;
@@ -1669,19 +1674,6 @@ static void DoCreateNewIndustry(Industry *i, TileIndex tile, IndustryType type,
i->random_colour = GB(r, 0, 4);
i->counter = GB(r, 4, 12);
i->random = initial_random_bits;
- i->produced_cargo_waiting[0] = 0;
- i->produced_cargo_waiting[1] = 0;
- i->incoming_cargo_waiting[0] = 0;
- i->incoming_cargo_waiting[1] = 0;
- i->incoming_cargo_waiting[2] = 0;
- i->this_month_production[0] = 0;
- i->this_month_production[1] = 0;
- i->this_month_transported[0] = 0;
- i->this_month_transported[1] = 0;
- i->last_month_pct_transported[0] = 0;
- i->last_month_pct_transported[1] = 0;
- i->last_month_transported[0] = 0;
- i->last_month_transported[1] = 0;
i->was_cargo_delivered = false;
i->last_prod_year = _cur_year;
i->founder = founder;
@@ -1712,10 +1704,9 @@ static void DoCreateNewIndustry(Industry *i, TileIndex tile, IndustryType type,
}
if (_generating_world) {
- i->last_month_production[0] = i->production_rate[0] * 8;
- i->last_month_production[1] = i->production_rate[1] * 8;
- } else {
- i->last_month_production[0] = i->last_month_production[1] = 0;
+ for (size_t ci = 0; ci < lengthof(i->last_month_production); ci++) {
+ i->last_month_production[ci] = i->production_rate[ci] * 8;
+ }
}
if (HasBit(indspec->callback_mask, CBM_IND_DECIDE_COLOUR)) {
@@ -2194,8 +2185,9 @@ void Industry::RecomputeProductionMultipliers()
assert(!indspec->UsesSmoothEconomy());
/* Rates are rounded up, so e.g. oilrig always produces some passengers */
- this->production_rate[0] = min(CeilDiv(indspec->production_rate[0] * this->prod_level, PRODLEVEL_DEFAULT), 0xFF);
- this->production_rate[1] = min(CeilDiv(indspec->production_rate[1] * this->prod_level, PRODLEVEL_DEFAULT), 0xFF);
+ for (size_t i = 0; i < lengthof(this->production_rate); i++) {
+ this->production_rate[i] = min(CeilDiv(indspec->production_rate[i] * this->prod_level, PRODLEVEL_DEFAULT), 0xFF);
+ }
}
diff --git a/src/industry_gui.cpp b/src/industry_gui.cpp
index 9108c4e7a..1229fec33 100644
--- a/src/industry_gui.cpp
+++ b/src/industry_gui.cpp
@@ -358,7 +358,7 @@ public:
const IndustrySpec *indsp = GetIndustrySpec(this->index[i]);
- CargoSuffix cargo_suffix[3];
+ CargoSuffix cargo_suffix[lengthof(indsp->accepts_cargo)];
GetAllCargoSuffixes(0, CST_FUND, NULL, this->index[i], indsp, indsp->accepts_cargo, cargo_suffix);
StringID str = STR_INDUSTRY_VIEW_REQUIRES_CARGO;
byte p = 0;
@@ -477,7 +477,7 @@ public:
}
/* Draw the accepted cargoes, if any. Otherwise, will print "Nothing". */
- CargoSuffix cargo_suffix[3];
+ CargoSuffix cargo_suffix[lengthof(indsp->accepts_cargo)];
GetAllCargoSuffixes(0, CST_FUND, NULL, this->selected_type, indsp, indsp->accepts_cargo, cargo_suffix);
StringID str = STR_INDUSTRY_VIEW_REQUIRES_CARGO;
byte p = 0;
@@ -683,8 +683,15 @@ static void UpdateIndustryProduction(Industry *i);
static inline bool IsProductionAlterable(const Industry *i)
{
const IndustrySpec *is = GetIndustrySpec(i->type);
+ bool has_prod = false;
+ for (size_t j = 0; j < lengthof(is->production_rate); j++) {
+ if (is->production_rate[j] != 0) {
+ has_prod = true;
+ break;
+ }
+ }
return ((_game_mode == GM_EDITOR || _cheats.setup_prod.value) &&
- (is->production_rate[0] != 0 || is->production_rate[1] != 0 || is->IsRawIndustry()) &&
+ (has_prod || is->IsRawIndustry()) &&
!_networking);
}
@@ -763,7 +770,7 @@ public:
y += 2 * FONT_HEIGHT_NORMAL;
}
- CargoSuffix cargo_suffix[3];
+ CargoSuffix cargo_suffix[lengthof(i->accepts_cargo)];
GetAllCargoSuffixes(0, CST_VIEW, i, i->type, ind, i->accepts_cargo, cargo_suffix);
bool stockpiling = HasBit(ind->callback_mask, CBM_IND_PRODUCTION_CARGO_ARRIVAL) || HasBit(ind->callback_mask, CBM_IND_PRODUCTION_256_TICKS);
@@ -1514,7 +1521,7 @@ enum CargoesFieldType {
CFT_HEADER, ///< Header text.
};
-static const uint MAX_CARGOES = 3; ///< Maximum number of cargoes carried in a #CFT_CARGO field in #CargoesField.
+static const uint MAX_CARGOES = 16; ///< Maximum number of cargoes carried in a #CFT_CARGO field in #CargoesField.
/** Data about a single field in the #IndustryCargoesWindow panel. */
struct CargoesField {
diff --git a/src/industrytype.h b/src/industrytype.h
index 03b6c7973..da09a6d9b 100644
--- a/src/industrytype.h
+++ b/src/industrytype.h
@@ -95,45 +95,48 @@ struct IndustryTileTable {
IndustryGfx gfx;
};
+const int INDUSTRY_NUM_INPUTS = 16; ///< Number of cargo types an industry can accept
+const int INDUSTRY_NUM_OUTPUTS = 16; ///< Number of cargo types an industry can produce
+
/**
* Defines the data structure for constructing industry.
*/
struct IndustrySpec {
- const IndustryTileTable * const *table;///< List of the tiles composing the industry
- byte num_table; ///< Number of elements in the table
- uint8 cost_multiplier; ///< Base construction cost multiplier.
- uint32 removal_cost_multiplier; ///< Base removal cost multiplier.
- uint32 prospecting_chance; ///< Chance prospecting succeeds
- IndustryType conflicting[3]; ///< Industries this industry cannot be close to
- byte check_proc; ///< Index to a procedure to check for conflicting circumstances
- CargoID produced_cargo[2];
- byte production_rate[2];
+ const IndustryTileTable * const *table; ///< List of the tiles composing the industry
+ byte num_table; ///< Number of elements in the table
+ uint8 cost_multiplier; ///< Base construction cost multiplier.
+ uint32 removal_cost_multiplier; ///< Base removal cost multiplier.
+ uint32 prospecting_chance; ///< Chance prospecting succeeds
+ IndustryType conflicting[3]; ///< Industries this industry cannot be close to
+ byte check_proc; ///< Index to a procedure to check for conflicting circumstances
+ CargoID produced_cargo[INDUSTRY_NUM_OUTPUTS];
+ byte production_rate[INDUSTRY_NUM_OUTPUTS];
/**
* minimum amount of cargo transported to the stations.
* If the waiting cargo is less than this number, no cargo is moved to it.
*/
byte minimal_cargo;
- CargoID accepts_cargo[3]; ///< 3 accepted cargoes.
- uint16 input_cargo_multiplier[3][2]; ///< Input cargo multipliers (multiply amount of incoming cargo for the produced cargoes)
- IndustryLifeType life_type; ///< This is also known as Industry production flag, in newgrf specs
- byte climate_availability; ///< Bitmask, giving landscape enums as bit position
- IndustryBehaviour behaviour; ///< How this industry will behave, and how others entities can use it
- byte map_colour; ///< colour used for the small map
- StringID name; ///< Displayed name of the industry
- StringID new_industry_text; ///< Message appearing when the industry is built
- StringID closure_text; ///< Message appearing when the industry closes
- StringID production_up_text; ///< Message appearing when the industry's production is increasing
- StringID production_down_text; ///< Message appearing when the industry's production is decreasing
- StringID station_name; ///< Default name for nearby station
- byte appear_ingame[NUM_LANDSCAPE]; ///< Probability of appearance in game
- byte appear_creation[NUM_LANDSCAPE]; ///< Probability of appearance during map creation
- uint8 number_of_sounds; ///< Number of sounds available in the sounds array
- const uint8 *random_sounds; ///< array of random sounds.
+ CargoID accepts_cargo[INDUSTRY_NUM_INPUTS]; ///< 16 accepted cargoes.
+ uint16 input_cargo_multiplier[INDUSTRY_NUM_INPUTS][INDUSTRY_NUM_OUTPUTS]; ///< Input cargo multipliers (multiply amount of incoming cargo for the produced cargoes)
+ IndustryLifeType life_type; ///< This is also known as Industry production flag, in newgrf specs
+ byte climate_availability; ///< Bitmask, giving landscape enums as bit position
+ IndustryBehaviour behaviour; ///< How this industry will behave, and how others entities can use it
+ byte map_colour; ///< colour used for the small map
+ StringID name; ///< Displayed name of the industry
+ StringID new_industry_text; ///< Message appearing when the industry is built
+ StringID closure_text; ///< Message appearing when the industry closes
+ StringID production_up_text; ///< Message appearing when the industry's production is increasing
+ StringID production_down_text; ///< Message appearing when the industry's production is decreasing
+ StringID station_name; ///< Default name for nearby station
+ byte appear_ingame[NUM_LANDSCAPE]; ///< Probability of appearance in game
+ byte appear_creation[NUM_LANDSCAPE]; ///< Probability of appearance during map creation
+ uint8 number_of_sounds; ///< Number of sounds available in the sounds array
+ const uint8 *random_sounds; ///< array of random sounds.
/* Newgrf data */
- uint16 callback_mask; ///< Bitmask of industry callbacks that have to be called
- uint8 cleanup_flag; ///< flags indicating which data should be freed upon cleaning up
- bool enabled; ///< entity still available (by default true).newgrf can disable it, though
- GRFFileProps grf_prop; ///< properties related to the grf file
+ uint16 callback_mask; ///< Bitmask of industry callbacks that have to be called
+ uint8 cleanup_flag; ///< flags indicating which data should be freed upon cleaning up
+ bool enabled; ///< entity still available (by default true).newgrf can disable it, though
+ GRFFileProps grf_prop; ///< properties related to the grf file
bool IsRawIndustry() const;
bool IsProcessingIndustry() const;
@@ -144,6 +147,7 @@ struct IndustrySpec {
/**
* Defines the data structure of each individual tile of an industry.
+ * @note A tile can at most accept 3 types of cargo, even if an industry as a whole can accept more types.
*/
struct IndustryTileSpec {
CargoID accepts_cargo[3]; ///< Cargo accepted by this tile
diff --git a/src/newgrf_industries.cpp b/src/newgrf_industries.cpp
index bf003fb6f..c3ddda79a 100644
--- a/src/newgrf_industries.cpp
+++ b/src/newgrf_industries.cpp
@@ -602,7 +602,12 @@ void IndustryProductionCallback(Industry *ind, int reason)
*/
bool IndustryTemporarilyRefusesCargo(Industry *ind, CargoID cargo_type)
{
- assert(cargo_type == ind->accepts_cargo[0] || cargo_type == ind->accepts_cargo[1] || cargo_type == ind->accepts_cargo[2]);
+ assert(
+ cargo_type == ind->accepts_cargo[0] || cargo_type == ind->accepts_cargo[1] || cargo_type == ind->accepts_cargo[2] || cargo_type == ind->accepts_cargo[3] ||
+ cargo_type == ind->accepts_cargo[4] || cargo_type == ind->accepts_cargo[5] || cargo_type == ind->accepts_cargo[6] || cargo_type == ind->accepts_cargo[7] ||
+ cargo_type == ind->accepts_cargo[8] || cargo_type == ind->accepts_cargo[9] || cargo_type == ind->accepts_cargo[10] || cargo_type == ind->accepts_cargo[11] ||
+ cargo_type == ind->accepts_cargo[12] || cargo_type == ind->accepts_cargo[13] || cargo_type == ind->accepts_cargo[14] || cargo_type == ind->accepts_cargo[15]
+ );
const IndustrySpec *indspec = GetIndustrySpec(ind->type);
if (HasBit(indspec->callback_mask, CBM_IND_REFUSE_CARGO)) {
diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp
index cca9ad328..1529aca2b 100644
--- a/src/saveload/afterload.cpp
+++ b/src/saveload/afterload.cpp
@@ -3015,6 +3015,27 @@ bool AfterLoadGame()
}
}
+ if (IsSavegameVersionBefore(202)) {
+ /* Make sure added industry cargo slots are cleared */
+ Industry *i;
+ FOR_ALL_INDUSTRIES(i) {
+ for (size_t ci = 2; ci < lengthof(i->produced_cargo); ci++) {
+ i->produced_cargo[ci] = CT_INVALID;
+ i->produced_cargo_waiting[ci] = 0;
+ i->production_rate[ci] = 0;
+ i->last_month_production[ci] = 0;
+ i->last_month_transported[ci] = 0;
+ i->last_month_pct_transported[ci] = 0;
+ i->this_month_production[ci] = 0;
+ i->this_month_transported[ci] = 0;
+ }
+ for (size_t ci = 3; ci < lengthof(i->accepts_cargo); ci++) {
+ i->accepts_cargo[ci] = CT_INVALID;
+ i->incoming_cargo_waiting[ci] = 0;
+ }
+ }
+ }
+
/* Station acceptance is some kind of cache */
if (IsSavegameVersionBefore(127)) {
Station *st;
diff --git a/src/saveload/industry_sl.cpp b/src/saveload/industry_sl.cpp
index 615e8e152..9727e4e51 100644
--- a/src/saveload/industry_sl.cpp
+++ b/src/saveload/industry_sl.cpp
@@ -26,18 +26,28 @@ static const SaveLoad _industry_desc[] = {
SLE_VAR(Industry, location.h, SLE_FILE_U8 | SLE_VAR_U16),
SLE_REF(Industry, town, REF_TOWN),
SLE_CONDNULL( 2, 0, 60), ///< used to be industry's produced_cargo
- SLE_CONDARR(Industry, produced_cargo, SLE_UINT8, 2, 78, SL_MAX_VERSION),
- SLE_CONDARR(Industry, incoming_cargo_waiting, SLE_UINT16, 3, 70, SL_MAX_VERSION),
- SLE_ARR(Industry, produced_cargo_waiting, SLE_UINT16, 2),
- SLE_ARR(Industry, production_rate, SLE_UINT8, 2),
+ SLE_CONDARR(Industry, produced_cargo, SLE_UINT8, 2, 78, 201),
+ SLE_CONDARR(Industry, produced_cargo, SLE_UINT8, 16, 202, SL_MAX_VERSION),
+ SLE_CONDARR(Industry, incoming_cargo_waiting, SLE_UINT16, 3, 70, 201),
+ SLE_CONDARR(Industry, incoming_cargo_waiting, SLE_UINT16, 16, 202, SL_MAX_VERSION),
+ SLE_CONDARR(Industry, produced_cargo_waiting, SLE_UINT16, 2, 0, 201),
+ SLE_CONDARR(Industry, produced_cargo_waiting, SLE_UINT16, 16, 202, SL_MAX_VERSION),
+ SLE_CONDARR(Industry, production_rate, SLE_UINT8, 2, 0, 201),
+ SLE_CONDARR(Industry, production_rate, SLE_UINT8, 16, 202, SL_MAX_VERSION),
SLE_CONDNULL( 3, 0, 60), ///< used to be industry's accepts_cargo
- SLE_CONDARR(Industry, accepts_cargo, SLE_UINT8, 3, 78, SL_MAX_VERSION),
+ SLE_CONDARR(Industry, accepts_cargo, SLE_UINT8, 3, 78, 201),
+ SLE_CONDARR(Industry, accepts_cargo, SLE_UINT8, 16, 202, SL_MAX_VERSION),
SLE_VAR(Industry, prod_level, SLE_UINT8),
- SLE_ARR(Industry, this_month_production, SLE_UINT16, 2),
- SLE_ARR(Industry, this_month_transported, SLE_UINT16, 2),
- SLE_ARR(Industry, last_month_pct_transported, SLE_UINT8, 2),
- SLE_ARR(Industry, last_month_production, SLE_UINT16, 2),
- SLE_ARR(Industry, last_month_transported, SLE_UINT16, 2),
+ SLE_CONDARR(Industry, this_month_production, SLE_UINT16, 2, 0, 201),
+ SLE_CONDARR(Industry, this_month_production, SLE_UINT16, 16, 202, SL_MAX_VERSION),
+ SLE_CONDARR(Industry, this_month_transported, SLE_UINT16, 2, 0, 201),
+ SLE_CONDARR(Industry, this_month_transported, SLE_UINT16, 16, 202, SL_MAX_VERSION),
+ SLE_CONDARR(Industry, last_month_pct_transported, SLE_UINT8, 2, 0, 201),
+ SLE_CONDARR(Industry, last_month_pct_transported, SLE_UINT8, 16, 202, SL_MAX_VERSION),
+ SLE_CONDARR(Industry, last_month_production, SLE_UINT16, 2, 0, 201),
+ SLE_CONDARR(Industry, last_month_production, SLE_UINT16, 16, 202, SL_MAX_VERSION),
+ SLE_CONDARR(Industry, last_month_transported, SLE_UINT16, 2, 0, 201),
+ SLE_CONDARR(Industry, last_month_transported, SLE_UINT16, 16, 202, SL_MAX_VERSION),
SLE_VAR(Industry, counter, SLE_UINT16),
diff --git a/src/saveload/saveload.cpp b/src/saveload/saveload.cpp
index f23d13a08..8cf5ee36b 100644
--- a/src/saveload/saveload.cpp
+++ b/src/saveload/saveload.cpp
@@ -269,8 +269,9 @@
* 199
* 200 #6805 Extend railtypes to 64, adding uint16 to map array.
* 201 #6885 Extend NewGRF persistant storages.
+ * 202 #6867 Increase industry cargo slots to 16 in, 16 out
*/
-extern const uint16 SAVEGAME_VERSION = 201; ///< Current savegame version of OpenTTD.
+extern const uint16 SAVEGAME_VERSION = 202; ///< Current savegame version of OpenTTD.
SavegameType _savegame_type; ///< type of savegame we are loading
FileToSaveLoad _file_to_saveload; ///< File to save or load in the openttd loop.
diff --git a/src/subsidy.cpp b/src/subsidy.cpp
index bd2ed07be..fa327efa9 100644
--- a/src/subsidy.cpp
+++ b/src/subsidy.cpp
@@ -383,15 +383,21 @@ bool FindSubsidyIndustryCargoRoute()
CargoID cid;
/* Randomize cargo type */
- if (src_ind->produced_cargo[1] != CT_INVALID && HasBit(Random(), 0)) {
- cid = src_ind->produced_cargo[1];
- trans = src_ind->last_month_pct_transported[1];
- total = src_ind->last_month_production[1];
- } else {
- cid = src_ind->produced_cargo[0];
- trans = src_ind->last_month_pct_transported[0];
- total = src_ind->last_month_production[0];
+ int num_cargos = 0;
+ for (size_t ci = 0; ci < lengthof(src_ind->produced_cargo); ci++) {
+ if (src_ind->produced_cargo[ci] != CT_INVALID) num_cargos++;
}
+ if (num_cargos == 0) return false; // industry produces nothing
+ int cargo_num = RandomRange(num_cargos) + 1;
+ int cargo_index;
+ for (cargo_index = 0; cargo_index < lengthof(src_ind->produced_cargo); cargo_index++) {
+ if (src_ind->produced_cargo[cargo_index] != CT_INVALID) cargo_num--;
+ if (cargo_num == 0) break;
+ }
+ assert(cargo_num == 0); // indicates loop didn't break as intended
+ cid = src_ind->produced_cargo[cargo_index];
+ trans = src_ind->last_month_pct_transported[cargo_index];
+ total = src_ind->last_month_production[cargo_index];
/* Quit if no production in this industry
* or if the pct transported is already large enough
@@ -435,14 +441,11 @@ bool FindSubsidyCargoDestination(CargoID cid, SourceType src_type, SourceID src)
case ST_INDUSTRY: {
/* Select a random industry. */
const Industry *dst_ind = Industry::GetRandom();
+ if (dst_ind == NULL) return false;
/* The industry must accept the cargo */
- if (dst_ind == NULL ||
- (cid != dst_ind->accepts_cargo[0] &&
- cid != dst_ind->accepts_cargo[1] &&
- cid != dst_ind->accepts_cargo[2])) {
- return false;
- }
+ bool valid = std::find(dst_ind->accepts_cargo, endof(dst_ind->accepts_cargo), cid) != endof(dst_ind->accepts_cargo);
+ if (!valid) return false;
dst = dst_ind->index;
break;
diff --git a/src/table/build_industry.h b/src/table/build_industry.h
index a0783332e..62264eb6f 100644
--- a/src/table/build_industry.h
+++ b/src/table/build_industry.h
@@ -1195,8 +1195,12 @@ enum IndustryTypes {
#define MI(tbl, sndc, snd, d, pc, ai1, ai2, ai3, ai4, ag1, ag2, ag3, ag4, col, \
c1, c2, c3, proc, p1, r1, p2, r2, m, a1, im1, a2, im2, a3, im3, pr, clim, bev, in, intx, s1, s2, s3) \
- {tbl, lengthof(tbl), d, 0, pc, {c1, c2, c3}, proc, {p1, p2}, {r1, r2}, m, \
- {a1, a2, a3}, {{im1, 0}, {im2, 0}, {im3, 0}}, pr, clim, bev, col, in, intx, s1, s2, s3, STR_UNDEFINED, {ai1, ai2, ai3, ai4}, {ag1, ag2, ag3, ag4}, \
+ {tbl, lengthof(tbl), d, 0, pc, {c1, c2, c3}, proc, \
+ {p1, p2, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID}, \
+ {r1, r2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, m, \
+ {a1, a2, a3, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID}, \
+ {{im1, 0}, {im2, 0}, {im3, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, \
+ pr, clim, bev, col, in, intx, s1, s2, s3, STR_UNDEFINED, {ai1, ai2, ai3, ai4}, {ag1, ag2, ag3, ag4}, \
sndc, snd, 0, 0, true, GRFFileProps(INVALID_INDUSTRYTYPE)}
/* Format:
tile table count and sounds table
@@ -1594,7 +1598,7 @@ static const IndustrySpec _origin_industry_specs[NEW_INDUSTRYOFFSET] = {
* @param a2 next frame of animation
* @param a3 chooses between animation or construction state
*/
-#define MT(ca1, c1, ca2, c2, ca3, c3, sl, a1, a2, a3) {{c1, c2, c3}, {ca1, ca2, ca3}, sl, a1, a2, a3, 0, {0, ANIM_STATUS_NO_ANIMATION, 2, 0}, INDTILE_SPECIAL_NONE, true, GRFFileProps(INVALID_INDUSTRYTILE)}
+#define MT(ca1, c1, ca2, c2, ca3, c3, sl, a1, a2, a3) {{c1, c2, c3, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID}, {ca1, ca2, ca3}, sl, a1, a2, a3, 0, {0, ANIM_STATUS_NO_ANIMATION, 2, 0}, INDTILE_SPECIAL_NONE, true, GRFFileProps(INVALID_INDUSTRYTILE)}
static const IndustryTileSpec _origin_industry_tile_specs[NEW_INDUSTRYTILEOFFSET] = {
/* Coal Mine */
MT(0, CT_INVALID, 0, CT_INVALID, 0, CT_INVALID, SLOPE_STEEP, INDUSTRYTILE_NOANIM, INDUSTRYTILE_NOANIM, false),
diff --git a/src/table/newgrf_debug_data.h b/src/table/newgrf_debug_data.h
index afe19bbed..a6aa71616 100644
--- a/src/table/newgrf_debug_data.h
+++ b/src/table/newgrf_debug_data.h
@@ -272,10 +272,10 @@ static const NIFeature _nif_industrytile = {
/*** NewGRF industries ***/
static const NIProperty _nip_industries[] = {
- NIP(0x10, Industry, produced_cargo[0], NIT_CARGO, "produced cargo 0"),
- NIP(0x10, Industry, produced_cargo[1], NIT_CARGO, "produced cargo 1"),
- NIP(0x11, Industry, accepts_cargo[0], NIT_CARGO, "accepted cargo 0"),
- NIP(0x11, Industry, accepts_cargo[1], NIT_CARGO, "accepted cargo 1"),
+ NIP(0x10, Industry, produced_cargo[0], NIT_CARGO, "produced cargo 0"),
+ NIP(0x10, Industry, produced_cargo[1], NIT_CARGO, "produced cargo 1"),
+ NIP(0x11, Industry, accepts_cargo[0], NIT_CARGO, "accepted cargo 0"),
+ NIP(0x11, Industry, accepts_cargo[1], NIT_CARGO, "accepted cargo 1"),
NIP(0x11, Industry, accepts_cargo[2], NIT_CARGO, "accepted cargo 2"),
NIP_END()
};