src/economy_new.h
author celestar
Tue, 13 Mar 2007 15:46:40 +0000
branchgamebalance
changeset 9885 84104c79839f
parent 9884 c1169958d5ff
child 9886 67b675b827c1
permissions -rw-r--r--
(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 */