Skip to content

Instantly share code, notes, and snippets.

@LordAro
Last active August 19, 2017 09:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save LordAro/6979a2322dd45341ce741a22d7acfb28 to your computer and use it in GitHub Desktop.
Save LordAro/6979a2322dd45341ce741a22d7acfb28 to your computer and use it in GitHub Desktop.
diff --git a/src/industry_cmd.cpp b/src/industry_cmd.cpp
index 8fea6953a..4d1516cf0 100644
--- a/src/industry_cmd.cpp
+++ b/src/industry_cmd.cpp
@@ -2461,39 +2461,30 @@ static void ReportNewsProductionChangeIndustry(Industry *ind, CargoID type, int
static const uint PERCENT_TRANSPORTED_60 = 153;
static const uint PERCENT_TRANSPORTED_80 = 204;
-/**
- * Change industry production or do closure
- * @param i Industry for which changes are performed
- * @param monthly true if it's the monthly call, false if it's the random call
- */
-static void ChangeIndustryProduction(Industry *i, bool monthly)
+static byte ChangeIndustryProductionOriginal(Industry *i, bool monthly, StringID *str, bool *suppress_message)
{
- StringID str = STR_NULL;
- bool closeit = false;
- const IndustrySpec *indspec = GetIndustrySpec(i->type);
bool standard = false;
- bool suppress_message = false;
- bool recalculate_multipliers = false; ///< reinitialize production_rate to match prod_level
- /* don't use smooth economy for industries using production related callbacks */
- bool smooth_economy = indspec->UsesSmoothEconomy();
byte div = 0;
byte mul = 0;
int8 increment = 0;
+ byte new_prod_level = i->prod_level;
+
+ const IndustrySpec *indspec = GetIndustrySpec(i->type);
bool callback_enabled = HasBit(indspec->callback_mask, monthly ? CBM_IND_MONTHLYPROD_CHANGE : CBM_IND_PRODUCTION_CHANGE);
if (callback_enabled) {
uint16 res = GetIndustryCallback(monthly ? CBID_INDUSTRY_MONTHLYPROD_CHANGE : CBID_INDUSTRY_PRODUCTION_CHANGE, 0, Random(), i, i->type, i->location.tile);
if (res != CALLBACK_FAILED) { // failed callback means "do nothing"
- suppress_message = HasBit(res, 7);
+ *suppress_message = HasBit(res, 7);
/* Get the custom message if any */
- if (HasBit(res, 8)) str = MapGRFStringID(indspec->grf_prop.grffile->grfid, GB(GetRegister(0x100), 0, 16));
+ if (HasBit(res, 8)) *str = MapGRFStringID(indspec->grf_prop.grffile->grfid, GB(GetRegister(0x100), 0, 16));
res = GB(res, 0, 4);
switch (res) {
default: NOT_REACHED();
case 0x0: break; // Do nothing, but show the custom message if any
case 0x1: div = 1; break; // Halve industry production. If production reaches the quarter of the default, the industry is closed instead.
case 0x2: mul = 1; break; // Double industry production if it hasn't reached eight times of the original yet.
- case 0x3: closeit = true; break; // The industry announces imminent closure, and is physically removed from the map next month.
+ case 0x3: new_prod_level = PRODLEVEL_MINIMUM; break; // The industry announces imminent closure, and is physically removed from the map next month.
case 0x4: standard = true; break; // Do the standard random production change as if this industry was a primary one.
case 0x5: case 0x6: case 0x7: // Divide production by 4, 8, 16
case 0x8: div = res - 0x3; break; // Divide production by 32
@@ -2504,120 +2495,129 @@ static void ChangeIndustryProduction(Industry *i, bool monthly)
increment = res == 0x0D ? -1 : 1;
break;
case 0xF: // Set production to third byte of register 0x100
- i->prod_level = Clamp(GB(GetRegister(0x100), 16, 8), PRODLEVEL_MINIMUM, PRODLEVEL_MAXIMUM);
- recalculate_multipliers = true;
+ new_prod_level = Clamp(GB(GetRegister(0x100), 16, 8), PRODLEVEL_MINIMUM, PRODLEVEL_MAXIMUM);
break;
}
}
} else {
- if (monthly != smooth_economy) return;
- if (indspec->life_type == INDUSTRYLIFE_BLACK_HOLE) return;
+ if (indspec->life_type == INDUSTRYLIFE_BLACK_HOLE) return new_prod_level;
}
if (standard || (!callback_enabled && (indspec->life_type & (INDUSTRYLIFE_ORGANIC | INDUSTRYLIFE_EXTRACTIVE)) != 0)) {
/* decrease or increase */
bool only_decrease = (indspec->behaviour & INDUSTRYBEH_DONT_INCR_PROD) && _settings_game.game_creation.landscape == LT_TEMPERATE;
+ 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
+ }
+ }
+ }
- if (smooth_economy) {
- closeit = true;
- for (byte j = 0; j < lengthof(i->produced_cargo); j++) {
- if (i->produced_cargo[j] == CT_INVALID) 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.
- * Bonus for very high station ratings (over 80%): 16% chance for decrease. */
- } else if (Chance16I(1, ((i->last_month_pct_transported[j] > PERCENT_TRANSPORTED_80) ? 6 : 3), r)) {
- mult *= -1;
- }
+ /* Increase if needed */
+ while (mul-- != 0 && new_prod_level < PRODLEVEL_MAXIMUM) {
+ new_prod_level = min(new_prod_level * 2, PRODLEVEL_MAXIMUM);
+ if (*str == STR_NULL) *str = indspec->production_up_text;
+ }
- /* 4.5% chance for 3-23% (or 1 unit for very low productions) production change,
- * determined by mult value. If mult = 1 prod. increases, else (-1) it decreases. */
- if (Chance16I(1, 22, r >> 16)) {
- new_prod += mult * (max(((RandomRange(50) + 10) * old_prod) >> 8, 1U));
- }
+ /* Decrease if needed */
+ while (div-- != 0 && new_prod_level > PRODLEVEL_MINIMUM) {
+ new_prod_level = max(new_prod_level / 2, (int)PRODLEVEL_MINIMUM); // typecast to int required to please MSVC
+ if (*str == STR_NULL) *str = indspec->production_down_text;
+ }
- /* Prevent production to overflow or Oil Rig passengers to be over-"produced" */
- new_prod = Clamp(new_prod, 1, 255);
+ /* Increase or Decreasing the production level if needed */
+ new_prod_level = ClampU(new_prod_level + increment, PRODLEVEL_MINIMUM, PRODLEVEL_MAXIMUM);
+ return new_prod_level;
+}
- if (((indspec->behaviour & INDUSTRYBEH_BUILT_ONWATER) != 0) && j == 1) {
- new_prod = Clamp(new_prod, 0, 16);
- }
+/**
+ * Change industry production or do closure
+ * @param i Industry for which changes are performed
+ * @param monthly true if it's the monthly call, false if it's the random call
+ */
+static void ChangeIndustryProduction(Industry *i, bool monthly)
+{
+ bool closeit = false;
+ StringID str = STR_NULL;
+ bool suppress_message = false;
- /* Do not stop closing the industry when it has the lowest possible production rate */
- if (new_prod == old_prod && old_prod > 1) {
- closeit = false;
- continue;
- }
+ /* don't use smooth economy for industries using production related callbacks */
+ const IndustrySpec *indspec = GetIndustrySpec(i->type);
+ bool smooth_economy = indspec->UsesSmoothEconomy();
+ if (smooth_economy) {
+ /* decrease or increase */
+ bool only_decrease = (indspec->behaviour & INDUSTRYBEH_DONT_INCR_PROD) && _settings_game.game_creation.landscape == LT_TEMPERATE;
+ closeit = true;
+ for (byte j = 0; j < lengthof(i->produced_cargo); j++) {
+ if (i->produced_cargo[j] == CT_INVALID) 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.
+ * Bonus for very high station ratings (over 80%): 16% chance for decrease. */
+ } else if (Chance16I(1, ((i->last_month_pct_transported[j] > PERCENT_TRANSPORTED_80) ? 6 : 3), r)) {
+ mult *= -1;
+ }
- percent = (old_prod == 0) ? 100 : (new_prod * 100 / old_prod - 100);
- i->production_rate[j] = new_prod;
+ /* 4.5% chance for 3-23% (or 1 unit for very low productions) production change,
+ * determined by mult value. If mult = 1 prod. increases, else (-1) it decreases. */
+ if (Chance16I(1, 22, r >> 16)) {
+ new_prod += mult * (max(((RandomRange(50) + 10) * old_prod) >> 8, 1U));
+ }
- /* Close the industry when it has the lowest possible production rate */
- if (new_prod > 1) closeit = false;
+ /* Prevent production to overflow or Oil Rig passengers to be over-"produced" */
+ new_prod = Clamp(new_prod, 1, 255);
- if (abs(percent) >= 10) {
- ReportNewsProductionChangeIndustry(i, i->produced_cargo[j], percent);
- }
+ if (((indspec->behaviour & INDUSTRYBEH_BUILT_ONWATER) != 0) && j == 1) {
+ new_prod = Clamp(new_prod, 0, 16);
}
- } else {
- 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
- }
+
+ /* Do not stop closing the industry when it has the lowest possible production rate */
+ if (new_prod == old_prod && old_prod > 1) {
+ closeit = false;
+ continue;
}
- }
- }
- if (!callback_enabled && (indspec->life_type & INDUSTRYLIFE_PROCESSING)) {
- if ( (byte)(_cur_year - i->last_prod_year) >= 5 && Chance16(1, smooth_economy ? 180 : 2)) {
- closeit = true;
- }
- }
+ percent = (old_prod == 0) ? 100 : (new_prod * 100 / old_prod - 100);
+ i->production_rate[j] = new_prod;
- /* Increase if needed */
- while (mul-- != 0 && i->prod_level < PRODLEVEL_MAXIMUM) {
- i->prod_level = min(i->prod_level * 2, PRODLEVEL_MAXIMUM);
- recalculate_multipliers = true;
- if (str == STR_NULL) str = indspec->production_up_text;
- }
+ /* Close the industry when it has the lowest possible production rate */
+ if (new_prod > 1) closeit = false;
- /* Decrease if needed */
- while (div-- != 0 && !closeit) {
- if (i->prod_level == PRODLEVEL_MINIMUM) {
- closeit = true;
- } else {
- i->prod_level = max(i->prod_level / 2, (int)PRODLEVEL_MINIMUM); // typecast to int required to please MSVC
- recalculate_multipliers = true;
- if (str == STR_NULL) str = indspec->production_down_text;
+ if (abs(percent) >= 10) {
+ ReportNewsProductionChangeIndustry(i, i->produced_cargo[j], percent);
+ }
+ }
+
+ } else {
+ byte new_prod_level = ChangeIndustryProductionOriginal(i, monthly, &str, &suppress_message);
+ if (new_prod_level == PRODLEVEL_MINIMUM) closeit = true;
+ if (new_prod_level != i->prod_level) {
+ i->prod_level = new_prod_level;
+ /* Recalculate production_rate
+ * For non-smooth economy these should always be synchronized with prod_level */
+ i->RecomputeProductionMultipliers();
}
}
- /* Increase or Decreasing the production level if needed */
- if (increment != 0) {
- if (increment < 0 && i->prod_level == PRODLEVEL_MINIMUM) {
+ bool callback_enabled = HasBit(indspec->callback_mask, monthly ? CBM_IND_MONTHLYPROD_CHANGE : CBM_IND_PRODUCTION_CHANGE);
+ if (!callback_enabled && (indspec->life_type & INDUSTRYLIFE_PROCESSING)) {
+ if ( (byte)(_cur_year - i->last_prod_year) >= 5 && Chance16(1, smooth_economy ? 180 : 2)) {
closeit = true;
- } else {
- i->prod_level = ClampU(i->prod_level + increment, PRODLEVEL_MINIMUM, PRODLEVEL_MAXIMUM);
- recalculate_multipliers = true;
}
}
- /* Recalculate production_rate
- * For non-smooth economy these should always be synchronized with prod_level */
- if (recalculate_multipliers) i->RecomputeProductionMultipliers();
-
/* Close if needed and allowed */
if (closeit && !CheckIndustryCloseDownProtection(i->type)) {
i->prod_level = PRODLEVEL_CLOSURE;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment