Changeset - r24430:e39e393df7ba
[Not reviewed]
master
0 8 0
Pavel Stupnikov - 3 years ago 2020-12-14 22:35:07
dp@dpointer.org
Add: new economy "frozen" that stops production changes and industry closures (#8282)
8 files changed with 54 insertions and 35 deletions:
0 comments (0 inline, 0 general)
src/economy_type.h
Show inline comments
 
/*
 
 * This file is part of OpenTTD.
 
 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
 
 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 
 */
 

	
 
/** @file economy_type.h Types related to the economy. */
 

	
 
#ifndef ECONOMY_TYPE_H
 
#define ECONOMY_TYPE_H
 

	
 
#include "core/overflowsafe_type.hpp"
 
#include "core/enum_type.hpp"
 

	
 
typedef OverflowSafeInt64 Money;
 

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

	
 
/** Data of the economy. */
 
struct Economy {
 
	Money max_loan;                       ///< NOSAVE: Maximum possible loan
 
	int16 fluct;                          ///< Economy fluctuation status
 
	byte interest_rate;                   ///< Interest
 
	byte infl_amount;                     ///< inflation amount
 
	byte infl_amount_pr;                  ///< inflation rate for payment rates
 
	uint32 industry_daily_change_counter; ///< Bits 31-16 are number of industry to be performed, 15-0 are fractional collected daily
 
	uint32 industry_daily_increment;      ///< The value which will increment industry_daily_change_counter. Computed value. NOSAVE
 
	uint64 inflation_prices;              ///< Cumulated inflation of prices since game start; 16 bit fractional part
 
	uint64 inflation_payment;             ///< Cumulated inflation of cargo paypent since game start; 16 bit fractional part
 

	
 
	/* Old stuff for savegame conversion only */
 
	Money old_max_loan_unround;           ///< Old: Unrounded max loan
 
	uint16 old_max_loan_unround_fract;    ///< Old: Fraction of the unrounded max loan
 
};
 

	
 
/** Score categories in the detailed performance rating. */
 
enum ScoreID {
 
	SCORE_BEGIN      = 0,
 
	SCORE_VEHICLES   = 0,
 
	SCORE_STATIONS   = 1,
 
	SCORE_MIN_PROFIT = 2,
 
	SCORE_MIN_INCOME = 3,
src/industry_cmd.cpp
Show inline comments
 
@@ -1715,50 +1715,50 @@ static void PopulateStationsNearby(Indus
 
 * @param t                   Nearest town.
 
 * @param founder             Founder of the industry; OWNER_NONE in case of random construction.
 
 * @param initial_random_bits Random bits for the industry.
 
 */
 
static void DoCreateNewIndustry(Industry *i, TileIndex tile, IndustryType type, const IndustryTileLayout &layout, size_t layout_index, Town *t, Owner founder, uint16 initial_random_bits)
 
{
 
	const IndustrySpec *indspec = GetIndustrySpec(type);
 

	
 
	i->location = TileArea(tile, 1, 1);
 
	i->type = type;
 
	Industry::IncIndustryTypeCount(type);
 

	
 
	MemCpyT(i->produced_cargo,  indspec->produced_cargo,  lengthof(i->produced_cargo));
 
	MemCpyT(i->production_rate, indspec->production_rate, lengthof(i->production_rate));
 
	MemCpyT(i->accepts_cargo,   indspec->accepts_cargo,   lengthof(i->accepts_cargo));
 

	
 
	MemSetT(i->produced_cargo_waiting,     0, lengthof(i->produced_cargo_waiting));
 
	MemSetT(i->this_month_production,      0, lengthof(i->this_month_production));
 
	MemSetT(i->this_month_transported,     0, lengthof(i->this_month_transported));
 
	MemSetT(i->last_month_pct_transported, 0, lengthof(i->last_month_pct_transported));
 
	MemSetT(i->last_month_transported,     0, lengthof(i->last_month_transported));
 
	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);
 
		}
 
	}
 

	
 
	i->town = t;
 
	i->owner = OWNER_NONE;
 

	
 
	uint16 r = Random();
 
	i->random_colour = GB(r, 0, 4);
 
	i->counter = GB(r, 4, 12);
 
	i->random = initial_random_bits;
 
	i->was_cargo_delivered = false;
 
	i->last_prod_year = _cur_year;
 
	i->founder = founder;
 

	
 
	i->construction_date = _date;
 
	i->construction_type = (_game_mode == GM_EDITOR) ? ICT_SCENARIO_EDITOR :
 
			(_generating_world ? ICT_MAP_GENERATION : ICT_NORMAL_GAMEPLAY);
 

	
 
	/* Adding 1 here makes it conform to specs of var44 of varaction2 for industries
 
	 * 0 = created prior of newindustries
 
	 * else, chosen layout + 1 */
 
	i->selected_layout = (byte)(layout_index + 1);
 
@@ -2283,49 +2283,49 @@ static void UpdateIndustryStatistics(Ind
 
		if (i->produced_cargo[j] != CT_INVALID) {
 
			byte pct = 0;
 
			if (i->this_month_production[j] != 0) {
 
				i->last_prod_year = _cur_year;
 
				pct = min(i->this_month_transported[j] * 256 / i->this_month_production[j], 255);
 
			}
 
			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;
 
		}
 
	}
 
}
 

	
 
