|
@@ -53,30 +53,52 @@ enum IndustryControlFlags : byte {
|
|
|
INDCTL_NO_CLOSURE = 1 << 2,
|
|
|
/** Mask of all flags set */
|
|
|
INDCTL_MASK = INDCTL_NO_PRODUCTION_DECREASE | INDCTL_NO_PRODUCTION_INCREASE | INDCTL_NO_CLOSURE,
|
|
|
};
|
|
|
DECLARE_ENUM_AS_BIT_SET(IndustryControlFlags);
|
|
|
|
|
|
static const int THIS_MONTH = 0;
|
|
|
static const int LAST_MONTH = 1;
|
|
|
|
|
|
/**
|
|
|
* Defines the internal data of a functional industry.
|
|
|
*/
|
|
|
struct Industry : IndustryPool::PoolItem<&_industry_pool> {
|
|
|
struct ProducedHistory {
|
|
|
uint16_t production; ///< Total produced
|
|
|
uint16_t transported; ///< Total transported
|
|
|
|
|
|
uint8_t PctTransported() const
|
|
|
{
|
|
|
if (this->production == 0) return 0;
|
|
|
return ClampTo<uint8_t>(this->transported * 256 / this->production);
|
|
|
}
|
|
|
};
|
|
|
|
|
|
struct ProducedCargo {
|
|
|
CargoID cargo; ///< Cargo type
|
|
|
uint16_t waiting; ///< Amount of cargo produced
|
|
|
uint8_t rate; ///< Production rate
|
|
|
std::array<ProducedHistory, 2> history; ///< History of cargo produced and transported
|
|
|
};
|
|
|
|
|
|
struct AcceptedCargo {
|
|
|
CargoID cargo; ///< Cargo type
|
|
|
uint16_t waiting; ///< Amount of cargo waiting to processed
|
|
|
TimerGameCalendar::Date last_accepted; ///< Last day cargo was accepted by this industry
|
|
|
};
|
|
|
|
|
|
using ProducedCargoArray = std::array<ProducedCargo, INDUSTRY_NUM_OUTPUTS>;
|
|
|
using AcceptedCargoArray = std::array<AcceptedCargo, INDUSTRY_NUM_INPUTS>;
|
|
|
|
|
|
TileArea location; ///< Location of the industry
|
|
|
Town *town; ///< Nearest town
|
|
|
Station *neutral_station; ///< Associated neutral station
|
|
|
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
|
|
|
ProducedCargoArray produced; ///< INDUSTRY_NUM_OUTPUTS production cargo slots
|
|
|
AcceptedCargoArray accepted; ///< INDUSTRY_NUM_INPUTS input cargo slots
|
|
|
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.
|
|
|
Owner owner; ///< owner of the industry. Which SHOULD always be (imho) OWNER_NONE
|
|
|
byte random_colour; ///< randomized colour of the industry, for display purpose
|
|
|
TimerGameCalendar::Year last_prod_year; ///< last year of production
|
|
@@ -87,13 +109,12 @@ struct Industry : IndustryPool::PoolItem
|
|
|
StationList stations_near; ///< NOSAVE: List of nearby stations.
|
|
|
mutable std::string cached_name; ///< NOSAVE: Cache of the resolved name of the industry
|
|
|
|
|
|
Owner founder; ///< Founder of the industry
|
|
|
TimerGameCalendar::Date construction_date; ///< Date of the construction of the industry
|
|
|
uint8 construction_type; ///< Way the industry was constructed (@see IndustryConstructionType)
|
|
|
TimerGameCalendar::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
|
|
|
Owner exclusive_supplier; ///< Which company has exclusive rights to deliver cargo (INVALID_OWNER = anyone)
|
|
|
Owner exclusive_consumer; ///< Which company has exclusive rights to take cargo (INVALID_OWNER = anyone)
|
|
|
std::string text; ///< General text with additional information.
|
|
|
|
|
|
uint16 random; ///< Random value used for randomisation of all kinds of things
|
|
@@ -112,49 +133,45 @@ struct Industry : IndustryPool::PoolItem
|
|
|
*/
|
|
|
inline bool TileBelongsToIndustry(TileIndex tile) const
|
|
|
{
|
|
|
return IsTileType(tile, MP_INDUSTRY) && GetIndustryIndex(tile) == this->index;
|
|
|
}
|
|
|
|
|
|
inline int GetCargoProducedIndex(CargoID cargo) const
|
|
|
inline ProducedCargoArray::iterator GetCargoProduced(CargoID cargo)
|
|
|
{
|
|
|
if (!IsValidCargoID(cargo)) 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;
|
|
|
if (!IsValidCargoID(cargo)) return std::end(this->produced);
|
|
|
return std::find_if(std::begin(this->produced), std::end(this->produced), [&cargo](const auto &p) { return p.cargo == cargo; });
|
|
|
}
|
|
|
|
|
|
inline int GetCargoAcceptedIndex(CargoID cargo) const
|
|
|
inline AcceptedCargoArray::iterator GetCargoAccepted(CargoID cargo)
|
|
|
{
|
|
|
if (!IsValidCargoID(cargo)) 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;
|
|
|
if (!IsValidCargoID(cargo)) return std::end(this->accepted);
|
|
|
return std::find_if(std::begin(this->accepted), std::end(this->accepted), [&cargo](const auto &a) { return a.cargo == cargo; });
|
|
|
}
|
|
|
|
|
|
/** Test if this industry accepts any cargo.
|
|
|
* @return true iff the industry accepts any cargo.
|
|
|
*/
|
|
|
bool IsCargoAccepted() const { return std::any_of(std::begin(this->accepts_cargo), std::end(this->accepts_cargo), [](const auto &cargo) { return IsValidCargoID(cargo); }); }
|
|
|
bool IsCargoAccepted() const { return std::any_of(std::begin(this->accepted), std::end(this->accepted), [](const auto &a) { return IsValidCargoID(a.cargo); }); }
|
|
|
|
|
|
/** Test if this industry produces any cargo.
|
|
|
* @return true iff the industry produces any cargo.
|
|
|
*/
|
|
|
bool IsCargoProduced() const { return std::any_of(std::begin(this->produced_cargo), std::end(this->produced_cargo), [](const auto &cargo) { return IsValidCargoID(cargo); }); }
|
|
|
bool IsCargoProduced() const { return std::any_of(std::begin(this->produced), std::end(this->produced), [](const auto &p) { return IsValidCargoID(p.cargo); }); }
|
|
|
|
|
|
/** Test if this industry accepts a specific cargo.
|
|
|
* @param cargo Cargo type to test.
|
|
|
* @return true iff the industry accepts the given cargo type.
|
|
|
*/
|
|
|
bool IsCargoAccepted(CargoID cargo) const { return std::any_of(std::begin(this->accepts_cargo), std::end(this->accepts_cargo), [&cargo](const auto &cid) { return cid == cargo; }); }
|
|
|
bool IsCargoAccepted(CargoID cargo) const { return std::any_of(std::begin(this->accepted), std::end(this->accepted), [&cargo](const auto &a) { return a.cargo == cargo; }); }
|
|
|
|
|
|
/** Test if this industry produces a specific cargo.
|
|
|
* @param cargo Cargo type to test.
|
|
|
* @return true iff the industry produces the given cargo types.
|
|
|
*/
|
|
|
bool IsCargoProduced(CargoID cargo) const { return std::any_of(std::begin(this->produced_cargo), std::end(this->produced_cargo), [&cargo](const auto &cid) { return cid == cargo; }); }
|
|
|
bool IsCargoProduced(CargoID cargo) const { return std::any_of(std::begin(this->produced), std::end(this->produced), [&cargo](const auto &p) { return p.cargo == cargo; }); }
|
|
|
|
|
|
/**
|
|
|
* Get the industry of the given tile
|
|
|
* @param tile the tile to get the industry from
|
|
|
* @pre IsTileType(t, MP_INDUSTRY)
|
|
|
* @return the industry
|