Changeset - r23041:7dd9cd83d20f
[Not reviewed]
master
0 14 0
Niels Martin Hansen - 6 years ago 2018-07-26 17:29:54
nielsm@indvikleren.dk
Add: NewGRF support for 16-in-16-out industries
14 files changed with 394 insertions and 77 deletions:
0 comments (0 inline, 0 general)
src/economy.cpp
Show inline comments
 
@@ -1062,6 +1062,7 @@ static uint DeliverGoodsToIndustry(const
 

	
 
		uint amount = min(num_pieces, 0xFFFFU - ind->incoming_cargo_waiting[cargo_index]);
 
		ind->incoming_cargo_waiting[cargo_index] += amount;
 
		ind->last_cargo_accepted_at[cargo_index] = _date;
 
		num_pieces -= amount;
 
		accepted += amount;
 
	}
 
@@ -1138,7 +1139,6 @@ static void TriggerIndustryProduction(In
 
	uint16 callback = indspec->callback_mask;
 

	
 
	i->was_cargo_delivered = true;
 
	i->last_cargo_accepted_at = _date;
 

	
 
	if (HasBit(callback, CBM_IND_PRODUCTION_CARGO_ARRIVAL) || HasBit(callback, CBM_IND_PRODUCTION_256_TICKS)) {
 
		if (HasBit(callback, CBM_IND_PRODUCTION_CARGO_ARRIVAL)) {
 
@@ -1151,7 +1151,7 @@ static void TriggerIndustryProduction(In
 
			uint cargo_waiting = i->incoming_cargo_waiting[ci_in];
 
			if (cargo_waiting == 0) continue;
 

	
 
			for (uint ci_out = 0; ci_out < lengthof(i->produced_cargo_waiting), ci_out++) {
 
			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);
 
			}
 

	
src/industry.h
Show inline comments
 
@@ -12,6 +12,7 @@
 
#ifndef INDUSTRY_H
 
#define INDUSTRY_H
 

	
 
#include <algorithm>
 
#include "newgrf_storage.h"
 
#include "subsidy_type.h"
 
#include "industry_map.h"
 
@@ -64,7 +65,7 @@ struct Industry : IndustryPool::PoolItem
 
	OwnerByte founder;                  ///< Founder of the industry
 
	Date construction_date;             ///< Date of the construction of the industry
 
	uint8 construction_type;            ///< Way the industry was constructed (@see IndustryConstructionType)
 
	Date last_cargo_accepted_at;        ///< Last day cargo was accepted by this industry
 
	Date last_cargo_accepted_at[INDUSTRY_NUM_INPUTS]; ///< Last day each cargo type was accepted by this industry
 
	byte selected_layout;               ///< Which tile layout was used when creating the industry
 

	
 
	uint16 random;                      ///< Random value used for randomisation of all kinds of things
 
@@ -86,6 +87,22 @@ struct Industry : IndustryPool::PoolItem
 
		return IsTileType(tile, MP_INDUSTRY) && GetIndustryIndex(tile) == this->index;
 
	}
 

	
 
	inline int GetCargoProducedIndex(CargoID cargo) const
 
	{
 
		if (cargo == CT_INVALID) return -1;
 
		const CargoID *pos = std::find(this->produced_cargo, endof(this->produced_cargo), cargo);
 
		if (pos == endof(this->produced_cargo)) return -1;
 
		return pos - this->produced_cargo;
 
	}
 

	
 
	inline int GetCargoAcceptedIndex(CargoID cargo) const
 
	{
 
		if (cargo == CT_INVALID) return -1;
 
		const CargoID *pos = std::find(this->accepts_cargo, endof(this->accepts_cargo), cargo);
 
		if (pos == endof(this->accepts_cargo)) return -1;
 
		return pos - this->accepts_cargo;
 
	}
 

	
 
	/**
 
	 * Get the industry of the given tile
 
	 * @param tile the tile to get the industry from
src/industry_cmd.cpp
Show inline comments
 
@@ -394,35 +394,49 @@ static void AddAcceptedCargo_Industry(Ti
 
{
 
	IndustryGfx gfx = GetIndustryGfx(tile);
 
	const IndustryTileSpec *itspec = GetIndustryTileSpec(gfx);
 

	
 
	/* When we have to use a callback, we put our data in the next two variables */
 
	CargoID raw_accepts_cargo[lengthof(itspec->accepts_cargo)];
 
	uint8 raw_cargo_acceptance[lengthof(itspec->acceptance)];
 

	
 
	/* And then these will always point to a same sized array with the required data */
 
	const CargoID *accepts_cargo = itspec->accepts_cargo;
 
	const uint8 *cargo_acceptance = itspec->acceptance;
 
	const Industry *ind = Industry::GetByTile(tile);
 

	
 
	/* Starting point for acceptance */
 
	CargoID accepts_cargo[lengthof(itspec->accepts_cargo)];
 
	int8 cargo_acceptance[lengthof(itspec->acceptance)];
 
	MemCpyT(accepts_cargo, itspec->accepts_cargo, lengthof(accepts_cargo));
 
	MemCpyT(cargo_acceptance, itspec->acceptance, lengthof(cargo_acceptance));
 

	
 
	if (itspec->special_flags & INDTILE_SPECIAL_ACCEPTS_ALL_CARGO) {
 
		/* Copy all accepted cargoes from industry itself */
 
		for (uint i = 0; i < lengthof(ind->accepts_cargo); i++) {
 
			CargoID *pos = std::find(accepts_cargo, endof(accepts_cargo), ind->accepts_cargo[i]);
 
			if (pos == endof(accepts_cargo)) {
 
				/* Not found, insert */
 
				pos = std::find(accepts_cargo, endof(accepts_cargo), CT_INVALID);
 
				if (pos == endof(accepts_cargo)) continue; // nowhere to place, give up on this one
 
				*pos = ind->accepts_cargo[i];
 
			}
 
			cargo_acceptance[pos - accepts_cargo] += 8;
 
		}
 
	}
 

	
 
	if (HasBit(itspec->callback_mask, CBM_INDT_ACCEPT_CARGO)) {
 
		/* Try callback for accepts list, if success override all existing accepts */
 
		uint16 res = GetIndustryTileCallback(CBID_INDTILE_ACCEPT_CARGO, 0, 0, gfx, Industry::GetByTile(tile), tile);
 
		if (res != CALLBACK_FAILED) {
 
			accepts_cargo = raw_accepts_cargo;
 
			for (uint i = 0; i < lengthof(itspec->accepts_cargo); i++) raw_accepts_cargo[i] = GetCargoTranslation(GB(res, i * 5, 5), itspec->grf_prop.grffile);
 
			MemSetT(accepts_cargo, CT_INVALID, lengthof(accepts_cargo));
 
			for (uint i = 0; i < 3; i++) accepts_cargo[i] = GetCargoTranslation(GB(res, i * 5, 5), itspec->grf_prop.grffile);
 
		}
 
	}
 

	
 
	if (HasBit(itspec->callback_mask, CBM_INDT_CARGO_ACCEPTANCE)) {
 
		/* Try callback for acceptance list, if success override all existing acceptance */
 
		uint16 res = GetIndustryTileCallback(CBID_INDTILE_CARGO_ACCEPTANCE, 0, 0, gfx, Industry::GetByTile(tile), tile);
 
		if (res != CALLBACK_FAILED) {
 
			cargo_acceptance = raw_cargo_acceptance;
 
			for (uint i = 0; i < lengthof(itspec->accepts_cargo); i++) raw_cargo_acceptance[i] = GB(res, i * 4, 4);
 
			MemSetT(cargo_acceptance, 0, lengthof(cargo_acceptance));
 
			for (uint i = 0; i < 3; i++) cargo_acceptance[i] = GB(res, i * 4, 4);
 
		}
 
	}
 

	
 
	const Industry *ind = Industry::GetByTile(tile);
 
	for (byte i = 0; i < lengthof(itspec->accepts_cargo); i++) {
 
		CargoID a = accepts_cargo[i];
 
		if (a == CT_INVALID || cargo_acceptance[i] == 0) continue; // work only with valid cargoes
 
		if (a == CT_INVALID || cargo_acceptance[i] <= 0) continue; // work only with valid cargoes
 

	
 
		/* Add accepted cargo */
 
		acceptance[a] += cargo_acceptance[i];
 
@@ -1659,6 +1673,7 @@ static void DoCreateNewIndustry(Industry
 
	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));
 
	MemSetT(i->last_cargo_accepted_at,     0, lengthof(i->last_cargo_accepted_at));
 

	
 
	/* don't use smooth economy for industries using production related callbacks */
 
	if (indspec->UsesSmoothEconomy()) {
 
@@ -1718,28 +1733,56 @@ static void DoCreateNewIndustry(Industry
 
	}
 

	
 
	if (HasBit(indspec->callback_mask, CBM_IND_INPUT_CARGO_TYPES)) {
 
		/* Clear all input cargo types */
 
		for (uint j = 0; j < lengthof(i->accepts_cargo); j++) i->accepts_cargo[j] = CT_INVALID;
 
		for (uint j = 0; j < lengthof(i->accepts_cargo); j++) {
 
		/* Query actual types */
 
		uint maxcargoes = (indspec->behaviour & INDUSTRYBEH_CARGOTYPES_UNLIMITED) ? lengthof(i->accepts_cargo) : 3;
 
		for (uint j = 0; j < maxcargoes; j++) {
 
			uint16 res = GetIndustryCallback(CBID_INDUSTRY_INPUT_CARGO_TYPES, j, 0, i, type, INVALID_TILE);
 
			if (res == CALLBACK_FAILED || GB(res, 0, 8) == CT_INVALID) break;
 
			if (indspec->grf_prop.grffile->grf_version >= 8 && res >= 0x100) {
 
				ErrorUnknownCallbackResult(indspec->grf_prop.grffile->grfid, CBID_INDUSTRY_INPUT_CARGO_TYPES, res);
 
				break;
 
			}
 
			i->accepts_cargo[j] = GetCargoTranslation(GB(res, 0, 8), indspec->grf_prop.grffile);
 
			CargoID cargo = GetCargoTranslation(GB(res, 0, 8), indspec->grf_prop.grffile);
 
			if (std::find(indspec->accepts_cargo, endof(indspec->accepts_cargo), cargo) == endof(indspec->accepts_cargo)) {
 
				/* Cargo not in spec, error in NewGRF */
 
				ErrorUnknownCallbackResult(indspec->grf_prop.grffile->grfid, CBID_INDUSTRY_INPUT_CARGO_TYPES, res);
 
				break;
 
			}
 
			if (std::find(i->accepts_cargo, i->accepts_cargo + j, cargo) != i->accepts_cargo + j) {
 
				/* Duplicate cargo */
 
				ErrorUnknownCallbackResult(indspec->grf_prop.grffile->grfid, CBID_INDUSTRY_INPUT_CARGO_TYPES, res);
 
				break;
 
			}
 
			i->accepts_cargo[j] = cargo;
 
		}
 
	}
 

	
 
	if (HasBit(indspec->callback_mask, CBM_IND_OUTPUT_CARGO_TYPES)) {
 
		/* Clear all output cargo types */
 
		for (uint j = 0; j < lengthof(i->produced_cargo); j++) i->produced_cargo[j] = CT_INVALID;
 
		for (uint j = 0; j < lengthof(i->produced_cargo); j++) {
 
		/* Query actual types */
 
		uint maxcargoes = (indspec->behaviour & INDUSTRYBEH_CARGOTYPES_UNLIMITED) ? lengthof(i->produced_cargo) : 2;
 
		for (uint j = 0; j < maxcargoes; j++) {
 
			uint16 res = GetIndustryCallback(CBID_INDUSTRY_OUTPUT_CARGO_TYPES, j, 0, i, type, INVALID_TILE);
 
			if (res == CALLBACK_FAILED || GB(res, 0, 8) == CT_INVALID) break;
 
			if (indspec->grf_prop.grffile->grf_version >= 8 && res >= 0x100) {
 
				ErrorUnknownCallbackResult(indspec->grf_prop.grffile->grfid, CBID_INDUSTRY_OUTPUT_CARGO_TYPES, res);
 
				break;
 
			}
 
			i->produced_cargo[j] = GetCargoTranslation(GB(res, 0, 8), indspec->grf_prop.grffile);
 
			CargoID cargo = GetCargoTranslation(GB(res, 0, 8), indspec->grf_prop.grffile);
 
			if (std::find(indspec->produced_cargo, endof(indspec->produced_cargo), cargo) == endof(indspec->produced_cargo)) {
 
				/* Cargo not in spec, error in NewGRF */
 
				ErrorUnknownCallbackResult(indspec->grf_prop.grffile->grfid, CBID_INDUSTRY_OUTPUT_CARGO_TYPES, res);
 
				break;
 
			}
 
			if (std::find(i->produced_cargo, i->produced_cargo + j, cargo) != i->produced_cargo + j) {
 
				/* Duplicate cargo */
 
				ErrorUnknownCallbackResult(indspec->grf_prop.grffile->grfid, CBID_INDUSTRY_OUTPUT_CARGO_TYPES, res);
 
				break;
 
			}
 
			i->produced_cargo[j] = cargo;
 
		}
 
	}
 

	
src/industry_gui.cpp
Show inline comments
 
@@ -74,12 +74,7 @@ static void ShowIndustryCargoesWindow(In
 

	
 
/**
 
 * Gets the string to display after the cargo name (using callback 37)
 
 * @param cargo the cargo for which the suffix is requested
 
 * - 00 - first accepted cargo type
 
 * - 01 - second accepted cargo type
 
 * - 02 - third accepted cargo type
 
 * - 03 - first produced cargo type
 
 * - 04 - second produced cargo type
 
 * @param cargo the cargo for which the suffix is requested, meaning depends on presence of flag 18 in prop 1A
 
 * @param cst the cargo suffix type (for which window is it requested). @see CargoSuffixType
 
 * @param ind the industry (NULL if in fund window)
 
 * @param ind_type the industry type
 
@@ -134,9 +129,14 @@ static void GetCargoSuffix(uint cargo, C
 
	}
 
}
 

	
 
enum CargoSuffixInOut {
 
	CARGOSUFFIX_OUT = 0,
 
	CARGOSUFFIX_IN  = 1,
 
};
 

	
 
/**
 
 * Gets all strings to display after the cargoes of industries (using callback 37)
 
 * @param cb_offset The offset for the cargo used in cb37, 0 for accepted cargoes, 3 for produced cargoes
 
 * @param use_input get suffixes for output cargoes or input cargoes?
 
 * @param cst the cargo suffix type (for which window is it requested). @see CargoSuffixType
 
 * @param ind the industry (NULL if in fund window)
 
 * @param ind_type the industry type
 
@@ -145,14 +145,40 @@ static void GetCargoSuffix(uint cargo, C
 
 * @param suffixes is filled with the suffixes
 
 */
 
template <typename TC, typename TS>
 
static inline void GetAllCargoSuffixes(uint cb_offset, CargoSuffixType cst, const Industry *ind, IndustryType ind_type, const IndustrySpec *indspec, const TC &cargoes, TS &suffixes)
 
static inline void GetAllCargoSuffixes(CargoSuffixInOut use_input, CargoSuffixType cst, const Industry *ind, IndustryType ind_type, const IndustrySpec *indspec, const TC &cargoes, TS &suffixes)
 
{
 
	assert_compile(lengthof(cargoes) <= lengthof(suffixes));
 
	for (uint j = 0; j < lengthof(cargoes); j++) {
 
		if (cargoes[j] != CT_INVALID) {
 
			GetCargoSuffix(cb_offset + j, cst, ind, ind_type, indspec, suffixes[j]);
 
		} else {
 

	
 
	if (indspec->behaviour & INDUSTRYBEH_CARGOTYPES_UNLIMITED) {
 
		/* Reworked behaviour with new many-in-many-out scheme */
 
		for (uint j = 0; j < lengthof(suffixes); j++) {
 
			if (cargoes[j] != CT_INVALID) {
 
				byte local_id = indspec->grf_prop.grffile->cargo_map[cargoes[j]]; // should we check the value for valid?
 
				uint cargotype = local_id << 16 | use_input;
 
				GetCargoSuffix(cargotype, cst, ind, ind_type, indspec, suffixes[j]);
 
			} else {
 
				suffixes[j].text[0] = '\0';
 
				suffixes[j].display = CSD_CARGO;
 
			}
 
		}
 
	} else {
 
		/* Compatible behaviour with old 3-in-2-out scheme */
 
		for (uint j = 0; j < lengthof(suffixes); j++) {
 
			suffixes[j].text[0] = '\0';
 
			suffixes[j].display = CSD_CARGO;
 
		}
 
		switch (use_input) {
 
			case CARGOSUFFIX_OUT:
 
				if (cargoes[0] != CT_INVALID) GetCargoSuffix(3, cst, ind, ind_type, indspec, suffixes[0]);
 
				if (cargoes[1] != CT_INVALID) GetCargoSuffix(4, cst, ind, ind_type, indspec, suffixes[1]);
 
				break;
 
			case CARGOSUFFIX_IN:
 
				if (cargoes[0] != CT_INVALID) GetCargoSuffix(0, cst, ind, ind_type, indspec, suffixes[0]);
 
				if (cargoes[1] != CT_INVALID) GetCargoSuffix(1, cst, ind, ind_type, indspec, suffixes[1]);
 
				if (cargoes[2] != CT_INVALID) GetCargoSuffix(2, cst, ind, ind_type, indspec, suffixes[2]);
 
				break;
 
			default:
 
				NOT_REACHED();
 
		}
 
	}
 
}
 
@@ -359,7 +385,7 @@ public:
 
					const IndustrySpec *indsp = GetIndustrySpec(this->index[i]);
 

	
 
					CargoSuffix cargo_suffix[lengthof(indsp->accepts_cargo)];
 
					GetAllCargoSuffixes(0, CST_FUND, NULL, this->index[i], indsp, indsp->accepts_cargo, cargo_suffix);
 
					GetAllCargoSuffixes(CARGOSUFFIX_IN, CST_FUND, NULL, this->index[i], indsp, indsp->accepts_cargo, cargo_suffix);
 
					StringID str = STR_INDUSTRY_VIEW_REQUIRES_CARGO;
 
					byte p = 0;
 
					SetDParam(0, STR_JUST_NOTHING);
 
@@ -373,7 +399,7 @@ public:
 
					d = maxdim(d, GetStringBoundingBox(str));
 

	
 
					/* Draw the produced cargoes, if any. Otherwise, will print "Nothing". */
 
					GetAllCargoSuffixes(3, CST_FUND, NULL, this->index[i], indsp, indsp->produced_cargo, cargo_suffix);
 
					GetAllCargoSuffixes(CARGOSUFFIX_OUT, CST_FUND, NULL, this->index[i], indsp, indsp->produced_cargo, cargo_suffix);
 
					str = STR_INDUSTRY_VIEW_PRODUCES_CARGO;
 
					p = 0;
 
					SetDParam(0, STR_JUST_NOTHING);
 
@@ -478,7 +504,7 @@ public:
 

	
 
				/* Draw the accepted cargoes, if any. Otherwise, will print "Nothing". */
 
				CargoSuffix cargo_suffix[lengthof(indsp->accepts_cargo)];
 
				GetAllCargoSuffixes(0, CST_FUND, NULL, this->selected_type, indsp, indsp->accepts_cargo, cargo_suffix);
 
				GetAllCargoSuffixes(CARGOSUFFIX_IN, CST_FUND, NULL, this->selected_type, indsp, indsp->accepts_cargo, cargo_suffix);
 
				StringID str = STR_INDUSTRY_VIEW_REQUIRES_CARGO;
 
				byte p = 0;
 
				SetDParam(0, STR_JUST_NOTHING);
 
@@ -493,7 +519,7 @@ public:
 
				y += FONT_HEIGHT_NORMAL;
 

	
 
				/* Draw the produced cargoes, if any. Otherwise, will print "Nothing". */
 
				GetAllCargoSuffixes(3, CST_FUND, NULL, this->selected_type, indsp, indsp->produced_cargo, cargo_suffix);
 
				GetAllCargoSuffixes(CARGOSUFFIX_OUT, CST_FUND, NULL, this->selected_type, indsp, indsp->produced_cargo, cargo_suffix);
 
				str = STR_INDUSTRY_VIEW_PRODUCES_CARGO;
 
				p = 0;
 
				SetDParam(0, STR_JUST_NOTHING);
 
@@ -771,7 +797,7 @@ public:
 
		}
 

	
 
		CargoSuffix cargo_suffix[lengthof(i->accepts_cargo)];
 
		GetAllCargoSuffixes(0, CST_VIEW, i, i->type, ind, i->accepts_cargo, cargo_suffix);
 
		GetAllCargoSuffixes(CARGOSUFFIX_IN, 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);
 

	
 
		uint left_side = left + WD_FRAMERECT_LEFT * 4; // Indent accepted cargoes.
 
@@ -810,7 +836,7 @@ public:
 
			y += FONT_HEIGHT_NORMAL;
 
		}
 

	
 
		GetAllCargoSuffixes(3, CST_VIEW, i, i->type, ind, i->produced_cargo, cargo_suffix);
 
		GetAllCargoSuffixes(CARGOSUFFIX_OUT, CST_VIEW, i, i->type, ind, i->produced_cargo, cargo_suffix);
 
		first = true;
 
		for (byte j = 0; j < lengthof(i->produced_cargo); j++) {
 
			if (i->produced_cargo[j] == CT_INVALID) continue;
 
@@ -1262,7 +1288,7 @@ protected:
 
		SetDParam(p++, i->index);
 

	
 
		static CargoSuffix cargo_suffix[lengthof(i->produced_cargo)];
 
		GetAllCargoSuffixes(3, CST_DIR, i, i->type, indsp, i->produced_cargo, cargo_suffix);
 
		GetAllCargoSuffixes(CARGOSUFFIX_OUT, CST_DIR, i, i->type, indsp, i->produced_cargo, cargo_suffix);
 

	
 
		/* Industry productions */
 
		for (byte j = 0; j < lengthof(i->produced_cargo); j++) {
src/industry_type.h
Show inline comments
 
@@ -37,6 +37,10 @@ static const IndustryGfx  INVALID_INDUST
 

	
 
static const int INDUSTRY_COMPLETED = 3; ///< final stage of industry construction.
 

	
 
static const int INDUSTRY_NUM_INPUTS = 16;  ///< Number of cargo types an industry can accept
 
static const int INDUSTRY_NUM_OUTPUTS = 16; ///< Number of cargo types an industry can produce
 

	
 

	
 
void CheckIndustries();
 

	
 
#endif /* INDUSTRY_TYPE_H */
src/industrytype.h
Show inline comments
 
@@ -80,6 +80,7 @@ enum IndustryBehaviour {
 
	INDUSTRYBEH_PRODCALLBACK_RANDOM   = 1 << 15, ///< Production callback needs random bits in var 10
 
	INDUSTRYBEH_NOBUILT_MAPCREATION   = 1 << 16, ///< Do not force one instance of this type to appear on map generation
 
	INDUSTRYBEH_CANCLOSE_LASTINSTANCE = 1 << 17, ///< Allow closing down the last instance of this type
 
	INDUSTRYBEH_CARGOTYPES_UNLIMITED  = 1 << 18, ///< Allow produced/accepted cargoes callbacks to supply more than 2 and 3 types
 
};
 
DECLARE_ENUM_AS_BIT_SET(IndustryBehaviour)
 

	
 
@@ -87,6 +88,7 @@ DECLARE_ENUM_AS_BIT_SET(IndustryBehaviou
 
enum IndustryTileSpecialFlags {
 
	INDTILE_SPECIAL_NONE                  = 0,
 
	INDTILE_SPECIAL_NEXTFRAME_RANDOMBITS  = 1 << 0, ///< Callback 0x26 needs random bits
 
	INDTILE_SPECIAL_ACCEPTS_ALL_CARGO     = 1 << 1, ///< Tile always accepts all cargoes the associated industry accepts
 
};
 
DECLARE_ENUM_AS_BIT_SET(IndustryTileSpecialFlags)
 

	
 
@@ -95,9 +97,6 @@ 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.
 
 */
 
@@ -150,8 +149,8 @@ struct IndustrySpec {
 
 * @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
 
	uint8 acceptance[3];                  ///< Level of acceptance per cargo type
 
	CargoID accepts_cargo[INDUSTRY_NUM_INPUTS]; ///< Cargo accepted by this tile
 
	int8 acceptance[INDUSTRY_NUM_INPUTS]; ///< Level of acceptance per cargo type (signed, may be negative!)
 
	Slope slopes_refused;                 ///< slope pattern on which this tile cannot be built
 
	byte anim_production;                 ///< Animation frame to start when goods are produced
 
	byte anim_next;                       ///< Next frame in an animation
src/lang/english.txt
Show inline comments
 
@@ -2970,6 +2970,8 @@ STR_NEWGRF_ERROR_READ_BOUNDS            
 
STR_NEWGRF_ERROR_GRM_FAILED                                     :Requested GRF resources not available (sprite {3:NUM})
 
STR_NEWGRF_ERROR_FORCEFULLY_DISABLED                            :{1:RAW_STRING} was disabled by {2:RAW_STRING}
 
STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT                          :Invalid/unknown sprite layout format (sprite {3:NUM})
 
STR_NEWGRF_ERROR_LIST_PROPERTY_TOO_LONG                         :Too many elements in property value list (sprite {3:NUM}, property {4:HEX})
 
STR_NEWGRF_ERROR_INDPROD_CALLBACK                               :Invalid industry production callback (sprite {3:NUM}, "{1:RAW_STRING}")
 

	
 
# NewGRF related 'general' warnings
 
STR_NEWGRF_POPUP_CAUTION_CAPTION                                :{WHITE}Caution!
src/newgrf.cpp
Show inline comments
 
@@ -3083,6 +3083,10 @@ static ChangeInfoResult IgnoreIndustryTi
 
			buf->ReadWord();
 
			break;
 

	
 
		case 0x13:
 
			buf->Skip(buf->ReadByte() * 2);
 
			break;
 

	
 
		default:
 
			ret = CIR_UNKNOWN;
 
			break;
 
@@ -3172,7 +3176,7 @@ static ChangeInfoResult IndustrytilesCha
 
			case 0x0C: {
 
				uint16 acctp = buf->ReadWord();
 
				tsp->accepts_cargo[prop - 0x0A] = GetCargoTranslation(GB(acctp, 0, 8), _cur.grffile);
 
				tsp->acceptance[prop - 0x0A] = GB(acctp, 8, 8);
 
				tsp->acceptance[prop - 0x0A] = Clamp(GB(acctp, 8, 8), 0, 16);
 
				break;
 
			}
 

	
 
@@ -3201,6 +3205,26 @@ static ChangeInfoResult IndustrytilesCha
 
				tsp->special_flags = (IndustryTileSpecialFlags)buf->ReadByte();
 
				break;
 

	
 
			case 0x13: { // variable length cargo acceptance
 
				byte num_cargoes = buf->ReadByte();
 
				if (num_cargoes > lengthof(tsp->acceptance)) {
 
					GRFError *error = DisableGrf(STR_NEWGRF_ERROR_LIST_PROPERTY_TOO_LONG);
 
					error->param_value[1] = prop;
 
					return CIR_DISABLED;
 
				}
 
				for (uint i = 0; i < lengthof(tsp->acceptance); i++) {
 
					if (i < num_cargoes) {
 
						tsp->accepts_cargo[i] = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
 
						/* Tile acceptance can be negative to counteract the INDTILE_SPECIAL_ACCEPTS_ALL_CARGO flag */
 
						tsp->acceptance[i] = (int8)buf->ReadByte();
 
					} else {
 
						tsp->accepts_cargo[i] = CT_INVALID;
 
						tsp->acceptance[i] = 0;
 
					}
 
				}
 
				break;
 
			}
 

	
 
			default:
 
				ret = CIR_UNKNOWN;
 
				break;
 
@@ -3280,11 +3304,17 @@ static ChangeInfoResult IgnoreIndustryPr
 
			for (byte j = 0; j < 3; j++) buf->ReadByte();
 
			break;
 

	
 
		case 0x15: {
 
			byte number_of_sounds = buf->ReadByte();
 
			for (uint8 j = 0; j < number_of_sounds; j++) {
 
				buf->ReadByte();
 
			}
 
		case 0x15:
 
		case 0x25:
 
		case 0x26:
 
		case 0x27:
 
			buf->Skip(buf->ReadByte());
 
			break;
 

	
 
		case 0x28: {
 
			int num_inputs = buf->ReadByte();
 
			int num_outputs = buf->ReadByte();
 
			buf->Skip(num_inputs * num_outputs * 2);
 
			break;
 
		}
 

	
 
@@ -3642,6 +3672,77 @@ static ChangeInfoResult IndustriesChange
 
				break;
 
			}
 

	
 
			case 0x25: { // variable length produced cargoes
 
				byte num_cargoes = buf->ReadByte();
 
				if (num_cargoes > lengthof(indsp->produced_cargo)) {
 
					GRFError *error = DisableGrf(STR_NEWGRF_ERROR_LIST_PROPERTY_TOO_LONG);
 
					error->param_value[1] = prop;
 
					return CIR_DISABLED;
 
				}
 
				for (uint i = 0; i < lengthof(indsp->produced_cargo); i++) {
 
					if (i < num_cargoes) {
 
						CargoID cargo = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
 
						indsp->produced_cargo[i] = cargo;
 
					} else {
 
						indsp->produced_cargo[i] = CT_INVALID;
 
					}
 
				}
 
				break;
 
			}
 

	
 
			case 0x26: { // variable length accepted cargoes
 
				byte num_cargoes = buf->ReadByte();
 
				if (num_cargoes > lengthof(indsp->accepts_cargo)) {
 
					GRFError *error = DisableGrf(STR_NEWGRF_ERROR_LIST_PROPERTY_TOO_LONG);
 
					error->param_value[1] = prop;
 
					return CIR_DISABLED;
 
				}
 
				for (uint i = 0; i < lengthof(indsp->accepts_cargo); i++) {
 
					if (i < num_cargoes) {
 
						CargoID cargo = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
 
						indsp->accepts_cargo[i] = cargo;
 
					} else {
 
						indsp->accepts_cargo[i] = CT_INVALID;
 
					}
 
				}
 
				break;
 
			}
 

	
 
			case 0x27: { // variable length production rates
 
				byte num_cargoes = buf->ReadByte();
 
				if (num_cargoes > lengthof(indsp->production_rate)) {
 
					GRFError *error = DisableGrf(STR_NEWGRF_ERROR_LIST_PROPERTY_TOO_LONG);
 
					error->param_value[1] = prop;
 
					return CIR_DISABLED;
 
				}
 
				for (uint i = 0; i < lengthof(indsp->production_rate); i++) {
 
					if (i < num_cargoes) {
 
						indsp->production_rate[i] = buf->ReadByte();
 
					} else {
 
						indsp->production_rate[i] = 0;
 
					}
 
				}
 
				break;
 
			}
 

	
 
			case 0x28: { // variable size input/output production multiplier table
 
				byte num_inputs = buf->ReadByte();
 
				byte num_outputs = buf->ReadByte();
 
				if (num_inputs > lengthof(indsp->accepts_cargo) || num_outputs > lengthof(indsp->produced_cargo)) {
 
					GRFError *error = DisableGrf(STR_NEWGRF_ERROR_LIST_PROPERTY_TOO_LONG);
 
					error->param_value[1] = prop;
 
					return CIR_DISABLED;
 
				}
 
				for (uint i = 0; i < lengthof(indsp->accepts_cargo); i++) {
 
					for (uint j = 0; j < lengthof(indsp->produced_cargo); j++) {
 
						uint16 mult = 0;
 
						if (i < num_inputs && j < num_outputs) mult = buf->ReadWord();
 
						indsp->input_cargo_multiplier[i][j] = mult;
 
					}
 
				}
 
				break;
 
			}
 

	
 
			default:
 
				ret = CIR_UNKNOWN;
 
				break;
 
@@ -4839,7 +4940,7 @@ static void NewSpriteGroup(ByteReader *b
 
				}
 

	
 
				case GSF_INDUSTRIES: {
 
					if (type > 1) {
 
					if (type > 2) {
 
						grfmsg(1, "NewSpriteGroup: Unsupported industry production version %d, skipping", type);
 
						break;
 
					}
 
@@ -4849,21 +4950,63 @@ static void NewSpriteGroup(ByteReader *b
 
					act_group = group;
 
					group->version = type;
 
					if (type == 0) {
 
						group->num_input = 3;
 
						for (uint i = 0; i < 3; i++) {
 
							group->subtract_input[i] = (int16)buf->ReadWord(); // signed
 
						}
 
						group->num_output = 2;
 
						for (uint i = 0; i < 2; i++) {
 
							group->add_output[i] = buf->ReadWord(); // unsigned
 
						}
 
						group->again = buf->ReadByte();
 
					} else {
 
					} else if (type == 1) {
 
						group->num_input = 3;
 
						for (uint i = 0; i < 3; i++) {
 
							group->subtract_input[i] = buf->ReadByte();
 
						}
 
						group->num_output = 2;
 
						for (uint i = 0; i < 2; i++) {
 
							group->add_output[i] = buf->ReadByte();
 
						}
 
						group->again = buf->ReadByte();
 
					} else if (type == 2) {
 
						group->num_input = buf->ReadByte();
 
						if (group->num_input > lengthof(group->subtract_input)) {
 
							GRFError *error = DisableGrf(STR_NEWGRF_ERROR_INDPROD_CALLBACK);
 
							error->data = stredup("too many inputs (max 16)");
 
							return;
 
						}
 
						for (uint i = 0; i < group->num_input; i++) {
 
							byte rawcargo = buf->ReadByte();
 
							CargoID cargo = GetCargoTranslation(rawcargo, _cur.grffile);
 
							if (std::find(group->cargo_input, group->cargo_input + i, cargo) != group->cargo_input + i) {
 
								GRFError *error = DisableGrf(STR_NEWGRF_ERROR_INDPROD_CALLBACK);
 
								error->data = stredup("duplicate input cargo");
 
								return;
 
							}
 
							group->cargo_input[i] = cargo;
 
							group->subtract_input[i] = buf->ReadByte();
 
						}
 
						group->num_output = buf->ReadByte();
 
						if (group->num_output > lengthof(group->add_output)) {
 
							GRFError *error = DisableGrf(STR_NEWGRF_ERROR_INDPROD_CALLBACK);
 
							error->data = stredup("too many outputs (max 16)");
 
							return;
 
						}
 
						for (uint i = 0; i < group->num_output; i++) {
 
							byte rawcargo = buf->ReadByte();
 
							CargoID cargo = GetCargoTranslation(rawcargo, _cur.grffile);
 
							if (std::find(group->cargo_output, group->cargo_output + i, cargo) != group->cargo_output + i) {
 
								GRFError *error = DisableGrf(STR_NEWGRF_ERROR_INDPROD_CALLBACK);
 
								error->data = stredup("duplicate output cargo");
 
								return;
 
							}
 
							group->cargo_output[i] = cargo;
 
							group->add_output[i] = buf->ReadByte();
 
						}
 
						group->again = buf->ReadByte();
 
					} else {
 
						NOT_REACHED();
 
					}
 
					break;
 
				}
src/newgrf_industries.cpp
Show inline comments
 
@@ -304,6 +304,33 @@ static uint32 GetCountAndDistanceOfClose
 
			return GetCountAndDistanceOfClosestInstance(parameter, layout_filter, town_filter, this->industry);
 
		}
 

	
 
		case 0x69:
 
		case 0x6A:
 
		case 0x6B:
 
		case 0x6C:
 
		case 0x6D: {
 
			CargoID cargo = GetCargoTranslation(parameter, this->ro.grffile);
 
			int index = this->industry->GetCargoProducedIndex(cargo);
 
			if (index < 0) return 0; // invalid cargo
 
			if (variable == 0x69) return this->industry->produced_cargo_waiting[index];
 
			if (variable == 0x6A) return this->industry->this_month_production[index];
 
			if (variable == 0x6B) return this->industry->this_month_transported[index];
 
			if (variable == 0x6C) return this->industry->last_month_production[index];
 
			if (variable == 0x6D) return this->industry->last_month_transported[index];
 
			NOT_REACHED();
 
		}
 

	
 

	
 
		case 0x6E:
 
		case 0x6F: {
 
			CargoID cargo = GetCargoTranslation(parameter, this->ro.grffile);
 
			int index = this->industry->GetCargoAcceptedIndex(cargo);
 
			if (index < 0) return 0; // invalid cargo
 
			if (variable == 0x6E) return this->industry->last_cargo_accepted_at[index];
 
			if (variable == 0x6F) return this->industry->incoming_cargo_waiting[index];
 
			NOT_REACHED();
 
		}
 

	
 
		/* Get a variable from the persistent storage */
 
		case 0x7C: return (this->industry->psa != NULL) ? this->industry->psa->GetValue(parameter) : 0;
 

	
 
@@ -364,7 +391,10 @@ static uint32 GetCountAndDistanceOfClose
 

	
 
		case 0xB0: return Clamp(this->industry->construction_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0, 65535); // Date when built since 1920 (in days)
 
		case 0xB3: return this->industry->construction_type; // Construction type
 
		case 0xB4: return Clamp(this->industry->last_cargo_accepted_at - DAYS_TILL_ORIGINAL_BASE_YEAR, 0, 65535); // Date last cargo accepted since 1920 (in days)
 
		case 0xB4: {
 
			Date *latest = std::max_element(this->industry->last_cargo_accepted_at, endof(this->industry->last_cargo_accepted_at));
 
			return Clamp((*latest) - DAYS_TILL_ORIGINAL_BASE_YEAR, 0, 65535); // Date last cargo accepted since 1920 (in days)
 
		}
 
	}
 

	
 
	DEBUG(grf, 1, "Unhandled industry variable 0x%X", variable);
 
@@ -575,13 +605,28 @@ void IndustryProductionCallback(Industry
 
		if (tgroup == NULL || tgroup->type != SGT_INDUSTRY_PRODUCTION) break;
 
		const IndustryProductionSpriteGroup *group = (const IndustryProductionSpriteGroup *)tgroup;
 

	
 
		bool deref = (group->version == 1);
 
		bool deref = (group->version >= 1);
 

	
 
		for (uint i = 0; i < 3; i++) {
 
			ind->incoming_cargo_waiting[i] = Clamp(ind->incoming_cargo_waiting[i] - DerefIndProd(group->subtract_input[i], deref) * multiplier, 0, 0xFFFF);
 
		}
 
		for (uint i = 0; i < 2; i++) {
 
			ind->produced_cargo_waiting[i] = Clamp(ind->produced_cargo_waiting[i] + max(DerefIndProd(group->add_output[i], deref), 0) * multiplier, 0, 0xFFFF);
 
		if (group->version < 2) {
 
			/* Callback parameters map directly to industry cargo slot indices */
 
			for (uint i = 0; i < group->num_input; i++) {
 
				ind->incoming_cargo_waiting[i] = Clamp(ind->incoming_cargo_waiting[i] - DerefIndProd(group->subtract_input[i], deref) * multiplier, 0, 0xFFFF);
 
			}
 
			for (uint i = 0; i < group->num_output; i++) {
 
				ind->produced_cargo_waiting[i] = Clamp(ind->produced_cargo_waiting[i] + max(DerefIndProd(group->add_output[i], deref), 0) * multiplier, 0, 0xFFFF);
 
			}
 
		} else {
 
			/* Callback receives list of cargos to apply for, which need to have their cargo slots in industry looked up */
 
			for (uint i = 0; i < group->num_input; i++) {
 
				int cargo_index = ind->GetCargoAcceptedIndex(group->cargo_input[i]);
 
				if (cargo_index < 0) continue;
 
				ind->incoming_cargo_waiting[cargo_index] = Clamp(ind->incoming_cargo_waiting[cargo_index] - DerefIndProd(group->subtract_input[i], deref) * multiplier, 0, 0xFFFF);
 
			}
 
			for (uint i = 0; i < group->num_output; i++) {
 
				int cargo_index = ind->GetCargoProducedIndex(group->cargo_output[i]);
 
				if (cargo_index < 0) continue;
 
				ind->produced_cargo_waiting[cargo_index] = Clamp(ind->produced_cargo_waiting[cargo_index] + max(DerefIndProd(group->add_output[i], deref), 0) * multiplier, 0, 0xFFFF);
 
			}
 
		}
 

	
 
		int32 again = DerefIndProd(group->again, deref);
 
@@ -602,12 +647,7 @@ void IndustryProductionCallback(Industry
 
 */
 
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] || 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]
 
	);
 
	assert(std::find(ind->accepts_cargo, endof(ind->accepts_cargo), cargo_type) != endof(ind->accepts_cargo));
 

	
 
	const IndustrySpec *indspec = GetIndustrySpec(ind->type);
 
	if (HasBit(indspec->callback_mask, CBM_IND_REFUSE_CARGO)) {
src/newgrf_spritegroup.h
Show inline comments
 
@@ -15,6 +15,7 @@
 
#include "town_type.h"
 
#include "engine_type.h"
 
#include "house_type.h"
 
#include "industry_type.h"
 

	
 
#include "newgrf_callbacks.h"
 
#include "newgrf_generic.h"
 
@@ -277,9 +278,14 @@ struct IndustryProductionSpriteGroup : S
 
	IndustryProductionSpriteGroup() : SpriteGroup(SGT_INDUSTRY_PRODUCTION) {}
 

	
 
	uint8 version;
 
	int16 subtract_input[3];  // signed
 
	uint16 add_output[2];     // unsigned
 
	uint8 num_input;                            ///< How many subtract_input values are valid
 
	int16 subtract_input[INDUSTRY_NUM_INPUTS];  ///< Take this much of the input cargo (can be negative, is indirect in cb version 1+)
 
	CargoID cargo_input[INDUSTRY_NUM_INPUTS];   ///< Which input cargoes to take from (only cb version 2)
 
	uint8 num_output;                           ///< How many add_output values are valid
 
	uint16 add_output[INDUSTRY_NUM_OUTPUTS];    ///< Add this much output cargo when successful (unsigned, is indirect in cb version 1+)
 
	CargoID cargo_output[INDUSTRY_NUM_OUTPUTS]; ///< Which output cargoes to add to (only cb version 2)
 
	uint8 again;
 

	
 
};
 

	
 
/**
src/saveload/afterload.cpp
Show inline comments
 
@@ -3033,6 +3033,15 @@ bool AfterLoadGame()
 
				i->accepts_cargo[ci] = CT_INVALID;
 
				i->incoming_cargo_waiting[ci] = 0;
 
			}
 
			/* Make sure last_cargo_accepted_at is copied to elements for every valid input cargo.
 
			 * The loading routine should put the original singular value into the first array element. */
 
			for (size_t ci = 0; ci < lengthof(i->accepts_cargo); ci++) {
 
				if (i->accepts_cargo[ci] != CT_INVALID) {
 
					i->last_cargo_accepted_at[ci] = i->last_cargo_accepted_at[0];
 
				} else {
 
					i->last_cargo_accepted_at[ci] = 0;
 
				}
 
			}
 
		}
 
	}
 

	
src/saveload/industry_sl.cpp
Show inline comments
 
@@ -61,7 +61,8 @@ static const SaveLoad _industry_desc[] =
 
	SLE_CONDVAR(Industry, founder,                    SLE_UINT8,                 70, SL_MAX_VERSION),
 
	SLE_CONDVAR(Industry, construction_date,          SLE_INT32,                 70, SL_MAX_VERSION),
 
	SLE_CONDVAR(Industry, construction_type,          SLE_UINT8,                 70, SL_MAX_VERSION),
 
	SLE_CONDVAR(Industry, last_cargo_accepted_at,     SLE_INT32,                 70, SL_MAX_VERSION),
 
	SLE_CONDVAR(Industry, last_cargo_accepted_at[0],  SLE_INT32,                 70, 201),
 
	SLE_CONDARR(Industry, last_cargo_accepted_at,     SLE_INT32, 16,            202, SL_MAX_VERSION),
 
	SLE_CONDVAR(Industry, selected_layout,            SLE_UINT8,                 73, SL_MAX_VERSION),
 

	
 
	SLEG_CONDARR(_old_ind_persistent_storage.storage, SLE_UINT32, 16,            76, 160),
src/subsidy.cpp
Show inline comments
 
@@ -384,12 +384,12 @@ bool FindSubsidyIndustryCargoRoute()
 

	
 
	/* Randomize cargo type */
 
	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++;
 
	uint cargo_index;
 
	for (cargo_index = 0; cargo_index < lengthof(src_ind->produced_cargo); cargo_index++) {
 
		if (src_ind->produced_cargo[cargo_index] != 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;
src/table/newgrf_debug_data.h
Show inline comments
 
@@ -272,11 +272,38 @@ 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(0x11, Industry, accepts_cargo[2],  NIT_CARGO, "accepted cargo 2"),
 
	NIP(0x25, Industry, produced_cargo[ 0], NIT_CARGO, "produced cargo 0"),
 
	NIP(0x25, Industry, produced_cargo[ 1], NIT_CARGO, "produced cargo 1"),
 
	NIP(0x25, Industry, produced_cargo[ 2], NIT_CARGO, "produced cargo 2"),
 
	NIP(0x25, Industry, produced_cargo[ 3], NIT_CARGO, "produced cargo 3"),
 
	NIP(0x25, Industry, produced_cargo[ 4], NIT_CARGO, "produced cargo 4"),
 
	NIP(0x25, Industry, produced_cargo[ 5], NIT_CARGO, "produced cargo 5"),
 
	NIP(0x25, Industry, produced_cargo[ 6], NIT_CARGO, "produced cargo 6"),
 
	NIP(0x25, Industry, produced_cargo[ 7], NIT_CARGO, "produced cargo 7"),
 
	NIP(0x25, Industry, produced_cargo[ 8], NIT_CARGO, "produced cargo 8"),
 
	NIP(0x25, Industry, produced_cargo[ 9], NIT_CARGO, "produced cargo 9"),
 
	NIP(0x25, Industry, produced_cargo[10], NIT_CARGO, "produced cargo 10"),
 
	NIP(0x25, Industry, produced_cargo[11], NIT_CARGO, "produced cargo 11"),
 
	NIP(0x25, Industry, produced_cargo[12], NIT_CARGO, "produced cargo 12"),
 
	NIP(0x25, Industry, produced_cargo[13], NIT_CARGO, "produced cargo 13"),
 
	NIP(0x25, Industry, produced_cargo[14], NIT_CARGO, "produced cargo 14"),
 
	NIP(0x25, Industry, produced_cargo[15], NIT_CARGO, "produced cargo 15"),
 
	NIP(0x26, Industry, accepts_cargo[ 0],  NIT_CARGO, "accepted cargo 0"),
 
	NIP(0x26, Industry, accepts_cargo[ 1],  NIT_CARGO, "accepted cargo 1"),
 
	NIP(0x26, Industry, accepts_cargo[ 2],  NIT_CARGO, "accepted cargo 2"),
 
	NIP(0x26, Industry, accepts_cargo[ 3],  NIT_CARGO, "accepted cargo 3"),
 
	NIP(0x26, Industry, accepts_cargo[ 4],  NIT_CARGO, "accepted cargo 4"),
 
	NIP(0x26, Industry, accepts_cargo[ 5],  NIT_CARGO, "accepted cargo 5"),
 
	NIP(0x26, Industry, accepts_cargo[ 6],  NIT_CARGO, "accepted cargo 6"),
 
	NIP(0x26, Industry, accepts_cargo[ 7],  NIT_CARGO, "accepted cargo 7"),
 
	NIP(0x26, Industry, accepts_cargo[ 8],  NIT_CARGO, "accepted cargo 8"),
 
	NIP(0x26, Industry, accepts_cargo[ 9],  NIT_CARGO, "accepted cargo 9"),
 
	NIP(0x26, Industry, accepts_cargo[10],  NIT_CARGO, "accepted cargo 10"),
 
	NIP(0x26, Industry, accepts_cargo[11],  NIT_CARGO, "accepted cargo 11"),
 
	NIP(0x26, Industry, accepts_cargo[12],  NIT_CARGO, "accepted cargo 12"),
 
	NIP(0x26, Industry, accepts_cargo[13],  NIT_CARGO, "accepted cargo 13"),
 
	NIP(0x26, Industry, accepts_cargo[14],  NIT_CARGO, "accepted cargo 14"),
 
	NIP(0x26, Industry, accepts_cargo[15],  NIT_CARGO, "accepted cargo 15"),
 
	NIP_END()
 
};
 

	
0 comments (0 inline, 0 general)