Skip to content

Commit

Permalink
Fix: Add stable economy type that doesn't ruin scenarios with non-sta…
Browse files Browse the repository at this point in the history
…ndard industry generation
  • Loading branch information
ldpl committed Jul 28, 2020
1 parent 452e1e3 commit 9ad15a5
Show file tree
Hide file tree
Showing 8 changed files with 54 additions and 35 deletions.
9 changes: 9 additions & 0 deletions src/economy_type.h
Expand Up @@ -15,6 +15,15 @@

typedef OverflowSafeInt64 Money;

/** Type of the game economy. */
enum EconomyType : uint8 {
ET_BEGIN = 0,
ET_ORIGINAL = 0,
ET_SMOOTH = 1,
ET_STABLE = 2,
ET_END = 3,
};

/** Data of the economy. */
struct Economy {
Money max_loan; ///< NOSAVE: Maximum possible loan
Expand Down
47 changes: 24 additions & 23 deletions src/industry_cmd.cpp
Expand Up @@ -1736,8 +1736,8 @@ static void DoCreateNewIndustry(Industry *i, TileIndex tile, IndustryType type,
MemSetT(i->incoming_cargo_waiting, 0, lengthof(i->incoming_cargo_waiting));
MemSetT(i->last_cargo_accepted_at, 0, lengthof(i->last_cargo_accepted_at));

/* don't use smooth economy for industries using production related callbacks */
if (indspec->UsesSmoothEconomy()) {
/* Randomize inital production if non-original economy is used and there are no production related callbacks. */
if (!indspec->UsesOriginalEconomy()) {
for (size_t ci = 0; ci < lengthof(i->production_rate); ci++) {
i->production_rate[ci] = min((RandomRange(256) + 128) * i->production_rate[ci] >> 8, 255);
}
Expand Down Expand Up @@ -2303,7 +2303,7 @@ static void UpdateIndustryStatistics(Industry *i)
void Industry::RecomputeProductionMultipliers()
{
const IndustrySpec *indspec = GetIndustrySpec(this->type);
assert(!indspec->UsesSmoothEconomy());
assert(indspec->UsesOriginalEconomy());

/* Rates are rounded up, so e.g. oilrig always produces some passengers */
for (size_t i = 0; i < lengthof(this->production_rate); i++) {
Expand Down Expand Up @@ -2603,8 +2603,8 @@ static void ChangeIndustryProduction(Industry *i, bool monthly)
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();
/* use original economy for industries using production related callbacks */
bool original_economy = indspec->UsesOriginalEconomy();
byte div = 0;
byte mul = 0;
int8 increment = 0;
Expand Down Expand Up @@ -2639,15 +2639,25 @@ static void ChangeIndustryProduction(Industry *i, bool monthly)
}
}
} else {
if (monthly != smooth_economy) return;
if (monthly == original_economy) return;
if (!original_economy && _settings_game.economy.type == ET_STABLE) return;
if (indspec->life_type == INDUSTRYLIFE_BLACK_HOLE) return;
}

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 (smooth_economy) {
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_STABLE) { // smooth economy
closeit = true;
for (byte j = 0; j < lengthof(i->produced_cargo); j++) {
if (i->produced_cargo[j] == CT_INVALID) continue;
Expand Down Expand Up @@ -2697,20 +2707,11 @@ static void ChangeIndustryProduction(Industry *i, bool monthly)
ReportNewsProductionChangeIndustry(i, i->produced_cargo[j], percent);
}
}
} 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
}
}
}
}

if (!callback_enabled && (indspec->life_type & INDUSTRYLIFE_PROCESSING)) {
if ( (byte)(_cur_year - i->last_prod_year) >= 5 && Chance16(1, smooth_economy ? 180 : 2)) {
if ( (byte)(_cur_year - i->last_prod_year) >= 5 && Chance16(1, original_economy ? 2 : 180)) {
closeit = true;
}
}
Expand Down Expand Up @@ -2933,14 +2934,14 @@ Money IndustrySpec::GetRemovalCost() const
}

