mirror of https://github.com/OpenTTD/OpenTTD
(svn r17433) -Codechange: Store cumulated inflation in savegame and compute all prices from that instead of storing all prices separately.
Note: Savegame conversion computes the inflation from max loan. Prices from modified savegames will get lost. TTO savegames will also behave slightly different. -Change: NewGRF price modifiers now take effect everytime when loading NewGRFs instead of once on gamestart.release/1.0
parent
2ce1a608a8
commit
438a429549
177
src/economy.cpp
177
src/economy.cpp
|
@ -107,10 +107,9 @@ const ScoreInfo _score_info[] = {
|
||||||
int _score_part[MAX_COMPANIES][SCORE_END];
|
int _score_part[MAX_COMPANIES][SCORE_END];
|
||||||
Economy _economy;
|
Economy _economy;
|
||||||
Prices _price;
|
Prices _price;
|
||||||
uint16 _price_frac[NUM_PRICES];
|
static Money _cargo_payment_rates[NUM_CARGO];
|
||||||
Money _cargo_payment_rates[NUM_CARGO];
|
|
||||||
uint16 _cargo_payment_rates_frac[NUM_CARGO];
|
|
||||||
Money _additional_cash_required;
|
Money _additional_cash_required;
|
||||||
|
static byte _price_base_multiplier[NUM_PRICES];
|
||||||
|
|
||||||
Money CalculateCompanyValue(const Company *c)
|
Money CalculateCompanyValue(const Company *c)
|
||||||
{
|
{
|
||||||
|
@ -585,20 +584,11 @@ static void CompaniesGenStatistics()
|
||||||
InvalidateWindow(WC_COMPANY_LEAGUE, 0);
|
InvalidateWindow(WC_COMPANY_LEAGUE, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AddSingleInflation(Money *value, uint16 *frac, int32 amt)
|
/**
|
||||||
{
|
* Add monthly inflation
|
||||||
/* Is it safe to add inflation ? */
|
* @param check_year Shall the inflation get stopped after 170 years?
|
||||||
if ((INT64_MAX / amt) < (*value + 1)) {
|
*/
|
||||||
*value = INT64_MAX / amt;
|
void AddInflation(bool check_year)
|
||||||
*frac = 0;
|
|
||||||
} else {
|
|
||||||
int64 tmp = (int64)*value * amt + *frac;
|
|
||||||
*frac = GB(tmp, 0, 16);
|
|
||||||
*value += tmp >> 16;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void AddInflation(bool check_year = true)
|
|
||||||
{
|
{
|
||||||
/* The cargo payment inflation differs from the normal inflation, so the
|
/* The cargo payment inflation differs from the normal inflation, so the
|
||||||
* relative amount of money you make with a transport decreases slowly over
|
* relative amount of money you make with a transport decreases slowly over
|
||||||
|
@ -622,23 +612,63 @@ static void AddInflation(bool check_year = true)
|
||||||
* 12 -> months per year
|
* 12 -> months per year
|
||||||
* This is only a good approxiamtion for small values
|
* This is only a good approxiamtion for small values
|
||||||
*/
|
*/
|
||||||
int32 inf = _economy.infl_amount * 54;
|
_economy.inflation_prices += min((_economy.inflation_prices * _economy.infl_amount * 54) >> 16, MAX_INFLATION);
|
||||||
|
_economy.inflation_payment += min((_economy.inflation_payment * _economy.infl_amount_pr * 54) >> 16, MAX_INFLATION);
|
||||||
|
}
|
||||||
|
|
||||||
for (uint i = 0; i != NUM_PRICES; i++) {
|
/**
|
||||||
AddSingleInflation((Money*)&_price + i, _price_frac + i, inf);
|
* Computes all prices, payments and maximum loan.
|
||||||
|
*/
|
||||||
|
void RecomputePrices()
|
||||||
|
{
|
||||||
|
/* Setup maximum loan */
|
||||||
|
_economy.max_loan = (_settings_game.difficulty.max_loan * _economy.inflation_prices >> 16) / 50000 * 50000;
|
||||||
|
|
||||||
|
assert_compile(sizeof(_price) == NUM_PRICES * sizeof(Money));
|
||||||
|
|
||||||
|
/* Setup price bases */
|
||||||
|
for (uint i = 0; i < NUM_PRICES; i++) {
|
||||||
|
Money price = _price_base_specs[i].start_price;
|
||||||
|
|
||||||
|
/* Apply difficulty settings */
|
||||||
|
uint mod = 1;
|
||||||
|
switch (_price_base_specs[i].category) {
|
||||||
|
case PCAT_RUNNING:
|
||||||
|
mod = _settings_game.difficulty.vehicle_costs;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PCAT_CONSTRUCTION:
|
||||||
|
mod = _settings_game.difficulty.construction_cost;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
if (mod < 1) {
|
||||||
|
price = price * 3 >> 2;
|
||||||
|
} else if (mod > 1) {
|
||||||
|
price = price * 9 >> 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Apply inflation */
|
||||||
|
price = (int64)price * _economy.inflation_prices;
|
||||||
|
|
||||||
|
/* Apply newgrf modifiers, and remove fractional part of inflation */
|
||||||
|
int shift = _price_base_multiplier[i] - 8 - 16;
|
||||||
|
if (shift >= 0) {
|
||||||
|
price <<= shift;
|
||||||
|
} else {
|
||||||
|
price >>= -shift;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Store value */
|
||||||
|
((Money *)&_price)[i] = price;
|
||||||
}
|
}
|
||||||
|
|
||||||
AddSingleInflation(&_economy.max_loan_unround, &_economy.max_loan_unround_fract, inf);
|
/* Setup cargo payment */
|
||||||
|
memset(_cargo_payment_rates, 0, sizeof(_cargo_payment_rates));
|
||||||
if (_economy.max_loan + 50000 <= _economy.max_loan_unround) _economy.max_loan += 50000;
|
const CargoSpec *cs;
|
||||||
|
FOR_ALL_CARGOSPECS(cs) {
|
||||||
inf = _economy.infl_amount_pr * 54;
|
_cargo_payment_rates[cs->Index()] = ((int64)cs->initial_payment * _economy.inflation_payment) >> 16;
|
||||||
for (CargoID i = 0; i < NUM_CARGO; i++) {
|
|
||||||
AddSingleInflation(
|
|
||||||
(Money*)_cargo_payment_rates + i,
|
|
||||||
_cargo_payment_rates_frac + i,
|
|
||||||
inf
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
InvalidateWindowClasses(WC_BUILD_VEHICLE);
|
InvalidateWindowClasses(WC_BUILD_VEHICLE);
|
||||||
|
@ -695,8 +725,6 @@ static void HandleEconomyFluctuations()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static byte price_base_multiplier[NUM_PRICES];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reset changes to the price base multipliers.
|
* Reset changes to the price base multipliers.
|
||||||
*/
|
*/
|
||||||
|
@ -706,7 +734,7 @@ void ResetPriceBaseMultipliers()
|
||||||
|
|
||||||
/* 8 means no multiplier. */
|
/* 8 means no multiplier. */
|
||||||
for (i = 0; i < NUM_PRICES; i++)
|
for (i = 0; i < NUM_PRICES; i++)
|
||||||
price_base_multiplier[i] = 8;
|
_price_base_multiplier[i] = 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -719,7 +747,7 @@ void ResetPriceBaseMultipliers()
|
||||||
void SetPriceBaseMultiplier(uint price, byte factor)
|
void SetPriceBaseMultiplier(uint price, byte factor)
|
||||||
{
|
{
|
||||||
assert(price < NUM_PRICES);
|
assert(price < NUM_PRICES);
|
||||||
price_base_multiplier[price] = factor;
|
_price_base_multiplier[price] = min(factor, MAX_PRICE_MODIFIER);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -745,82 +773,24 @@ void StartupIndustryDailyChanges(bool init_counter)
|
||||||
|
|
||||||
void StartupEconomy()
|
void StartupEconomy()
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
|
|
||||||
assert_compile(sizeof(_price) == NUM_PRICES * sizeof(Money));
|
|
||||||
|
|
||||||
/* Setup price bases */
|
|
||||||
for (i = 0; i < NUM_PRICES; i++) {
|
|
||||||
Money price = _price_base_specs[i].start_price;
|
|
||||||
|
|
||||||
/* Apply difficulty settings */
|
|
||||||
uint mod = 1;
|
|
||||||
switch (_price_base_specs[i].category) {
|
|
||||||
case PCAT_RUNNING:
|
|
||||||
mod = _settings_game.difficulty.vehicle_costs;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PCAT_CONSTRUCTION:
|
|
||||||
mod = _settings_game.difficulty.construction_cost;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
if (mod < 1) {
|
|
||||||
price = price * 3 >> 2;
|
|
||||||
} else if (mod > 1) {
|
|
||||||
price = price * 9 >> 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Apply newgrf modifiers */
|
|
||||||
if (price_base_multiplier[i] > 8) {
|
|
||||||
price <<= price_base_multiplier[i] - 8;
|
|
||||||
} else {
|
|
||||||
price >>= 8 - price_base_multiplier[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Store start value */
|
|
||||||
((Money*)&_price)[i] = price;
|
|
||||||
_price_frac[i] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
_economy.interest_rate = _settings_game.difficulty.initial_interest;
|
_economy.interest_rate = _settings_game.difficulty.initial_interest;
|
||||||
_economy.infl_amount = _settings_game.difficulty.initial_interest;
|
_economy.infl_amount = _settings_game.difficulty.initial_interest;
|
||||||
_economy.infl_amount_pr = max(0, _settings_game.difficulty.initial_interest - 1);
|
_economy.infl_amount_pr = max(0, _settings_game.difficulty.initial_interest - 1);
|
||||||
_economy.max_loan_unround = _economy.max_loan = _settings_game.difficulty.max_loan;
|
|
||||||
_economy.fluct = GB(Random(), 0, 8) + 168;
|
_economy.fluct = GB(Random(), 0, 8) + 168;
|
||||||
|
|
||||||
|
/* Set up prices */
|
||||||
|
RecomputePrices();
|
||||||
|
|
||||||
StartupIndustryDailyChanges(true); // As we are starting a new game, initialize the counter too
|
StartupIndustryDailyChanges(true); // As we are starting a new game, initialize the counter too
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResetEconomy()
|
/**
|
||||||
|
* Resets economy to initial values
|
||||||
|
*/
|
||||||
|
void InitializeEconomy()
|
||||||
{
|
{
|
||||||
/* Test if resetting the economy is needed. */
|
_economy.inflation_prices = _economy.inflation_payment = 1 << 16;
|
||||||
bool needed = false;
|
|
||||||
|
|
||||||
const CargoSpec *cs;
|
|
||||||
FOR_ALL_CARGOSPECS(cs) {
|
|
||||||
if (_cargo_payment_rates[cs->Index()] == 0) {
|
|
||||||
needed = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!needed) return;
|
|
||||||
|
|
||||||
/* Remember old unrounded maximum loan value. NewGRF has the ability
|
|
||||||
* to change all the other inflation affected base costs. */
|
|
||||||
Money old_value = _economy.max_loan_unround;
|
|
||||||
|
|
||||||
/* Reset the economy */
|
|
||||||
StartupEconomy();
|
|
||||||
InitializeLandscapeVariables(false);
|
|
||||||
|
|
||||||
/* Reapply inflation, ignoring the year */
|
|
||||||
while (old_value > _economy.max_loan_unround) {
|
|
||||||
AddInflation(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Money GetPriceByIndex(uint8 index)
|
Money GetPriceByIndex(uint8 index)
|
||||||
|
@ -1415,7 +1385,10 @@ void LoadUnloadStation(Station *st)
|
||||||
void CompaniesMonthlyLoop()
|
void CompaniesMonthlyLoop()
|
||||||
{
|
{
|
||||||
CompaniesGenStatistics();
|
CompaniesGenStatistics();
|
||||||
if (_settings_game.economy.inflation) AddInflation();
|
if (_settings_game.economy.inflation) {
|
||||||
|
AddInflation();
|
||||||
|
RecomputePrices();
|
||||||
|
}
|
||||||
CompaniesPayInterest();
|
CompaniesPayInterest();
|
||||||
/* Reset the _current_company flag */
|
/* Reset the _current_company flag */
|
||||||
_current_company = OWNER_NONE;
|
_current_company = OWNER_NONE;
|
||||||
|
|
|
@ -24,16 +24,12 @@
|
||||||
|
|
||||||
void ResetPriceBaseMultipliers();
|
void ResetPriceBaseMultipliers();
|
||||||
void SetPriceBaseMultiplier(uint price, byte factor);
|
void SetPriceBaseMultiplier(uint price, byte factor);
|
||||||
void ResetEconomy();
|
|
||||||
|
|
||||||
extern const ScoreInfo _score_info[];
|
extern const ScoreInfo _score_info[];
|
||||||
extern int _score_part[MAX_COMPANIES][SCORE_END];
|
extern int _score_part[MAX_COMPANIES][SCORE_END];
|
||||||
extern Economy _economy;
|
extern Economy _economy;
|
||||||
/* Prices and also the fractional part. */
|
/* Prices and also the fractional part. */
|
||||||
extern Prices _price;
|
extern Prices _price;
|
||||||
extern uint16 _price_frac[NUM_PRICES];
|
|
||||||
extern Money _cargo_payment_rates[NUM_CARGO];
|
|
||||||
extern uint16 _cargo_payment_rates_frac[NUM_CARGO];
|
|
||||||
|
|
||||||
int UpdateCompanyRatingAndValue(Company *c, bool update);
|
int UpdateCompanyRatingAndValue(Company *c, bool update);
|
||||||
void StartupIndustryDailyChanges(bool init_counter);
|
void StartupIndustryDailyChanges(bool init_counter);
|
||||||
|
@ -46,4 +42,8 @@ void LoadUnloadStation(Station *st);
|
||||||
|
|
||||||
Money GetPriceByIndex(uint8 index);
|
Money GetPriceByIndex(uint8 index);
|
||||||
|
|
||||||
|
void InitializeEconomy();
|
||||||
|
void RecomputePrices();
|
||||||
|
void AddInflation(bool check_year = true);
|
||||||
|
|
||||||
#endif /* ECONOMY_FUNC_H */
|
#endif /* ECONOMY_FUNC_H */
|
||||||
|
|
|
@ -19,15 +19,19 @@
|
||||||
typedef OverflowSafeInt64 Money;
|
typedef OverflowSafeInt64 Money;
|
||||||
|
|
||||||
struct Economy {
|
struct Economy {
|
||||||
Money max_loan; ///< Maximum possible loan
|
Money max_loan; ///< NOSAVE: Maximum possible loan
|
||||||
Money max_loan_unround; ///< Economy fluctuation status
|
int16 fluct; ///< Economy fluctuation status
|
||||||
uint16 max_loan_unround_fract; ///< Fraction of the unrounded max loan
|
|
||||||
int16 fluct;
|
|
||||||
byte interest_rate; ///< Interest
|
byte interest_rate; ///< Interest
|
||||||
byte infl_amount; ///< inflation amount
|
byte infl_amount; ///< inflation amount
|
||||||
byte infl_amount_pr; ///< inflation rate for payment rates
|
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_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
|
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
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ScoreID {
|
enum ScoreID {
|
||||||
|
@ -149,6 +153,23 @@ struct PriceBaseSpec {
|
||||||
/** The "steps" in loan size, in British Pounds! */
|
/** The "steps" in loan size, in British Pounds! */
|
||||||
static const int LOAN_INTERVAL = 10000;
|
static const int LOAN_INTERVAL = 10000;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maximum inflation (including fractional part) without causing overflows in int64 price computations.
|
||||||
|
* This allows for 32 bit base prices (21 are currently needed).
|
||||||
|
* Considering the sign bit and 16 fractional bits, there are 15 bits left.
|
||||||
|
* 170 years of 4% inflation result in a inflation of about 822, so 10 bits are actually enough.
|
||||||
|
* Note, that NewGRF multipliers share the 16 fractional bits.
|
||||||
|
* @see MAX_PRICE_MODIFIER
|
||||||
|
*/
|
||||||
|
static const uint64 MAX_INFLATION = (1ull << (63 - 32)) - 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maximum NewGRF price modifier including the shift offset of 8 bits.
|
||||||
|
* Increasing base prices by factor 65536 should be enough.
|
||||||
|
* @see MAX_INFLATION
|
||||||
|
*/
|
||||||
|
static const int MAX_PRICE_MODIFIER = 16 + 8;
|
||||||
|
|
||||||
struct CargoPayment;
|
struct CargoPayment;
|
||||||
typedef uint32 CargoPaymentID;
|
typedef uint32 CargoPaymentID;
|
||||||
|
|
||||||
|
|
|
@ -29,8 +29,6 @@ void SubtractMoneyFromCompanyFract(CompanyID company, CommandCost cost);
|
||||||
bool CheckOwnership(Owner owner);
|
bool CheckOwnership(Owner owner);
|
||||||
bool CheckTileOwnership(TileIndex tile);
|
bool CheckTileOwnership(TileIndex tile);
|
||||||
|
|
||||||
void InitializeLandscapeVariables(bool only_constants);
|
|
||||||
|
|
||||||
/* misc functions */
|
/* misc functions */
|
||||||
/**
|
/**
|
||||||
* Mark a tile given by its index dirty for repaint.
|
* Mark a tile given by its index dirty for repaint.
|
||||||
|
|
17
src/misc.cpp
17
src/misc.cpp
|
@ -121,7 +121,7 @@ void InitializeGame(uint size_x, uint size_y, bool reset_date, bool reset_settin
|
||||||
#endif /* ENABLE_NETWORK */
|
#endif /* ENABLE_NETWORK */
|
||||||
InitializeAnimatedTiles();
|
InitializeAnimatedTiles();
|
||||||
|
|
||||||
InitializeLandscapeVariables(false);
|
InitializeEconomy();
|
||||||
|
|
||||||
ResetObjectToPlace();
|
ResetObjectToPlace();
|
||||||
|
|
||||||
|
@ -132,18 +132,3 @@ void InitializeGame(uint size_x, uint size_y, bool reset_date, bool reset_settin
|
||||||
GamelogGRFAddList(_grfconfig);
|
GamelogGRFAddList(_grfconfig);
|
||||||
GamelogStopAction();
|
GamelogStopAction();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Calculate constants that depend on the landscape type. */
|
|
||||||
void InitializeLandscapeVariables(bool only_constants)
|
|
||||||
{
|
|
||||||
if (only_constants) return;
|
|
||||||
|
|
||||||
memset(_cargo_payment_rates, 0, sizeof(_cargo_payment_rates));
|
|
||||||
memset(_cargo_payment_rates_frac, 0, sizeof(_cargo_payment_rates_frac));
|
|
||||||
|
|
||||||
const CargoSpec *cs;
|
|
||||||
FOR_ALL_CARGOSPECS(cs) {
|
|
||||||
_cargo_payment_rates[cs->Index()] = cs->initial_payment;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -234,6 +234,8 @@ static void InitializeWindowsAndCaches()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RecomputePrices();
|
||||||
|
|
||||||
SetCachedEngineCounts();
|
SetCachedEngineCounts();
|
||||||
|
|
||||||
Station::RecomputeIndustriesNearForAll();
|
Station::RecomputeIndustriesNearForAll();
|
||||||
|
@ -530,9 +532,6 @@ bool AfterLoadGame()
|
||||||
/* Connect front and rear engines of multiheaded trains */
|
/* Connect front and rear engines of multiheaded trains */
|
||||||
ConnectMultiheadedTrains();
|
ConnectMultiheadedTrains();
|
||||||
|
|
||||||
/* reinit the landscape variables (landscape might have changed) */
|
|
||||||
InitializeLandscapeVariables(true);
|
|
||||||
|
|
||||||
/* Update all vehicles */
|
/* Update all vehicles */
|
||||||
AfterLoadVehicles(true);
|
AfterLoadVehicles(true);
|
||||||
|
|
||||||
|
@ -1929,6 +1928,24 @@ bool AfterLoadGame()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (CheckSavegameVersion(126)) {
|
||||||
|
/* Recompute inflation based on old unround loan limit
|
||||||
|
* Note: Max loan is 500000. With an inflation of 4% across 170 years
|
||||||
|
* that results in a max loan of about 0.7 * 2^31.
|
||||||
|
* So taking the 16 bit fractional part into account there are plenty of bits left
|
||||||
|
* for unmodified savegames ...
|
||||||
|
*/
|
||||||
|
uint64 aimed_inflation = (_economy.old_max_loan_unround << 16 | _economy.old_max_loan_unround_fract) / _settings_game.difficulty.max_loan;
|
||||||
|
|
||||||
|
/* ... well, just clamp it then. */
|
||||||
|
if (aimed_inflation > MAX_INFLATION) aimed_inflation = MAX_INFLATION;
|
||||||
|
|
||||||
|
/* Simulate the inflation, so we also get the payment inflation */
|
||||||
|
while (_economy.inflation_prices < aimed_inflation) {
|
||||||
|
AddInflation(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
AfterLoadLabelMaps();
|
AfterLoadLabelMaps();
|
||||||
|
|
||||||
GamelogPrintDebug(1);
|
GamelogPrintDebug(1);
|
||||||
|
@ -1950,7 +1967,7 @@ void ReloadNewGRFData()
|
||||||
/* reload grf data */
|
/* reload grf data */
|
||||||
GfxLoadSprites();
|
GfxLoadSprites();
|
||||||
LoadStringWidthTable();
|
LoadStringWidthTable();
|
||||||
ResetEconomy();
|
RecomputePrices();
|
||||||
/* reload vehicles */
|
/* reload vehicles */
|
||||||
ResetVehiclePosHash();
|
ResetVehiclePosHash();
|
||||||
AfterLoadVehicles(false);
|
AfterLoadVehicles(false);
|
||||||
|
|
|
@ -15,29 +15,31 @@
|
||||||
|
|
||||||
#include "saveload.h"
|
#include "saveload.h"
|
||||||
|
|
||||||
/** Prices */
|
/** Prices in pre 126 savegames */
|
||||||
static void SaveLoad_PRIC()
|
static void Load_PRIC()
|
||||||
{
|
{
|
||||||
int vt = CheckSavegameVersion(65) ? (SLE_FILE_I32 | SLE_VAR_I64) : SLE_INT64;
|
int vt = CheckSavegameVersion(65) ? SLE_FILE_I32 : SLE_FILE_I64;
|
||||||
SlArray(&_price, NUM_PRICES, vt);
|
SlArray(NULL, NUM_PRICES, vt | SLE_VAR_NULL);
|
||||||
SlArray(&_price_frac, NUM_PRICES, SLE_UINT16);
|
SlArray(NULL, NUM_PRICES, SLE_FILE_U16 | SLE_VAR_NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Cargo payment rates */
|
/** Cargo payment rates in pre 126 savegames */
|
||||||
static void SaveLoad_CAPR()
|
static void Load_CAPR()
|
||||||
{
|
{
|
||||||
uint num_cargo = CheckSavegameVersion(55) ? 12 : NUM_CARGO;
|
uint num_cargo = CheckSavegameVersion(55) ? 12 : NUM_CARGO;
|
||||||
int vt = CheckSavegameVersion(65) ? (SLE_FILE_I32 | SLE_VAR_I64) : SLE_INT64;
|
int vt = CheckSavegameVersion(65) ? SLE_FILE_I32 : SLE_FILE_I64;
|
||||||
SlArray(&_cargo_payment_rates, num_cargo, vt);
|
SlArray(NULL, num_cargo, vt | SLE_VAR_NULL);
|
||||||
SlArray(&_cargo_payment_rates_frac, num_cargo, SLE_UINT16);
|
SlArray(NULL, num_cargo, SLE_FILE_U16 | SLE_VAR_NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const SaveLoad _economy_desc[] = {
|
static const SaveLoad _economy_desc[] = {
|
||||||
SLE_CONDVAR(Economy, max_loan, SLE_FILE_I32 | SLE_VAR_I64, 0, 64),
|
SLE_CONDNULL(4, 0, 64), // max_loan
|
||||||
SLE_CONDVAR(Economy, max_loan, SLE_INT64, 65, SL_MAX_VERSION),
|
SLE_CONDNULL(8, 65, SL_MAX_VERSION), // max_loan
|
||||||
SLE_CONDVAR(Economy, max_loan_unround, SLE_FILE_I32 | SLE_VAR_I64, 0, 64),
|
SLE_CONDVAR(Economy, old_max_loan_unround, SLE_FILE_I32 | SLE_VAR_I64, 0, 64),
|
||||||
SLE_CONDVAR(Economy, max_loan_unround, SLE_INT64, 65, SL_MAX_VERSION),
|
SLE_CONDVAR(Economy, old_max_loan_unround, SLE_INT64, 65, 125),
|
||||||
SLE_CONDVAR(Economy, max_loan_unround_fract, SLE_UINT16, 70, SL_MAX_VERSION),
|
SLE_CONDVAR(Economy, old_max_loan_unround_fract, SLE_UINT16, 70, 125),
|
||||||
|
SLE_CONDVAR(Economy, inflation_prices, SLE_UINT64, 126, SL_MAX_VERSION),
|
||||||
|
SLE_CONDVAR(Economy, inflation_payment, SLE_UINT64, 126, SL_MAX_VERSION),
|
||||||
SLE_VAR(Economy, fluct, SLE_INT16),
|
SLE_VAR(Economy, fluct, SLE_INT16),
|
||||||
SLE_VAR(Economy, interest_rate, SLE_UINT8),
|
SLE_VAR(Economy, interest_rate, SLE_UINT8),
|
||||||
SLE_VAR(Economy, infl_amount, SLE_UINT8),
|
SLE_VAR(Economy, infl_amount, SLE_UINT8),
|
||||||
|
@ -97,7 +99,7 @@ static void Ptrs_CAPY()
|
||||||
|
|
||||||
extern const ChunkHandler _economy_chunk_handlers[] = {
|
extern const ChunkHandler _economy_chunk_handlers[] = {
|
||||||
{ 'CAPY', Save_CAPY, Load_CAPY, Ptrs_CAPY, CH_ARRAY},
|
{ 'CAPY', Save_CAPY, Load_CAPY, Ptrs_CAPY, CH_ARRAY},
|
||||||
{ 'PRIC', SaveLoad_PRIC, SaveLoad_PRIC, NULL, CH_RIFF | CH_AUTO_LENGTH},
|
{ 'PRIC', NULL, Load_PRIC, NULL, CH_RIFF | CH_AUTO_LENGTH},
|
||||||
{ 'CAPR', SaveLoad_CAPR, SaveLoad_CAPR, NULL, CH_RIFF | CH_AUTO_LENGTH},
|
{ 'CAPR', NULL, Load_CAPR, NULL, CH_RIFF | CH_AUTO_LENGTH},
|
||||||
{ 'ECMY', Save_ECMY, Load_ECMY, NULL, CH_RIFF | CH_LAST},
|
{ 'ECMY', Save_ECMY, Load_ECMY, NULL, CH_RIFF | CH_LAST},
|
||||||
};
|
};
|
||||||
|
|
|
@ -669,76 +669,6 @@ static bool LoadOldDepot(LoadgameState *ls, int num)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32 _old_price;
|
|
||||||
static uint16 _old_price_frac;
|
|
||||||
static const OldChunks price_chunk[] = {
|
|
||||||
OCL_VAR ( OC_INT32, 1, &_old_price ),
|
|
||||||
OCL_VAR ( OC_UINT16, 1, &_old_price_frac ),
|
|
||||||
OCL_END()
|
|
||||||
};
|
|
||||||
|
|
||||||
static bool LoadOldPrice(LoadgameState *ls, int num)
|
|
||||||
{
|
|
||||||
if (_savegame_type == SGT_TTO && num == 25) {
|
|
||||||
/* clear_fields == build_road_depot (TTO didn't have this price) */
|
|
||||||
((Money*)&_price)[25] = ((Money*)&_price)[6];
|
|
||||||
_price_frac[25] = _price_frac[6];
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!LoadChunk(ls, NULL, price_chunk)) return false;
|
|
||||||
|
|
||||||
if (_savegame_type == SGT_TTO) {
|
|
||||||
/* base prices are different in these two cases */
|
|
||||||
if (num == 15) _old_price = ClampToI32(((Money)_old_price) * 20 / 3); // build_railvehicle
|
|
||||||
if (num == 17) _old_price = ClampToI32(((Money)_old_price) * 10); // aircraft_base
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* We use a struct to store the prices, but they are ints in a row..
|
|
||||||
* so just access the struct as an array of int32s */
|
|
||||||
((Money*)&_price)[num] = _old_price;
|
|
||||||
_price_frac[num] = _old_price_frac;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const OldChunks cargo_payment_rate_chunk[] = {
|
|
||||||
OCL_VAR ( OC_INT32, 1, &_old_price ),
|
|
||||||
OCL_VAR ( OC_UINT16, 1, &_old_price_frac ),
|
|
||||||
|
|
||||||
OCL_NULL( 2 ), ///< Junk
|
|
||||||
OCL_END()
|
|
||||||
};
|
|
||||||
|
|
||||||
static bool LoadOldCargoPaymentRate(LoadgameState *ls, int num)
|
|
||||||
{
|
|
||||||
if (_savegame_type == SGT_TTO && num == 11) { // TTD has 1 more cargo type
|
|
||||||
_cargo_payment_rates[num] = _cargo_payment_rates[9];
|
|
||||||
_cargo_payment_rates_frac[num] = _cargo_payment_rates_frac[9];
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!LoadChunk(ls, NULL, cargo_payment_rate_chunk)) return false;
|
|
||||||
|
|
||||||
if (_savegame_type == SGT_TTO) {
|
|
||||||
/* SVXConverter about cargo payment rates correction:
|
|
||||||
* "increase them to compensate for the faster time advance in TTD compared to TTO
|
|
||||||
* which otherwise would cause much less income while the annual running costs of
|
|
||||||
* the vehicles stay the same" */
|
|
||||||
|
|
||||||
Money m = ((((Money)_old_price) << 16) + (uint)_old_price_frac) * 124 / 74;
|
|
||||||
|
|
||||||
_old_price = m >> 16;
|
|
||||||
_old_price_frac = GB((int64)m, 0, 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
_cargo_payment_rates[num] = -_old_price;
|
|
||||||
_cargo_payment_rates_frac[num] = _old_price_frac;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static StationID _current_station_id;
|
static StationID _current_station_id;
|
||||||
static uint16 _waiting_acceptance;
|
static uint16 _waiting_acceptance;
|
||||||
static uint8 _cargo_source;
|
static uint8 _cargo_source;
|
||||||
|
@ -1670,11 +1600,13 @@ static const OldChunks main_chunk[] = {
|
||||||
|
|
||||||
OCL_ASSERT( OC_TTO, 0x3A2E ),
|
OCL_ASSERT( OC_TTO, 0x3A2E ),
|
||||||
|
|
||||||
OCL_CHUNK( 49, LoadOldPrice ),
|
OCL_CNULL( OC_TTO, 48 * 6 ), ///< prices
|
||||||
|
OCL_CNULL( OC_TTD, 49 * 6 ), ///< prices
|
||||||
|
|
||||||
OCL_ASSERT( OC_TTO, 0x3B4E ),
|
OCL_ASSERT( OC_TTO, 0x3B4E ),
|
||||||
|
|
||||||
OCL_CHUNK( 12, LoadOldCargoPaymentRate ),
|
OCL_CNULL( OC_TTO, 11 * 8 ), ///< cargo payment rates
|
||||||
|
OCL_CNULL( OC_TTD, 12 * 8 ), ///< cargo payment rates
|
||||||
|
|
||||||
OCL_ASSERT( OC_TTD, 0x4CBA ),
|
OCL_ASSERT( OC_TTD, 0x4CBA ),
|
||||||
OCL_ASSERT( OC_TTO, 0x3BA6 ),
|
OCL_ASSERT( OC_TTO, 0x3BA6 ),
|
||||||
|
@ -1735,19 +1667,19 @@ static const OldChunks main_chunk[] = {
|
||||||
OCL_VAR ( OC_FILE_I16 | OC_VAR_I32, 1, &_saved_scrollpos_y ),
|
OCL_VAR ( OC_FILE_I16 | OC_VAR_I32, 1, &_saved_scrollpos_y ),
|
||||||
OCL_VAR ( OC_FILE_U16 | OC_VAR_U8, 1, &_saved_scrollpos_zoom ),
|
OCL_VAR ( OC_FILE_U16 | OC_VAR_U8, 1, &_saved_scrollpos_zoom ),
|
||||||
|
|
||||||
OCL_VAR ( OC_FILE_U32 | OC_VAR_I64, 1, &_economy.max_loan ),
|
OCL_NULL( 4 ), ///< max_loan
|
||||||
OCL_VAR ( OC_FILE_U32 | OC_VAR_I64, 1, &_economy.max_loan_unround ),
|
OCL_VAR ( OC_FILE_U32 | OC_VAR_I64, 1, &_economy.old_max_loan_unround ),
|
||||||
OCL_VAR ( OC_INT16, 1, &_economy.fluct ),
|
OCL_VAR ( OC_INT16, 1, &_economy.fluct ),
|
||||||
|
|
||||||
OCL_VAR ( OC_UINT16, 1, &_disaster_delay ),
|
OCL_VAR ( OC_UINT16, 1, &_disaster_delay ),
|
||||||
|
|
||||||
OCL_ASSERT( OC_TTO, 0x496E4 ),
|
OCL_ASSERT( OC_TTO, 0x496E4 ),
|
||||||
|
|
||||||
OCL_CNULL( OC_TTD, 144 ), ///< cargo-stuff, calculated in InitializeLandscapeVariables
|
OCL_CNULL( OC_TTD, 144 ), ///< cargo-stuff
|
||||||
|
|
||||||
OCL_CCHUNK( OC_TTD, 256, LoadOldEngineName ),
|
OCL_CCHUNK( OC_TTD, 256, LoadOldEngineName ),
|
||||||
|
|
||||||
OCL_CNULL( OC_TTD, 144 ), ///< AI cargo-stuff, calculated in InitializeLandscapeVariables
|
OCL_CNULL( OC_TTD, 144 ), ///< AI cargo-stuff
|
||||||
OCL_NULL( 2 ), ///< Company indexes of companies, no longer in use
|
OCL_NULL( 2 ), ///< Company indexes of companies, no longer in use
|
||||||
OCL_NULL( 1 ), ///< Station tick counter, no longer in use
|
OCL_NULL( 1 ), ///< Station tick counter, no longer in use
|
||||||
|
|
||||||
|
@ -1778,7 +1710,7 @@ static const OldChunks main_chunk[] = {
|
||||||
OCL_VAR ( OC_TTD | OC_UINT8, 1, &_settings_game.game_creation.snow_line ),
|
OCL_VAR ( OC_TTD | OC_UINT8, 1, &_settings_game.game_creation.snow_line ),
|
||||||
|
|
||||||
OCL_CNULL( OC_TTD, 32 ), ///< new_industry_randtable, no longer used (because of new design)
|
OCL_CNULL( OC_TTD, 32 ), ///< new_industry_randtable, no longer used (because of new design)
|
||||||
OCL_CNULL( OC_TTD, 36 ), ///< cargo-stuff, calculated in InitializeLandscapeVariables
|
OCL_CNULL( OC_TTD, 36 ), ///< cargo-stuff
|
||||||
|
|
||||||
OCL_ASSERT( OC_TTD, 0x77179 ),
|
OCL_ASSERT( OC_TTD, 0x77179 ),
|
||||||
OCL_ASSERT( OC_TTO, 0x4971D ),
|
OCL_ASSERT( OC_TTO, 0x4971D ),
|
||||||
|
@ -1865,6 +1797,12 @@ bool LoadTTOMain(LoadgameState *ls)
|
||||||
/* We have a new difficulty setting */
|
/* We have a new difficulty setting */
|
||||||
_settings_game.difficulty.town_council_tolerance = Clamp(_settings_game.difficulty.diff_level, 0, 2);
|
_settings_game.difficulty.town_council_tolerance = Clamp(_settings_game.difficulty.diff_level, 0, 2);
|
||||||
|
|
||||||
|
/* SVXConverter about cargo payment rates correction:
|
||||||
|
* "increase them to compensate for the faster time advance in TTD compared to TTO
|
||||||
|
* which otherwise would cause much less income while the annual running costs of
|
||||||
|
* the vehicles stay the same" */
|
||||||
|
_economy.inflation_payment = min(_economy.inflation_payment * 124 / 74, MAX_INFLATION);
|
||||||
|
|
||||||
DEBUG(oldloader, 3, "Finished converting game data");
|
DEBUG(oldloader, 3, "Finished converting game data");
|
||||||
DEBUG(oldloader, 1, "TTO savegame successfully converted");
|
DEBUG(oldloader, 1, "TTO savegame successfully converted");
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,7 @@
|
||||||
|
|
||||||
#include "saveload_internal.h"
|
#include "saveload_internal.h"
|
||||||
|
|
||||||
extern const uint16 SAVEGAME_VERSION = 125;
|
extern const uint16 SAVEGAME_VERSION = 126;
|
||||||
|
|
||||||
SavegameType _savegame_type; ///< type of savegame we are loading
|
SavegameType _savegame_type; ///< type of savegame we are loading
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue