diff --git a/src/industry.h b/src/industry.h --- a/src/industry.h +++ b/src/industry.h @@ -56,24 +56,46 @@ enum IndustryControlFlags : byte { }; 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(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 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; + using AcceptedCargoArray = std::array; + 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. @@ -90,7 +112,6 @@ struct Industry : IndustryPool::PoolItem 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) @@ -115,43 +136,39 @@ struct Industry : IndustryPool::PoolItem 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