/**
* Determines whether this industrytype uses smooth economy or whether it uses standard/newgrf production changes.
* @return true if smooth economy is used.
* Determines whether this industrytype uses standard/newgrf production changes.
* @return true if original economy is used.
*/
bool IndustrySpec::UsesSmoothEconomy() const
bool IndustrySpec::UsesOriginalEconomy() const
{
return _settings_game.economy.smooth_economy &&
!(HasBit(this->callback_mask, CBM_IND_PRODUCTION_256_TICKS) || HasBit(this->callback_mask, CBM_IND_PRODUCTION_CARGO_ARRIVAL)) && // production callbacks
!(HasBit(this->callback_mask, CBM_IND_MONTHLYPROD_CHANGE) || HasBit(this->callback_mask, CBM_IND_PRODUCTION_CHANGE) || HasBit(this->callback_mask, CBM_IND_PROD_CHANGE_BUILD)); // production change callbacks
return _settings_game.economy.type == ET_ORIGINAL ||
HasBit(this->callback_mask, CBM_IND_PRODUCTION_256_TICKS) || HasBit(this->callback_mask, CBM_IND_PRODUCTION_CARGO_ARRIVAL) || // production callbacks
HasBit(this->callback_mask, CBM_IND_MONTHLYPROD_CHANGE) || HasBit(this->callback_mask, CBM_IND_PRODUCTION_CHANGE) || HasBit(this->callback_mask, CBM_IND_PROD_CHANGE_BUILD); // production change callbacks
}

