(svn r9141) [gamebalance] -Add: Random events that can occur monthly and affect the economy as a whole (i.e. are not local to a town or industry)
/* $Id$ */
/** @file */
#ifndef ECONOMY_NEW_H
#define ECONOMY_NEW_H
#include "debug.h" // debug outputs
#include "fixedt.h" // FixedT data types
#include "date.h" // current year / date
#include "variables.h" // difficulty
#include "functions.h" // RandomRange
/**
* Handles all the economic data and events
*/
class CEconomy {
private:
FixedT<int32, 16> m_basic_growth; ///< Basic growth number, depends solely on difficulty setting
FixedT<int64, 16> m_activity_level; ///< Economic Activity Level, an indicator for the GDP per capita of the map
byte m_long_term_cycle; ///< The period of the long-term cycle suggested by Kondratiev
byte m_short_term_cycle; ///< The period of the short-term cycle (see Juglar, others)
FixedT<int32, 16> m_long_term_ampl; ///< Amplitude of the long-term cycle
FixedT<int32, 16> m_short_term_ampl; ///< Amplitude of the short-term cycle
public:
/**
* Starts the economy. This sets the basic growth by the difficulty level and adjust the current
* EAL by the year of the game. We also set the economic cycles here.
* @warning This should be run once per game only
*/
CEconomy() {
/* Set basic growth */
FixedT<int32, 16> growth(_opt.diff.economic_growth, 2);
m_basic_growth = (growth + 1) / 100 + 1;
DEBUG(eco, 3, "Starting a new economy with a basic growth factor of %.3f in the year %d", (double)m_basic_growth, _cur_year);
/* Set up the economic cycles */
m_long_term_cycle = RandomRange(15) + 45;
m_short_term_cycle = RandomRange(4) + 6;
m_long_term_ampl = RandomRange(5) + 10;
m_short_term_ampl = RandomRange(10) + 15;
m_long_term_ampl /= 1000;
m_short_term_ampl /= 1000;
DEBUG(eco, 4, "Adjusting economic cycles to %d and %d years", m_long_term_cycle, m_short_term_cycle);
DEBUG(eco, 4, "Adjusting economic cycles to %f and %f (amplitude)", (double)m_long_term_ampl, (double)m_short_term_ampl);
m_activity_level = 1;
m_activity_level = pow(m_basic_growth, _cur_year - 1820);
DEBUG(eco, 4, "Adjusting basic EAL for current year (offset %d) to %.3f", _cur_year - 1820, (double)m_activity_level);
}
/**
* Removes an economy.
*/
~CEconomy() {
DEBUG(eco, 3, "Ending economy");
}
/**
* Adjusts the economic settings on a yearly level.
*/
void YearlyLoop()
{
FixedT<int32, 16> growth = m_basic_growth;
growth += GetCyclicGrowth();
DEBUG(eco, 3, "Entering the yearly loop for economy");
m_activity_level *= growth;
DEBUG(eco, 4, "Set global EAL to %.3f", (double)m_activity_level);
}
/**
* Adds random events to the economic growth. This should call a random event every
* 20 months. Well at least it should if RandomRange would be distributed in a
* linear fashion. Note that there's one event in RandomEvents with a value of
* -100 that doesn't have a positive "partner". This one simulates a big crash
* or any other catastrohic event (war, disease, terrorism, whatever).
* @todo Add news events for higher modifications in the economy (=> 2%)
*/
void MonthlyLoop()
{
/* Modifications of the global economic activity one-tenth of a percent */
static const int RandomEvents[] = {-1, 1, -2, 2, -5, 5, -10, 10, -12, 12, -15, 15, -20, 20, -25, 25, 32, -32, 50, -50, -100};
/* I didn't use the 19, because it hardly ever is the return of RandomRange for whatever reason */
if (RandomRange(20) != 18) return;
FixedT<int32, 16> mod( RandomEvents[RandomRange(lengthof(RandomEvents))], 1000);
mod += 1;
m_activity_level *= mod;
DEBUG(eco, 5, "Added a random event with a value of %f, adjusted EAL to %f", (double)mod, (double)m_activity_level);
}
/**
* Computes the modification of economic growth by cyclic events
* @return The growth modification
*/
FixedT<int32, 16> GetCyclicGrowth() const
{
FixedT<int32, 16> long_term (PI * 2 * (_cur_year - 1800), m_long_term_cycle);
FixedT<int32, 16> short_term(PI * 2 * (_cur_year - 1800), m_short_term_cycle);
DEBUG(eco, 5, "Cyclic Growth is %.4f", (double)(m_long_term_ampl * cos(long_term) + m_short_term_ampl * cos(short_term)));
return ( m_long_term_ampl * cos(long_term) + m_short_term_ampl * cos(short_term) );
}
};
extern CEconomy *_eco;
void InitializeEconomy();
#endif /* ECONOMY_NEW_H */