/**
 
 * Recompute #production_rate for current #prod_level.
 
 * This function is only valid when not using smooth economy.
 
 */
 
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++) {
 
		this->production_rate[i] = min(CeilDiv(indspec->production_rate[i] * this->prod_level, PRODLEVEL_DEFAULT), 0xFF);
 
	}
 
}
 

	
 
void Industry::FillCachedName() const
 
{
 
	char buf[256];
 
	int64 args_array[] = { this->index };
 
	StringParameters tmp_params(args_array);
 
	char *end = GetStringWithArgs(buf, STR_INDUSTRY_NAME, &tmp_params, lastof(buf));
 
	this->cached_name.assign(buf, end);
 
}
 

	
 
void ClearAllIndustryCachedNames()
 
{
 
	for (Industry *ind : Industry::Iterate()) {
 
		ind->cached_name.clear();
 
	}
 
}
 

	
 
/**
 
@@ -2583,93 +2583,103 @@ static void ReportNewsProductionChangeIn
 
	SetDParam(1, ind->index);
 
	AddIndustryNewsItem(
 
		percent >= 0 ? STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_SMOOTH : STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_SMOOTH,
 
		nt,
 
		ind->index
 
	);
 
}
 

	
 
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)
 
{
 
	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();
 
	/* use original economy for industries using production related callbacks */
 
	bool original_economy = indspec->UsesOriginalEconomy();
 
	byte div = 0;
 
	byte mul = 0;
 
	int8 increment = 0;
 

	
 
	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);
 
			/* Get the custom message if any */
 
			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 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
 
				case 0x9: case 0xA: case 0xB:     // Multiply production by 4, 8, 16
 
				case 0xC: mul = res - 0x7; break; // Multiply production by 32
 
				case 0xD:                         // decrement production
 
				case 0xE:                         // increment production
 
					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;
 
					break;
 
			}
 
		}
 
	} else {
 
		if (monthly != smooth_economy) return;
 
		if (monthly == original_economy) return;
 
		if (!original_economy && _settings_game.economy.type == ET_FROZEN) 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_SMOOTH) {
 
			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;
 
				}
 

	
 
				/* 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));
 
@@ -2677,62 +2687,53 @@ static void ChangeIndustryProduction(Ind
 

	
 
				/* Prevent production to overflow or Oil Rig passengers to be over-"produced" */
 
				new_prod = Clamp(new_prod, 1, 255);
 

	
 
				if (((indspec->behaviour & INDUSTRYBEH_BUILT_ONWATER) != 0) && j == 1 && !(indspec->behaviour & INDUSTRYBEH_WATER_NO_CLAMP_PROD)) {
 
					new_prod = Clamp(new_prod, 0, 16);
 
				}
 

	
 
				/* 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;
 
				}
 

	
 
				percent = (old_prod == 0) ? 100 : (new_prod * 100 / old_prod - 100);
 
				i->production_rate[j] = new_prod;
 

	
 
				/* Close the industry when it has the lowest possible production rate */
 
				if (new_prod > 1) closeit = false;
 

	
 
				if (abs(percent) >= 10) {
 
					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;
 
		}
 
	}
 

	
 
	/* 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;
 
	}
 

	
 
	/* 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;
 
		}
 
	}
 

	
 
	/* Increase or Decreasing the production level if needed */
 
	if (increment != 0) {
 
@@ -2913,56 +2914,56 @@ bool IndustrySpec::IsProcessingIndustry(
 

	
 
/**
 
 * Get the cost for constructing this industry
 
 * @return the cost (inflation corrected etc)
 
 */
 
Money IndustrySpec::GetConstructionCost() const
 
{
 
	/* Building raw industries like secondary uses different price base */
 
	return (_price[(_settings_game.construction.raw_industry_construction == 1 && this->IsRawIndustry()) ?
 
			PR_BUILD_INDUSTRY_RAW : PR_BUILD_INDUSTRY] * this->cost_multiplier) >> 8;
 
}
 

	
 
/**
 
 * Get the cost for removing this industry
 
 * Take note that the cost will always be zero for non-grf industries.
 
 * Only if the grf author did specified a cost will it be applicable.
 
 * @return the cost (inflation corrected etc)
 
 */
 
Money IndustrySpec::GetRemovalCost() const
 
{
 
	return (_price[PR_CLEAR_INDUSTRY] * this->removal_cost_multiplier) >> 8;
 
}
 

	
 
/**
 
 * 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()
 
{
 
	if (HasBit(this->cleanup_flag, CLEAN_RANDOMSOUNDS)) {
 
		free(this->random_sounds);
 
	}
 
}
 

	
 
static CommandCost TerraformTile_Industry(TileIndex tile, DoCommandFlag flags, int z_new, Slope tileh_new)
 
{
 
	if (AutoslopeEnabled()) {
 
		/* We imitate here TTDP's behaviour:
 
		 *  - Both new and old slope must not be steep.
 
		 *  - TileMaxZ must not be changed.
 
		 *  - Allow autoslope by default.
 
		 *  - Disallow autoslope if callback succeeds and returns non-zero.
 
		 */
 
		Slope tileh_old = GetTileSlope(tile);
 
		/* TileMaxZ must not be changed. Slopes must not be steep. */
 
		if (!IsSteepSlope(tileh_old) && !IsSteepSlope(tileh_new) && (GetTileMaxZ(tile) == z_new + GetSlopeMaxZ(tileh_new))) {
 
			const IndustryGfx gfx = GetIndustryGfx(tile);
 
			const IndustryTileSpec *itspec = GetIndustryTileSpec(gfx);
 

	
src/industry_gui.cpp
Show inline comments
 
@@ -1059,69 +1059,69 @@ public:
 

	
 
			case IL_MULTIPLIER:
 
				i->prod_level = ClampU(RoundDivSU(value * PRODLEVEL_DEFAULT, 100), PRODLEVEL_MINIMUM, PRODLEVEL_MAXIMUM);
 
				break;
 

	
 
			default:
 
				i->production_rate[this->editbox_line - IL_RATE1] = ClampU(RoundDivSU(value, 8), 0, 255);
 
				break;
 
		}
 
		UpdateIndustryProduction(i);
 
		this->SetDirty();
 
	}
 

	
 
	/**
 
	 * Some data on this window has become invalid.
 
	 * @param data Information about the changed data.
 
	 * @param gui_scope Whether the call is done from GUI scope. You may not do everything when not in GUI scope. See #InvalidateWindowData() for details.
 
	 */
 
	void OnInvalidateData(int data = 0, bool gui_scope = true) override
 
	{
 
		if (!gui_scope) return;
 
		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;
 
		}
 
	}
 

	
 
	bool IsNewGRFInspectable() const override
 
	{
 
		return ::IsNewGRFInspectable(GSF_INDUSTRIES, this->window_number);
 
	}
 

	
 
	void ShowNewGRFInspectWindow() const override
 
	{
 
		::ShowNewGRFInspectWindow(GSF_INDUSTRIES, this->window_number);
 
	}
 
};
 

	
 
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) {
 
			i->last_month_production[j] = 8 * i->production_rate[j];
 
		}
 
	}
 
}
 

	
 