IndustrySpec::~IndustrySpec()
Expand Down
4 changes: 2 additions & 2 deletions src/industry_gui.cpp
Expand Up @@ -1080,7 +1080,7 @@ class IndustryViewWindow : public Window
const Industry *i = Industry::Get(this->window_number);
if (IsProductionAlterable(i)) {
const IndustrySpec *ind = GetIndustrySpec(i->type);
this->editable = ind->UsesSmoothEconomy() ? EA_RATE : EA_MULTIPLIER;
this->editable = ind->UsesOriginalEconomy() ? EA_MULTIPLIER : EA_RATE;
} else {
this->editable = EA_NONE;
}
Expand All @@ -1100,7 +1100,7 @@ class IndustryViewWindow : public Window
static void UpdateIndustryProduction(Industry *i)
{
const IndustrySpec *indspec = GetIndustrySpec(i->type);
if (!indspec->UsesSmoothEconomy()) i->RecomputeProductionMultipliers();
if (indspec->UsesOriginalEconomy()) i->RecomputeProductionMultipliers();

for (byte j = 0; j < lengthof(i->produced_cargo); j++) {
if (i->produced_cargo[j] != CT_INVALID) {
Expand Down
2 changes: 1 addition & 1 deletion src/industrytype.h
Expand Up @@ -144,7 +144,7 @@ struct IndustrySpec {
bool IsProcessingIndustry() const;
Money GetConstructionCost() const;
Money GetRemovalCost() const;
bool UsesSmoothEconomy() const;
bool UsesOriginalEconomy() const;

~IndustrySpec();
};
Expand Down
7 changes: 5 additions & 2 deletions src/lang/english.txt
Expand Up @@ -1553,8 +1553,11 @@ STR_CONFIG_SETTING_ENDING_YEAR :Scoring end yea
STR_CONFIG_SETTING_ENDING_YEAR_HELPTEXT :Year the game ends for scoring purposes. At the end of this year, the company's score is recorded and the high-score screen is displayed, but the players can continue playing after that.{}If this is before the starting year, the high-score screen is never displayed.
STR_CONFIG_SETTING_ENDING_YEAR_VALUE :{NUM}
STR_CONFIG_SETTING_ENDING_YEAR_ZERO :Never
STR_CONFIG_SETTING_SMOOTH_ECONOMY :Enable smooth economy (more, smaller changes): {STRING2}
STR_CONFIG_SETTING_SMOOTH_ECONOMY_HELPTEXT :When enabled, industry production changes more often, and in smaller steps. This setting has usually no effect, if industry types are provided by a NewGRF
STR_CONFIG_SETTING_ECONOMY_TYPE :Economy type: {STRING2}
STR_CONFIG_SETTING_ECONOMY_TYPE_HELPTEXT :Smooth economy makes production changes more often, and in smaller steps. Stable stops production changes and industry closures. This setting has usually no effect, if industry types are provided by a NewGRF.
STR_CONFIG_SETTING_ECONOMY_TYPE_ORIGINAL :Original
STR_CONFIG_SETTING_ECONOMY_TYPE_SMOOTH :Smooth
STR_CONFIG_SETTING_ECONOMY_TYPE_STABLE :Stable
STR_CONFIG_SETTING_ALLOW_SHARES :Allow buying shares from other companies: {STRING2}
STR_CONFIG_SETTING_ALLOW_SHARES_HELPTEXT :When enabled, allow buying and selling of company shares. Shares will only be available for companies reaching a certain age
STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES :Minimum company age to trade shares: {STRING2}
Expand Down
2 changes: 1 addition & 1 deletion src/settings_gui.cpp
Expand Up @@ -1729,7 +1729,7 @@ static SettingsContainer &GetSettingsTree()
industries->Add(new SettingEntry("construction.industry_platform"));
industries->Add(new SettingEntry("economy.multiple_industry_per_town"));
industries->Add(new SettingEntry("game_creation.oil_refinery_limit"));
industries->Add(new SettingEntry("economy.smooth_economy"));
industries->Add(new SettingEntry("economy.type"));
industries->Add(new SettingEntry("station.serve_neutral_industries"));
}

Expand Down
3 changes: 2 additions & 1 deletion src/settings_type.h
Expand Up @@ -11,6 +11,7 @@
#define SETTINGS_TYPE_H

#include "date_type.h"
#include "economy_type.h"
#include "town_type.h"
#include "transport_type.h"
#include "network/core/config.h"
Expand Down Expand Up @@ -470,7 +471,7 @@ struct VehicleSettings {
struct EconomySettings {
bool inflation; ///< disable inflation
bool bribe; ///< enable bribing the local authority
bool smooth_economy; ///< smooth economy
EconomyType type; ///< economy type (original/smooth/stable)
bool allow_shares; ///< allow the buying/selling of shares
uint8 min_years_for_shares; ///< minimum age of a company for it to trade shares
uint8 feeder_payment_share; ///< percentage of leg payment to virtually pay in feeder systems
Expand Down
15 changes: 10 additions & 5 deletions src/table/settings.ini
Expand Up @@ -1429,12 +1429,17 @@ strhelp = STR_CONFIG_SETTING_ENDING_YEAR_HELPTEXT
strval = STR_CONFIG_SETTING_ENDING_YEAR_VALUE
cat = SC_ADVANCED
[SDT_BOOL]
[SDT_VAR]
base = GameSettings
var = economy.smooth_economy
def = true
str = STR_CONFIG_SETTING_SMOOTH_ECONOMY
strhelp = STR_CONFIG_SETTING_SMOOTH_ECONOMY_HELPTEXT
var = economy.type
type = SLE_UINT8
guiflags = SGF_MULTISTRING
def = ET_SMOOTH
min = ET_BEGIN
max = ET_END - 1
str = STR_CONFIG_SETTING_ECONOMY_TYPE
strhelp = STR_CONFIG_SETTING_ECONOMY_TYPE_HELPTEXT
strval = STR_CONFIG_SETTING_ECONOMY_TYPE_ORIGINAL
proc = InvalidateIndustryViewWindow
cat = SC_BASIC
Expand Down

0 comments on commit 9ad15a5

Please sign in to comment.