Add: Industries can produce and accept up to 16 different cargoes

This commit is contained in:
Niels Martin Hansen 2018-07-25 19:20:17 +02:00
parent 32b9ee7063
commit 8859381d30
12 changed files with 165 additions and 116 deletions

View File

@ -1147,14 +1147,15 @@ static void TriggerIndustryProduction(Industry *i)
SetWindowDirty(WC_INDUSTRY_VIEW, i->index); SetWindowDirty(WC_INDUSTRY_VIEW, i->index);
} }
} else { } else {
for (uint cargo_index = 0; cargo_index < lengthof(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[cargo_index]; uint cargo_waiting = i->incoming_cargo_waiting[ci_in];
if (cargo_waiting == 0) continue; 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); for (uint ci_out = 0; ci_out < lengthof(i->produced_cargo_waiting), ci_out++) {
i->produced_cargo_waiting[1] = min(i->produced_cargo_waiting[1] + (cargo_waiting * indspec->input_cargo_multiplier[cargo_index][1] / 256), 0xFFFF); 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;
} }
} }

View File

@ -15,6 +15,7 @@
#include "newgrf_storage.h" #include "newgrf_storage.h"
#include "subsidy_type.h" #include "subsidy_type.h"
#include "industry_map.h" #include "industry_map.h"
#include "industrytype.h"
#include "tilearea_type.h" #include "tilearea_type.h"
@ -37,20 +38,20 @@ enum ProductionLevels {
* Defines the internal data of a functional industry. * Defines the internal data of a functional industry.
*/ */
struct Industry : IndustryPool::PoolItem<&_industry_pool> { struct Industry : IndustryPool::PoolItem<&_industry_pool> {
TileArea location; ///< Location of the industry TileArea location; ///< Location of the industry
Town *town; ///< Nearest town Town *town; ///< Nearest town
CargoID produced_cargo[2]; ///< 2 production cargo slots CargoID produced_cargo[INDUSTRY_NUM_OUTPUTS]; ///< 16 production cargo slots
uint16 produced_cargo_waiting[2]; ///< amount of cargo produced per cargo uint16 produced_cargo_waiting[INDUSTRY_NUM_OUTPUTS]; ///< amount of cargo produced per cargo
uint16 incoming_cargo_waiting[3]; ///< incoming cargo waiting to be processed uint16 incoming_cargo_waiting[INDUSTRY_NUM_INPUTS]; ///< incoming cargo waiting to be processed
byte production_rate[2]; ///< production rate for each cargo byte production_rate[INDUSTRY_NUM_OUTPUTS]; ///< production rate for each cargo
byte prod_level; ///< general production level byte prod_level; ///< general production level
CargoID accepts_cargo[3]; ///< 3 input cargo slots CargoID accepts_cargo[INDUSTRY_NUM_INPUTS]; ///< 16 input cargo slots
uint16 this_month_production[2]; ///< stats of this month's production per cargo uint16 this_month_production[INDUSTRY_NUM_OUTPUTS]; ///< stats of this month's production per cargo
uint16 this_month_transported[2]; ///< stats of this month's transport per cargo uint16 this_month_transported[INDUSTRY_NUM_OUTPUTS]; ///< stats of this month's transport per cargo
byte last_month_pct_transported[2]; ///< percentage transported per cargo in the last full month byte last_month_pct_transported[INDUSTRY_NUM_OUTPUTS]; ///< 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_production[INDUSTRY_NUM_OUTPUTS]; ///< 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 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) uint16 counter; ///< used for animation and/or production (if available cargo)
IndustryType type; ///< type of industry. IndustryType type; ///< type of industry.
OwnerByte owner; ///< owner of the industry. Which SHOULD always be (imho) OWNER_NONE OwnerByte owner; ///< owner of the industry. Which SHOULD always be (imho) OWNER_NONE

View File

@ -1118,8 +1118,9 @@ static void ProduceIndustryGoods(Industry *i)
if (HasBit(indsp->callback_mask, CBM_IND_PRODUCTION_256_TICKS)) IndustryProductionCallback(i, 1); if (HasBit(indsp->callback_mask, CBM_IND_PRODUCTION_256_TICKS)) IndustryProductionCallback(i, 1);
IndustryBehaviour indbehav = indsp->behaviour; IndustryBehaviour indbehav = indsp->behaviour;
i->produced_cargo_waiting[0] = min(0xffff, i->produced_cargo_waiting[0] + i->production_rate[0]); for (size_t j = 0; j < lengthof(i->produced_cargo_waiting); j++) {
i->produced_cargo_waiting[1] = min(0xffff, i->produced_cargo_waiting[1] + i->production_rate[1]); i->produced_cargo_waiting[j] = min(0xffff, i->produced_cargo_waiting[j] + i->production_rate[j]);
}
if ((indbehav & INDUSTRYBEH_PLANT_FIELDS) != 0) { if ((indbehav & INDUSTRYBEH_PLANT_FIELDS) != 0) {
uint16 cb_res = CALLBACK_FAILED; uint16 cb_res = CALLBACK_FAILED;
@ -1648,18 +1649,22 @@ static void DoCreateNewIndustry(Industry *i, TileIndex tile, IndustryType type,
i->type = type; i->type = type;
Industry::IncIndustryTypeCount(type); Industry::IncIndustryTypeCount(type);
i->produced_cargo[0] = indspec->produced_cargo[0]; MemCpyT(i->produced_cargo, indspec->produced_cargo, lengthof(i->produced_cargo));
i->produced_cargo[1] = indspec->produced_cargo[1]; MemCpyT(i->production_rate, indspec->production_rate, lengthof(i->production_rate));
i->accepts_cargo[0] = indspec->accepts_cargo[0]; MemCpyT(i->accepts_cargo, indspec->accepts_cargo, lengthof(i->accepts_cargo));
i->accepts_cargo[1] = indspec->accepts_cargo[1];
i->accepts_cargo[2] = indspec->accepts_cargo[2]; MemSetT(i->produced_cargo_waiting, 0, lengthof(i->produced_cargo_waiting));
i->production_rate[0] = indspec->production_rate[0]; MemSetT(i->this_month_production, 0, lengthof(i->this_month_production));
i->production_rate[1] = indspec->production_rate[1]; 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 */ /* don't use smooth economy for industries using production related callbacks */
if (indspec->UsesSmoothEconomy()) { if (indspec->UsesSmoothEconomy()) {
i->production_rate[0] = min((RandomRange(256) + 128) * i->production_rate[0] >> 8, 255); for (size_t ci = 0; ci < lengthof(i->production_rate); ci++) {
i->production_rate[1] = min((RandomRange(256) + 128) * i->production_rate[1] >> 8, 255); i->production_rate[ci] = min((RandomRange(256) + 128) * i->production_rate[ci] >> 8, 255);
}
} }
i->town = t; i->town = t;
@ -1669,19 +1674,6 @@ static void DoCreateNewIndustry(Industry *i, TileIndex tile, IndustryType type,
i->random_colour = GB(r, 0, 4); i->random_colour = GB(r, 0, 4);
i->counter = GB(r, 4, 12); i->counter = GB(r, 4, 12);
i->random = initial_random_bits; 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->was_cargo_delivered = false;
i->last_prod_year = _cur_year; i->last_prod_year = _cur_year;
i->founder = founder; i->founder = founder;
@ -1712,10 +1704,9 @@ static void DoCreateNewIndustry(Industry *i, TileIndex tile, IndustryType type,
} }
if (_generating_world) { if (_generating_world) {
i->last_month_production[0] = i->production_rate[0] * 8; for (size_t ci = 0; ci < lengthof(i->last_month_production); ci++) {
i->last_month_production[1] = i->production_rate[1] * 8; i->last_month_production[ci] = i->production_rate[ci] * 8;
} else { }
i->last_month_production[0] = i->last_month_production[1] = 0;
} }
if (HasBit(indspec->callback_mask, CBM_IND_DECIDE_COLOUR)) { if (HasBit(indspec->callback_mask, CBM_IND_DECIDE_COLOUR)) {
@ -2194,8 +2185,9 @@ void Industry::RecomputeProductionMultipliers()
assert(!indspec->UsesSmoothEconomy()); assert(!indspec->UsesSmoothEconomy());
/* Rates are rounded up, so e.g. oilrig always produces some passengers */ /* 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); for (size_t i = 0; i < lengthof(this->production_rate); i++) {
this->production_rate[1] = min(CeilDiv(indspec->production_rate[1] * this->prod_level, PRODLEVEL_DEFAULT), 0xFF); this->production_rate[i] = min(CeilDiv(indspec->production_rate[i] * this->prod_level, PRODLEVEL_DEFAULT), 0xFF);
}
} }

View File

@ -358,7 +358,7 @@ public:
const IndustrySpec *indsp = GetIndustrySpec(this->index[i]); 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); GetAllCargoSuffixes(0, CST_FUND, NULL, this->index[i], indsp, indsp->accepts_cargo, cargo_suffix);
StringID str = STR_INDUSTRY_VIEW_REQUIRES_CARGO; StringID str = STR_INDUSTRY_VIEW_REQUIRES_CARGO;
byte p = 0; byte p = 0;
@ -477,7 +477,7 @@ public:
} }
/* Draw the accepted cargoes, if any. Otherwise, will print "Nothing". */ /* 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); GetAllCargoSuffixes(0, CST_FUND, NULL, this->selected_type, indsp, indsp->accepts_cargo, cargo_suffix);
StringID str = STR_INDUSTRY_VIEW_REQUIRES_CARGO; StringID str = STR_INDUSTRY_VIEW_REQUIRES_CARGO;
byte p = 0; byte p = 0;
@ -683,8 +683,15 @@ static void UpdateIndustryProduction(Industry *i);
static inline bool IsProductionAlterable(const Industry *i) static inline bool IsProductionAlterable(const Industry *i)
{ {
const IndustrySpec *is = GetIndustrySpec(i->type); 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) && 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); !_networking);
} }
@ -763,7 +770,7 @@ public:
y += 2 * FONT_HEIGHT_NORMAL; 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); 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); 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. 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. */ /** Data about a single field in the #IndustryCargoesWindow panel. */
struct CargoesField { struct CargoesField {

View File

@ -95,45 +95,48 @@ struct IndustryTileTable {
IndustryGfx gfx; 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. * Defines the data structure for constructing industry.
*/ */
struct IndustrySpec { struct IndustrySpec {
const IndustryTileTable * const *table;///< List of the tiles composing the industry const IndustryTileTable * const *table; ///< List of the tiles composing the industry
byte num_table; ///< Number of elements in the table byte num_table; ///< Number of elements in the table
uint8 cost_multiplier; ///< Base construction cost multiplier. uint8 cost_multiplier; ///< Base construction cost multiplier.
uint32 removal_cost_multiplier; ///< Base removal cost multiplier. uint32 removal_cost_multiplier; ///< Base removal cost multiplier.
uint32 prospecting_chance; ///< Chance prospecting succeeds uint32 prospecting_chance; ///< Chance prospecting succeeds
IndustryType conflicting[3]; ///< Industries this industry cannot be close to IndustryType conflicting[3]; ///< Industries this industry cannot be close to
byte check_proc; ///< Index to a procedure to check for conflicting circumstances byte check_proc; ///< Index to a procedure to check for conflicting circumstances
CargoID produced_cargo[2]; CargoID produced_cargo[INDUSTRY_NUM_OUTPUTS];
byte production_rate[2]; byte production_rate[INDUSTRY_NUM_OUTPUTS];
/** /**
* minimum amount of cargo transported to the stations. * minimum amount of cargo transported to the stations.
* If the waiting cargo is less than this number, no cargo is moved to it. * If the waiting cargo is less than this number, no cargo is moved to it.
*/ */
byte minimal_cargo; byte minimal_cargo;
CargoID accepts_cargo[3]; ///< 3 accepted cargoes. CargoID accepts_cargo[INDUSTRY_NUM_INPUTS]; ///< 16 accepted cargoes.
uint16 input_cargo_multiplier[3][2]; ///< Input cargo multipliers (multiply amount of incoming cargo for the produced 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 IndustryLifeType life_type; ///< This is also known as Industry production flag, in newgrf specs
byte climate_availability; ///< Bitmask, giving landscape enums as bit position byte climate_availability; ///< Bitmask, giving landscape enums as bit position
IndustryBehaviour behaviour; ///< How this industry will behave, and how others entities can use it IndustryBehaviour behaviour; ///< How this industry will behave, and how others entities can use it
byte map_colour; ///< colour used for the small map byte map_colour; ///< colour used for the small map
StringID name; ///< Displayed name of the industry StringID name; ///< Displayed name of the industry
StringID new_industry_text; ///< Message appearing when the industry is built StringID new_industry_text; ///< Message appearing when the industry is built
StringID closure_text; ///< Message appearing when the industry closes StringID closure_text; ///< Message appearing when the industry closes
StringID production_up_text; ///< Message appearing when the industry's production is increasing 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 production_down_text; ///< Message appearing when the industry's production is decreasing
StringID station_name; ///< Default name for nearby station StringID station_name; ///< Default name for nearby station
byte appear_ingame[NUM_LANDSCAPE]; ///< Probability of appearance in game byte appear_ingame[NUM_LANDSCAPE]; ///< Probability of appearance in game
byte appear_creation[NUM_LANDSCAPE]; ///< Probability of appearance during map creation byte appear_creation[NUM_LANDSCAPE]; ///< Probability of appearance during map creation
uint8 number_of_sounds; ///< Number of sounds available in the sounds array uint8 number_of_sounds; ///< Number of sounds available in the sounds array
const uint8 *random_sounds; ///< array of random sounds. const uint8 *random_sounds; ///< array of random sounds.
/* Newgrf data */ /* Newgrf data */
uint16 callback_mask; ///< Bitmask of industry callbacks that have to be called 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 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 bool enabled; ///< entity still available (by default true).newgrf can disable it, though
GRFFileProps grf_prop; ///< properties related to the grf file GRFFileProps grf_prop; ///< properties related to the grf file
bool IsRawIndustry() const; bool IsRawIndustry() const;
bool IsProcessingIndustry() const; bool IsProcessingIndustry() const;
@ -144,6 +147,7 @@ struct IndustrySpec {
/** /**
* Defines the data structure of each individual tile of an industry. * 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 { struct IndustryTileSpec {
CargoID accepts_cargo[3]; ///< Cargo accepted by this tile CargoID accepts_cargo[3]; ///< Cargo accepted by this tile

View File

@ -602,7 +602,12 @@ void IndustryProductionCallback(Industry *ind, int reason)
*/ */
bool IndustryTemporarilyRefusesCargo(Industry *ind, CargoID cargo_type) 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); const IndustrySpec *indspec = GetIndustrySpec(ind->type);
if (HasBit(indspec->callback_mask, CBM_IND_REFUSE_CARGO)) { if (HasBit(indspec->callback_mask, CBM_IND_REFUSE_CARGO)) {

View File

@ -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 */ /* Station acceptance is some kind of cache */
if (IsSavegameVersionBefore(127)) { if (IsSavegameVersionBefore(127)) {
Station *st; Station *st;

View File

@ -26,18 +26,28 @@ static const SaveLoad _industry_desc[] = {
SLE_VAR(Industry, location.h, SLE_FILE_U8 | SLE_VAR_U16), SLE_VAR(Industry, location.h, SLE_FILE_U8 | SLE_VAR_U16),
SLE_REF(Industry, town, REF_TOWN), SLE_REF(Industry, town, REF_TOWN),
SLE_CONDNULL( 2, 0, 60), ///< used to be industry's produced_cargo 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, produced_cargo, SLE_UINT8, 2, 78, 201),
SLE_CONDARR(Industry, incoming_cargo_waiting, SLE_UINT16, 3, 70, SL_MAX_VERSION), SLE_CONDARR(Industry, produced_cargo, SLE_UINT8, 16, 202, SL_MAX_VERSION),
SLE_ARR(Industry, produced_cargo_waiting, SLE_UINT16, 2), SLE_CONDARR(Industry, incoming_cargo_waiting, SLE_UINT16, 3, 70, 201),
SLE_ARR(Industry, production_rate, SLE_UINT8, 2), 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_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_VAR(Industry, prod_level, SLE_UINT8),
SLE_ARR(Industry, this_month_production, SLE_UINT16, 2), SLE_CONDARR(Industry, this_month_production, SLE_UINT16, 2, 0, 201),
SLE_ARR(Industry, this_month_transported, SLE_UINT16, 2), SLE_CONDARR(Industry, this_month_production, SLE_UINT16, 16, 202, SL_MAX_VERSION),
SLE_ARR(Industry, last_month_pct_transported, SLE_UINT8, 2), SLE_CONDARR(Industry, this_month_transported, SLE_UINT16, 2, 0, 201),
SLE_ARR(Industry, last_month_production, SLE_UINT16, 2), SLE_CONDARR(Industry, this_month_transported, SLE_UINT16, 16, 202, SL_MAX_VERSION),
SLE_ARR(Industry, last_month_transported, SLE_UINT16, 2), 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), SLE_VAR(Industry, counter, SLE_UINT16),

View File

@ -269,8 +269,9 @@
* 199 * 199
* 200 #6805 Extend railtypes to 64, adding uint16 to map array. * 200 #6805 Extend railtypes to 64, adding uint16 to map array.
* 201 #6885 Extend NewGRF persistant storages. * 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 SavegameType _savegame_type; ///< type of savegame we are loading
FileToSaveLoad _file_to_saveload; ///< File to save or load in the openttd loop. FileToSaveLoad _file_to_saveload; ///< File to save or load in the openttd loop.

View File

@ -383,15 +383,21 @@ bool FindSubsidyIndustryCargoRoute()
CargoID cid; CargoID cid;
/* Randomize cargo type */ /* Randomize cargo type */
if (src_ind->produced_cargo[1] != CT_INVALID && HasBit(Random(), 0)) { int num_cargos = 0;
cid = src_ind->produced_cargo[1]; for (size_t ci = 0; ci < lengthof(src_ind->produced_cargo); ci++) {
trans = src_ind->last_month_pct_transported[1]; if (src_ind->produced_cargo[ci] != CT_INVALID) num_cargos++;
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];
} }
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 /* Quit if no production in this industry
* or if the pct transported is already large enough * 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: { case ST_INDUSTRY: {
/* Select a random industry. */ /* Select a random industry. */
const Industry *dst_ind = Industry::GetRandom(); const Industry *dst_ind = Industry::GetRandom();
if (dst_ind == NULL) return false;
/* The industry must accept the cargo */ /* The industry must accept the cargo */
if (dst_ind == NULL || bool valid = std::find(dst_ind->accepts_cargo, endof(dst_ind->accepts_cargo), cid) != endof(dst_ind->accepts_cargo);
(cid != dst_ind->accepts_cargo[0] && if (!valid) return false;
cid != dst_ind->accepts_cargo[1] &&
cid != dst_ind->accepts_cargo[2])) {
return false;
}
dst = dst_ind->index; dst = dst_ind->index;
break; break;

View File

@ -1195,8 +1195,12 @@ enum IndustryTypes {
#define MI(tbl, sndc, snd, d, pc, ai1, ai2, ai3, ai4, ag1, ag2, ag3, ag4, col, \ #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) \ 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, \ {tbl, lengthof(tbl), d, 0, pc, {c1, c2, c3}, proc, \
{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}, \ {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)} sndc, snd, 0, 0, true, GRFFileProps(INVALID_INDUSTRYTYPE)}
/* Format: /* Format:
tile table count and sounds table 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 a2 next frame of animation
* @param a3 chooses between animation or construction state * @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] = { static const IndustryTileSpec _origin_industry_tile_specs[NEW_INDUSTRYTILEOFFSET] = {
/* Coal Mine */ /* Coal Mine */
MT(0, CT_INVALID, 0, CT_INVALID, 0, CT_INVALID, SLOPE_STEEP, INDUSTRYTILE_NOANIM, INDUSTRYTILE_NOANIM, false), MT(0, CT_INVALID, 0, CT_INVALID, 0, CT_INVALID, SLOPE_STEEP, INDUSTRYTILE_NOANIM, INDUSTRYTILE_NOANIM, false),

View File

@ -272,10 +272,10 @@ static const NIFeature _nif_industrytile = {
/*** NewGRF industries ***/ /*** NewGRF industries ***/
static const NIProperty _nip_industries[] = { static const NIProperty _nip_industries[] = {
NIP(0x10, Industry, produced_cargo[0], NIT_CARGO, "produced cargo 0"), NIP(0x10, Industry, produced_cargo[0], NIT_CARGO, "produced cargo 0"),
NIP(0x10, Industry, produced_cargo[1], NIT_CARGO, "produced cargo 1"), 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[0], NIT_CARGO, "accepted cargo 0"),
NIP(0x11, Industry, accepts_cargo[1], NIT_CARGO, "accepted cargo 1"), NIP(0x11, Industry, accepts_cargo[1], NIT_CARGO, "accepted cargo 1"),
NIP(0x11, Industry, accepts_cargo[2], NIT_CARGO, "accepted cargo 2"), NIP(0x11, Industry, accepts_cargo[2], NIT_CARGO, "accepted cargo 2"),
NIP_END() NIP_END()
}; };