/** Widget definition of the view industry gui */
 
static const NWidgetPart _nested_industry_view_widgets[] = {
 
	NWidget(NWID_HORIZONTAL),
 
		NWidget(WWT_CLOSEBOX, COLOUR_CREAM),
 
		NWidget(WWT_CAPTION, COLOUR_CREAM, WID_IV_CAPTION), SetDataTip(STR_INDUSTRY_VIEW_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
 
		NWidget(WWT_DEBUGBOX, COLOUR_CREAM),
 
		NWidget(WWT_SHADEBOX, COLOUR_CREAM),
 
		NWidget(WWT_DEFSIZEBOX, COLOUR_CREAM),
 
		NWidget(WWT_STICKYBOX, COLOUR_CREAM),
 
	EndContainer(),
 
	NWidget(WWT_PANEL, COLOUR_CREAM),
 
		NWidget(WWT_INSET, COLOUR_CREAM), SetPadding(2, 2, 2, 2),
 
			NWidget(NWID_VIEWPORT, INVALID_COLOUR, WID_IV_VIEWPORT), SetMinimalSize(254, 86), SetFill(1, 0), SetPadding(1, 1, 1, 1), SetResize(1, 1),
 
		EndContainer(),
 
	EndContainer(),
 
	NWidget(WWT_PANEL, COLOUR_CREAM, WID_IV_INFO), SetMinimalSize(260, 2), SetResize(1, 0),
src/industrytype.h
Show inline comments
 
@@ -123,49 +123,49 @@ struct IndustrySpec {
 
	IndustryLifeType life_type;                 ///< This is also known as Industry production flag, in newgrf specs
 
	byte climate_availability;                  ///< Bitmask, giving landscape enums as bit position
 
	IndustryBehaviour behaviour;                ///< How this industry will behave, and how others entities can use it
 
	byte map_colour;                            ///< colour used for the small map
 
	StringID name;                              ///< Displayed name of the industry
 
	StringID new_industry_text;                 ///< Message appearing when the industry is built
 
	StringID closure_text;                      ///< Message appearing when the industry closes
 
	StringID production_up_text;                ///< Message appearing when the industry's production is increasing
 
	StringID production_down_text;              ///< Message appearing when the industry's production is decreasing
 
	StringID station_name;                      ///< Default name for nearby station
 
	byte appear_ingame[NUM_LANDSCAPE];          ///< Probability of appearance in game
 
	byte appear_creation[NUM_LANDSCAPE];        ///< Probability of appearance during map creation
 
	uint8 number_of_sounds;                     ///< Number of sounds available in the sounds array
 
	const uint8 *random_sounds;                 ///< array of random sounds.
 
	/* Newgrf data */
 
	uint16 callback_mask;                       ///< Bitmask of industry callbacks that have to be called
 
	uint8 cleanup_flag;                         ///< flags indicating which data should be freed upon cleaning up
 
	bool enabled;                               ///< entity still available (by default true).newgrf can disable it, though
 
	GRFFileProps grf_prop;                      ///< properties related to the grf file
 

	
 
	bool IsRawIndustry() const;
 
	bool IsProcessingIndustry() const;
 
	Money GetConstructionCost() const;
 
	Money GetRemovalCost() const;
 
	bool UsesSmoothEconomy() const;
 
	bool UsesOriginalEconomy() const;
 

	
 
	~IndustrySpec();
 
};
 

	
 
/**
 
 * Defines the data structure of each individual tile of an industry.
 
 * @note A tile can at most accept 3 types of cargo, even if an industry as a whole can accept more types.
 
 */
 
struct IndustryTileSpec {
 
	CargoID accepts_cargo[INDUSTRY_NUM_INPUTS]; ///< Cargo accepted by this tile
 
	int8 acceptance[INDUSTRY_NUM_INPUTS]; ///< Level of acceptance per cargo type (signed, may be negative!)
 
	Slope slopes_refused;                 ///< slope pattern on which this tile cannot be built
 
	byte anim_production;                 ///< Animation frame to start when goods are produced
 
	byte anim_next;                       ///< Next frame in an animation
 
	/**
 
	 * When true, the tile has to be drawn using the animation
 
	 * state instead of the construction state
 
	 */
 
	bool anim_state;
 
	/* Newgrf data */
 
	uint8 callback_mask;                  ///< Bitmask of industry tile callbacks that have to be called
 
	AnimationInfo animation;              ///< Information about the animation (is it looping, how many loops etc)
 
	IndustryTileSpecialFlags special_flags; ///< Bitmask of extra flags used by the tile
 
	bool enabled;                         ///< entity still available (by default true).newgrf can disable it, though
src/lang/english.txt
Show inline comments
 
@@ -1532,50 +1532,53 @@ STR_CONFIG_SETTING_NEWS_INDUSTRY_CHANGES
 
STR_CONFIG_SETTING_NEWS_INDUSTRY_CHANGES_UNSERVED               :Other industry production changes: {STRING2}
 
STR_CONFIG_SETTING_NEWS_INDUSTRY_CHANGES_UNSERVED_HELPTEXT      :Display a newspaper when the production level of industries change, which are not served by the company or competitors
 
STR_CONFIG_SETTING_NEWS_ADVICE                                  :Advice / information on company's vehicles: {STRING2}
 
STR_CONFIG_SETTING_NEWS_ADVICE_HELPTEXT                         :Display messages about vehicles needing attention
 
STR_CONFIG_SETTING_NEWS_NEW_VEHICLES                            :New vehicles: {STRING2}
 
STR_CONFIG_SETTING_NEWS_NEW_VEHICLES_HELPTEXT                   :Display a newspaper when a new vehicle type becomes available
 
STR_CONFIG_SETTING_NEWS_CHANGES_ACCEPTANCE                      :Changes to cargo acceptance: {STRING2}
 
STR_CONFIG_SETTING_NEWS_CHANGES_ACCEPTANCE_HELPTEXT             :Display messages about stations changing acceptance of some cargoes
 
STR_CONFIG_SETTING_NEWS_SUBSIDIES                               :Subsidies: {STRING2}
 
STR_CONFIG_SETTING_NEWS_SUBSIDIES_HELPTEXT                      :Display a newspaper about subsidy related events
 
STR_CONFIG_SETTING_NEWS_GENERAL_INFORMATION                     :General information: {STRING2}
 
STR_CONFIG_SETTING_NEWS_GENERAL_INFORMATION_HELPTEXT            :Display newspaper about general events, such as purchase of exclusive rights or funding of road reconstruction
 

	
 
STR_CONFIG_SETTING_NEWS_MESSAGES_OFF                            :Off
 
STR_CONFIG_SETTING_NEWS_MESSAGES_SUMMARY                        :Summary
 
STR_CONFIG_SETTING_NEWS_MESSAGES_FULL                           :Full
 

	
 
STR_CONFIG_SETTING_COLOURED_NEWS_YEAR                           :Coloured news appears in: {STRING2}
 
STR_CONFIG_SETTING_COLOURED_NEWS_YEAR_HELPTEXT                  :Year that the newspaper announcements get printed in colour. Before this year, it uses monochrome black/white
 
STR_CONFIG_SETTING_STARTING_YEAR                                :Starting year: {STRING2}
 
STR_CONFIG_SETTING_ENDING_YEAR                                  :Scoring end year: {STRING2}
 
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. Frozen economy stops production changes and industry closures. This setting may have 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_FROZEN                          :Frozen
 
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}
 
STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES_HELPTEXT                :Set the minimum age of a company for others to be able to buy and sell shares from them.
 
STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE                         :Percentage of leg profit to pay in feeder systems: {STRING2}
 
STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE_HELPTEXT                :Percentage of income given to the intermediate legs in feeder systems, giving more control over the income
 
STR_CONFIG_SETTING_DRAG_SIGNALS_DENSITY                         :When dragging, place signals every: {STRING2}
 
STR_CONFIG_SETTING_DRAG_SIGNALS_DENSITY_HELPTEXT                :Set the distance at which signals will be built on a track up to the next obstacle (signal, junction), if signals are dragged
 
STR_CONFIG_SETTING_DRAG_SIGNALS_DENSITY_VALUE                   :{COMMA} tile{P 0 "" s}
 
STR_CONFIG_SETTING_DRAG_SIGNALS_FIXED_DISTANCE                  :When dragging, keep fixed distance between signals: {STRING2}
 
STR_CONFIG_SETTING_DRAG_SIGNALS_FIXED_DISTANCE_HELPTEXT         :Select the behaviour of signal placement when Ctrl+dragging signals. If disabled, signals are placed around tunnels or bridges to avoid long stretches without signals. If enabled, signals are placed every n tiles, making alignment of signals at parallel tracks easier
 
STR_CONFIG_SETTING_SEMAPHORE_BUILD_BEFORE_DATE                  :Automatically build semaphores before: {STRING2}
 
STR_CONFIG_SETTING_SEMAPHORE_BUILD_BEFORE_DATE_HELPTEXT         :Set the year when electric signals will be used for tracks. Before this year, non-electric signals will be used (which have the exact same function, but different looks)
 
STR_CONFIG_SETTING_ENABLE_SIGNAL_GUI                            :Enable the signal GUI: {STRING2}
 
STR_CONFIG_SETTING_ENABLE_SIGNAL_GUI_HELPTEXT                   :Display a window for choosing signal types to build, instead of only window-less signal-type rotation with Ctrl+clicking on built signals
 
STR_CONFIG_SETTING_DEFAULT_SIGNAL_TYPE                          :Signal type to build by default: {STRING2}
 
STR_CONFIG_SETTING_DEFAULT_SIGNAL_TYPE_HELPTEXT                 :Default signal type to use
 
STR_CONFIG_SETTING_DEFAULT_SIGNAL_NORMAL                        :Block signals
 
STR_CONFIG_SETTING_DEFAULT_SIGNAL_PBS                           :Path signals
 
STR_CONFIG_SETTING_DEFAULT_SIGNAL_PBSOWAY                       :One-way path signals
 
STR_CONFIG_SETTING_CYCLE_SIGNAL_TYPES                           :Cycle through signal types: {STRING2}
 
STR_CONFIG_SETTING_CYCLE_SIGNAL_TYPES_HELPTEXT                  :Select which signal types to cycle through, when Ctrl+clicking on a build signal with the signal tool
 
STR_CONFIG_SETTING_CYCLE_SIGNAL_NORMAL                          :Block signals only
 
STR_CONFIG_SETTING_CYCLE_SIGNAL_PBS                             :Path signals only
src/settings_gui.cpp
Show inline comments
 
@@ -1708,49 +1708,49 @@ static SettingsContainer &GetSettingsTre
 
			{
 
				authorities->Add(new SettingEntry("difficulty.town_council_tolerance"));
 
				authorities->Add(new SettingEntry("economy.bribe"));
 
				authorities->Add(new SettingEntry("economy.exclusive_rights"));
 
				authorities->Add(new SettingEntry("economy.fund_roads"));
 
				authorities->Add(new SettingEntry("economy.fund_buildings"));
 
				authorities->Add(new SettingEntry("economy.station_noise_level"));
 
			}
 

	
 
			SettingsPage *towns = environment->Add(new SettingsPage(STR_CONFIG_SETTING_ENVIRONMENT_TOWNS));
 
			{
 
				towns->Add(new SettingEntry("economy.town_growth_rate"));
 
				towns->Add(new SettingEntry("economy.allow_town_roads"));
 
				towns->Add(new SettingEntry("economy.allow_town_level_crossings"));
 
				towns->Add(new SettingEntry("economy.found_town"));
 
				towns->Add(new SettingEntry("economy.town_cargogen_mode"));
 
			}
 

	
 
			SettingsPage *industries = environment->Add(new SettingsPage(STR_CONFIG_SETTING_ENVIRONMENT_INDUSTRIES));
 
			{
 
				industries->Add(new SettingEntry("construction.raw_industry_construction"));
 
				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"));
 
			}
 

	
 
			SettingsPage *cdist = environment->Add(new SettingsPage(STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST));
 
			{
 
				cdist->Add(new SettingEntry("linkgraph.recalc_time"));
 
				cdist->Add(new SettingEntry("linkgraph.recalc_interval"));
 
				cdist->Add(new SettingEntry("linkgraph.distribution_pax"));
 
				cdist->Add(new SettingEntry("linkgraph.distribution_mail"));
 
				cdist->Add(new SettingEntry("linkgraph.distribution_armoured"));
 
				cdist->Add(new SettingEntry("linkgraph.distribution_default"));
 
				cdist->Add(new SettingEntry("linkgraph.accuracy"));
 
				cdist->Add(new SettingEntry("linkgraph.demand_distance"));
 
				cdist->Add(new SettingEntry("linkgraph.demand_size"));
 
				cdist->Add(new SettingEntry("linkgraph.short_path_saturation"));
 
			}
 

	
 
			environment->Add(new SettingEntry("station.modified_catchment"));
 
			environment->Add(new SettingEntry("construction.extra_tree_placement"));
 
		}
 

	
 
		SettingsPage *ai = main->Add(new SettingsPage(STR_CONFIG_SETTING_AI));
 
		{
 
			SettingsPage *npc = ai->Add(new SettingsPage(STR_CONFIG_SETTING_AI_NPC));
src/settings_type.h
Show inline comments
 
/*
 
 * This file is part of OpenTTD.
 
 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
 
 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 
 */
 

	
 
/** @file settings_type.h Types related to global configuration settings. */
 

	
 
#ifndef SETTINGS_TYPE_H
 
#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"
 
#include "company_type.h"
 
#include "cargotype.h"
 
#include "linkgraph/linkgraph_type.h"
 
#include "zoom_type.h"
 
#include "openttd.h"
 

	
 

	
 
/** Settings profiles and highscore tables. */
 
enum SettingsProfile {
 
	SP_BEGIN = 0,
 
	SP_EASY = SP_BEGIN,                       ///< Easy difficulty.
 
	SP_MEDIUM,                                ///< Medium difficulty.
 
	SP_HARD,                                  ///< Hard difficulty.
 

	
 
	SP_END,                                   ///< End of setting profiles.
 

	
 
	SP_CUSTOM = SP_END,                       ///< No profile, special "custom" highscore.
 
	SP_SAVED_HIGHSCORE_END,                   ///< End of saved highscore tables.
 

	
 
	SP_MULTIPLAYER = SP_SAVED_HIGHSCORE_END,  ///< Special "multiplayer" highscore. Not saved, always specific to the current game.
 
	SP_HIGHSCORE_END,                         ///< End of highscore tables.
 
@@ -449,49 +450,49 @@ struct VehicleSettings {
 
	uint8  smoke_amount;                     ///< amount of smoke/sparks locomotives produce
 
	uint8  train_acceleration_model;         ///< realistic acceleration for trains
 
	uint8  roadveh_acceleration_model;       ///< realistic acceleration for road vehicles
 
	uint8  train_slope_steepness;            ///< Steepness of hills for trains when using realistic acceleration
 
	uint8  roadveh_slope_steepness;          ///< Steepness of hills for road vehicles when using realistic acceleration
 
	bool   wagon_speed_limits;               ///< enable wagon speed limits
 
	bool   disable_elrails;                  ///< when true, the elrails are disabled
 
	UnitID max_trains;                       ///< max trains in game per company
 
	UnitID max_roadveh;                      ///< max trucks in game per company
 
	UnitID max_aircraft;                     ///< max planes in game per company
 
	UnitID max_ships;                        ///< max ships in game per company
 
	uint8  plane_speed;                      ///< divisor for speed of aircraft
 
	uint8  freight_trains;                   ///< value to multiply the weight of cargo by
 
	bool   dynamic_engines;                  ///< enable dynamic allocation of engine data
 
	bool   never_expire_vehicles;            ///< never expire vehicles
 
	byte   extend_vehicle_life;              ///< extend vehicle life by this many years
 
	byte   road_side;                        ///< the side of the road vehicles drive on
 
	uint8  plane_crashes;                    ///< number of plane crashes, 0 = none, 1 = reduced, 2 = normal
 
};
 

	
 
/** Settings related to the economy. */
 
struct EconomySettings {
 
	bool   inflation;                        ///< disable inflation
 
	bool   bribe;                            ///< enable bribing the local authority
 
	bool   smooth_economy;                   ///< smooth economy
 
	EconomyType type;                        ///< economy type (original/smooth/frozen)
 
	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
 
	byte   dist_local_authority;             ///< distance for town local authority, default 20
 
	bool   exclusive_rights;                 ///< allow buying exclusive rights
 
	bool   fund_buildings;                   ///< allow funding new buildings
 
	bool   fund_roads;                       ///< allow funding local road reconstruction
 
	bool   give_money;                       ///< allow giving other companies money
 
	bool   mod_road_rebuild;                 ///< roadworks remove unnecessary RoadBits
 
	bool   multiple_industry_per_town;       ///< allow many industries of the same type per town
 
	uint8  town_growth_rate;                 ///< town growth rate
 
	uint8  larger_towns;                     ///< the number of cities to build. These start off larger and grow twice as fast
 
	uint8  initial_city_size;                ///< multiplier for the initial size of the cities compared to towns
 
	TownLayout town_layout;                  ///< select town layout, @see TownLayout
 
	TownCargoGenMode town_cargogen_mode;     ///< algorithm for generating cargo from houses, @see TownCargoGenMode
 
	bool   allow_town_roads;                 ///< towns are allowed to build roads (always allowed when generating world / in SE)
 
	TownFounding found_town;                 ///< town founding.
 
	bool   station_noise_level;              ///< build new airports when the town noise level is still within accepted limits
 
	uint16 town_noise_population[3];         ///< population to base decision on noise evaluation (@see town_council_tolerance)
 
	bool   allow_town_level_crossings;       ///< towns are allowed to build level crossings
 
	bool   infrastructure_maintenance;       ///< enable monthly maintenance fee for owner infrastructure
 
};
 

	
 
struct LinkGraphSettings {
src/table/settings.ini
Show inline comments
 
@@ -1408,54 +1408,59 @@ cat      = SC_BASIC
 
name     = ""old_ending_year_slv_105""
 
var      = _old_ending_year_slv_105
 
flags    = SLF_NOT_IN_CONFIG
 
type     = SLE_INT32
 
to       = SLV_105
 
def      = DEF_END_YEAR
 
min      = MIN_YEAR
 
max      = MAX_YEAR
 

	
 
[SDT_VAR]
 
base     = GameSettings
 
var      = game_creation.ending_year
 
type     = SLE_INT32
 
from     = SLV_ENDING_YEAR
 
guiflags = SGF_0ISDISABLED
 
def      = DEF_END_YEAR
 
min      = MIN_YEAR
 
max      = MAX_YEAR
 
interval = 1
 
str      = STR_CONFIG_SETTING_ENDING_YEAR
 
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
 

	
 
[SDT_BOOL]
 
base     = GameSettings
 
var      = economy.allow_shares
 
def      = false
 
str      = STR_CONFIG_SETTING_ALLOW_SHARES
 
strhelp  = STR_CONFIG_SETTING_ALLOW_SHARES_HELPTEXT
 
proc     = InvalidateCompanyWindow
 

	
 
[SDT_VAR]
 
base     = GameSettings
 
var      = economy.min_years_for_shares
 
type     = SLE_UINT8
 
from     = SLV_TRADING_AGE
 
def      = 6
 
min      = 0
 
max      = 255
 
interval = 1
 
str      = STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES
 
strhelp  = STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES_HELPTEXT
 
strval   = STR_JUST_INT
 
cat      = SC_EXPERT
0 comments (0 inline, 0 general)