Last active
August 19, 2017 09:00
-
-
Save LordAro/6979a2322dd45341ce741a22d7acfb28 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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