|
@@ -443,25 +443,25 @@ static void AddAcceptedCargo_Industry(Ti
|
|
|
|
|
|
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) {
|
|
|
MemSetT(cargo_acceptance, 0, lengthof(cargo_acceptance));
|
|
|
for (uint i = 0; i < 3; i++) cargo_acceptance[i] = GB(res, i * 4, 4);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
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 (!IsValidCargoID(a) || cargo_acceptance[i] <= 0) continue; // work only with valid cargoes
|
|
|
|
|
|
/* Add accepted cargo */
|
|
|
acceptance[a] += cargo_acceptance[i];
|
|
|
|
|
|
/* Maybe set 'always accepted' bit (if it's not set already) */
|
|
|
if (HasBit(*always_accepted, a)) continue;
|
|
|
|
|
|
bool accepts = false;
|
|
|
for (uint cargo_index = 0; cargo_index < lengthof(ind->accepts_cargo); cargo_index++) {
|
|
|
/* Test whether the industry itself accepts the cargo type */
|
|
|
if (ind->accepts_cargo[cargo_index] == a) {
|
|
|
accepts = true;
|
|
@@ -525,25 +525,25 @@ static CommandCost ClearTile_Industry(Ti
|
|
|
* Move produced cargo from industry to nearby stations.
|
|
|
* @param tile Industry tile
|
|
|
* @return true if any cargo was moved.
|
|
|
*/
|
|
|
static bool TransportIndustryGoods(TileIndex tile)
|
|
|
{
|
|
|
Industry *i = Industry::GetByTile(tile);
|
|
|
const IndustrySpec *indspec = GetIndustrySpec(i->type);
|
|
|
bool moved_cargo = false;
|
|
|
|
|
|
for (uint j = 0; j < lengthof(i->produced_cargo_waiting); j++) {
|
|
|
uint cw = ClampTo<uint8_t>(i->produced_cargo_waiting[j]);
|
|
|
if (cw > indspec->minimal_cargo && i->produced_cargo[j] != CT_INVALID) {
|
|
|
if (cw > indspec->minimal_cargo && IsValidCargoID(i->produced_cargo[j])) {
|
|
|
i->produced_cargo_waiting[j] -= cw;
|
|
|
|
|
|
/* fluctuating economy? */
|
|
|
if (EconomyIsInRecession()) cw = (cw + 1) / 2;
|
|
|
|
|
|
i->this_month_production[j] += cw;
|
|
|
|
|
|
uint am = MoveGoodsToStation(i->produced_cargo[j], cw, SourceType::Industry, i->index, &i->stations_near, i->exclusive_consumer);
|
|
|
i->this_month_transported[j] += am;
|
|
|
|
|
|
moved_cargo |= (am != 0);
|
|
|
}
|
|
@@ -982,25 +982,25 @@ bool IsTileForestIndustry(TileIndex tile
|
|
|
{
|
|
|
/* Check for industry tile */
|
|
|
if (!IsTileType(tile, MP_INDUSTRY)) return false;
|
|
|
|
|
|
const Industry *ind = Industry::GetByTile(tile);
|
|
|
|
|
|
/* Check for organic industry (i.e. not processing or extractive) */
|
|
|
if ((GetIndustrySpec(ind->type)->life_type & INDUSTRYLIFE_ORGANIC) == 0) return false;
|
|
|
|
|
|
/* Check for wood production */
|
|
|
for (uint i = 0; i < lengthof(ind->produced_cargo); i++) {
|
|
|
/* The industry produces wood. */
|
|
|
if (ind->produced_cargo[i] != CT_INVALID && CargoSpec::Get(ind->produced_cargo[i])->label == 'WOOD') return true;
|
|
|
if (IsValidCargoID(ind->produced_cargo[i]) && CargoSpec::Get(ind->produced_cargo[i])->label == 'WOOD') return true;
|
|
|
}
|
|
|
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
static const byte _plantfarmfield_type[] = {1, 1, 1, 1, 1, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6};
|
|
|
|
|
|
/**
|
|
|
* Check whether the tile can be replaced by a farm field.
|
|
|
* @param tile the tile to investigate.
|
|
|
* @param allow_fields if true, the method will return true even if
|
|
|
* the tile is a farm tile, otherwise the tile may not be a farm tile
|
|
@@ -1858,25 +1858,25 @@ static void DoCreateNewIndustry(Industry
|
|
|
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;
|
|
|
}
|
|
|
CargoID cargo = GetCargoTranslation(GB(res, 0, 8), indspec->grf_prop.grffile);
|
|
|
/* Industries without "unlimited" cargo types support depend on the specific order/slots of cargo types.
|
|
|
* They need to be able to blank out specific slots without aborting the callback sequence,
|
|
|
* and solve this by returning undefined cargo indexes. Skip these. */
|
|
|
if (cargo == CT_INVALID && !(indspec->behaviour & INDUSTRYBEH_CARGOTYPES_UNLIMITED)) continue;
|
|
|
if (!IsValidCargoID(cargo) && !(indspec->behaviour & INDUSTRYBEH_CARGOTYPES_UNLIMITED)) continue;
|
|
|
/* Verify valid cargo */
|
|
|
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;
|
|
@@ -1888,25 +1888,25 @@ static void DoCreateNewIndustry(Industry
|
|
|
for (uint j = 0; j < lengthof(i->produced_cargo); j++) i->produced_cargo[j] = CT_INVALID;
|
|
|
/* 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;
|
|
|
}
|
|
|
CargoID cargo = GetCargoTranslation(GB(res, 0, 8), indspec->grf_prop.grffile);
|
|
|
/* Allow older GRFs to skip slots. */
|
|
|
if (cargo == CT_INVALID && !(indspec->behaviour & INDUSTRYBEH_CARGOTYPES_UNLIMITED)) continue;
|
|
|
if (!IsValidCargoID(cargo) && !(indspec->behaviour & INDUSTRYBEH_CARGOTYPES_UNLIMITED)) continue;
|
|
|
/* Verify valid cargo */
|
|
|
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;
|
|
@@ -2411,25 +2411,25 @@ void GenerateIndustries()
|
|
|
PlaceInitialIndustry(it, false);
|
|
|
}
|
|
|
_industry_builder.Reset();
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Monthly update of industry statistics.
|
|
|
* @param i Industry to update.
|
|
|
*/
|
|
|
static void UpdateIndustryStatistics(Industry *i)
|
|
|
{
|
|
|
for (byte j = 0; j < lengthof(i->produced_cargo); j++) {
|
|
|
if (i->produced_cargo[j] != CT_INVALID) {
|
|
|
if (IsValidCargoID(i->produced_cargo[j])) {
|
|
|
byte pct = 0;
|
|
|
if (i->this_month_production[j] != 0) {
|
|
|
i->last_prod_year = TimerGameCalendar::year;
|
|
|
pct = ClampTo<byte>(i->this_month_transported[j] * 256 / i->this_month_production[j]);
|
|
|
}
|
|
|
i->last_month_pct_transported[j] = pct;
|
|
|
|
|
|
i->last_month_production[j] = i->this_month_production[j];
|
|
|
i->this_month_production[j] = 0;
|
|
|
|
|
|
i->last_month_transported[j] = i->this_month_transported[j];
|
|
|
i->this_month_transported[j] = 0;
|
|
@@ -2613,25 +2613,25 @@ static bool CheckIndustryCloseDownProtec
|
|
|
|
|
|
/**
|
|
|
* Can given cargo type be accepted or produced by the industry?
|
|
|
* @param cargo: Cargo type
|
|
|
* @param ind: Industry
|
|
|
* @param *c_accepts: Pointer to boolean for acceptance of cargo
|
|
|
* @param *c_produces: Pointer to boolean for production of cargo
|
|
|
* @return: \c *c_accepts is set when industry accepts the cargo type,
|
|
|
* \c *c_produces is set when the industry produces the cargo type
|
|
|
*/
|
|
|
static void CanCargoServiceIndustry(CargoID cargo, Industry *ind, bool *c_accepts, bool *c_produces)
|
|
|
{
|
|
|
if (cargo == CT_INVALID) return;
|
|
|
if (!IsValidCargoID(cargo)) return;
|
|
|
|
|
|
/* Check for acceptance of cargo */
|
|
|
for (byte j = 0; j < lengthof(ind->accepts_cargo); j++) {
|
|
|
if (cargo == ind->accepts_cargo[j] && !IndustryTemporarilyRefusesCargo(ind, cargo)) {
|
|
|
*c_accepts = true;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/* Check for produced cargo */
|
|
|
for (byte j = 0; j < lengthof(ind->produced_cargo); j++) {
|
|
|
if (cargo == ind->produced_cargo[j]) {
|
|
@@ -2791,25 +2791,25 @@ static void ChangeIndustryProduction(Ind
|
|
|
if (original_economy) {
|
|
|
if (only_decrease || Chance16(1, 3)) {
|
|
|
/* If more than 60% transported, 66% chance of increase, else 33% chance of increase */
|
|
|
if (!only_decrease && (i->last_month_pct_transported[0] > PERCENT_TRANSPORTED_60) != Chance16(1, 3)) {
|
|
|
mul = 1; // Increase production
|
|
|
} else {
|
|
|
div = 1; // Decrease production
|
|
|
}
|
|
|
}
|
|
|
} else if (_settings_game.economy.type == ET_SMOOTH) {
|
|
|
closeit = !(i->ctlflags & (INDCTL_NO_CLOSURE | INDCTL_NO_PRODUCTION_DECREASE));
|
|
|
for (byte j = 0; j < lengthof(i->produced_cargo); j++) {
|
|
|
if (i->produced_cargo[j] == CT_INVALID) continue;
|
|
|
if (!IsValidCargoID(i->produced_cargo[j])) continue;
|
|
|
uint32 r = Random();
|
|
|
int old_prod, new_prod, percent;
|
|
|
/* If over 60% is transported, mult is 1, else mult is -1. */
|
|
|
int mult = (i->last_month_pct_transported[j] > PERCENT_TRANSPORTED_60) ? 1 : -1;
|
|
|
|
|
|
new_prod = old_prod = i->production_rate[j];
|
|
|
|
|
|
/* For industries with only_decrease flags (temperate terrain Oil Wells),
|
|
|
* the multiplier will always be -1 so they will only decrease. */
|
|
|
if (only_decrease) {
|
|
|
mult = -1;
|
|
|
/* For normal industries, if over 60% is transported, 33% chance for decrease.
|