Subversion Repositories RAND

Rev

Rev 1077 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

// player.cpp

#include "CvGameCoreDLL.h"
#include "CvGlobals.h"
#include "CvArea.h"
#include "CvGameAI.h"
#include "CvMap.h"
#include "CvViewport.h"
#include "CvPlot.h"
#include "CvRandom.h"
#include "CvTeamAI.h"
#include "CvGameCoreUtils.h"
#include "CvPlayerAI.h"
#include "CvPlayer.h"
#include "CvGameCoreUtils.h"
#include "CvArtFileMgr.h"
#include "CvDiploParameters.h"
#include "CvInitCore.h"
#include "CyArgsList.h"
#include "CvInfos.h"
#include "CvPopupInfo.h"
#include "CvDiploParameters.h"
#include "FProfiler.h"
#include "CvGameTextMgr.h"
#include "CyCity.h"
#include "CyPlot.h"
#include "CyUnit.h"
#include "CvEventReporter.h"
#include "CvTaggedSaveFormatWrapper.h"
#include "CvPipeline.h"

#include "CvDLLInterfaceIFaceBase.h"
#include "CvDLLEntityIFaceBase.h"
#include "CvDLLEngineIFaceBase.h"
#include "CvDLLFAStarIFaceBase.h"
#include "CvDLLPythonIFaceBase.h"
/************************************************************************************************/
/* BETTER_BTS_AI_MOD                      05/09/09                                jdog5000      */
/*                                                                                              */
/* General AI                                                                                   */
/************************************************************************************************/
#include "CvDLLFlagEntityIFaceBase.h"
/************************************************************************************************/
/* BETTER_BTS_AI_MOD                       END                                                  */
/************************************************************************************************/
/************************************************************************************************/
/* BETTER_BTS_AI_MOD                      10/02/09                                jdog5000      */
/*                                                                                              */
/* AI logging                                                                                   */
/************************************************************************************************/
#include "BetterBTSAI.h"
/************************************************************************************************/
/* BETTER_BTS_AI_MOD                       END                                                  */
/************************************************************************************************/
#include <math.h>
// BUG - Ignore Harmless Barbarians - start
#include "CvBugOptions.h"
// BUG - Ignore Harmless Barbarians - end
#include "FDataStreamBuffer.h"
#include<hash_map>

//      Koshling - save flag indicating this player has no data in the save as they have never
//      been alive
#define PLAYER_UI_FLAG_OMITTED 2

//#define VALIDATION_FOR_PLOT_GROUPS

//      Helper class used to efficiently cache unit upgrade paths for this player
class CvUpgradeCache
{
        typedef struct upgradePair
        {
                UnitTypes               eFrom;
                UnitClassTypes  eTo;
        } upgradePair;

public:
        CvUpgradeCache(PlayerTypes eOwner)
        {
                m_validUpgrades = NULL;
                m_numUpgrades = 0;
                m_eOwner = eOwner;
        }
        virtual ~CvUpgradeCache()
        {
                SAFE_DELETE_ARRAY(m_validUpgrades);
        }

        bool upgradeAvailable(UnitTypes eFromUnit, UnitClassTypes eToUnitClass)
        {
                PROFILE_FUNC();

                upgradePair     key;

                key.eFrom = eFromUnit;
                key.eTo = eToUnitClass;

                if ( m_validUpgrades == NULL )
                {
                        init();
                }

                return (bsearch((const void*)&key, (const void*)m_validUpgrades, m_numUpgrades, sizeof(upgradePair), upgradePairComparison) != NULL);
        }

private:
        void    init(void)
        {
                PROFILE_FUNC();

                std::list<upgradePair> directUpgrades;
                int iI, iJ;

                //      First populate the direct upgrades
                for(iI = 0; iI < GC.getNumUnitInfos(); iI++)
                {
                        for(iJ = 0; iJ < GC.getNumUnitClassInfos(); iJ++)
                        {
                                if (GC.getUnitInfo((UnitTypes)iI).getUpgradeUnitClass((UnitClassTypes)iJ))
                                {
                                        upgradePair newPair;

                                        newPair.eFrom = (UnitTypes)iI;
                                        newPair.eTo = (UnitClassTypes)iJ;

                                        directUpgrades.push_back(newPair);
                                }
                        }
                }

                std::list<upgradePair> upgrades;

                //      Now walk the direct upgrade links to fully populate the chains
                bool* bUnitUpgrades = new bool[GC.getNumUnitClassInfos()];

                for(iI = 0; iI < GC.getNumUnitInfos(); iI++)
                {
                        memset(bUnitUpgrades,0,sizeof(bool)*GC.getNumUnitClassInfos());

                        populateUpgradeChain((UnitTypes)iI, bUnitUpgrades, directUpgrades);

                        for(iJ = 0; iJ < GC.getNumUnitClassInfos(); iJ++)
                        {
                                if ( bUnitUpgrades[iJ] )
                                {
                                        upgradePair newPair;

                                        newPair.eFrom = (UnitTypes)iI;
                                        newPair.eTo = (UnitClassTypes)iJ;

                                        upgrades.push_back(newPair);
                                }
                        }
                }

                //      Now store them all and sort the array for easy searching
                m_numUpgrades = upgrades.size();
                m_validUpgrades = new upgradePair[m_numUpgrades];

                iI = 0;
                for(std::list<upgradePair>::const_iterator itr = upgrades.begin(); itr != upgrades.end(); ++itr)
                {
                        m_validUpgrades[iI++] = (*itr);
                }

                qsort(m_validUpgrades, m_numUpgrades, sizeof(upgradePair), upgradePairComparison);
        }

        void populateUpgradeChain(UnitTypes eType, bool* abValid, const std::list<upgradePair>& directUpgrades)
        {
                for(std::list<upgradePair>::const_iterator itr = directUpgrades.begin(); itr != directUpgrades.end(); ++itr)
                {
                        if ( (*itr).eFrom == eType )
                        {
                                abValid[(*itr).eTo] = true;
                                populateUpgradeChain((UnitTypes)(GC.getCivilizationInfo(GET_PLAYER(m_eOwner).getCivilizationType()).getCivilizationUnits((*itr).eTo)), abValid, directUpgrades);
                        }
                }
        }

#if 0
        bool upgradeAvailable(UnitTypes eFromUnit, UnitClassTypes eToUnitClass, int iCount)
        {
                UnitTypes eLoopUnit;
                int iI;
                int numUnitClassInfos = GC.getNumUnitClassInfos();

                if (iCount > numUnitClassInfos)
                {
                        return false;
                }

                CvUnitInfo &fromUnitInfo = GC.getUnitInfo(eFromUnit);
                CvCivilizationInfo& civilizationInfo = GC.getCivilizationInfo(GET_PLAYER(m_eOwner).getCivilizationType());

                if (fromUnitInfo.getUpgradeUnitClass(eToUnitClass))
                {
                        return true;
                }

                for (iI = 0; iI < numUnitClassInfos; iI++)
                {
                        if (fromUnitInfo.getUpgradeUnitClass(iI))
                        {
                                eLoopUnit = ((UnitTypes)(civilizationInfo.getCivilizationUnits(iI)));

                                if (eLoopUnit != NO_UNIT)
                                {
                                        if (upgradeAvailable(eLoopUnit, eToUnitClass, (iCount + 1)))
                                        {
                                                return true;
                                        }
                                }
                        }
                }

                return false;
        }
#endif

        static int upgradePairComparison(const void* first, const void* second)
        {
                if ( ((upgradePair*)first)->eFrom == ((upgradePair*)second)->eFrom )
                {
                        return (((upgradePair*)first)->eTo - ((upgradePair*)second)->eTo);
                }
                else
                {
                        return (((upgradePair*)first)->eFrom - ((upgradePair*)second)->eFrom);
                }
        }

private:
        int                                     m_numUpgrades;
        upgradePair*            m_validUpgrades;
        PlayerTypes                     m_eOwner;
};

CRITICAL_SECTION        CvPlayer::c_canConstructCacheSection;
CRITICAL_SECTION        CvPlayer::c_allCitiesPropertySection;
CRITICAL_SECTION        CvPlayer::c_buildingProcessingSection;
CRITICAL_SECTION        CvPlayer::c_GroupCycleSection;
bool                            CvPlayer::m_staticsInitialized = false;

// Public Functions...

// Public Functions...

//Disable this passed in initialization list warning, as it is only stored in the constructor of CvBuildingList and not used
#pragma warning( disable : 4355 )

CvPlayer::CvPlayer()
: m_GameObject(this),
m_BuildingList(this, NULL),
m_UnitList(this, NULL),
m_Properties(this),
m_pBuildLists(NULL),
m_cachedBonusCount(NULL)
{
        if ( !m_staticsInitialized )
        {
                InitializeCriticalSectionAndSpinCount(&c_canConstructCacheSection, 4000);
                InitializeCriticalSection(&c_allCitiesPropertySection);
                InitializeCriticalSection(&c_buildingProcessingSection);
                InitializeCriticalSectionAndSpinCount(&c_GroupCycleSection, 4000);
                m_staticsInitialized = true;
        }

        m_aiSeaPlotYield = new int[NUM_YIELD_TYPES];
        m_aiYieldRateModifier = new int[NUM_YIELD_TYPES];
        m_aiCapitalYieldRateModifier = new int[NUM_YIELD_TYPES];
        m_aiExtraYieldThreshold = new int[NUM_YIELD_TYPES];
        m_aiTradeYieldModifier = new int[NUM_YIELD_TYPES];
        m_aiFreeCityCommerce = new int[NUM_COMMERCE_TYPES];
        m_aiCommercePercent = new int[NUM_COMMERCE_TYPES];
        m_aiCommerceRate = new int[NUM_COMMERCE_TYPES];
        m_abCommerceDirty = new bool[NUM_COMMERCE_TYPES];
        m_aiCommerceRateModifier = new int[NUM_COMMERCE_TYPES];
        m_aiCapitalCommerceRateModifier = new int[NUM_COMMERCE_TYPES];
        m_aiStateReligionBuildingCommerce = new int[NUM_COMMERCE_TYPES];
        m_aiSpecialistExtraCommerce = new int[NUM_COMMERCE_TYPES];
        m_aiSpecialistExtraYield = new int[NUM_YIELD_TYPES];
        m_aiCommerceFlexibleCount = new int[NUM_COMMERCE_TYPES];
        m_aiGoldPerTurnByPlayer = new int[MAX_PLAYERS];
        m_aiEspionageSpendingWeightAgainstTeam = new int[MAX_TEAMS];

        m_abFeatAccomplished = new bool[NUM_FEAT_TYPES];
        m_abOptions = new bool[NUM_PLAYEROPTION_TYPES];

        m_paiBonusExport = NULL;
        m_paiBonusImport = NULL;
        m_paiImprovementCount = NULL;
        m_paiFreeBuildingCount = NULL;
        m_paiExtraBuildingHappiness = NULL;
        m_paiExtraBuildingHealth = NULL;
        m_paiFeatureHappiness = NULL;
        m_paiUnitClassCount = NULL;
        m_paiUnitClassMaking = NULL;
        m_paiBuildingClassCount = NULL;
        m_paiBuildingClassMaking = NULL;
        m_paiHurryCount = NULL;
        m_paiSpecialBuildingNotRequiredCount = NULL;
        m_paiHasCivicOptionCount = NULL;
        m_paiNoCivicUpkeepCount = NULL;
        m_paiHasReligionCount = NULL;
        m_paiHasCorporationCount = NULL;
        m_paiUpkeepCount = NULL;
        m_paiSpecialistValidCount = NULL;
        m_paiForbiddenCivicCount = NULL;
        m_aiPathLengthCache = NULL;
        m_aiCostPathLengthCache = NULL;
        m_bCanConstruct = NULL;
        m_bCanConstructCached = NULL;
        m_bCanConstructDefaultParam = NULL;
        m_bCanConstructCachedDefaultParam = NULL;
        m_upgradeCache = NULL;

        m_pabResearchingTech = NULL;
        m_pabLoyalMember = NULL;

        m_paeCivics = NULL;

        m_ppaaiSpecialistExtraYield = NULL;
        m_ppaaiImprovementYieldChange = NULL;

/************************************************************************************************/
/* Afforess                       Start          12/9/09                                                */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/
        m_paiUnitCombatProductionModifier = NULL;
        m_paiBonusMintedPercent = NULL;
        m_pabAutomatedCanBuild = NULL;
        m_paiBuildingClassProductionModifier = NULL;
        m_paiUnitClassProductionModifier = NULL;
        m_ppaaiTerrainYieldChange = NULL;
        m_paiResourceConsumption = NULL;
        m_paiFreeSpecialistCount = NULL;
        m_ppiBuildingCommerceModifier = NULL;
        m_ppiBuildingClassCommerceChange = NULL;
        m_ppiSpecialistCommercePercentChanges = NULL;
        m_ppiSpecialistYieldPercentChanges = NULL;
        m_ppiDiplomacyActions = NULL;
        m_ppiBonusCommerceModifier = NULL;
        m_aiLandmarkYield = new int[NUM_YIELD_TYPES];
        m_aiModderOptions = new int[NUM_MODDEROPTION_TYPES];
        m_aiCeaseContactCounter = new int[MAX_PLAYERS];
        m_aiFreeCityYield = new int[NUM_YIELD_TYPES];
/************************************************************************************************/
/* Afforess                          END                                                            */
/************************************************************************************************/

        m_paiImprovementUpgradeRateModifierSpecific = NULL;
        m_ppaaiSpecialistExtraCommerce = NULL;
/************************************************************************************************/
/* AI_AUTO_PLAY_MOD                        09/01/07                                MRGENIE      */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/
        m_bDisableHuman = false;
/************************************************************************************************/
/* AI_AUTO_PLAY_MOD                        END                                                  */
/************************************************************************************************/
/************************************************************************************************/
/* REVOLUTION_MOD                         02/04/08                                jdog5000      */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/
        m_iFreeUnitCountdown = 0;

        m_iStabilityIndex = 500;
        m_iStabilityIndexAverage = 500;
       
        m_bRebel = false;
        m_iMotherPlayer = -1;

        // Used for DynamicCivNames
        CvWString m_szName;
        CvWString m_szCivDesc;
        CvWString m_szCivShort;
        CvWString m_szCivAdj;
/************************************************************************************************/
/* REVOLUTION_MOD                          END                                                  */
/************************************************************************************************/

/************************************************************************************************/
/* REVOLUTIONDCM_MOD                         02/04/08                            Glider1        */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/
        // RevolutionDCM start - new diplomacy option
        setDoNotBotherStatus(NO_PLAYER);
/************************************************************************************************/
/* REVOLUTIONDCM_MOD                         END                                 Glider1        */
/************************************************************************************************/

/************************************************************************************************/
/* UNOFFICIAL_PATCH                       12/07/09                             EmperorFool      */
/*                                                                                              */
/* Bugfix                                                                                       */
/************************************************************************************************/
        // Free Tech Popup Fix
        m_bChoosingFreeTech = false;
        m_bChoosingReligion = false;
/************************************************************************************************/
/* UNOFFICIAL_PATCH                        END                                                  */
/************************************************************************************************/

        m_zobristValue = GC.getGameINLINE().getSorenRand().getInt();

        m_iNumAnimalsSubdued = 0;
        m_iNumAnarchyTurns = 0;
        m_iNumCivicSwitches = 0;
        m_iNumCivicsSwitched = 0;

        reset(NO_PLAYER, true);

        InitializeCriticalSectionAndSpinCount(&m_cModifySection, 4000);
}


CvPlayer::~CvPlayer()
{
        uninit();

        SAFE_DELETE_ARRAY(m_aiSeaPlotYield);
        SAFE_DELETE_ARRAY(m_aiYieldRateModifier);
        SAFE_DELETE_ARRAY(m_aiCapitalYieldRateModifier);
        SAFE_DELETE_ARRAY(m_aiExtraYieldThreshold);
        SAFE_DELETE_ARRAY(m_aiTradeYieldModifier);
        SAFE_DELETE_ARRAY(m_aiFreeCityCommerce);
        SAFE_DELETE_ARRAY(m_aiCommercePercent);
        SAFE_DELETE_ARRAY(m_aiCommerceRate);
        SAFE_DELETE_ARRAY(m_abCommerceDirty);
        SAFE_DELETE_ARRAY(m_aiCommerceRateModifier);
        SAFE_DELETE_ARRAY(m_aiCapitalCommerceRateModifier);
        SAFE_DELETE_ARRAY(m_aiStateReligionBuildingCommerce);
        SAFE_DELETE_ARRAY(m_aiSpecialistExtraCommerce);
        SAFE_DELETE_ARRAY(m_aiSpecialistExtraYield);
        SAFE_DELETE_ARRAY(m_aiCommerceFlexibleCount);
        SAFE_DELETE_ARRAY(m_aiGoldPerTurnByPlayer);
        SAFE_DELETE_ARRAY(m_aiEspionageSpendingWeightAgainstTeam);
        SAFE_DELETE_ARRAY(m_abFeatAccomplished);
        SAFE_DELETE_ARRAY(m_abOptions);
/************************************************************************************************/
/* Afforess                       Start          02/02/10                                               */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/
        SAFE_DELETE_ARRAY(m_aiLandmarkYield);
        SAFE_DELETE_ARRAY(m_aiModderOptions);
        SAFE_DELETE_ARRAY(m_aiCeaseContactCounter);
        SAFE_DELETE_ARRAY(m_aiFreeCityYield);
/************************************************************************************************/
/* Afforess                          END                                                            */
/************************************************************************************************/
        SAFE_DELETE_ARRAY(m_cachedBonusCount);

        DeleteCriticalSection(&m_cModifySection);
}


void CvPlayer::init(PlayerTypes eID)
{
        LeaderHeadTypes eBestPersonality;
        int iValue;
        int iBestValue;
        int iI, iJ;

        //--------------------------------
        // Init saved data
        reset(eID);

        //--------------------------------
        // Init containers
        m_plotGroups.init();

        //m_cities.init();
        clearAllCities();

        //m_units.init();
        clearAllUnits();

        //m_selectionGroups.init();
        clearAllSelectionGroups();

        m_eventsTriggered.init();

        //--------------------------------
        // Init non-saved data
        setupGraphical();

        //--------------------------------
        // Init other game data
        FAssert(getTeam() != NO_TEAM);
        GET_TEAM(getTeam()).changeNumMembers(1);

        if ((GC.getInitCore().getSlotStatus(getID()) == SS_TAKEN) || (GC.getInitCore().getSlotStatus(getID()) == SS_COMPUTER))
        {
                setAlive(true);

                if (GC.getGameINLINE().isOption(GAMEOPTION_RANDOM_PERSONALITIES))
                {
                        if (!isBarbarian() && !isMinorCiv())
                        {
                                iBestValue = 0;
                                eBestPersonality = NO_LEADER;

                                for (iI = 0; iI < GC.getNumLeaderHeadInfos(); iI++)
                                {
                                        if (iI != GC.getDefineINT("BARBARIAN_LEADER")) // XXX minor civ???
                                        {
                                                iValue = (1 + GC.getGameINLINE().getSorenRandNum(10000, "Choosing Personality"));

                                                for (iJ = 0; iJ < MAX_CIV_PLAYERS; iJ++)
                                                {
                                                        if (GET_PLAYER((PlayerTypes)iJ).isAlive())
                                                        {
                                                                if (GET_PLAYER((PlayerTypes)iJ).getPersonalityType() == ((LeaderHeadTypes)iI))
                                                                {
                                                                        iValue /= 2;
                                                                }
                                                        }
                                                }

                                                if (iValue > iBestValue)
                                                {
                                                        iBestValue = iValue;
                                                        eBestPersonality = ((LeaderHeadTypes)iI);
                                                }
                                        }
                                }

                                if (eBestPersonality != NO_LEADER)
                                {
                                        setPersonalityType(eBestPersonality);
                                }
                        }
                }

                changeBaseFreeUnits(GC.getDefineINT("INITIAL_BASE_FREE_UNITS"));
                changeBaseFreeMilitaryUnits(GC.getDefineINT("INITIAL_BASE_FREE_MILITARY_UNITS"));
                changeFreeUnitsPopulationPercent(GC.getDefineINT("INITIAL_FREE_UNITS_POPULATION_PERCENT"));
                changeFreeMilitaryUnitsPopulationPercent(GC.getDefineINT("INITIAL_FREE_MILITARY_UNITS_POPULATION_PERCENT"));
                changeGoldPerUnit(GC.getDefineINT("INITIAL_GOLD_PER_UNIT"));
                changeTradeRoutes(GC.getDefineINT("INITIAL_TRADE_ROUTES"));
                changeStateReligionHappiness(GC.getDefineINT("INITIAL_STATE_RELIGION_HAPPINESS"));
                changeStateReligionHealth(GC.getDefineINT("INITIAL_STATE_RELIGION_HEALTH"));           
                changeNonStateReligionHappiness(GC.getDefineINT("INITIAL_NON_STATE_RELIGION_HAPPINESS"));

                for (iI = 0; iI < NUM_YIELD_TYPES; iI++)
                {
                        changeTradeYieldModifier(((YieldTypes)iI), GC.getYieldInfo((YieldTypes)iI).getTradeModifier());
                }

                for (iI = 0; iI < NUM_COMMERCE_TYPES; iI++)
                {
                        setCommercePercent(((CommerceTypes)iI), GC.getCommerceInfo((CommerceTypes)iI).getInitialPercent());
                }

                FAssertMsg((GC.getNumTraitInfos() > 0), "GC.getNumTraitInfos() is less than or equal to zero but is expected to be larger than zero in CvPlayer::init");
                for (iI = 0; iI < GC.getNumTraitInfos(); iI++)
                {
                        if (hasTrait((TraitTypes)iI))
                        {
                                processTrait((TraitTypes)iI, 1);
                        }
                }

                updateMaxAnarchyTurns();

                for (iI = 0; iI < NUM_YIELD_TYPES; iI++)
                {
                        updateExtraYieldThreshold((YieldTypes)iI);
                }
/************************************************************************************************/
/* Afforess                       Start          04/06/10                                               */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/
                GC.getInitCore().checkInitialCivics();
               
/************************************************************************************************/
/* Afforess                          END                                                            */
/************************************************************************************************/

                for (iI = 0; iI < GC.getNumCivicOptionInfos(); iI++)
                {
                        setCivics(((CivicOptionTypes)iI), ((CivicTypes)(GC.getCivilizationInfo(getCivilizationType()).getCivilizationInitialCivics(iI))));
                }

                for (iI = 0; iI < GC.getNumEventInfos(); iI++)
                {
                        resetEventOccured((EventTypes)iI, false);
                }

                for (iI = 0; iI < GC.getNumEventTriggerInfos(); iI++)
                {
                        resetTriggerFired((EventTriggerTypes)iI);
                }

                for (iI = 0; iI < GC.getNumUnitClassInfos(); ++iI)
                {
                        UnitTypes eUnit = ((UnitTypes)(GC.getCivilizationInfo(getCivilizationType()).getCivilizationUnits(iI)));

                        if (NO_UNIT != eUnit)
                        {
                                if (GC.getUnitInfo(eUnit).isFound())
                                {
                                        setUnitExtraCost((UnitClassTypes)iI, getNewCityProductionValue());
                                }
                        }
                }
        }


/************************************************************************************************/
/* REVOLUTIONDCM_MOD                         02/04/08                            Glider1        */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/
        // RevolutionDCM start - new diplomacy option
        setDoNotBotherStatus(NO_PLAYER);
/************************************************************************************************/
/* REVOLUTIONDCM_MOD                         END                                 Glider1        */
/************************************************************************************************/

        AI_init();
/************************************************************************************************/
/* Afforess  Food Threshold Modifier   Start          08/16/09                                           */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/
        setPopulationgrowthratepercentage(0);
        setReligionSpreadRate(0);
        setDistantUnitSupportCostModifier(0);
        setExtraCityDefense(0);
/************************************************************************************************/
/* Afforess  Food Threshold Modifier                        END                                          */
/************************************************************************************************/

        m_contractBroker.init(eID);

        m_UnitList.init();
}

/************************************************************************************************/
/* REVOLUTION_MOD                         01/04/08                                jdog5000      */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/
//
// Copy of CvPlayer::init but with modifications for use in the middle of a game
//
void CvPlayer::initInGame(PlayerTypes eID, bool bSetAlive, bool bDeclareWar)
{
        LeaderHeadTypes eBestPersonality;
        int iValue;
        int iBestValue;
        int iI, iJ;

        //--------------------------------
        // Init saved data
        reset(eID);

        //--------------------------------
        // Init containers
        m_plotGroups.init();

        //m_cities.init();
        clearAllCities();

        //m_units.init();
        clearAllUnits();

        //m_selectionGroups.init();
        clearAllSelectionGroups();

        m_eventsTriggered.init();

        m_contractBroker.init(eID);

        //--------------------------------
        // Init non-saved data
        setupGraphical();

        //--------------------------------
        // Init other game data
        FAssert(getTeam() != NO_TEAM);

        // Some effects on team necessary if this is the only member of the team
        int iOtherTeamMembers = 0;
        for (iI = 0; iI < MAX_CIV_PLAYERS; iI++)
        {
                if( iI != getID() )
                {
                        if( GET_PLAYER((PlayerTypes)iI).getTeam() == getTeam() )
                        {
                                iOtherTeamMembers++;
                        }
                }
        }

        bool bTeamInit = false;
        if( (iOtherTeamMembers == 0) || GET_TEAM(getTeam()).getNumMembers() == 0 )
        {
                bTeamInit = true;
                GET_TEAM(getTeam()).init(getTeam(), bDeclareWar);
                GET_TEAM(getTeam()).resetPlotAndCityData();
        }

        if( bTeamInit || (GET_TEAM(getTeam()).getNumMembers() == iOtherTeamMembers) )
        {
                GET_TEAM(getTeam()).changeNumMembers(1);
        }

        if ((GC.getInitCore().getSlotStatus(getID()) == SS_TAKEN) || (GC.getInitCore().getSlotStatus(getID()) == SS_COMPUTER))
        {
                if( bSetAlive )
                {
                        setAlive(true);
                }

                if (GC.getGameINLINE().isOption(GAMEOPTION_RANDOM_PERSONALITIES))
                {
                        if (!isBarbarian() && !isMinorCiv())
                        {
                                iBestValue = 0;
                                eBestPersonality = NO_LEADER;

                                for (iI = 0; iI < GC.getNumLeaderHeadInfos(); iI++)
                                {
                                        if (iI != GC.getDefineINT("BARBARIAN_LEADER")) // XXX minor civ???
                                        {
                                                iValue = (1 + GC.getGameINLINE().getSorenRandNum(10000, "Choosing Personality"));

                                                for (iJ = 0; iJ < MAX_CIV_PLAYERS; iJ++)
                                                {
                                                        if (GET_PLAYER((PlayerTypes)iJ).isAlive())
                                                        {
                                                                if (GET_PLAYER((PlayerTypes)iJ).getPersonalityType() == ((LeaderHeadTypes)iI))
                                                                {
                                                                        iValue /= 2;
                                                                }
                                                        }
                                                }

                                                if (iValue > iBestValue)
                                                {
                                                        iBestValue = iValue;
                                                        eBestPersonality = ((LeaderHeadTypes)iI);
                                                }
                                        }
                                }

                                if (eBestPersonality != NO_LEADER)
                                {
                                        setPersonalityType(eBestPersonality);
                                }
                        }
                }

                changeBaseFreeUnits(GC.getDefineINT("INITIAL_BASE_FREE_UNITS"));
                changeBaseFreeMilitaryUnits(GC.getDefineINT("INITIAL_BASE_FREE_MILITARY_UNITS"));
                changeFreeUnitsPopulationPercent(GC.getDefineINT("INITIAL_FREE_UNITS_POPULATION_PERCENT"));
                changeFreeMilitaryUnitsPopulationPercent(GC.getDefineINT("INITIAL_FREE_MILITARY_UNITS_POPULATION_PERCENT"));
                changeGoldPerUnit(GC.getDefineINT("INITIAL_GOLD_PER_UNIT"));
                changeTradeRoutes(GC.getDefineINT("INITIAL_TRADE_ROUTES"));
                changeStateReligionHappiness(GC.getDefineINT("INITIAL_STATE_RELIGION_HAPPINESS"));
                changeStateReligionHealth(GC.getDefineINT("INITIAL_STATE_RELIGION_HEALTH"));           
                changeNonStateReligionHappiness(GC.getDefineINT("INITIAL_NON_STATE_RELIGION_HAPPINESS"));

                for (iI = 0; iI < NUM_YIELD_TYPES; iI++)
                {
                        changeTradeYieldModifier(((YieldTypes)iI), GC.getYieldInfo((YieldTypes)iI).getTradeModifier());
                }

                for (iI = 0; iI < NUM_COMMERCE_TYPES; iI++)
                {
                        setCommercePercent(((CommerceTypes)iI), GC.getCommerceInfo((CommerceTypes)iI).getInitialPercent());
                }

                FAssertMsg((GC.getNumTraitInfos() > 0), "GC.getNumTraitInfos() is less than or equal to zero but is expected to be larger than zero in CvPlayer::init");
                for (iI = 0; iI < GC.getNumTraitInfos(); iI++)
                {
                        if (hasTrait((TraitTypes)iI))
                        {
                                processTrait((TraitTypes)iI, 1);
                        }
                }

                updateMaxAnarchyTurns();

                for (iI = 0; iI < NUM_YIELD_TYPES; iI++)
                {
                        updateExtraYieldThreshold((YieldTypes)iI);
                }

                for (iI = 0; iI < GC.getNumCivicOptionInfos(); iI++)
                {
                        setCivics(((CivicOptionTypes)iI), ((CivicTypes)(GC.getCivilizationInfo(getCivilizationType()).getCivilizationInitialCivics(iI))));
                }

                // Reset all triggers at first, set those whose events have fired in next block
                for (iI = 0; iI < GC.getNumEventTriggerInfos(); iI++)
                {
                        resetTriggerFired((EventTriggerTypes)iI);
                }

                for (iI = 0; iI < GC.getNumEventInfos(); iI++)
                {
/* original bts code
                        resetEventOccured((EventTypes)iI, false);
*/

                        // Has global trigger fired already?
                               
                        const EventTriggeredData* pEvent = NULL;
                        for (iJ = 0; iJ < MAX_CIV_PLAYERS; iJ++)
                        {
                                if( iJ != getID() )
                                {
                                        pEvent = GET_PLAYER((PlayerTypes)iJ).getEventOccured((EventTypes)iI, true);
                                        if ( pEvent != NULL )
                                        {
                                                CvEventTriggerInfo& kTrigger = GC.getEventTriggerInfo(pEvent->m_eTrigger);
                                                if( kTrigger.isGlobal() )
                                                {
                                                        setTriggerFired( *pEvent, false, false );
                                                        break;
                                                }
                                                else if( kTrigger.isTeam() && GET_PLAYER((PlayerTypes)iJ).getTeam() == getTeam() )
                                                {
                                                        setTriggerFired( *pEvent, false, false );
                                                        break;
                                                }
                                        }
                                }
                        }
                       
                        resetEventOccured((EventTypes)iI, false);
                }

                for (iI = 0; iI < GC.getNumUnitClassInfos(); ++iI)
                {
                        UnitTypes eUnit = ((UnitTypes)(GC.getCivilizationInfo(getCivilizationType()).getCivilizationUnits(iI)));

                        if (NO_UNIT != eUnit)
                        {
                                if (GC.getUnitInfo(eUnit).isFound())
                                {
                                        setUnitExtraCost((UnitClassTypes)iI, getNewCityProductionValue());
                                }
                        }
                }
        }

        resetPlotAndCityData();

/************************************************************************************************/
/* REVOLUTIONDCM_MOD                         02/04/08                            Glider1        */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/
        // RevolutionDCM start - new diplomacy option
        setDoNotBotherStatus(NO_PLAYER);
        // RevolutionDCM end
/************************************************************************************************/
/* REVOLUTIONDCM_MOD                         END                                 Glider1        */
/************************************************************************************************/
        m_UnitList.init();

        AI_init();
}

//
// Reset all data for this player stored in plot and city objects
//
void CvPlayer::resetPlotAndCityData( )
{
        CvPlot* pLoopPlot;
        CvCity* pLoopCity;
        for (int iPlot = 0; iPlot < GC.getMapINLINE().numPlotsINLINE(); ++iPlot)
        {
                pLoopPlot = GC.getMapINLINE().plotByIndexINLINE(iPlot);

                pLoopPlot->setCulture(getID(), 0, false, false);
                pLoopPlot->setFoundValue(getID(), 0);

                pLoopCity = pLoopPlot->getPlotCity();
                if( pLoopCity != NULL )
                {
                        pLoopCity->setCulture(getID(), 0, false, false);
                        pLoopCity->changeNumRevolts(getID(), -pLoopCity->getNumRevolts(getID()));
                        pLoopCity->setEverOwned(getID(), false);
                        pLoopCity->setTradeRoute(getID(), false);
                }
        }
}
/************************************************************************************************/
/* BETTER_BTS_AI_MOD                       END                                                  */
/************************************************************************************************/


void CvPlayer::uninit()
{
        SAFE_DELETE_ARRAY(m_paiBonusExport);
        SAFE_DELETE_ARRAY(m_paiBonusImport);
        SAFE_DELETE_ARRAY(m_paiImprovementCount);
        SAFE_DELETE_ARRAY(m_paiFreeBuildingCount);
        SAFE_DELETE_ARRAY(m_paiExtraBuildingHappiness);
        SAFE_DELETE_ARRAY(m_paiExtraBuildingHealth);
        SAFE_DELETE_ARRAY(m_paiFeatureHappiness);
        SAFE_DELETE_ARRAY(m_paiUnitClassCount);
        SAFE_DELETE_ARRAY(m_paiUnitClassMaking);
        SAFE_DELETE_ARRAY(m_paiBuildingClassCount);
        SAFE_DELETE_ARRAY(m_paiBuildingClassMaking);
        SAFE_DELETE_ARRAY(m_paiHurryCount);
        SAFE_DELETE_ARRAY(m_paiSpecialBuildingNotRequiredCount);
        SAFE_DELETE_ARRAY(m_paiHasCivicOptionCount);
        SAFE_DELETE_ARRAY(m_paiNoCivicUpkeepCount);
        SAFE_DELETE_ARRAY(m_paiHasReligionCount);
        SAFE_DELETE_ARRAY(m_paiHasCorporationCount);
        SAFE_DELETE_ARRAY(m_paiUpkeepCount);
        SAFE_DELETE_ARRAY(m_paiSpecialistValidCount);
        SAFE_DELETE_ARRAY(m_paiForbiddenCivicCount);
       
        SAFE_DELETE_ARRAY(m_pabResearchingTech);
        SAFE_DELETE_ARRAY(m_pabLoyalMember);

        SAFE_DELETE_ARRAY(m_paeCivics);
        SAFE_DELETE_ARRAY(m_aiPathLengthCache);
        SAFE_DELETE_ARRAY(m_aiCostPathLengthCache);

        SAFE_DELETE_ARRAY(m_bCanConstruct);
        SAFE_DELETE_ARRAY(m_bCanConstructCached);
        SAFE_DELETE_ARRAY(m_bCanConstructDefaultParam);
        SAFE_DELETE_ARRAY(m_bCanConstructCachedDefaultParam);

        SAFE_DELETE(m_upgradeCache);

        SAFE_DELETE(m_pBuildLists);

        m_triggersFired.clear();
        m_mapScoreHistory.clear();

        if (m_ppaaiSpecialistExtraYield != NULL)
        {
                for (int iI = 0; iI < GC.getNumSpecialistInfos(); iI++)
                {
                        SAFE_DELETE_ARRAY(m_ppaaiSpecialistExtraYield[iI]);
                }
                SAFE_DELETE_ARRAY(m_ppaaiSpecialistExtraYield);
        }

        if (m_ppaaiImprovementYieldChange != NULL)
        {
                for (int iI = 0; iI < GC.getNumImprovementInfos(); iI++)
                {
                        SAFE_DELETE_ARRAY(m_ppaaiImprovementYieldChange[iI]);
                }
                SAFE_DELETE_ARRAY(m_ppaaiImprovementYieldChange);
        }

/************************************************************************************************/
/* Afforess                       Start          12/9/09                                                */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/
        SAFE_DELETE_ARRAY(m_paiUnitCombatProductionModifier);
        SAFE_DELETE_ARRAY(m_paiBonusMintedPercent);
        SAFE_DELETE_ARRAY(m_paiBuildingClassProductionModifier);
        SAFE_DELETE_ARRAY(m_paiUnitClassProductionModifier);
        SAFE_DELETE_ARRAY(m_pabAutomatedCanBuild);
        SAFE_DELETE_ARRAY(m_paiResourceConsumption);
        SAFE_DELETE_ARRAY(m_paiFreeSpecialistCount);
        SAFE_DELETE_ARRAY(m_paiImprovementUpgradeRateModifierSpecific);
        if (m_ppaaiSpecialistExtraCommerce != NULL)
        {
                for (int iI = 0; iI < GC.getNumSpecialistInfos(); iI++)
                {
                        SAFE_DELETE_ARRAY(m_ppaaiSpecialistExtraCommerce[iI]);
                }
                SAFE_DELETE_ARRAY(m_ppaaiSpecialistExtraCommerce);
        }
        if (m_ppaaiTerrainYieldChange != NULL)
        {
                for (int iI = 0; iI < GC.getNumTerrainInfos(); iI++)
                {
                        SAFE_DELETE_ARRAY(m_ppaaiTerrainYieldChange[iI]);
                }
                SAFE_DELETE_ARRAY(m_ppaaiTerrainYieldChange);
        }
        if (m_ppiBuildingCommerceModifier != NULL)
        {
                for (int iI = 0; iI < GC.getNumBuildingInfos(); iI++)
                {
                        SAFE_DELETE_ARRAY(m_ppiBuildingCommerceModifier[iI]);
                }
                SAFE_DELETE_ARRAY(m_ppiBuildingCommerceModifier);
        }
        if (m_ppiBuildingClassCommerceChange != NULL)
        {
                for (int iI = 0; iI < GC.getNumBuildingClassInfos(); iI++)
                {
                        SAFE_DELETE_ARRAY(m_ppiBuildingClassCommerceChange[iI]);
                }
                SAFE_DELETE_ARRAY(m_ppiBuildingClassCommerceChange);
        }
        if (m_ppiBonusCommerceModifier != NULL)
        {
                for (int iI = 0; iI < GC.getNumBonusInfos(); iI++)
                {
                        SAFE_DELETE_ARRAY(m_ppiBonusCommerceModifier[iI]);
                }
                SAFE_DELETE_ARRAY(m_ppiBonusCommerceModifier);
        }
        if (m_ppiSpecialistCommercePercentChanges != NULL)
        {
                for (int iI = 0; iI < GC.getNumSpecialistInfos(); iI++)
                {
                        SAFE_DELETE_ARRAY(m_ppiSpecialistCommercePercentChanges[iI]);
                }
                SAFE_DELETE_ARRAY(m_ppiSpecialistCommercePercentChanges);
        }
        if (m_ppiSpecialistYieldPercentChanges != NULL)
        {
                for (int iI = 0; iI < GC.getNumSpecialistInfos(); iI++)
                {
                        SAFE_DELETE_ARRAY(m_ppiSpecialistYieldPercentChanges[iI]);
                }
                SAFE_DELETE_ARRAY(m_ppiSpecialistYieldPercentChanges);
        }
        if (m_ppiDiplomacyActions != NULL)
        {
                for (int iI = 0; iI < MAX_PLAYERS; iI++)
                {
                        SAFE_DELETE_ARRAY(m_ppiDiplomacyActions[iI]);
                }
                SAFE_DELETE_ARRAY(m_ppiDiplomacyActions);
        }
/************************************************************************************************/
/* Afforess                          END                                                            */
/************************************************************************************************/
        m_groupCycle.clear();

        m_researchQueue.clear();

        m_cityNames.clear();

        m_contractBroker.reset();

        m_plotGroups.uninit();

        //m_cities.uninit();
        clearAllCities();

        //m_units.uninit();
        clearAllUnits();

        //m_selectionGroups.uninit();
        clearAllSelectionGroups();

        m_eventsTriggered.uninit();

        clearMessages();

        clearPopups();

        clearDiplomacy();
}


// FUNCTION: reset()
// Initializes data members that are serialized.
void CvPlayer::reset(PlayerTypes eID, bool bConstructorCall)
{
        int iI, iJ;

        //--------------------------------
        // Uninit class
        uninit();

        // < M.A.D. Nukes Start >
        m_iMADDeterrent = 0;
        m_iMADIncoming = 0;
        m_iMADOutgoing = 0;
        m_iMADNukesCount = 0;
        for(iI = 0; iI < MAX_PLAYERS; iI++)
        {
                m_bMADTrigger[iI] = false;
        }
        // < M.A.D. Nukes End   >

        m_iStartingX = INVALID_PLOT_COORD;
        m_iStartingY = INVALID_PLOT_COORD;
        m_iTotalPopulation = 0;
        m_iTotalLand = 0;
        m_iTotalLandScored = 0;
        m_iGold = 0;
        m_iInterest = 0;       
        m_iGoldPerTurn = 0;
        m_iAdvancedStartPoints = -1;
        m_iGoldenAgeTurns = 0;
        m_iNumUnitGoldenAges = 0;
        m_iStrikeTurns = 0;
        m_iAnarchyTurns = 0;
        m_iMaxAnarchyTurns = 0;
        m_iAnarchyModifier = 0;
        m_iGoldenAgeModifier = 0;
        m_iGlobalHurryModifier = 0;
        m_iGreatPeopleCreated = 0;
        m_iGreatGeneralsCreated = 0;
        m_iGreatPeopleThresholdModifier = 0;
        m_iGreatGeneralsThresholdModifier = 0;
        m_iGreatPeopleRateModifier = 0;
        m_iGreatGeneralRateModifier = 0;
        m_iDomesticGreatGeneralRateModifier = 0;
        m_iStateReligionGreatPeopleRateModifier = 0;
        m_iMaxGlobalBuildingProductionModifier = 0;
        m_iMaxTeamBuildingProductionModifier = 0;
        m_iMaxPlayerBuildingProductionModifier = 0;
        m_iFreeExperience = 0;
        m_iFeatureProductionModifier = 0;
        m_iWorkerSpeedModifier = 0;
        m_iImprovementUpgradeRateModifier = 0;
        m_iMilitaryProductionModifier = 0;
        m_iSpaceProductionModifier = 0;
        m_iCityDefenseModifier = 0;
/************************************************************************************************/
/* REVDCM                                 09/02/10                                phungus420    */
/*                                                                                              */
/* Player Functions                                                                             */
/************************************************************************************************/
        m_iNonStateReligionCommerceCount = 0;
        m_iUpgradeAnywhereCount = 0;
        m_iRevIdxLocal = 0;
        m_iRevIdxNational = 0;
        m_iRevIdxDistanceModifier = 0;
        m_iRevIdxHolyCityGood = 0;
        m_iRevIdxHolyCityBad = 0;
        m_fRevIdxNationalityMod = 0;
        m_fRevIdxBadReligionMod = 0;
        m_fRevIdxGoodReligionMod = 0;
        m_bInquisitionConditions = false;
        m_iUnitUpgradePriceModifier = 0;
        m_iCityLimit = 0;
        m_iCityOverLimitUnhappy = 0;
        m_iForeignUnhappyPercent = 0;
/************************************************************************************************/
/* REVDCM                                  END                                                  */
/************************************************************************************************/
        m_iNumNukeUnits = 0;
        m_iNumOutsideUnits = 0;
        m_iBaseFreeUnits = 0;
        m_iBaseFreeMilitaryUnits = 0;
        m_iFreeUnitsPopulationPercent = 0;
        m_iFreeMilitaryUnitsPopulationPercent = 0;
        m_iGoldPerUnit = 0;
        m_iGoldPerMilitaryUnit = 0;
        m_iExtraUnitCost = 0;
        m_iNumMilitaryUnits = 0;
        m_iHappyPerMilitaryUnit = 0;
        m_iMilitaryFoodProductionCount = 0;
        m_iConscriptCount = 0;
        m_iMaxConscript = 0;
        m_iHighestUnitLevel = 1;
        m_iOverflowResearch = 0;
        m_iNoUnhealthyPopulationCount = 0;
        m_iExpInBorderModifier = 0;
        m_iBuildingOnlyHealthyCount = 0;
        //DPII < Maintenance Modifier >
        m_iMaintenanceModifier = 0;
        m_iCoastalDistanceMaintenanceModifier = 0;
        m_iConnectedCityMaintenanceModifier = 0;
        //DPII < Maintenance Modifier >
        m_iDistanceMaintenanceModifier = 0;
        m_iNumCitiesMaintenanceModifier = 0;
        m_iCorporationMaintenanceModifier = 0;
        m_iTotalMaintenance = 0;
        m_iUpkeepModifier = 0;
        m_iLevelExperienceModifier = 0;
        m_iExtraHealth = 0;
        m_iBuildingGoodHealth = 0;
        m_iBuildingBadHealth = 0;
        m_iExtraHappiness = 0;
        m_iBuildingHappiness = 0;
        m_iLargestCityHappiness = 0;
        m_iWarWearinessPercentAnger = 0;
        m_iWarWearinessModifier = 0;
        m_iFreeSpecialist = 0;
        m_iNoForeignTradeCount = 0;
        m_iNoCorporationsCount = 0;
        m_iNoForeignCorporationsCount = 0;
        m_iCoastalTradeRoutes = 0;
        m_iTradeRoutes = 0;
        m_iRevolutionTimer = 0;
        m_iConversionTimer = 0;
        m_iStateReligionCount = 0;
        m_iNoNonStateReligionSpreadCount = 0;
        m_iStateReligionHappiness = 0;
        m_iStateReligionHealth = 0;    
        m_iNonStateReligionHappiness = 0;
        m_iStateReligionUnitProductionModifier = 0;
        m_iStateReligionBuildingProductionModifier = 0;
        m_iStateReligionFreeExperience = 0;
        m_iCapitalCityID = FFreeList::INVALID_INDEX;
        m_iCitiesLost = 0;
        m_iWinsVsBarbs = 0;
        m_iAssets = 0;
        m_iPower = 0;
        m_iTechPower = 0;
        m_iUnitPower = 0;
        m_iPopulationScore = 0;
        m_iLandScore = 0;
        m_iTechScore = 0;
        m_iWondersScore = 0;
        m_iCombatExperience = 0;
        m_iPopRushHurryCount = 0;
        m_iInflationModifier = 0;
        m_accruedCostRatioTimes10000 = 10000;   //      1:1 at the start
        m_uiStartTime = 0;

        m_bAlive = false;
        m_bEverAlive = false;
        m_bTurnActive = false;
        m_bAutoMoves = false;
        m_bEndTurn = false;
        m_bPbemNewTurn = false;
        m_bExtendedGame = false;
        m_bFoundedFirstCity = false;
        m_bStrike = false;
        //TB Nukefix
        m_bNukesValid = false;
        m_iNationalHurryAngerModifier = 0;
        m_iNationalEnemyWarWearinessModifier = 0;
        m_iFixedBordersCount = 0;
        m_iFieldCommandersEverCount = 0;
        m_iSeizedForeignConnectednessPercent = 0;
        m_iWarMongerIndex = 0;

        m_Properties.clear();
        m_canHaveBuilder.clear();

        setTurnHadUIInteraction(false);

        m_civicSwitchHistory.clear();

/************************************************************************************************/
/* UNOFFICIAL_PATCH                       12/07/09                             EmperorFool      */
/*                                                                                              */
/* Bugfix                                                                                       */
/************************************************************************************************/
        // Free Tech Popup Fix
        m_bChoosingFreeTech = false;
/************************************************************************************************/
/* UNOFFICIAL_PATCH                        END                                                  */
/************************************************************************************************/

/************************************************************************************************/
/* AI_AUTO_PLAY_MOD                        09/01/07                            MRGENIE          */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/
        m_bDisableHuman = false;
/************************************************************************************************/
/* AI_AUTO_PLAY_MOD                        END                                                  */
/************************************************************************************************/


/************************************************************************************************/
/* REVOLUTION_MOD                         02/04/09                                jdog5000      */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/
        m_iFreeUnitCountdown = 0;

        m_iStabilityIndex = 500;
        m_iStabilityIndexAverage = 500;

        m_bRebel = false;
        m_iMotherPlayer = -1;

        // Used for DynamicCivNames
        m_szName.clear();
        m_szCivDesc.clear();
        m_szCivShort.clear();
        m_szCivAdj.clear();
/************************************************************************************************/
/* REVOLUTION_MOD                          END                                                  */
/************************************************************************************************/
        m_eID = eID;
        updateTeamType();
        updateHuman();

        if (m_eID != NO_PLAYER)
        {
                m_ePersonalityType = GC.getInitCore().getLeader(m_eID); //??? Is this repeated data???
        }
        else
        {
                m_ePersonalityType = NO_LEADER;
        }
        m_eCurrentEra = ((EraTypes)0);  //??? Is this repeated data???
        m_eLastStateReligion = NO_RELIGION;
        m_eParent = NO_PLAYER;
/************************************************************************************************/
/* Afforess                       Start          12/9/09                                                */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/
    m_ePledgedVote = NO_PLAYER_VOTE;
        m_eSecretaryGeneralVote = NO_TEAM;
    m_iEnslavementChance = 0;
        m_iForeignTradeRouteModifier = 0;
        m_iTaxRateUnhappiness = 0;
        m_iCivicHappiness = 0;
        m_iFractionalXPEarnedInCity = 0;
        m_iUnitUpgradePriceModifier = 0;
       
        m_iWorldHappiness = 0;
        m_iProjectHappiness = 0;
        m_iWorldHealth = 0;
        m_iProjectHealth = 0;
        m_iForceAllTradeRoutes = 0;
        m_iWorldTradeRoutes = 0;
        m_iNoCapitalUnhappiness = 0;
        m_iTaxationAnger = 0;
        m_iLastTurnTaxRate = 0;
        m_iCivilizationHealth = 0;
        m_iAllowsAmbassadorsCount = 0;
       
        m_bShowLandmarks = true;

        m_iBuildingInflation = 0;
        m_iCivicInflation = 0;
        m_iProjectInflation = 0;
        m_iTechInflation = 0;
       
        m_iHurryCostModifier = 0;
        m_iHurryInflationModifier = 0;
        m_iHurryCount = 0;

        m_bAliveSanityCounter = 0;

        m_eBestRoute = NO_ROUTE;

        m_iNoLandmarkAngerCount = 0;
        m_iLandmarkHappiness = 0;
        m_eDemandWarAgainstTeam = NO_TEAM;
       
        m_iCorporationSpreadModifier = 0;
        m_iCorporateTaxIncome = 0;

        m_eCurrentAgeSegment = AGE_SEGMENT_DAWN;
        m_eCurrentCulturalAge = FIRST_CULTURAL_AGE;
        m_iCulture = 0;
       
        m_iFractionalCombatExperience = 0;

        m_bInhibitPlotGroupRecalc = false;
/************************************************************************************************/
/* Afforess                          END                                                            */
/************************************************************************************************/

        for (iI = 0; iI < NUM_YIELD_TYPES; iI++)
        {
                m_aiSeaPlotYield[iI] = 0;
                m_aiYieldRateModifier[iI] = 0;
                m_aiCapitalYieldRateModifier[iI] = 0;
                m_aiExtraYieldThreshold[iI] = 0;
                m_aiTradeYieldModifier[iI] = 0;
/************************************************************************************************/
/* Afforess                       Start          04/15/10                                               */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/
                m_aiLandmarkYield[iI] = 0;
                m_aiFreeCityYield[iI] = 0;
/************************************************************************************************/
/* Afforess                          END                                                            */
/************************************************************************************************/             
                m_aiSpecialistExtraYield[iI] = 0;
        }

        for (iI = 0; iI < NUM_COMMERCE_TYPES; iI++)
        {
                m_aiFreeCityCommerce[iI] = 0;
                m_aiCommercePercent[iI] = 0;
                m_aiCommerceRate[iI] = 0;
                m_abCommerceDirty[iI] = false;
                m_aiCommerceRateModifier[iI] = 0;
                m_aiCapitalCommerceRateModifier[iI] = 0;
                m_aiStateReligionBuildingCommerce[iI] = 0;
                m_aiSpecialistExtraCommerce[iI] = 0;
                m_aiCommerceFlexibleCount[iI] = 0;
        }

        for (iI = 0; iI < MAX_PLAYERS; iI++)
        {
                m_aiGoldPerTurnByPlayer[iI] = 0;
                if (!bConstructorCall && getID() != NO_PLAYER)
                {
                        GET_PLAYER((PlayerTypes) iI).m_aiGoldPerTurnByPlayer[getID()] = 0;
                }
        }

        for (iI = 0; iI < MAX_TEAMS; iI++)
        {
                m_aiEspionageSpendingWeightAgainstTeam[iI] = 0;

                if (!bConstructorCall && getTeam() != NO_TEAM)
                {
                        for (iJ = 0; iJ < MAX_PLAYERS; iJ++)
                        {
                                if (GET_PLAYER((PlayerTypes) iJ).getTeam() == iI)
                                {
                                        GET_PLAYER((PlayerTypes) iJ).setEspionageSpendingWeightAgainstTeam(getTeam(), 0);
                                }
                        }
                }
        }

        for (iI = 0; iI < NUM_FEAT_TYPES; iI++)
        {
                m_abFeatAccomplished[iI] = false;
        }

        for (iI = 0; iI < NUM_PLAYEROPTION_TYPES; iI++)
        {
                m_abOptions[iI] = false;
        }

        m_szScriptData = "";

        SAFE_DELETE_ARRAY(m_cachedBonusCount);
        m_cachedBonusCountGameTurn = -1;

        if (!bConstructorCall)
        {
                FAssertMsg(0 < GC.getNumBonusInfos(), "GC.getNumBonusInfos() is not greater than zero but it is used to allocate memory in CvPlayer::reset");
                FAssertMsg(m_paiBonusExport==NULL, "about to leak memory, CvPlayer::m_paiBonusExport");
                m_paiBonusExport = new int [GC.getNumBonusInfos()];
                FAssertMsg(m_paiBonusImport==NULL, "about to leak memory, CvPlayer::m_paiBonusImport");
                m_paiBonusImport = new int [GC.getNumBonusInfos()];
                for (iI = 0; iI < GC.getNumBonusInfos(); iI++)
                {
                        m_paiBonusExport[iI] = 0;
                        m_paiBonusImport[iI] = 0;
                }

                FAssertMsg(0 < GC.getNumImprovementInfos(), "GC.getNumImprovementInfos() is not greater than zero but it is used to allocate memory in CvPlayer::reset");
                FAssertMsg(m_paiImprovementCount==NULL, "about to leak memory, CvPlayer::m_paiImprovementCount");
                m_paiImprovementCount = new int [GC.getNumImprovementInfos()];
                for (iI = 0; iI < GC.getNumImprovementInfos(); iI++)
                {
                        m_paiImprovementCount[iI] = 0;
                }

                FAssertMsg(m_paiFreeBuildingCount==NULL, "about to leak memory, CvPlayer::m_paiFreeBuildingCount");
                m_paiFreeBuildingCount = new int [GC.getNumBuildingInfos()];
                FAssertMsg(m_paiExtraBuildingHappiness==NULL, "about to leak memory, CvPlayer::m_paiExtraBuildingHappiness");
                m_paiExtraBuildingHappiness = new int [GC.getNumBuildingInfos()];
                FAssertMsg(m_paiExtraBuildingHealth==NULL, "about to leak memory, CvPlayer::m_paiExtraBuildingHealth");
                m_paiExtraBuildingHealth = new int [GC.getNumBuildingInfos()];
                for (iI = 0; iI < GC.getNumBuildingInfos(); iI++)
                {
                        m_paiFreeBuildingCount[iI] = 0;
                        m_paiExtraBuildingHappiness[iI] = 0;
                        m_paiExtraBuildingHealth[iI] = 0;
                }

                FAssertMsg(m_paiFeatureHappiness==NULL, "about to leak memory, CvPlayer::m_paiFeatureHappiness");
                m_paiFeatureHappiness = new int [GC.getNumFeatureInfos()];
                for (iI = 0; iI < GC.getNumFeatureInfos(); iI++)
                {
                        m_paiFeatureHappiness[iI] = 0;
                }

                FAssertMsg(m_paiUnitClassCount==NULL, "about to leak memory, CvPlayer::m_paiUnitClassCount");
                m_paiUnitClassCount = new int [GC.getNumUnitClassInfos()];
                FAssertMsg(m_paiUnitClassMaking==NULL, "about to leak memory, CvPlayer::m_paiUnitClassMaking");
                m_paiUnitClassMaking = new int [GC.getNumUnitClassInfos()];
                for (iI = 0; iI < GC.getNumUnitClassInfos(); iI++)
                {
                        m_paiUnitClassCount[iI] = 0;
                        m_paiUnitClassMaking[iI] = 0;
                }

                FAssertMsg(m_paiBuildingClassCount==NULL, "about to leak memory, CvPlayer::m_paiBuildingClassCount");
                m_paiBuildingClassCount = new int [GC.getNumBuildingClassInfos()];
                FAssertMsg(m_paiBuildingClassMaking==NULL, "about to leak memory, CvPlayer::m_paiBuildingClassMaking");
                m_paiBuildingClassMaking = new int [GC.getNumBuildingClassInfos()];
                for (iI = 0; iI < GC.getNumBuildingClassInfos(); iI++)
                {
                        m_paiBuildingClassCount[iI] = 0;
                        m_paiBuildingClassMaking[iI] = 0;
                }

                FAssertMsg(m_paiHurryCount==NULL, "about to leak memory, CvPlayer::m_paiHurryCount");
                m_paiHurryCount = new int [GC.getNumHurryInfos()];
                for (iI = 0; iI < GC.getNumHurryInfos(); iI++)
                {
                        m_paiHurryCount[iI] = 0;
                }

                FAssertMsg(m_paiSpecialBuildingNotRequiredCount==NULL, "about to leak memory, CvPlayer::m_paiSpecialBuildingNotRequiredCount");
                m_paiSpecialBuildingNotRequiredCount = new int [GC.getNumSpecialBuildingInfos()];
                for (iI = 0; iI < GC.getNumSpecialBuildingInfos(); iI++)
                {
                        m_paiSpecialBuildingNotRequiredCount[iI] = 0;
                }
       
                FAssertMsg(m_paiHasCivicOptionCount==NULL, "about to leak memory, CvPlayer::m_paiHasCivicOptionCount");
                m_paiHasCivicOptionCount = new int[GC.getNumCivicOptionInfos()];
                FAssertMsg(m_paiNoCivicUpkeepCount==NULL, "about to leak memory, CvPlayer::m_paiNoCivicUpkeepCount");
                m_paiNoCivicUpkeepCount = new int[GC.getNumCivicOptionInfos()];
                FAssertMsg(m_paeCivics==NULL, "about to leak memory, CvPlayer::m_paeCivics");
                m_paeCivics = new CivicTypes [GC.getNumCivicOptionInfos()];
                for (iI = 0; iI < GC.getNumCivicOptionInfos(); iI++)
                {
                        m_paiHasCivicOptionCount[iI] = 0;
                        m_paiNoCivicUpkeepCount[iI] = 0;
                        m_paeCivics[iI] = NO_CIVIC;
                }

                FAssertMsg(m_bCanConstruct==NULL, "about to leak memory, CvPlayer::m_bCanConstruct");
                m_bCanConstruct = new bool[GC.getNumBuildingInfos()];

                FAssertMsg(m_bCanConstructCached==NULL, "about to leak memory, CvPlayer::m_bCanConstructCached");
                m_bCanConstructCached = new bool[GC.getNumBuildingInfos()];
                for (iI = 0; iI < GC.getNumBuildingInfos(); iI++)
                {
                        m_bCanConstructCached[iI] = false;
                }

                FAssertMsg(m_bCanConstructDefaultParam==NULL, "about to leak memory, CvPlayer::m_bCanConstructDefaultParam");
                m_bCanConstructDefaultParam = new bool[GC.getNumBuildingInfos()];

                FAssertMsg(m_bCanConstructCachedDefaultParam==NULL, "about to leak memory, CvPlayer::m_bCanConstructCachedDefaultParam");
                m_bCanConstructCachedDefaultParam = new bool[GC.getNumBuildingInfos()];
                for (iI = 0; iI < GC.getNumBuildingInfos(); iI++)
                {
                        m_bCanConstructCachedDefaultParam[iI] = false;
                }
               
                FAssertMsg(m_aiPathLengthCache==NULL, "about to leak memory, CvPlayer::m_aiPathLengthCache");
                m_aiPathLengthCache = new int[GC.getNumTechInfos()];
                for (iI = 0; iI < GC.getNumTechInfos(); iI++)
                {
                        m_aiPathLengthCache[iI] = -1;
                }
               
                FAssertMsg(m_aiCostPathLengthCache==NULL, "about to leak memory, CvPlayer::m_aiCostPathLengthCache");
                m_aiCostPathLengthCache = new int[GC.getNumTechInfos()];
                for (iI = 0; iI < GC.getNumTechInfos(); iI++)
                {
                        m_aiCostPathLengthCache[iI] = -1;
                }

                FAssertMsg(m_paiHasReligionCount==NULL, "about to leak memory, CvPlayer::m_paiHasReligionCount");
                m_paiHasReligionCount = new int[GC.getNumReligionInfos()];
                for (iI = 0;iI < GC.getNumReligionInfos();iI++)
                {
                        m_paiHasReligionCount[iI] = 0;
                }
       
                FAssertMsg(m_paiHasCorporationCount==NULL, "about to leak memory, CvPlayer::m_paiHasCorporationCount");
                m_paiHasCorporationCount = new int[GC.getNumCorporationInfos()];
                for (iI = 0;iI < GC.getNumCorporationInfos();iI++)
                {
                        m_paiHasCorporationCount[iI] = 0;
                }

                FAssertMsg(m_pabResearchingTech==NULL, "about to leak memory, CvPlayer::m_pabResearchingTech");
                m_pabResearchingTech = new bool[GC.getNumTechInfos()];
                for (iI = 0; iI < GC.getNumTechInfos(); iI++)
                {
                        m_pabResearchingTech[iI] = false;
                }

                FAssertMsg(m_pabLoyalMember==NULL, "about to leak memory, CvPlayer::m_pabLoyalMember");
                m_pabLoyalMember = new bool[GC.getNumVoteSourceInfos()];
                for (iI = 0; iI < GC.getNumVoteSourceInfos(); iI++)
                {
                        m_pabLoyalMember[iI] = true;
                }

                FAssertMsg(0 < GC.getNumUpkeepInfos(), "GC.getNumUpkeepInfos() is not greater than zero but it is used to allocate memory in CvPlayer::reset");
                FAssertMsg(m_paiUpkeepCount==NULL, "about to leak memory, CvPlayer::m_paiUpkeepCount");
                m_paiUpkeepCount = new int[GC.getNumUpkeepInfos()];
                for (iI = 0; iI < GC.getNumUpkeepInfos(); iI++)
                {
                        m_paiUpkeepCount[iI] = 0;
                }

                FAssertMsg(0 < GC.getNumSpecialistInfos(), "GC.getNumSpecialistInfos() is not greater than zero but it is used to allocate memory in CvPlayer::reset");
                FAssertMsg(m_paiSpecialistValidCount==NULL, "about to leak memory, CvPlayer::m_paiSpecialistValidCount");
                m_paiSpecialistValidCount = new int[GC.getNumSpecialistInfos()];
                for (iI = 0; iI < GC.getNumSpecialistInfos(); iI++)
                {
                        m_paiSpecialistValidCount[iI] = 0;
                }

                m_paiForbiddenCivicCount = new int[GC.getNumCivicInfos()];
                for (iI = 0; iI < GC.getNumCivicInfos(); iI++)
                {
                        m_paiForbiddenCivicCount[iI] = 0;
                }
               
                FAssertMsg(0 < GC.getNumSpecialistInfos(), "GC.getNumSpecialistInfos() is not greater than zero but it is used to allocate memory in CvPlayer::reset");
                FAssertMsg(m_ppaaiSpecialistExtraYield==NULL, "about to leak memory, CvPlayer::m_ppaaiSpecialistExtraYield");
                m_ppaaiSpecialistExtraYield = new int*[GC.getNumSpecialistInfos()];
/************************************************************************************************/
/* Afforess                       Start          03/27/10                                               */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/
                m_paiFreeSpecialistCount = new int[GC.getNumSpecialistInfos()];
/************************************************************************************************/
/* Afforess                          END                                                            */
/************************************************************************************************/
                for (iI = 0; iI < GC.getNumSpecialistInfos(); iI++)
                {
                        m_ppaaiSpecialistExtraYield[iI] = new int[NUM_YIELD_TYPES];
                        for (iJ = 0; iJ < NUM_YIELD_TYPES; iJ++)
                        {
                                m_ppaaiSpecialistExtraYield[iI][iJ] = 0;
                        }
/************************************************************************************************/
/* Afforess                       Start          03/27/10                                               */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/
                        m_paiFreeSpecialistCount[iI] = 0;
/************************************************************************************************/
/* Afforess                          END                                                            */
/************************************************************************************************/
                }
                //TB Traits begin              
                FAssertMsg(0 < GC.getNumSpecialistInfos(), "GC.getNumSpecialistInfos() is not greater than zero but it is used to allocate memory in CvPlayer::reset");
                FAssertMsg(m_ppaaiSpecialistExtraCommerce==NULL, "about to leak memory, CvPlayer::m_ppaaiSpecialistExtraCommerce");
                m_ppaaiSpecialistExtraCommerce = new int*[GC.getNumSpecialistInfos()];
                for (iI = 0; iI < GC.getNumSpecialistInfos(); iI++)
                {
                        m_ppaaiSpecialistExtraCommerce[iI] = new int[NUM_COMMERCE_TYPES];
                        for (iJ = 0; iJ < NUM_COMMERCE_TYPES; iJ++)
                        {
                                m_ppaaiSpecialistExtraCommerce[iI][iJ] = 0;
                        }
                }

                //TB Traits end
                FAssertMsg(m_ppaaiImprovementYieldChange==NULL, "about to leak memory, CvPlayer::m_ppaaiImprovementYieldChange");
                m_ppaaiImprovementYieldChange = new int*[GC.getNumImprovementInfos()];
                //TB Traits begin
                FAssertMsg(m_paiImprovementUpgradeRateModifierSpecific==NULL, "about to leak memory, CvPlayer::m_paiImprovementUpgradeRateModifierSpecific");
                m_paiImprovementUpgradeRateModifierSpecific = new int [GC.getNumImprovementInfos()];
                //TB Traits end
                for (iI = 0; iI < GC.getNumImprovementInfos(); iI++)
                {
                        m_ppaaiImprovementYieldChange[iI] = new int[NUM_YIELD_TYPES];
                        for (iJ = 0; iJ < NUM_YIELD_TYPES; iJ++)
                        {
                                m_ppaaiImprovementYieldChange[iI][iJ] = 0;
                        }
                        //TB Traits begin
                        m_paiImprovementUpgradeRateModifierSpecific[iI] = 0;
                        //TB Traits end
                }

/************************************************************************************************/
/* Afforess                       Start          12/9/09                                                */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/
                FAssertMsg(m_paiUnitCombatProductionModifier==NULL, "about to leak memory, CvPlayer::m_paiUnitCombatProductionModifier");
                m_paiUnitCombatProductionModifier = new int [GC.getNumUnitCombatInfos()];
                for (iI = 0; iI < GC.getNumUnitCombatInfos(); iI++)
                {
                        m_paiUnitCombatProductionModifier[iI] = 0;
                }
               
                FAssertMsg(m_paiBonusMintedPercent==NULL, "about to leak memory, CvPlayer::m_paiBonusMintedPercent");
                m_paiBonusMintedPercent = new int [GC.getNumBonusInfos()];
                for (iI = 0; iI < GC.getNumBonusInfos(); iI++)
                {
                        m_paiBonusMintedPercent[iI] = 0;
                }

                FAssertMsg(m_paiBuildingClassProductionModifier==NULL, "about to leak memory, CvPlayer::m_paiBuildingClassProductionModifier");
                m_paiBuildingClassProductionModifier = new int [GC.getNumBuildingClassInfos()];
                for (iI = 0; iI < GC.getNumBuildingClassInfos(); iI++)
                {
                        m_paiBuildingClassProductionModifier[iI] = 0;
                }
               
                FAssertMsg(m_paiUnitClassProductionModifier==NULL, "about to leak memory, CvPlayer::m_paiUnitClassProductionModifier");
                m_paiUnitClassProductionModifier = new int [GC.getNumUnitClassInfos()];
                for (iI = 0; iI < GC.getNumUnitClassInfos(); iI++)
                {
                        m_paiUnitClassProductionModifier[iI] = 0;
                }

                FAssertMsg(m_pabAutomatedCanBuild==NULL, "about to leak memory, CvPlayer::m_pabAutomatedCanBuild");
                m_pabAutomatedCanBuild = new bool [GC.getNumBuildInfos()];
                for (iI = 0; iI < GC.getNumBuildInfos(); iI++)
                {
                        m_pabAutomatedCanBuild[iI] = true;
                }
               
                FAssertMsg(m_paiResourceConsumption==NULL, "about to leak memory, CvPlayer::m_paiResourceConsumption");
                m_paiResourceConsumption = new int [GC.getNumBonusInfos()];
                for (iI = 0; iI < GC.getNumBonusInfos(); iI++)
                {
                        m_paiResourceConsumption[iI] = 0;
                }

                FAssertMsg(m_ppaaiTerrainYieldChange==NULL, "about to leak memory, CvPlayer::m_ppaaiTerrainYieldChange");
                m_ppaaiTerrainYieldChange = new int*[GC.getNumTerrainInfos()];
                for (iI = 0; iI < GC.getNumTerrainInfos(); iI++)
                {
                        m_ppaaiTerrainYieldChange[iI] = new int[NUM_YIELD_TYPES];
                        for (iJ = 0; iJ < NUM_YIELD_TYPES; iJ++)
                        {
                                m_ppaaiTerrainYieldChange[iI][iJ] = 0;
                        }
                }
                FAssertMsg(m_ppiBuildingCommerceModifier==NULL, "about to leak memory, CvPlayer::m_ppiBuildingCommerceModifier");
                m_ppiBuildingCommerceModifier = new int*[GC.getNumBuildingInfos()];
                for (iI = 0; iI < GC.getNumBuildingInfos(); iI++)
                {
                        m_ppiBuildingCommerceModifier[iI] = new int[NUM_COMMERCE_TYPES];
                        for (iJ = 0; iJ < NUM_COMMERCE_TYPES; iJ++)
                        {
                                m_ppiBuildingCommerceModifier[iI][iJ] = 0;
                        }
                }
                FAssertMsg(m_ppiBuildingClassCommerceChange==NULL, "about to leak memory, CvPlayer::m_ppiBuildingClassCommerceChange");
                m_ppiBuildingClassCommerceChange = new int*[GC.getNumBuildingClassInfos()];
                for (iI = 0; iI < GC.getNumBuildingClassInfos(); iI++)
                {
                        m_ppiBuildingClassCommerceChange[iI] = new int[NUM_COMMERCE_TYPES];
                        for (iJ = 0; iJ < NUM_COMMERCE_TYPES; iJ++)
                        {
                                m_ppiBuildingClassCommerceChange[iI][iJ] = 0;
                        }
                }

                FAssertMsg(m_ppiBonusCommerceModifier==NULL, "about to leak memory, CvPlayer::m_ppiBonusCommerceModifier");
                m_ppiBonusCommerceModifier = new int*[GC.getNumBonusInfos()];
                for (iI = 0; iI < GC.getNumBonusInfos(); iI++)
                {
                        m_ppiBonusCommerceModifier[iI] = new int[NUM_COMMERCE_TYPES];
                        for (iJ = 0; iJ < NUM_COMMERCE_TYPES; iJ++)
                        {
                                m_ppiBonusCommerceModifier[iI][iJ] = 0;
                        }
                }
               
                FAssertMsg(m_ppiSpecialistCommercePercentChanges==NULL, "about to leak memory, CvPlayer::m_ppiSpecialistCommercePercentChanges");
                FAssertMsg(m_ppiSpecialistYieldPercentChanges==NULL, "about to leak memory, CvPlayer::m_ppiSpecialistYieldPercentChanges");
                m_ppiSpecialistCommercePercentChanges = new int*[GC.getNumSpecialistInfos()];
                m_ppiSpecialistYieldPercentChanges = new int*[GC.getNumSpecialistInfos()];
                for (iI = 0; iI < GC.getNumSpecialistInfos(); iI++)
                {
                        m_ppiSpecialistCommercePercentChanges[iI] = new int[NUM_COMMERCE_TYPES];
                        for (iJ = 0; iJ < NUM_COMMERCE_TYPES; iJ++)
                        {
                                m_ppiSpecialistCommercePercentChanges[iI][iJ] = 0;
                        }
                        m_ppiSpecialistYieldPercentChanges[iI] = new int[NUM_YIELD_TYPES];
                        for (iJ = 0; iJ < NUM_YIELD_TYPES; iJ++)
                        {
                                m_ppiSpecialistYieldPercentChanges[iI][iJ] = 0;
                        }
                }
               
                for (iI = 0; iI < NUM_MODDEROPTION_TYPES; iI++)
                {
                        m_aiModderOptions[iI] = 0;
                }

                for (iI = 0; iI < MAX_PLAYERS; iI++)
                {
                        m_aiCeaseContactCounter[iI] = 0;
                }
/************************************************************************************************/
/* Afforess                          END                                                            */
/************************************************************************************************/
                m_mapEventsOccured.clear();
                m_mapEventCountdown.clear();
                m_aFreeUnitCombatPromotions.clear();
                m_aFreeUnitClassPromotions.clear();
                m_aVote.clear();
                m_aUnitExtraCosts.clear();
                m_triggersFired.clear();
        }

        m_plotGroups.removeAll();

        //m_cities.removeAll();
        clearAllCities();

        //m_units.removeAll();
        clearAllUnits();
        m_pTempUnit = NULL;

        //m_selectionGroups.removeAll();
        clearAllSelectionGroups();

        m_eventsTriggered.removeAll();

        if (!bConstructorCall)
        {
                m_BuildingList.init();
                AI_reset(false);
        }

/************************************************************************************************/
/* REVOLUTIONDCM_MOD                         02/04/08                            Glider1        */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/
        // RevolutionDCM start - new diplomacy option
        setDoNotBotherStatus(NO_PLAYER);
        // RevolutionDCM end
/************************************************************************************************/
/* REVOLUTIONDCM_MOD                         END                                 Glider1        */
/************************************************************************************************/
        m_UnitList.init();

        m_iNumAnimalsSubdued = 0;
        m_iNumAnarchyTurns = 0;
        m_iNumCivicSwitches = 0;
        m_iNumCivicsSwitched = 0;
        m_unitConstructionCounts.clear();

        m_bMaintenanceDirty = false;
        m_bUpdatesDeferred = false;
        Commanders.clear();
}

/************************************************************************************************/
/* CHANGE_PLAYER                          08/17/08                                jdog5000      */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/
//
// for logging
//
void CvPlayer::logMsg(char* format, ... )
{
        if (GC.isXMLLogging())
        {
                static char buf[2048];
                _vsnprintf( buf, 2048-4, format, (char*)(&format+1) );
                gDLL->logMsg("sdkDbg.log", buf);
        }
}

/************************************************************************************************/
/* CHANGE_PLAYER                           END                                                  */
/************************************************************************************************/

/************************************************************************************************/
/* CHANGE_PLAYER                          08/17/08                                jdog5000      */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/
//
// for stripping obsolete trait bonuses
// for complete reset, use in conjunction with addTraitBonuses
//
void CvPlayer::clearTraitBonuses( )
{
        int iI;

        FAssertMsg((GC.getNumTraitInfos() > 0), "GC.getNumTraitInfos() is less than or equal to zero but is expected to be larger than zero in CvPlayer::init");
        for (iI = 0; iI < GC.getNumTraitInfos(); iI++)
        {
                if (hasTrait((TraitTypes)iI))
                {
                        processTrait((TraitTypes)iI, -1);
                }
        }
}

//
// for adding new trait bonuses
//
void CvPlayer::addTraitBonuses( )
{
        int iI;

        FAssertMsg((GC.getNumTraitInfos() > 0), "GC.getNumTraitInfos() is less than or equal to zero but is expected to be larger than zero in CvPlayer::init");
        for (iI = 0; iI < GC.getNumTraitInfos(); iI++)
        {
                if (hasTrait((TraitTypes)iI))
                {
                        processTrait((TraitTypes)iI, 1);
                }
        }

        updateMaxAnarchyTurns();

        for (iI = 0; iI < NUM_YIELD_TYPES; iI++)
        {
                updateExtraYieldThreshold((YieldTypes)iI);
        }
}
/************************************************************************************************/
/* CHANGE_PLAYER                           END                                                  */
/************************************************************************************************/

/************************************************************************************************/
/* CHANGE_PLAYER                          08/17/08                                jdog5000      */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/
//
// for changing the personality of the player
//
void CvPlayer::changePersonalityType( )
{
        LeaderHeadTypes eBestPersonality;
        int iValue;
        int iBestValue;
        int iI, iJ;

        if (GC.getGameINLINE().isOption(GAMEOPTION_RANDOM_PERSONALITIES))
        {
                if (!isBarbarian())
                {
                        iBestValue = 0;
                        eBestPersonality = NO_LEADER;

                        for (iI = 0; iI < GC.getNumLeaderHeadInfos(); iI++)
                        {
                                if (iI != GC.getDefineINT("BARBARIAN_LEADER")) // XXX minor civ???
                                {
                                        iValue = (1 + GC.getGameINLINE().getSorenRandNum(10000, "Choosing Personality"));

                                        for (iJ = 0; iJ < MAX_CIV_PLAYERS; iJ++)
                                        {
                                                if (GET_PLAYER((PlayerTypes)iJ).isAlive())
                                                {
                                                        if (GET_PLAYER((PlayerTypes)iJ).getPersonalityType() == ((LeaderHeadTypes)iI))
                                                        {
                                                                iValue /= 2;
                                                        }
                                                }
                                        }

                                        if (iValue > iBestValue)
                                        {
                                                iBestValue = iValue;
                                                eBestPersonality = ((LeaderHeadTypes)iI);
                                        }
                                }
                        }

                        if (eBestPersonality != NO_LEADER)
                        {
                                setPersonalityType(eBestPersonality);
                        }
                }
        }
        else
        {
                setPersonalityType( getLeaderType() );
        }
}
/************************************************************************************************/
/* CHANGE_PLAYER                           END                                                  */
/************************************************************************************************/

/************************************************************************************************/
/* CHANGE_PLAYER                          08/17/08                                jdog5000      */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/
//
// reset state of event logic, unit prices
//
void CvPlayer::resetCivTypeEffects( )
{
        int iI;

        if( !isAlive() )
        {
                for (iI = 0; iI < GC.getNumCivicOptionInfos(); iI++)
                {
                        setCivics(((CivicOptionTypes)iI), ((CivicTypes)(GC.getCivilizationInfo(getCivilizationType()).getCivilizationInitialCivics(iI))));
                }

                for (iI = 0; iI < GC.getNumEventInfos(); iI++)
                {
                        resetEventOccured((EventTypes)iI, false);
                }

                for (iI = 0; iI < GC.getNumEventTriggerInfos(); iI++)
                {
                        if( (!GC.getEventTriggerInfo((EventTriggerTypes)iI).isGlobal()) && (!GC.getEventTriggerInfo((EventTriggerTypes)iI).isTeam() || GET_TEAM(getTeam()).getNumMembers() == 1) )
                        {
                                resetTriggerFired((EventTriggerTypes)iI);
                        }
                }
        }

        for (iI = 0; iI < GC.getNumUnitClassInfos(); ++iI)
        {
                UnitTypes eUnit = ((UnitTypes)(GC.getCivilizationInfo(getCivilizationType()).getCivilizationUnits(iI)));

                if (NO_UNIT != eUnit)
                {
                        if (GC.getUnitInfo(eUnit).isFound())
                        {
                                setUnitExtraCost((UnitClassTypes)iI, getNewCityProductionValue());
                        }
                }
        }
}
/************************************************************************************************/
/* CHANGE_PLAYER                           END                                                  */
/************************************************************************************************/

/************************************************************************************************/
/* CHANGE_PLAYER                          08/17/08                                jdog5000      */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/
//
// for switching the leaderhead of this player
//
void CvPlayer::changeLeader( LeaderHeadTypes eNewLeader )
{
        LeaderHeadTypes eOldLeader = getLeaderType();

        if( eOldLeader == eNewLeader )
                return;

        // Clear old traits
        clearTraitBonuses();

        GC.getInitCore().setLeader( getID(), eNewLeader );

        // Add new traits
        addTraitBonuses();

        // Set new personality
        changePersonalityType();

        if( isAlive() || isEverAlive() )
        {
                gDLL->getInterfaceIFace()->setDirty(HighlightPlot_DIRTY_BIT, true);
                gDLL->getInterfaceIFace()->setDirty(CityInfo_DIRTY_BIT, true);
                gDLL->getInterfaceIFace()->setDirty(UnitInfo_DIRTY_BIT, true);
                gDLL->getInterfaceIFace()->setDirty(InfoPane_DIRTY_BIT, true);
                gDLL->getInterfaceIFace()->setDirty(Flag_DIRTY_BIT, true);
                gDLL->getInterfaceIFace()->setDirty(MinimapSection_DIRTY_BIT, true);
                gDLL->getInterfaceIFace()->setDirty(Score_DIRTY_BIT, true);
                gDLL->getInterfaceIFace()->setDirty(Foreign_Screen_DIRTY_BIT, true);
        }

        AI_init();
}
/************************************************************************************************/
/* CHANGE_PLAYER                           END                                                  */
/************************************************************************************************/

/************************************************************************************************/
/* CHANGE_PLAYER                          05/09/09                                jdog5000      */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/
//
// for changing the civilization of this player
//
void CvPlayer::changeCiv( CivilizationTypes eNewCiv )
{
        CivilizationTypes eOldCiv = getCivilizationType();
        PlayerColorTypes eColor = (PlayerColorTypes)GC.getCivilizationInfo(eNewCiv).getDefaultPlayerColor();

        if( eOldCiv == eNewCiv )
                return;

        for (int iI = 0; iI < MAX_CIV_PLAYERS; iI++)
        {
                if (eColor == NO_PLAYERCOLOR || (GET_PLAYER((PlayerTypes)iI).getPlayerColor() == eColor && iI != getID()) )
                {
                        for (int iK = 0; iK < GC.getNumPlayerColorInfos(); iK++)
                        {
                                if (iK != GC.getCivilizationInfo((CivilizationTypes)GC.getDefineINT("BARBARIAN_CIVILIZATION")).getDefaultPlayerColor())
                                {
                                        bool bValid = true;

                                        for (int iL = 0; iL < MAX_CIV_PLAYERS; iL++)
                                        {
                                                if (GET_PLAYER((PlayerTypes)iL).getPlayerColor() == iK)
                                                {
                                                        bValid = false;
                                                        break;
                                                }
                                        }

                                        if (bValid)
                                        {
                                                eColor = (PlayerColorTypes)iK;
                                                iI = MAX_CIV_PLAYERS;
                                                break;
                                        }
                                }
                        }
                }
        }

        GC.getInitCore().setCiv( getID(), eNewCiv );
        GC.getInitCore().setColor( getID(), eColor );

        resetCivTypeEffects();

        if( isAlive() )
        {
                // if the player is alive and showing on scoreboard, etc
                // change colors, graphics, flags, units
                GC.getInitCore().setFlagDecal( getID(), (CvWString)GC.getCivilizationInfo(eNewCiv).getFlagTexture() );
                GC.getInitCore().setArtStyle( getID(), (ArtStyleTypes)GC.getCivilizationInfo(eNewCiv).getArtStyleType() );

                // Forces update of units flags
                EraTypes eEra = getCurrentEra();
                bool bAuto = m_bDisableHuman;
                m_bDisableHuman = true;
                //setCurrentEra((EraTypes)((eEra + 1)%GC.getNumEraInfos()));
                setCurrentEra((EraTypes)0);
                setCurrentEra((EraTypes)(GC.getNumEraInfos() - 1));

                setCurrentEra(eEra);
                m_bDisableHuman = bAuto;
                gDLL->getInterfaceIFace()->makeInterfaceDirty();
               

                int iLoop = 0;
                CvCity* pLoopCity;
                // dirty all of this player's cities...
                for (pLoopCity = firstCity(&iLoop); pLoopCity != NULL; pLoopCity = nextCity(&iLoop))
                {
                        if (pLoopCity->getOwnerINLINE() == getID())
                        {
                                pLoopCity->setLayoutDirty(true);
                        }
                }

                //update unit eras
                CvUnit* pLoopUnit;
                CvPlot* pLoopPlot;
                for(pLoopUnit = firstUnit(&iLoop); pLoopUnit != NULL; pLoopUnit = nextUnit(&iLoop))
                {
                        pLoopUnit->reloadEntity();
                        pLoopPlot = pLoopUnit->plot();
/*
                        if( pLoopPlot != NULL )
                        {
                               
                                CvFlagEntity* pFlag = pLoopPlot->getFlagSymbol();

                                if( pFlag != NULL )
                                {

                                        if( gDLL->getFlagEntityIFace()->getPlayer(pFlag) == getID() )
                                        {
                                                gDLL->getFlagEntityIFace()->destroy(pFlag);
                                                CvFlagEntity* pNewFlag = gDLL->getFlagEntityIFace()->create(getID());
                                                if (pFlag != NULL)
                                                {
                                                        gDLL->getFlagEntityIFace()->setPlot(pNewFlag, pLoopPlot, false);
                                                }

                                                gDLL->getFlagEntityIFace()->updateGraphicEra(pNewFlag);
                                        }

                                }
                               
                                pLoopPlot->setFlagDirty(true);
                                //pLoopPlot->updateGraphicEra();
                        }
*/

                }

                //update flag eras
                gDLL->getInterfaceIFace()->setDirty(Flag_DIRTY_BIT, true);

                if (getID() == GC.getGameINLINE().getActivePlayer())
                {
                        gDLL->getInterfaceIFace()->setDirty(Soundtrack_DIRTY_BIT, true);
                }

                gDLL->getInterfaceIFace()->makeInterfaceDirty();

                // Need to force redraw
                gDLL->getEngineIFace()->SetDirty(CultureBorders_DIRTY_BIT, true);
                gDLL->getEngineIFace()->SetDirty(MinimapTexture_DIRTY_BIT, true);
                gDLL->getEngineIFace()->SetDirty(GlobeTexture_DIRTY_BIT, true);
                gDLL->getEngineIFace()->SetDirty(GlobePartialTexture_DIRTY_BIT, true);

                gDLL->getInterfaceIFace()->setDirty(ColoredPlots_DIRTY_BIT, true);
                gDLL->getInterfaceIFace()->setDirty(HighlightPlot_DIRTY_BIT, true);
                gDLL->getInterfaceIFace()->setDirty(CityInfo_DIRTY_BIT, true);
                gDLL->getInterfaceIFace()->setDirty(UnitInfo_DIRTY_BIT, true);
                gDLL->getInterfaceIFace()->setDirty(InfoPane_DIRTY_BIT, true);
                gDLL->getInterfaceIFace()->setDirty(GlobeLayer_DIRTY_BIT, true);
                gDLL->getInterfaceIFace()->setDirty(MinimapSection_DIRTY_BIT, true);
                gDLL->getEngineIFace()->SetDirty(MinimapTexture_DIRTY_BIT, true);
                gDLL->getInterfaceIFace()->setDirty(Score_DIRTY_BIT, true);
                gDLL->getInterfaceIFace()->setDirty(Foreign_Screen_DIRTY_BIT, true);
                gDLL->getInterfaceIFace()->setDirty(SelectionSound_DIRTY_BIT, true);
                gDLL->getInterfaceIFace()->setDirty(GlobeInfo_DIRTY_BIT, true);
        }
        else if( isEverAlive() )
        {
                // Not currently alive, but may show on some people's scoreboard
                // or graphs
                // change colors
                gDLL->getInterfaceIFace()->setDirty(InfoPane_DIRTY_BIT, true);
                gDLL->getInterfaceIFace()->setDirty(Score_DIRTY_BIT, true);
        }

        setupGraphical();
}
/************************************************************************************************/
/* CHANGE_PLAYER                           END                                                  */
/************************************************************************************************/

/************************************************************************************************/
/* CHANGE_PLAYER                          08/17/08                                jdog5000      */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/
//
// for changing whether this player is human or not
//
void CvPlayer::setIsHuman( bool bNewValue )
{
        if( bNewValue == isHuman() )
                return;

        if( bNewValue )
                GC.getInitCore().setSlotStatus( getID(), SS_TAKEN );
        else
                GC.getInitCore().setSlotStatus( getID(), SS_COMPUTER ); // or SS_OPEN for multiplayer?

}
/************************************************************************************************/
/* CHANGE_PLAYER                          END                                                  */
/************************************************************************************************/

/************************************************************************************************/
/* REVOLUTION_MOD                         01/01/08                                jdog5000      */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/
//
// for setting status of player to rebel, which affords some benefits
//
void CvPlayer::setIsRebel( bool bNewValue )
{
        if( bNewValue == isRebel() )
                return;
        else
                m_bRebel = bNewValue;
}

bool CvPlayer::isRebel() const
{
        return m_bRebel;
}
/************************************************************************************************/
/* REVOLUTION_MOD                          END                                                  */
/************************************************************************************************/

/************************************************************************************************/
/* REVOLUTION_MOD                         06/11/08                                jdog5000      */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/
int CvPlayer::getStabilityIndex( ) const
{
        return m_iStabilityIndex;
}

void CvPlayer::setStabilityIndex( int iNewValue )
{
        m_iStabilityIndex = range(iNewValue,0,1000);
}

void CvPlayer::changeStabilityIndex( int iChange )
{
        setStabilityIndex( getStabilityIndex() + iChange );
}

int CvPlayer::getStabilityIndexAverage( ) const
{
        return m_iStabilityIndexAverage;
}

void CvPlayer::setStabilityIndexAverage( int iNewValue )
{
        m_iStabilityIndexAverage = range(iNewValue,0,1000);
}

void CvPlayer::updateStabilityIndexAverage( )
{
        setStabilityIndexAverage( (2*getStabilityIndexAverage() + getStabilityIndex())/3 );
}
/************************************************************************************************/
/* REVOLUTION_MOD                          END                                                  */
/************************************************************************************************/

//////////////////////////////////////
// graphical only setup
//////////////////////////////////////
void CvPlayer::setupGraphical()
{
        if (!GC.IsGraphicsInitialized())
                return;

        CvCity* pLoopCity;
        CvUnit* pLoopUnit;

        // Setup m_cities
        int iLoop = 0;
        for (pLoopCity = firstCity(&iLoop); pLoopCity != NULL; pLoopCity = nextCity(&iLoop))
        {
                pLoopCity->setupGraphical();
        }

        // Setup m_units
        for(pLoopUnit = firstUnit(&iLoop); pLoopUnit != NULL; pLoopUnit = nextUnit(&iLoop))
        {
                //pLoopUnit->setupGraphical();
                pLoopUnit->reloadEntity();
        }
}


void CvPlayer::initFreeState()
{
        setGold(0);
        changeGold(GC.getHandicapInfo(getHandicapType()).getStartingGold());
        changeGold(GC.getEraInfo(GC.getGameINLINE().getStartEra()).getStartingGold());

        clearResearchQueue();
}


void CvPlayer::initFreeUnits()
{
        UnitTypes eLoopUnit;
        int iFreeCount;
        int iI, iJ;

        if (GC.getGameINLINE().isOption(GAMEOPTION_ADVANCED_START) && !isBarbarian())
        {
                int iPoints = GC.getGameINLINE().getNumAdvancedStartPoints();

                iPoints *= GC.getHandicapInfo(getHandicapType()).getAdvancedStartPointsMod();
                iPoints /= 100;

                if (!isHuman())
                {
                        iPoints *= GC.getHandicapInfo(getHandicapType()).getAIAdvancedStartPercent();
                        iPoints /= 100;
                }

                setAdvancedStartPoints(iPoints);

                // Starting visibility
                CvPlot* pStartingPlot = getStartingPlot();
                if (NULL != pStartingPlot)
                {
                        for (int iPlotLoop = 0; iPlotLoop < GC.getMapINLINE().numPlots(); ++iPlotLoop)
                        {
                                CvPlot* pPlot = GC.getMapINLINE().plotByIndex(iPlotLoop);

                                if (plotDistance(pPlot->getX_INLINE(), pPlot->getY_INLINE(), pStartingPlot->getX_INLINE(), pStartingPlot->getY_INLINE()) <= GC.getDefineINT("ADVANCED_START_SIGHT_RANGE"))
                                {
                                        pPlot->setRevealed(getTeam(), true, false, NO_TEAM, false);
                                }
                        }
                }
        }
        else
        {
                for (iI = 0; iI < GC.getNumUnitClassInfos(); iI++)
                {
                        eLoopUnit = (UnitTypes)GC.getCivilizationInfo(getCivilizationType()).getCivilizationUnits(iI);

                        if (eLoopUnit != NO_UNIT)
                        {
                                iFreeCount = GC.getCivilizationInfo(getCivilizationType()).getCivilizationFreeUnitsClass(iI);

                                iFreeCount *= (GC.getEraInfo(GC.getGameINLINE().getStartEra()).getStartingUnitMultiplier() + ((!isHuman()) ? GC.getHandicapInfo(GC.getGameINLINE().getHandicapType()).getAIStartingUnitMultiplier() : 0));

                                for (iJ = 0; iJ < iFreeCount; iJ++)
                                {
                                        addFreeUnit(eLoopUnit);
                                }
                        }
                }

                iFreeCount = GC.getEraInfo(GC.getGameINLINE().getStartEra()).getStartingDefenseUnits();
                iFreeCount += GC.getHandicapInfo(getHandicapType()).getStartingDefenseUnits();

                if (!isHuman())
                {
                        iFreeCount += GC.getHandicapInfo(GC.getGameINLINE().getHandicapType()).getAIStartingDefenseUnits();
                }

                if (iFreeCount > 0)
                {
                        addFreeUnitAI(UNITAI_CITY_DEFENSE, iFreeCount);
                }

                iFreeCount = GC.getEraInfo(GC.getGameINLINE().getStartEra()).getStartingWorkerUnits();
                iFreeCount += GC.getHandicapInfo(getHandicapType()).getStartingWorkerUnits();

                if (!isHuman())
                {
                        iFreeCount += GC.getHandicapInfo(GC.getGameINLINE().getHandicapType()).getAIStartingWorkerUnits();
                }

                if (iFreeCount > 0)
                {
                        addFreeUnitAI(UNITAI_WORKER, iFreeCount);
                }

                iFreeCount = GC.getEraInfo(GC.getGameINLINE().getStartEra()).getStartingExploreUnits();
                iFreeCount += GC.getHandicapInfo(getHandicapType()).getStartingExploreUnits();

                if (!isHuman())
                {
                        iFreeCount += GC.getHandicapInfo(GC.getGameINLINE().getHandicapType()).getAIStartingExploreUnits();
                }

                if (iFreeCount > 0)
                {
                        addFreeUnitAI(UNITAI_EXPLORE, iFreeCount);
                }
        }
}


/************************************************************************************************/
/* LoR                                        11/03/10                          phungus420      */
/*                                                                                              */
/* Colonists                                                                                    */
/************************************************************************************************/
UnitTypes CvPlayer::getBestUnitType(UnitAITypes eUnitAI) const
{
        UnitTypes eLoopUnit;
        UnitTypes eBestUnit = NO_UNIT;
        bool bValid;
        int iValue;
        int iBestValue = 0;
        int iI, iJ;

        for (iI = 0; iI < GC.getNumUnitClassInfos(); iI++)
        {
                eLoopUnit = (UnitTypes)GC.getCivilizationInfo(getCivilizationType()).getCivilizationUnits(iI);

                if (eLoopUnit != NO_UNIT)
                {
                        if (canTrain(eLoopUnit))
                        {
                                bValid = true;

                                if (GC.getUnitInfo(eLoopUnit).getPrereqAndBonus() != NO_BONUS)
                                {
                                        bValid = false;
                                }

                                for (iJ = 0; iJ < GC.getNUM_UNIT_PREREQ_OR_BONUSES(); iJ++)
                                {
                                        if (GC.getUnitInfo(eLoopUnit).getPrereqOrBonuses(iJ) != NO_BONUS)
                                        {
                                                bValid = false;
                                        }
                                }

                                if (bValid)
                                {
                                        iValue = AI_unitValue(eLoopUnit, eUnitAI, NULL);

                                        if (iValue > iBestValue)
                                        {
                                                eBestUnit = eLoopUnit;
                                                iBestValue = iValue;
                                        }
                                }
                        }
                }
        }

        return eBestUnit;
}
/************************************************************************************************/
/* LoR                            END                                                           */
/************************************************************************************************/


void CvPlayer::addFreeUnitAI(UnitAITypes eUnitAI, int iCount)
{
        UnitTypes eLoopUnit;
        UnitTypes eBestUnit;
        bool bValid;
        int iValue;
        int iBestValue;
        int iI, iJ;

        eBestUnit = NO_UNIT;
        iBestValue = 0;

        for (iI = 0; iI < GC.getNumUnitClassInfos(); iI++)
        {
                eLoopUnit = (UnitTypes)GC.getCivilizationInfo(getCivilizationType()).getCivilizationUnits(iI);

                if (eLoopUnit != NO_UNIT)
                {
                        if (canTrain(eLoopUnit))
                        {
                                bValid = true;

                                if (GC.getUnitInfo(eLoopUnit).getPrereqAndBonus() != NO_BONUS)
                                {
                                        bValid = false;
                                }

                                for (iJ = 0; iJ < GC.getNUM_UNIT_PREREQ_OR_BONUSES(); iJ++)
                                {
                                        if (GC.getUnitInfo(eLoopUnit).getPrereqOrBonuses(iJ) != NO_BONUS)
                                        {
                                                bValid = false;
                                        }
                                }

                                if (bValid)
                                {
                                        iValue = AI_unitValue(eLoopUnit, eUnitAI, NULL);

                                        if (iValue > iBestValue)
                                        {
                                                eBestUnit = eLoopUnit;
                                                iBestValue = iValue;
                                        }
                                }
                        }
                }
        }

        if (eBestUnit != NO_UNIT)
        {
                for (iI = 0; iI < iCount; iI++)
                {
                        addFreeUnit(eBestUnit, eUnitAI);
                }
        }
}


void CvPlayer::addFreeUnit(UnitTypes eUnit, UnitAITypes eUnitAI)
{
        CvPlot* pStartingPlot;
        CvPlot* pBestPlot;
        CvPlot* pLoopPlot;
        int iRandOffset;
        int iI;

        if (GC.getGameINLINE().isOption(GAMEOPTION_ONE_CITY_CHALLENGE) && isHuman())
        {
                if ((eUnitAI == UNITAI_SETTLE) || (GC.getUnitInfo(eUnit).getDefaultUnitAIType() == UNITAI_SETTLE))
                {
                        if (AI_getNumAIUnits(UNITAI_SETTLE) >= 1)
                        {
                                return;
                        }
                }
        }

        pStartingPlot = getStartingPlot();

        if (pStartingPlot != NULL)
        {
                pBestPlot = NULL;

                if (isHuman())
                {
                        long lResult=0;
                        PYTHON_CALL_FUNCTION4(__FUNCTION__, gDLL->getPythonIFace()->getMapScriptModule(), "startHumansOnSameTile", NULL, &lResult);
                        if (lResult == 0)
                        {
                                if (!(GC.getUnitInfo(eUnit).isFound()))
                                {
                                        iRandOffset = GC.getGameINLINE().getSorenRandNum(NUM_CITY_PLOTS, "Place Units (Player)");

                                        for (iI = 0; iI < NUM_CITY_PLOTS; iI++)
                                        {
                                                pLoopPlot = plotCity(pStartingPlot->getX_INLINE(), pStartingPlot->getY_INLINE(), ((iI + iRandOffset) % NUM_CITY_PLOTS));

                                                if (pLoopPlot != NULL)
                                                {
                                                        if (pLoopPlot->getArea() == pStartingPlot->getArea())
                                                        {
                                                        /************************************************************************************************/
                                                        /* Afforess     Mountains Start          09/18/09                                                        */
                                                        /*                                                                                              */
                                                        /*                                                                                              */
                                                        /************************************************************************************************/
                                                                if (!(pLoopPlot->isImpassable(getTeam()))) // added getTeam()
                                                        /************************************************************************************************/
                                                        /* Afforess     Mountains End       END                                                              */
                                                        /************************************************************************************************/
                                                                {
                                                                        if (!(pLoopPlot->isUnit()))
                                                                        {
                                                                                if (!(pLoopPlot->isGoody()))
                                                                                {
                                                                                        pBestPlot = pLoopPlot;
                                                                                        break;
                                                                                }
                                                                        }
                                                                }
                                                        }
                                                }
                                        }
                                }
                        }
                }

                if (pBestPlot == NULL)
                {
                        pBestPlot = pStartingPlot;
                }

                initUnit(eUnit, pBestPlot->getX_INLINE(), pBestPlot->getY_INLINE(), eUnitAI, NO_DIRECTION, GC.getGameINLINE().getSorenRandNum(10000, "AI Unit Birthmark 14"));
        }
}


int CvPlayer::startingPlotRange() const
{
        int iRange;

        iRange = (GC.getMapINLINE().maxStepDistance() + 10);

        iRange *= GC.getDefineINT("STARTING_DISTANCE_PERCENT");
        iRange /= 100;

        iRange *= (GC.getMapINLINE().getLandPlots() / (GC.getWorldInfo(GC.getMapINLINE().getWorldSize()).getTargetNumCities() * GC.getGameINLINE().countCivPlayersAlive()));
        iRange /= NUM_CITY_PLOTS;

        iRange += std::min(((GC.getMapINLINE().getNumAreas() + 1) / 2), GC.getGameINLINE().countCivPlayersAlive());

        long lResult=0;
        if (PYTHON_CALL_FUNCTION4(__FUNCTION__, gDLL->getPythonIFace()->getMapScriptModule(), "minStartingDistanceModifier", NULL, &lResult))
        {
                iRange *= std::max<int>(0, (lResult + 100));
                iRange /= 100;
        }

        return std::max(iRange, GC.getDefineINT("MIN_CIV_STARTING_DISTANCE"));
}


bool CvPlayer::startingPlotWithinRange(CvPlot* pPlot, PlayerTypes ePlayer, int iRange, int iPass) const
{
        //PROFILE_FUNC();

        //XXX changes to AI_foundValue (which are far more flexible) make this function
        //    redundant but it is still called from Python.
        return false;
}

int CvPlayer::startingPlotDistanceFactor(CvPlot* pPlot, PlayerTypes ePlayer, int iRange) const
{
        PROFILE_FUNC();
       
        FAssert(ePlayer != getID());

        CvPlot* pStartingPlot;
       
        int iValue = 1000;

        pStartingPlot = getStartingPlot();

        if (pStartingPlot != NULL)
        {
                if (GC.getGameINLINE().isTeamGame())
                {
                        if (GET_PLAYER(ePlayer).getTeam() == getTeam())
                        {
                                iRange *= GC.getDefineINT("OWN_TEAM_STARTING_MODIFIER");
                                iRange /= 100;
                        }
                        else
                        {
                                iRange *= GC.getDefineINT("RIVAL_TEAM_STARTING_MODIFIER");
                                iRange /= 100;
                        }
                }

                int iDistance = stepDistance(pPlot->getX_INLINE(), pPlot->getY_INLINE(), pStartingPlot->getX_INLINE(), pStartingPlot->getY_INLINE());
                if (pStartingPlot->getArea() != pPlot->getArea())
                {
                        iDistance *= 4;                
                        iDistance /= 3;
                }

                iValue *= iDistance;
                iValue /= iRange ;

        }
   
        return std::max(1, iValue);

}


// Returns the id of the best area, or -1 if it doesn't matter:
int CvPlayer::findStartingArea() const
{
        PYTHON_ACCESS_LOCK_SCOPE
        PROFILE_FUNC();

        long result = -1;
        CyArgsList argsList;
        argsList.add(getID());          // pass in this players ID
        if (PYTHON_CALL_FUNCTION4(__FUNCTION__, gDLL->getPythonIFace()->getMapScriptModule(), "findStartingArea", argsList.makeFunctionArgs(), &result))
        {
                if (!gDLL->getPythonIFace()->pythonUsingDefaultImpl()) // Python override
                {
                        if (result == -1 || GC.getMapINLINE().getArea(result) != NULL)
                        {
                                return result;
                        }
                        else
                        {
                                FAssertMsg(false, "python findStartingArea() must return -1 or the ID of a valid area");
                        }
                }
        }

        int iBestValue = 0;
        int iBestArea = -1;
        int iValue;
        int iLoop = 0;

        CvArea *pLoopArea = NULL;

        // find best land area
        for(pLoopArea = GC.getMapINLINE().firstArea(&iLoop); pLoopArea != NULL; pLoopArea = GC.getMapINLINE().nextArea(&iLoop))
        {
                if (!(pLoopArea->isWater()))
                {
                        // iNumPlayersOnArea is the number of players starting on the area, plus this player
                        int iNumPlayersOnArea = (pLoopArea->getNumStartingPlots() + 1);
                        int iTileValue = ((pLoopArea->calculateTotalBestNatureYield() + (pLoopArea->countCoastalLand() * 2) + pLoopArea->getNumRiverEdges() + (pLoopArea->getNumTiles())) + 1);
                        iValue = iTileValue / iNumPlayersOnArea;

                        iValue *= std::min(NUM_CITY_PLOTS + 1, pLoopArea->getNumTiles() + 1);
                        iValue /= (NUM_CITY_PLOTS + 1);

                        if (iNumPlayersOnArea <= 2)
                        {
                                iValue *= 4;
                                iValue /= 3;
                        }

                        if (iValue > iBestValue)
                        {
                                iBestValue = iValue;
                                iBestArea = pLoopArea->getID();
                        }
                }
        }

        return iBestArea;
}


CvPlot* CvPlayer::findStartingPlot(bool bRandomize)
{
        PROFILE_FUNC();

        {
                PYTHON_ACCESS_LOCK_SCOPE

                long result = -1;
                CyArgsList argsList;
                argsList.add(getID());          // pass in this players ID
                if (PYTHON_CALL_FUNCTION4(__FUNCTION__, gDLL->getPythonIFace()->getMapScriptModule(), "findStartingPlot", argsList.makeFunctionArgs(), &result))
                {
                        if (!gDLL->getPythonIFace()->pythonUsingDefaultImpl()) // Python override
                        {
                                CvPlot *pPlot = GC.getMapINLINE().plotByIndexINLINE(result);
                                if (pPlot != NULL)
                                {
                                        return pPlot;
                                }
                                else
                                {
                                        FAssertMsg(false, "python findStartingPlot() returned an invalid plot index!");
                                }
                        }
                }
        }

        CvPlot* pLoopPlot;
        bool bValid;
        int iBestArea = -1;
        int iValue;
        //int iRange;
        int iI;

        bool bNew = false;
        if (getStartingPlot() != NULL)
        {
                iBestArea = getStartingPlot()->getArea();
                setStartingPlot(NULL, true);
                bNew = true;
        }

        AI_updateFoundValues(true);
       
        if (!bNew)
        {
                iBestArea = findStartingArea();
        }

        //iRange = startingPlotRange();
        for(int iPass = 0; iPass < GC.getMapINLINE().maxPlotDistance(); iPass++)
        {
                CvPlot *pBestPlot = NULL;
                int iBestValue = 0;
               
                for (iI = 0; iI < GC.getMapINLINE().numPlotsINLINE(); iI++)
                {
                        pLoopPlot = GC.getMapINLINE().plotByIndexINLINE(iI);

                        if ((iBestArea == -1) || (pLoopPlot->getArea() == iBestArea))
                        {
                                //the distance factor is now done inside foundValue
                                iValue = pLoopPlot->getFoundValue(getID());

                                if (bRandomize && iValue > 0)
                                {
                                        iValue += GC.getGameINLINE().getSorenRandNum(10000, "Randomize Starting Location");
                                }

                                if (iValue > iBestValue)
                                {
                                        bValid = true;

                                        if (bValid)
                                        {
                                                iBestValue = iValue;
                                                pBestPlot = pLoopPlot;
                                        }
                                }
                        }
                }

                if (pBestPlot != NULL)
                {
                        return pBestPlot;
                }

                FAssertMsg(iPass != 0, "CvPlayer::findStartingPlot - could not find starting plot in first pass.");
        }

        FAssertMsg(false, "Could not find starting plot.");
        return NULL;
}


CvPlotGroup* CvPlayer::initPlotGroup(CvPlot* pPlot, bool bRecalculateBonuses)
{
        CvPlotGroup* pPlotGroup;

        pPlotGroup = addPlotGroup();

        FAssertMsg(pPlotGroup != NULL, "PlotGroup is not assigned a valid value");

        pPlotGroup->init(pPlotGroup->getID(), getID(), pPlot, bRecalculateBonuses);

        return pPlotGroup;
}

CvCity* CvPlayer::initCity(int iX, int iY, bool bBumpUnits, bool bUpdatePlotGroups)
{
        PROFILE_FUNC();

        CvPlot* pCityPlot = GC.getMapINLINE().plotINLINE(iX,iY);
        int iI, iJ;

        if ( bUpdatePlotGroups )
        {
                //      Take this group out of plot groups to remove any existing bonuses
                //      from it (it might have a resource)
                for (iI = 0; iI < MAX_PLAYERS; iI++)
                {
                        if (GET_PLAYER((PlayerTypes)iI).isAlive())
                        {
                                CvPlotGroup* pOldPlotGroup = pCityPlot->getPlotGroup((PlayerTypes)iI);

                                if ( pOldPlotGroup != NULL )
                                {
                                        pOldPlotGroup->removePlot(pCityPlot);
                                }
                        }
                }
        }

        CvCity* pCity;

        pCity = addCity();

        FAssertMsg(pCity != NULL, "City is not assigned a valid value");
        FAssertMsg(!(GC.getMapINLINE().plotINLINE(iX, iY)->isCity()), "No city is expected at this plot when initializing new city");

        pCity->init(pCity->getID(), getID(), iX, iY, bBumpUnits, false);

        if ( bUpdatePlotGroups )
        {
                //      Set the city plots plot groups again
                for (iI = 0; iI < MAX_PLAYERS; iI++)
                {
                        if (GET_PLAYER((PlayerTypes)iI).isAlive())
                        {
                                //      Need to check whether any cultural border chnages for this city
                                //      have sliced anyone's trade networks
                                bool tradeNetworkPotentiallyCut = false;

                                if ( atWar(getTeam(), GET_PLAYER((PlayerTypes)iI).getTeam()) )
                                {
                                        for (iJ = 0; iJ < pCity->getNumCityPlots(); iJ++)
                                        {
                                                CvPlot* pPlot = pCity->getCityIndexPlot(iJ);

                                                if (pPlot != NULL && pPlot->getOwnerINLINE() == getID())
                                                {
                                                        if (pPlot->getPlotGroup((PlayerTypes)iI) != NULL )
                                                        {
                                                                //      Player who the city founder is at war with has
                                                                //      a trade route intersecting the are newly controlled by
                                                                //      the founded city
                                                                tradeNetworkPotentiallyCut = true;
                                                                break;
                                                        }
                                                }
                                        }
                                }

                                if ( tradeNetworkPotentiallyCut )
                                {
                                        //      Need to recalculate
                                        GET_PLAYER((PlayerTypes)iI).updatePlotGroups();
                                }
                                else
                                {
                                        //      No meaningful changes - just add this city plot back in
                                        pCityPlot->updatePlotGroup((PlayerTypes)iI);
                                }
                        }
                }
        }

        //Afforess : extra culture level for traits
        for (int iI = 0; iI < GC.getNumTraitInfos(); iI++)
        {
                if (hasTrait((TraitTypes)iI) && GC.getTraitInfo((TraitTypes)iI).isExtraCultureLevel())
                {
                        int iCulture = pCity->getCultureThreshold();
                        if (iCulture > 0)
                        {
                                pCity->setCulture(getID(), iCulture, true, true);
                        }
                }
        }

        return pCity;
}


void CvPlayer::acquireCity(CvCity* pOldCity, bool bConquest, bool bTrade, bool bUpdatePlotGroups)
{
        PROFILE_FUNC();

/************************************************************************************************/
/* REVOLUTION_MOD                         01/01/08                                jdog5000      */
/*                                                                                              */
/* Copy over city data                                                                          */
/************************************************************************************************/
        std::string scriptData;
        int iRevIdx;
        int iLocalRevIdx;
/************************************************************************************************/
/* REVOLUTION_MOD                          END                                                  */
/************************************************************************************************/

        CLLNode<IDInfo>* pUnitNode;
        CvCity* pNewCity;
        CvUnit* pLoopUnit;
        CvPlot* pCityPlot;
        CvPlot* pLoopPlot;
        bool* pabHasReligion;
        bool* pabHolyCity;
        bool* pabHasCorporation;
        bool* pabHeadquarters;
        int* paiNumRealBuilding;
        int* paiBuildingOriginalOwner;
        int* paiBuildingOriginalTime;
        CvWString szBuffer;
        CvWString szName;
        bool abEverOwned[MAX_PLAYERS];
        int aiCulture[MAX_PLAYERS];
        PlayerTypes eOldOwner;
        PlayerTypes eOriginalOwner;
        PlayerTypes eHighestCulturePlayer;
        BuildingTypes eBuilding;
        bool bRecapture;
        bool bRaze;
        bool bGift;
        int iRange;
        int iCaptureGold;
        int iGameTurnFounded;
        int iPopulation;
        int iHighestPopulation;
        int iHurryAngerTimer;
        int iConscriptAngerTimer;
        int iDefyResolutionAngerTimer;
        int iOccupationTimer;
        int iTeamCulturePercent;
        int iDamage;
        int iDX, iDY;
        int iI;
        CLinkList<IDInfo> oldUnits;

        // WATIGGI adapted by 45deg
        int iResistance;
        int iGoldPillageProb;
        int iGoldPillageAmount;
        int iResearchPillageProb;
        int iResearchPillageAmount;
        int iSpecialistProb;
       
        int iNumResearchBuildings;
        int iNumGoldBuildings;
        int iNumProductionBuildings;
        int iNumBuildings;
        int iNumShrines;
        bool bWallStreet;
        bool bOxfordUniversity;
        bool bUniversityOfSankore;
        bool bSpiralMinaret;
        bool bGreatLibrary;

        // end WATIGGI adapted by 45deg
        std::vector<int> aeFreeSpecialists;
        CvPlotGroup* originalTradeNetworkConnectivity[MAX_PLAYERS];

/************************************************************************************************/
/* Afforess                       Start          02/15/10                                               */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/
        int iOccupationRange = 0;
/************************************************************************************************/
/* Afforess                          END                                                            */
/************************************************************************************************/
/************************************************************************************************/
/* Afforess                       Start          06/14/10                                               */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/
        int iOccupationTimeModifier = 100;
        for (iI = 0; iI < GC.getNumBuildingInfos(); iI++)
        {
                if (pOldCity->getNumRealBuilding((BuildingTypes)iI) > 0)
                {
                        if (GC.getBuildingInfo((BuildingTypes)iI).getOccupationTimeModifier() != 0)
                        {
                                iOccupationTimeModifier += GC.getBuildingInfo((BuildingTypes)iI).getOccupationTimeModifier();
                        }
                }
        }
/************************************************************************************************/
/* Afforess                          END                                                            */
/************************************************************************************************/
        pCityPlot = pOldCity->plot();
        eOldOwner = pOldCity->getOwnerINLINE();

        //      Whose trade networks was this city relevant to prior to ownership change
        if ( bUpdatePlotGroups )
        {
                for(int iI = 0; iI < MAX_PLAYERS; iI++)
                {
                        originalTradeNetworkConnectivity[iI] = GET_PLAYER((PlayerTypes)iI).isAlive() ? pCityPlot->getPlotGroup((PlayerTypes)iI) : NULL;
                }
        }
       
        pUnitNode = pCityPlot->headUnitNode();

        while (pUnitNode != NULL)
        {
                oldUnits.insertAtEnd(pUnitNode->m_data);
                pUnitNode = pCityPlot->nextUnitNode(pUnitNode);
        }

        pUnitNode = oldUnits.head();

        while (pUnitNode != NULL)
        {
                pLoopUnit = ::getUnit(pUnitNode->m_data);
                pUnitNode = oldUnits.next(pUnitNode);

                if (pLoopUnit && pLoopUnit->getTeam() != getTeam())
                {
                        if (pLoopUnit->getDomainType() == DOMAIN_IMMOBILE)
                        {
                                pLoopUnit->kill(false, getID());
                        }
                }
        }
/************************************************************************************************/
/* Afforess                       Start          07/21/10                                               */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/
        iRange = pOldCity->getMaxCultureLevelAmongPlayers();

        iOccupationRange = iRange;

        if (hasFixedBorders())
        {
                pOldCity->clearCultureDistanceCache();
                for (iDX = -(iRange); iDX <= iRange; iDX++)
                {
                        for (iDY = -(iRange); iDY <= iRange; iDY++)
                        {
                                if (pOldCity->cultureDistance(iDX, iDY) <= iRange)
                                {
                                        pLoopPlot = plotXY(pOldCity->getX_INLINE(),pOldCity-> getY_INLINE(), iDX, iDY);

                                        if (pLoopPlot != NULL)
                                        {
                                                if (!pLoopPlot->isCity())      
                                                {
                                                        if ((pLoopPlot->getOwnerINLINE() == pOldCity->getOwnerINLINE()) || (pLoopPlot->getOwnerINLINE() == NO_PLAYER))
                                                        {
                                                                bool bCultureLevelFound = false;
                                                                bool bDoClaim = false;

                                                                for (int iJ = 0; iJ < GC.getNumCultureLevelInfos(); ++iJ)
                                                                {
                                                                        int iNumCitiesForRange = pLoopPlot->getCultureRangeCities(pOldCity->getOwnerINLINE(), iJ);
                                                                       
                                                                        // Occupy the tile if it is within the city's culture range, but not within any other city's range at the same or closer distance
                                                                        if ((iNumCitiesForRange == 1) && ((pOldCity->getCultureLevel() >= iJ) && (pOldCity->cultureDistance(iDX, iDY) == iJ)))
                                                                        {
                                                                                bDoClaim = true;
                                                                        }
                                                                       
                                                                        if (iNumCitiesForRange > 0)
                                                                        {
                                                                                bCultureLevelFound = true;
                                                                                break;
                                                                        }
                                                                }

                                                                // Occupy the tile if it is NOT within the city's culture range, but is within occupation range
                                                                if (!bCultureLevelFound)
                                                                {
                                                                        if (pOldCity->cultureDistance(iDX, iDY) <= pOldCity->getOccupationCultureLevel())
                                                                        {
                                                                                bDoClaim = true;
                                                                        }
                                                                }

                                                                if (bDoClaim && pLoopPlot->isPotentialCityWorkForArea(pOldCity->area()))
                                                                {                                                      
                                                                        pLoopPlot->setClaimingOwner(getID());
                                                                        pLoopPlot->setForceUnownedTimer(1);
                                                                }                                                              
                                                        }
                                                }
                                        }
                                }
                        }
                }
        }
        if (bConquest && !hasFixedBorders())
/************************************************************************************************/
/* Afforess                          END                                                            */
/************************************************************************************************/
        {
                iRange = pOldCity->getCultureLevel();

                for (iDX = -(iRange); iDX <= iRange; iDX++)
                {
                        for (iDY = -(iRange); iDY <= iRange; iDY++)
                        {
/************************************************************************************************/
/* Afforess                       Start          02/15/10                                               */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/
                                if ((pOldCity->cultureDistance(iDX, iDY) <= iRange) && (pOldCity->cultureDistance(iDX, iDY) > 1))
/************************************************************************************************/
/* Afforess                          END                                                            */
/************************************************************************************************/
                                {
                                        pLoopPlot = plotXY(pOldCity->getX_INLINE(),pOldCity-> getY_INLINE(), iDX, iDY);

                                        if (pLoopPlot != NULL)
                                        {
                                                if (pLoopPlot->getOwnerINLINE() == pOldCity->getOwnerINLINE()) 
                                                {
                                                        if (pLoopPlot->getNumCultureRangeCities(pOldCity->getOwnerINLINE()) == 1)
                                                        {
                                                                bool bForceUnowned = false;

                                                                for (iI = 0; iI < MAX_PLAYERS; iI++)
                                                                {
                                                                        if (GET_PLAYER((PlayerTypes)iI).isAlive())
                                                                        {
                                                                                if ((GET_PLAYER((PlayerTypes)iI).getTeam() != getTeam()) && (GET_PLAYER((PlayerTypes)iI).getTeam() != pOldCity->getTeam()))
                                                                                {
                                                                                        if (pLoopPlot->getNumCultureRangeCities((PlayerTypes)iI) > 0)
                                                                                        {
                                                                                                bForceUnowned = true;
                                                                                                break;
                                                                                        }
                                                                                }
                                                                        }
                                                                }

                                                                if (bForceUnowned)
                                                                {
                                                                        pLoopPlot->setForceUnownedTimer(GC.getDefineINT("FORCE_UNOWNED_CITY_TIMER"));
                                                                }
                                                        }
                                                }
                                        }
                                }
                        }
                }
        }

        if (pOldCity->getOriginalOwner() == pOldCity->getOwnerINLINE())
        {
                GET_PLAYER(pOldCity->getOriginalOwner()).changeCitiesLost(1);
        }
/************************************************************************************************/
/* REVOLUTION_MOD                         05/30/08                                jdog5000      */
/*                                                                                              */
/* For BarbarianCiv                                                                             */
/************************************************************************************************/
        // Added new BarbCiv specfic circumstance for counting a city as lost
        else if( !GC.getGame().isOption(GAMEOPTION_NO_BARBARIAN_CIV) && pOldCity->isCapital() && pOldCity->getOriginalOwner() == GC.getBARBARIAN_PLAYER() )
        {
                GET_PLAYER(pOldCity->getOwnerINLINE()).changeCitiesLost(1);
        }
/************************************************************************************************/
/* REVOLUTION_MOD                          END                                                  */
/************************************************************************************************/
        else if (pOldCity->getOriginalOwner() == getID())
        {
                GET_PLAYER(pOldCity->getOriginalOwner()).changeCitiesLost(-1);
        }

        if (bConquest)
        {
                {
                        MEMORY_TRACK_EXEMPT();

                        szBuffer = gDLL->getText("TXT_KEY_MISC_CAPTURED_CITY", pOldCity->getNameKey()).GetCString();
                        AddDLLMessage(getID(), true, GC.getEVENT_MESSAGE_TIME(), szBuffer, "AS2D_CITYCAPTURE", MESSAGE_TYPE_MAJOR_EVENT, ARTFILEMGR.getInterfaceArtInfo("WORLDBUILDER_CITY_EDIT")->getPath(), (ColorTypes)GC.getInfoTypeForString("COLOR_GREEN"), pOldCity->getX_INLINE(), pOldCity->getY_INLINE(), true, true);
                }
                szName.Format(L"%s (%s)", pOldCity->getName().GetCString(), GET_PLAYER(pOldCity->getOwnerINLINE()).getName());

                for (iI = 0; iI < MAX_PLAYERS; iI++)
                {
                        if (GET_PLAYER((PlayerTypes)iI).isAlive())
                        {
                                if (iI != getID())
                                {
                                        MEMORY_TRACK_EXEMPT();

                                        if (pOldCity->isRevealed(GET_PLAYER((PlayerTypes)iI).getTeam(), false))
                                        {
                                                szBuffer = gDLL->getText("TXT_KEY_MISC_CITY_CAPTURED_BY", szName.GetCString(), getCivilizationDescriptionKey());
                                                AddDLLMessage(((PlayerTypes)iI), false, GC.getEVENT_MESSAGE_TIME(), szBuffer, "AS2D_CITYCAPTURED", MESSAGE_TYPE_MAJOR_EVENT, ARTFILEMGR.getInterfaceArtInfo("WORLDBUILDER_CITY_EDIT")->getPath(), (ColorTypes)GC.getInfoTypeForString("COLOR_RED"), pOldCity->getX_INLINE(), pOldCity->getY_INLINE(), true, true);
                                        }
                                /************************************************************************************************/
                                /* Afforess                       Start          12/9/09                                                */
                                /*                                                                                              */
                                /*                                                                                              */
                                /************************************************************************************************/
                                        else if (GET_TEAM(GET_PLAYER((PlayerTypes)iI).getTeam()).isHasEmbassy(getTeam()))
                                        {
                                                szBuffer = gDLL->getText("TXT_KEY_MISC_CITY_CAPTURED_BY", szName.GetCString(), getCivilizationDescriptionKey());
                                                AddDLLMessage(((PlayerTypes)iI), false, GC.getEVENT_MESSAGE_TIME(), szBuffer, "AS2D_CITYCAPTURED", MESSAGE_TYPE_MAJOR_EVENT, NULL, (ColorTypes)GC.getInfoTypeForString("COLOR_RED"));
                                        }
                                /************************************************************************************************/
                                /* Afforess                          END                                                            */
                                /************************************************************************************************/
                                }
                        }
                }

                szBuffer = gDLL->getText("TXT_KEY_MISC_CITY_WAS_CAPTURED_BY", szName.GetCString(), getCivilizationDescriptionKey());
                GC.getGameINLINE().addReplayMessage(REPLAY_MESSAGE_MAJOR_EVENT, getID(), szBuffer, pOldCity->getX_INLINE(), pOldCity->getY_INLINE(), (ColorTypes)GC.getInfoTypeForString("COLOR_WARNING_TEXT"));
        }

        iCaptureGold = 0;

        if (bConquest)
        {
                PYTHON_ACCESS_LOCK_SCOPE

                long lCaptureGold;
                // Use python to determine city capture gold amounts...
                lCaptureGold = 0;

                CyCity* pyOldCity = new CyCity(pOldCity);

                CyArgsList argsList;
                argsList.add(gDLL->getPythonIFace()->makePythonObject(pyOldCity));      // pass in plot class
               
                PYTHON_CALL_FUNCTION4(__FUNCTION__, PYGameModule, "doCityCaptureGold", argsList.makeFunctionArgs(),&lCaptureGold);

                delete pyOldCity;       // python fxn must not hold on to this pointer

                iCaptureGold = (int)lCaptureGold;
        }

        changeGold(iCaptureGold);

        pabHasReligion = new bool[GC.getNumReligionInfos()];
        pabHolyCity = new bool[GC.getNumReligionInfos()];
        pabHasCorporation = new bool[GC.getNumCorporationInfos()];
        pabHeadquarters = new bool[GC.getNumCorporationInfos()];
        paiNumRealBuilding = new int[GC.getNumBuildingInfos()];
        paiBuildingOriginalOwner = new int[GC.getNumBuildingInfos()];
        paiBuildingOriginalTime = new int[GC.getNumBuildingInfos()];

        for (iI = 0; iI < GC.getNumVoteSourceInfos(); ++iI)
        {
                pOldCity->processVoteSourceBonus((VoteSourceTypes)iI, false);
        }

        //      Koshling - need to remove bonuses due io old owner's trade network
        //      else it can feed into yield modifiers which are then incorrectly
        //      copied over to the new owner
        for (iI = 0; iI < GC.getNumBonusInfos(); ++iI)
        {
                if (pOldCity->hasBonus((BonusTypes)iI))
                {
                        pOldCity->processBonus((BonusTypes)iI, -1);
                }
        }

        eOriginalOwner = pOldCity->getOriginalOwner();
        eHighestCulturePlayer = pOldCity->findHighestCulture();
        iGameTurnFounded = pOldCity->getGameTurnFounded();
        iPopulation = pOldCity->getPopulation();
        iHighestPopulation = pOldCity->getHighestPopulation();
        iHurryAngerTimer = pOldCity->getHurryAngerTimer();
        iConscriptAngerTimer = pOldCity->getConscriptAngerTimer();
        iDefyResolutionAngerTimer = pOldCity->getDefyResolutionAngerTimer();
        iOccupationTimer = pOldCity->getOccupationTimer();
        szName = pOldCity->getNameKey();
/************************************************************************************************/
/* REVOLUTION_MOD                         01/01/08                                jdog5000      */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/
        scriptData = pOldCity->getScriptData();
        iRevIdx = pOldCity->getRevolutionIndex();
        iLocalRevIdx = pOldCity->getLocalRevIndex();
/************************************************************************************************/
/* REVOLUTION_MOD                          END                                                  */
/************************************************************************************************/
        iDamage = pOldCity->getDefenseDamage();
        int iOldCityId = pOldCity->getID();

/************************************************************************************************/
/* Afforess                       Start          01/12/10                                               */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/
        int iCiv = pOldCity->getCivilizationType();
        if (pOldCity->isBarbarian())
        {
            iCiv = NO_CIVILIZATION;
        }
/************************************************************************************************/
/* Afforess                          END                                                            */
/************************************************************************************************/

       
        for (iI = 0; iI < GC.getNumSpecialistInfos(); ++iI)
        {
                aeFreeSpecialists.push_back(pOldCity->getAddedFreeSpecialistCount((SpecialistTypes)iI));
        }

        for (iI = 0; iI < MAX_PLAYERS; iI++)
        {
                abEverOwned[iI] = pOldCity->isEverOwned((PlayerTypes)iI);
                aiCulture[iI] = pOldCity->getCultureTimes100((PlayerTypes)iI);
        }

        abEverOwned[getID()] = true;

        for (iI = 0; iI < GC.getNumReligionInfos(); iI++)
        {
                pabHasReligion[iI] = pOldCity->isHasReligion((ReligionTypes)iI);
                pabHolyCity[iI] = pOldCity->isHolyCity((ReligionTypes)iI);
        }

        for (iI = 0; iI < GC.getNumCorporationInfos(); iI++)
        {
                pabHasCorporation[iI] = pOldCity->isHasCorporation((CorporationTypes)iI);
                pabHeadquarters[iI] = pOldCity->isHeadquarters((CorporationTypes)iI);
        }

        for (iI = 0; iI < GC.getNumBuildingInfos(); iI++)
        {
                paiNumRealBuilding[iI] = pOldCity->getNumRealBuilding((BuildingTypes)iI);
                paiBuildingOriginalOwner[iI] = pOldCity->getBuildingOriginalOwner((BuildingTypes)iI);
                paiBuildingOriginalTime[iI] = pOldCity->getBuildingOriginalTime((BuildingTypes)iI);
        }

        std::vector<BuildingYieldChange> aBuildingYieldChange;
        std::vector<BuildingCommerceChange> aBuildingCommerceChange;
        BuildingChangeArray aBuildingHappyChange;
        BuildingChangeArray aBuildingHealthChange;
        for (iI = 0; iI < GC.getNumBuildingClassInfos(); ++iI)
        {
                for (int iYield = 0; iYield < NUM_YIELD_TYPES; ++iYield)
                {
                        BuildingYieldChange kChange;
                        kChange.eBuildingClass = (BuildingClassTypes)iI;
                        kChange.eYield = (YieldTypes)iYield;
                        kChange.iChange = pOldCity->getBuildingYieldChange((BuildingClassTypes)iI, (YieldTypes)iYield);
                        if (0 != kChange.iChange)
                        {
                                aBuildingYieldChange.push_back(kChange);
                        }
                }

                for (int iCommerce = 0; iCommerce < NUM_COMMERCE_TYPES; ++iCommerce)
                {
                        BuildingCommerceChange kChange;
                        kChange.eBuildingClass = (BuildingClassTypes)iI;
                        kChange.eCommerce = (CommerceTypes)iCommerce;
                        kChange.iChange = pOldCity->getBuildingCommerceChange((BuildingClassTypes)iI, (CommerceTypes)iCommerce);
                        if (0 != kChange.iChange)
                        {
                                aBuildingCommerceChange.push_back(kChange);
                        }
                }

                int iChange = pOldCity->getBuildingHappyChange((BuildingClassTypes)iI);
                if (0 != iChange)
                {
                        aBuildingHappyChange.push_back(std::make_pair((BuildingClassTypes)iI, iChange));
                }

                iChange = pOldCity->getBuildingHealthChange((BuildingClassTypes)iI);
                if (0 != iChange)
                {
                        aBuildingHealthChange.push_back(std::make_pair((BuildingClassTypes)iI, iChange));
                }
        }

        bRecapture = ((eHighestCulturePlayer != NO_PLAYER) ? (GET_PLAYER(eHighestCulturePlayer).getTeam() == getTeam()) : false);
        // WATIGGI adapted by 45deg
        // 45deg - following code is incomplete; maybe I can add some code for gold/science pillage
        //if (bConquest && !bRecapture) ??
        if (bConquest)
        {
                //GC.msg("initialising pillage values");

                // analyse the cities buildings
                iNumResearchBuildings = 0;
                iNumGoldBuildings = 0;
                iNumProductionBuildings = 0;
                iNumBuildings = 0;
                iNumShrines = 0;
                bWallStreet = false;
                bOxfordUniversity = false;
                bSpiralMinaret = false;
                bUniversityOfSankore = false;
                bGreatLibrary = false;

/*              for (iI = 0; iI < GC.getNumBuildingInfos(); iI++)
                {
                        if (pOldCity->isHasRealBuilding((BuildingTypes)iI))
                        {
                                iNumBuildings += 1;

                                // see if its a wonder worth noting (including a shrine)
                                switch (iI)
                                {
                                // national wonders
                                case 93:
                                        // Oxford University
                                                // this is caught by the if statement below
                                        bOxfordUniversity = true;
                                        break;

                                case 94:
                                        // Wall Street
                                                // this is caught by the if statement below
                                        bWallStreet = true;
                                        break;
                               
                                // wonders
                                case 127:
                                        // University of Sankore - research bonus
                                        iNumResearchBuildings += 1;
                                        bUniversityOfSankore = true;
                                        break;

                                case 121:
                                        // The Three Geoges Dam - production bonus
                                        iNumProductionBuildings += 1;
                                        break;

                                case 112:
                                        // The Spiral Minaret - gold bonus
                                        iNumGoldBuildings += 1;
                                        bSpiralMinaret = true;
                                        break;

                                case 102:
                                        // The Great Library - research bonus
                                        iNumResearchBuildings += 1;
                                        bGreatLibrary = true;
                                        break;

                                // shrines
                                case 64:
                                        // The Temple of Solomon
                                        iNumGoldBuildings += 1;
                                        iNumShrines += 1;
                                        break;

                                case 68:
                                        // The Church of Nativity
                                        iNumGoldBuildings += 1;
                                        iNumShrines += 1;
                                        break;

                                case 72:
                                        // The Masjid Al-Harem
                                        iNumGoldBuildings += 1;
                                        iNumShrines += 1;
                                        break;

                                case 76:
                                        // The Kashi Vishwanath
                                        iNumGoldBuildings += 1;
                                        iNumShrines += 1;
                                        break;

                                case 80:
                                        // The Mahabodhi
                                        iNumGoldBuildings += 1;
                                        iNumShrines += 1;
                                        break;

                                case 84:
                                        // The Kong Miao
                                        iNumGoldBuildings += 1;
                                        iNumShrines += 1;
                                        break;

                                case 88:
                                        // The Dao Miao
                                        iNumGoldBuildings += 1;
                                        iNumShrines += 1;
                                        break;
                                }

                                // buildings like the Market, Library, Forge, etc that have modifiers
                                if (GC.getBuildingInfo((BuildingTypes)iI).getCommerceModifier(0) > 0)
                                {
                                        // gold building
                                        iNumGoldBuildings += 1;
                                }
                                else if (GC.getBuildingInfo((BuildingTypes)iI).getCommerceModifier(1) > 0)
                                {
                                        // research building
                                        iNumResearchBuildings += 1;
                                }
                                else if (GC.getBuildingInfo((BuildingTypes)iI).getYieldModifier(1) > 0)
                                {
                                        // production building
                                        iNumProductionBuildings += 1;
                                }
                        }
                }      
*/

                //GC.msg("iNumBuildings: %d", iNumBuildings);
                //GC.msg("iNumResearchBuildings: %d", iNumResearchBuildings);
                //GC.msg("iNumGoldBuildings: %d", iNumGoldBuildings);
                //GC.msg("iNumProductionBuildings: %d", iNumProductionBuildings);

                // calculate the gold pillage prob
                iGoldPillageProb = 0;
                iGoldPillageAmount = 0;

                // simple strategy that gives a 100% chance to a city with a shrine
                iGoldPillageProb = 0;
                iGoldPillageAmount = 10;

                if (iNumShrines > 0)
                        iGoldPillageProb = 100;

                if (iNumShrines > 0)
                        iGoldPillageAmount += (iNumShrines * 10);

                //if (bWallStreet)
                //      iGoldPillageAmount += 5;

                // original complex strategy that takes into consideration the quantity and quality of the buildings
                /*if (iNumGoldBuildings > 0)
                {
                        // rate of gold gather should be based on number of buildings only

                        // amount should be based on quality of the buildings only

                        // gold modifying buildings (includes WallStreet)
                        iGoldPillageProb += (iNumGoldBuildings * 3);
                        //GC.msg("+%d for %d gold buildings", (iNumGoldBuildings * 3), iNumGoldBuildings);
                       
                        // factor in shrines
                        if (iNumShrines > 0)
                        {
                                iGoldPillageProb += 10;
                                //GC.msg("+10 for having shrines");
                        }

                        iGoldPillageProb += (iNumShrines * 3);
                        //GC.msg("+%d for having %d shrines", (iNumShrines * 3), iNumShrines);

                        // factor in Wall Street
                        if (bWallStreet)
                        {
                                iGoldPillageProb += 5;
                                //GC.msg("+5 for Wall Street");
                        }
                }

                GC.msg("iGoldPillageProb is %d", iGoldPillageProb);

                // calculate the gold pillage amounts
                iGoldPillageAmount = 0;

                if (iGoldPillageProb > 0)
                {
                        // base amount
                        iGoldPillageAmount = 10;

                        // increase amounts for shrines
                        iGoldPillageAmount += (iNumShrines * 20);

                        // increase amounts for wall street
                        if (bWallStreet)
                        {
                                iGoldPillageAmount += 10;
                        }
                }
         
                        basically it will give:
                        - with 3 basic gold buildings - 9% chance of getting 10 gold per pillage
                        - with 3 basic and Wall Street - 17% chance of getting 20 gold per pillage
                        - with 3 basic and 1 shrine - 25% chance of getting 30 gold per pillage
                        - with 3 basic and 2 shrines - 31% chance of getting 50 gold per pillage
                        - with 1 basic gold building - 3% chance of getting 10 gold per pillage
                        - with 3 basic, WS and 1 shrine - 36% chance of getting 40 gold per pillage
                        - with 3 basic, WS and 2 shrines - 39% chance of getting 60 gold per pillage
               

                GC.msg("iGoldPillageAmount is %d", iGoldPillageAmount);
                */


                // calculate the research pillage prob
                iResearchPillageProb = 0;
                iResearchPillageAmount = 0;

                // simple strategy that gives either 0% or 100% chance depending on the presense of the GL and Oxford Uni.
                if (bGreatLibrary || bOxfordUniversity)
                        iResearchPillageProb = 100;

                if (bGreatLibrary)
                        iResearchPillageAmount += 100;          // ### doesn't factor in game speed or era

                if (bOxfordUniversity)
                        iResearchPillageAmount += 50;           // ### doesn't factor in game speed or era
               
                // original complex strategy that alters both the prob and amount based on quantity and quality of buildings.
                /*if (iNumResearchBuildings > 0)
                {
                        // rate of research gather should be based on number of buildings only

                        // amount should be based on quality of the buildings only

                        // research buildings
                        iResearchPillageProb += (iNumResearchBuildings * 3);

                        // factor in Great Library
                        if (bGreatLibrary)
                        {
                                iResearchPillageProb += 10;
                        }

                        // factor in Oxford University
                        if (bOxfordUniversity)
                        {
                                iResearchPillageProb += 5;
                        }
                }

                GC.msg("iResearchPillageProb is %d", iResearchPillageProb);

                // calculate the research pillage amounts
                iResearchPillageAmount = 0;

                if (iResearchPillageProb > 0)
                {
                        // base amount
                        iResearchPillageAmount += 10;

                        // factor in Great Library
                        if (bGreatLibrary)
                        {
                                iResearchPillageAmount += 100;
                        }

                        // factor in Oxford University
                        if (bOxfordUniversity)
                        {
                                iResearchPillageAmount += 50;
                        }
                }

               
                        basically it will give:
                        - with 1 research building - 3% chance of getting 10 research per pillage
                        - with 2 research buildings - 6% chance of getting 10 research per pillage
                        - with 3 research buildings - 9% chance of getting 10 research per pillage
                        - with 3 basic and Oxford - 17% chance of getting 60 research per pillage
                        - with 3 basic and GL - 22% chance of getting 110 research per pillage
                        - with 3 basic, Oxford and GL - 30% chance of getting 160 research per pillage
                        - with 2 basic and Oxford - 14% chance of getting 60 research per pillage
                        - with 2 basic, Oxford and GL - 27% chance of getting 160 research per pillage
               

                GC.msg("iResearchPillageAmount is %d", iResearchPillageAmount);
                */


                // calculate the specialist relocation prob
                iSpecialistProb = 0;

                // simple strategy that just takes into consideration the population size up to a size 10
                iSpecialistProb = pOldCity->getPopulation() * 10; // size 10 or above gives 100% chance of specialist

                // allways give a specialist if a world wonder exists (including a shrine)
                if (pOldCity->getNumWorldWonders() > 0)
                        iSpecialistProb = 100;

                if (pOldCity->isHolyCity())
                        iSpecialistProb = 100;

                if (pOldCity->isBarbarian())
                        iSpecialistProb = 0;

                // original complex strategy that took into consideration the likelihood of the city having specialists
                /*if (pOldCity->getPopulation() > 9)
                {
                        iSpecialistProb = min((pOldCity->getPopulation() / 3), ((int)((float)iNumBuildings * 0.80f) * 2));
                        //GC.msg("min(population/3, (numBuildings * 0.80) * 2) is %d", iSpecialistProb);

                        iSpecialistProb += pOldCity->getNumWorldWonders();
                        iSpecialistProb += pOldCity->getNumNationalWonders();
                }
               
                        basically it will give:
                        - with 20 pop and 6 buildings - 6% chance of getting specialist
                        - with 20 pop and 3 buildings - 4% chance of getting specialist
                        - with 10 pop and 2 buildings - 3% chance of getting specialist
                        - with 10 pop and 2 wonders - 5% chance of getting specialist
                        - with 9 pop and 6 buildings - 0% chance of getting specialist
                */



                //GC.msg("iSpecialistProb is %d", iSpecialistProb);

                // calculate the resistance factor
                iResistance = 0;

                if (pOldCity->isHolyCity())
                {
                        iResistance += 10;
                        //GC.msg("+10 for holy city!");
                }

                if (pOldCity->getNumWorldWonders() > 0)
                {
                        iResistance += 5;
                        //GC.msg("+5 for having wonders");
                }

                // world wonders
                iResistance += (pOldCity->getNumWorldWonders() * 5);
                //GC.msg("+%d for having %d world wonders", (pOldCity->getNumWorldWonders()*5), pOldCity->getNumWorldWonders());

                // national wonders
                iResistance += (pOldCity->getNumNationalWonders() * 5);
                //GC.msg("+%d for having %d national wonders", (pOldCity->getNumNationalWonders()*5), pOldCity->getNumNationalWonders());

                // cultural level
                iResistance += ((pOldCity->getCultureLevel() - 1) * 5);
                //GC.msg("+%d for culture level of %d", ((pOldCity->getCultureLevel()-1)*5), pOldCity->getCultureLevel());

                // (population is recalculated with each pillage)

                //GC.msg("iResistance is %d", iResistance);
        }
        // end WATIGGI adapted by 45deg
        pOldCity->kill(false, false);

        if (bTrade)
        {
                for (iDX = -1; iDX <= 1; iDX++)
                {
                        for (iDY = -1; iDY <= 1; iDY++)
                        {
                                pLoopPlot       = plotXY(pCityPlot->getX_INLINE(), pCityPlot->getY_INLINE(), iDX, iDY);

                                if (pLoopPlot != NULL)
                                {
                                        pLoopPlot->setCulture(eOldOwner, 0, false, false);
                                }
                        }
                }
        }

        pNewCity = initCity(pCityPlot->getX_INLINE(), pCityPlot->getY_INLINE(), !bConquest, false);

        FAssertMsg(pNewCity != NULL, "NewCity is not assigned a valid value");

        pNewCity->setPreviousOwner(eOldOwner);
        pNewCity->setOriginalOwner(eOriginalOwner);
        pNewCity->setGameTurnFounded(iGameTurnFounded);
        pNewCity->setPopulation((bConquest && !bRecapture) ? std::max(1, (iPopulation - 1)) : iPopulation);
        pNewCity->setHighestPopulation(iHighestPopulation);
        pNewCity->setName(szName);
        pNewCity->setNeverLost(false);
        pNewCity->changeDefenseDamage(iDamage);
       
/************************************************************************************************/
/* Afforess                       Start          01/12/10                                               */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/
        if (iCiv != NO_CIVILIZATION)
    {
        pNewCity->setCivilizationType(iCiv);
    }
/************************************************************************************************/
/* Afforess                          END                                                            */
/************************************************************************************************/

/************************************************************************************************/
/* REVOLUTION_MOD                         01/01/08                                jdog5000      */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/
        pNewCity->setScriptData(scriptData);
        pNewCity->setRevolutionIndex( iRevIdx );
        pNewCity->setLocalRevIndex( iLocalRevIdx );
/************************************************************************************************/
/* REVOLUTION_MOD                          END                                                  */
/************************************************************************************************/

        for (iI = 0; iI < MAX_PLAYERS; iI++)
        {
                pNewCity->setEverOwned(((PlayerTypes)iI), abEverOwned[iI]);
                pNewCity->setCultureTimes100(((PlayerTypes)iI), aiCulture[iI], false, false);
        }

        for (iI = 0; iI < GC.getNumBuildingInfos(); iI++)
        {
                int iNum = 0;

                if (paiNumRealBuilding[iI] > 0)
                {
                        BuildingClassTypes eBuildingClass = (BuildingClassTypes)GC.getBuildingInfo((BuildingTypes)iI).getBuildingClassType();
/************************************************************************************************/
/* Afforess                       Start          02/03/10                                              */
/*                                                                                              */
/*   Assimilation Bug Fix                                                                       */
/************************************************************************************************/
                        if ((::isWorldWonderClass(eBuildingClass)) || (GC.getGameINLINE().isOption(GAMEOPTION_ASSIMILATION)))
                        {
                                eBuilding = (BuildingTypes)iI;
/************************************************************************************************/
/* Afforess                          END                                                            */
/************************************************************************************************/
                        }
                        else
                        {                      
                                eBuilding = (BuildingTypes)GC.getCivilizationInfo(getCivilizationType()).getCivilizationBuildings(eBuildingClass);
                        }

                        if (eBuilding != NO_BUILDING)
                        {
                                if (bTrade || !(GC.getBuildingInfo((BuildingTypes)iI).isNeverCapture()))
                                {
                                        if (!isProductionMaxedBuildingClass(((BuildingClassTypes)(GC.getBuildingInfo(eBuilding).getBuildingClassType())), true))
                                        {
                                                if (pNewCity->isValidBuildingLocation(eBuilding))
                                                {
                                                        if (!bConquest || bRecapture || GC.getGameINLINE().getSorenRandNum(100, "Capture Probability") < GC.getBuildingInfo((BuildingTypes)iI).getConquestProbability())
                                                        {
                                                                iNum += paiNumRealBuilding[iI];
                                                        }
                                                }
                                        }
                                }

                                pNewCity->setNumRealBuildingTimed(eBuilding, std::min(pNewCity->getNumRealBuilding(eBuilding) + iNum, GC.getCITY_MAX_NUM_BUILDINGS()), false, ((PlayerTypes)(paiBuildingOriginalOwner[iI])), paiBuildingOriginalTime[iI]);
                        }
                }
        }

        for (std::vector<BuildingYieldChange>::iterator it = aBuildingYieldChange.begin(); it != aBuildingYieldChange.end(); ++it)
        {
                pNewCity->setBuildingYieldChange((*it).eBuildingClass, (*it).eYield, (*it).iChange);
        }

        for (std::vector<BuildingCommerceChange>::iterator it = aBuildingCommerceChange.begin(); it != aBuildingCommerceChange.end(); ++it)
        {
                pNewCity->setBuildingCommerceChange((*it).eBuildingClass, (*it).eCommerce, (*it).iChange);
        }

        for (BuildingChangeArray::iterator it = aBuildingHappyChange.begin(); it != aBuildingHappyChange.end(); ++it)
        {
                pNewCity->setBuildingHappyChange((*it).first, (*it).second);
        }

        for (BuildingChangeArray::iterator it = aBuildingHealthChange.begin(); it != aBuildingHealthChange.end(); ++it)
        {
                pNewCity->setBuildingHealthChange((*it).first, (*it).second);
        }

        for (iI = 0; iI < GC.getNumSpecialistInfos(); ++iI)
        {
                pNewCity->changeFreeSpecialistCount((SpecialistTypes)iI, aeFreeSpecialists[iI]);
        }

        for (iI = 0; iI < GC.getNumReligionInfos(); iI++)
        {
                if (pabHasReligion[iI])
                {
                        pNewCity->setHasReligion(((ReligionTypes)iI), true, false, true);
                }

                if (pabHolyCity[iI])
                {
                        GC.getGameINLINE().setHolyCity(((ReligionTypes)iI), pNewCity, false);
                        // Sanguo Mod Performance start, added by poyuzhe 07.26.09
                        for (int iJ = 0; iJ < GC.getMAX_PLAYERS(); iJ++)
                        {
                                if (GET_PLAYER((PlayerTypes)iJ).isAlive() && GET_PLAYER((PlayerTypes)iI).getStateReligion() == (ReligionTypes)iI)
                                {
                                        GET_PLAYER(getID()).AI_invalidateAttitudeCache((PlayerTypes)iJ);
                                        GET_PLAYER((PlayerTypes)iJ).AI_invalidateAttitudeCache(getID());
                                }
                        }
                        // Sanguo Mod Performance, end
                }
        }
/************************************************************************************************/
/* RevDCM                         Start          12/9/09                                                */
/*                                                                                              */
/* Inquisitions                                                                                 */
/************************************************************************************************/
        if(!(GET_PLAYER(eOldOwner).isHuman()))
        {
                GET_PLAYER(eOldOwner).AI_setHasInquisitionTarget();
        }
        if(!(GET_PLAYER(getID()).isHuman()))
        {
                GET_PLAYER(getID()).AI_setHasInquisitionTarget();
        }
/************************************************************************************************/
/* RevDCM                            END                                                            */
/************************************************************************************************/
        for (iI = 0; iI < GC.getNumCorporationInfos(); iI++)
        {
                if (pabHasCorporation[iI])
                {
                        pNewCity->setHasCorporation(((CorporationTypes)iI), true, false);
                }

                if (pabHeadquarters[iI])
                {
                        GC.getGameINLINE().setHeadquarters(((CorporationTypes)iI), pNewCity, false);
                }
        }

        if (bTrade)
        {
                if (isHuman() || (getTeam() == GET_PLAYER(eOldOwner).getTeam()))
                {
                        pNewCity->changeHurryAngerTimer(iHurryAngerTimer);
                        pNewCity->changeConscriptAngerTimer(iConscriptAngerTimer);
                        pNewCity->changeDefyResolutionAngerTimer(iDefyResolutionAngerTimer);
                }

                if (!bRecapture)
                {
                        pNewCity->changeOccupationTimer(iOccupationTimer);
                }
        }

        if (bConquest)
        {
                iTeamCulturePercent = pNewCity->calculateTeamCulturePercent(getTeam());

                if (iTeamCulturePercent < GC.getDefineINT("OCCUPATION_CULTURE_PERCENT_THRESHOLD"))
                {
                        // WATIGGI adapted by 45deg
                        pNewCity->setInConqueredMode(true);

                        // set gold pillage values
                        pNewCity->setGoldPillageProb(iGoldPillageProb);
                        pNewCity->setGoldPillageAmount(iGoldPillageAmount);

                        // set research pillage values
                        pNewCity->setResearchPillageProb(iResearchPillageProb);
                        pNewCity->setResearchPillageAmount(iResearchPillageAmount);

                        // set specialist values
                        pNewCity->setSpecialistRelocationProb(iSpecialistProb);

                        // set resistance values
                        pNewCity->setResistance(iResistance);
                        // end WATIGGI adapted by 45deg        
/************************************************************************************************/
/* Afforess                       Start          07/14/10                                               */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/
/*
                        pNewCity->changeOccupationTimer(((GC.getDefineINT("BASE_OCCUPATION_TURNS") + ((pNewCity->getPopulation() * GC.getDefineINT("OCCUPATION_TURNS_POPULATION_PERCENT")) / 100)) * (100 - iTeamCulturePercent)) / 100);
*/

                        int iOccupationTime = GC.getDefineINT("BASE_OCCUPATION_TURNS");\
                        //ls612: Remove the old define and replace it with something that scales with Gamespeeds
                        iOccupationTime += pNewCity->getPopulation() * GC.getGameSpeedInfo(GC.getGameINLINE().getGameSpeedType()).getOccupationTimePopulationPercent() / 100;
                        iOccupationTime *= (100 - iTeamCulturePercent) / 100;
                       
                        iOccupationTime *= std::max(0,iOccupationTimeModifier);
                        iOccupationTime /= 100;
                       
                        pNewCity->changeOccupationTimer(iOccupationTime);
/************************************************************************************************/
/* Afforess                          END                                                            */
/************************************************************************************************/

                }

                GC.getMapINLINE().verifyUnitValidPlot();
        }
/************************************************************************************************/
/* Afforess                       Start          02/15/10                                               */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/
        if (iOccupationRange > 0)
        {
                pNewCity->setOccupationCultureLevel((CultureLevelTypes)iOccupationRange);
        }
/************************************************************************************************/
/* Afforess                          END                                                            */
/************************************************************************************************/

        pNewCity->checkBuildings(true, true, true, true, true, false);

        pCityPlot->setRevealed(GET_PLAYER(eOldOwner).getTeam(), true, false, NO_TEAM, false);

        pNewCity->updateEspionageVisibility(false);

        pCityPlot->updateCulture(true, false);

        for (iI = 0; iI < NUM_DIRECTION_TYPES; iI++)
        {
                CvPlot* pAdjacentPlot = plotDirection(pCityPlot->getX_INLINE(), pCityPlot->getY_INLINE(), ((DirectionTypes)iI));

                if (pAdjacentPlot != NULL)
                {
                        pAdjacentPlot->updateCulture(true, false);
                }
        }

        bool bConquestCanRaze = false;
        if (bConquest)
        {
                PYTHON_ACCESS_LOCK_SCOPE

                CyCity* pyCity = new CyCity(pNewCity);
                CyArgsList argsList;
                argsList.add(getID());  // Player ID
                argsList.add(gDLL->getPythonIFace()->makePythonObject(pyCity)); // pass in city class
                long lResult=0;
                PYTHON_CALL_FUNCTION4(__FUNCTION__, PYGameModule, "canRazeCity", argsList.makeFunctionArgs(), &lResult);
                delete pyCity;  // python fxn must not hold on to this pointer

                if (lResult == 1)
                {
                        bConquestCanRaze = true;
                }
        }
        //      Don't bother with plot group caklculations if they are immediately to b superseded by
        //      an auto raze
        if ( bUpdatePlotGroups && (!bConquestCanRaze || !pNewCity->isAutoRaze()) )
        {
                PROFILE("CvPlayer::acquireCity.UpdatePlotGroups");

                for(int iI = 0; iI < MAX_PLAYERS; iI++)
                {
                        if ( GET_PLAYER((PlayerTypes)iI).isAlive() )
                        {
                                if ( originalTradeNetworkConnectivity[iI] == NULL )
                                {
                                        if ( pCityPlot->isTradeNetwork(GET_PLAYER((PlayerTypes)iI).getTeam()) )
                                        {
                                                GET_PLAYER((PlayerTypes)iI).updatePlotGroups(pCityPlot->area());
                                        }
                                }
                                else
                                {
                                        originalTradeNetworkConnectivity[iI]->recalculatePlots();
                                }
                        }
                }
        }

        CvEventReporter::getInstance().cityAcquired(eOldOwner, getID(), pNewCity, bConquest, bTrade);

/************************************************************************************************/
/* BETTER_BTS_AI_MOD                      10/02/09                                jdog5000      */
/*                                                                                              */
/* AI logging                                                                                   */
/************************************************************************************************/
        if( gPlayerLogLevel >= 1 )
        {
                logBBAIForTeam(getTeam(), "  Player %d (%S) acquires city %S bConq %d bTrade %d", getID(), getCivilizationDescription(0), pNewCity->getName(0).GetCString(), bConquest, bTrade );
        }
/************************************************************************************************/
/* BETTER_BTS_AI_MOD                       END                                                  */
/************************************************************************************************/

        SAFE_DELETE_ARRAY(pabHasReligion);
        SAFE_DELETE_ARRAY(pabHolyCity);
        SAFE_DELETE_ARRAY(pabHasCorporation);
        SAFE_DELETE_ARRAY(pabHeadquarters);
        SAFE_DELETE_ARRAY(paiNumRealBuilding);
        SAFE_DELETE_ARRAY(paiBuildingOriginalOwner);
        SAFE_DELETE_ARRAY(paiBuildingOriginalTime);

        if ( bConquestCanRaze )
        {
                //auto raze based on game rules
                if (pNewCity->isAutoRaze())
                {
                        if (iCaptureGold > 0)
                        {
                                MEMORY_TRACK_EXEMPT();

                                szBuffer = gDLL->getText("TXT_KEY_MISC_PILLAGED_CITY", iCaptureGold, pNewCity->getNameKey());
                                AddDLLMessage(getID(), true, GC.getEVENT_MESSAGE_TIME(), szBuffer, "AS2D_CITYRAZE", MESSAGE_TYPE_MAJOR_EVENT, ARTFILEMGR.getInterfaceArtInfo("WORLDBUILDER_CITY_EDIT")->getPath(), (ColorTypes)GC.getInfoTypeForString("COLOR_GREEN"), pNewCity->getX_INLINE(), pNewCity->getY_INLINE(), true, true);
                        }

                        pNewCity->doTask(TASK_RAZE);
                }
                else if (!isHuman())
                {
                        AI_conquerCity(pNewCity); // could delete the pointer...
                }
                else
                {
                        //popup raze option
                        eHighestCulturePlayer = pNewCity->getLiberationPlayer(true);
                        // WATIGGI adapted by 45deg

                        //bRaze = canRaze(pNewCity);
                        bRaze = false;  // overrides the test
                        // end WATIGGI adapted by 45deg
                        bGift = ((eHighestCulturePlayer != NO_PLAYER)
                                        && (eHighestCulturePlayer != getID())
                                        && ((getTeam() == GET_PLAYER(eHighestCulturePlayer).getTeam())
                                                || GET_TEAM(getTeam()).isOpenBorders(GET_PLAYER(eHighestCulturePlayer).getTeam())
                                                || GET_TEAM(GET_PLAYER(eHighestCulturePlayer).getTeam()).isVassal(getTeam())));

                        if (bRaze || bGift)
                        {
                                CvPopupInfo* pInfo = new CvPopupInfo(BUTTONPOPUP_RAZECITY);
                                pInfo->setData1(pNewCity->getID());
                                pInfo->setData2(eHighestCulturePlayer);
                                pInfo->setData3(iCaptureGold);
                                gDLL->getInterfaceIFace()->addPopup(pInfo, getID());
                        }
                        else
                        {
                                pNewCity->chooseProduction();
                                CvEventReporter::getInstance().cityAcquiredAndKept(getID(), pNewCity);
                        }
                }
        }
/************************************************************************************************/
/* REVOLUTION_MOD                         06/27/10                                jdog5000      */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/
/* original code
        else if (!bTrade)
*/

        // Silences double ask for accepting new city from Revolution mod
        else if (!bTrade && (GC.getGameINLINE().isOption(GAMEOPTION_NO_REVOLUTION)) )
/************************************************************************************************/
/* REVOLUTION_MOD                          END                                                  */
/************************************************************************************************/
        {
                if (isHuman())
                {
                        CvPopupInfo* pInfo = new CvPopupInfo(BUTTONPOPUP_DISBANDCITY);
                        pInfo->setData1(pNewCity->getID());
                        gDLL->getInterfaceIFace()->addPopup(pInfo, getID());
                }
                else
                {
                        CvEventReporter::getInstance().cityAcquiredAndKept(getID(), pNewCity);
                }
        }

        // Forcing events that deal with the old city not to expire just because we conquered that city
        for (CvEventMap::iterator it = m_mapEventsOccured.begin(); it != m_mapEventsOccured.end(); ++it)
        {
                EventTriggeredData &triggerData = it->second;
                if((triggerData.m_eOtherPlayer == eOldOwner) && (triggerData.m_iOtherPlayerCityId == iOldCityId))
                {
                        triggerData.m_iOtherPlayerCityId = -1;
                }
        }
}


void CvPlayer::killCities()
{
        CvCity* pLoopCity;
        int iLoop = 0;

        for (pLoopCity = firstCity(&iLoop); pLoopCity != NULL; pLoopCity = nextCity(&iLoop))
        {
                pLoopCity->kill(false);
        }

        GC.getGameINLINE().updatePlotGroups();
}


CvWString CvPlayer::getNewCityName() const
{
        CLLNode<CvWString>* pNode;
        CvWString szName;
        int iI;

        for (pNode = headCityNameNode(); (pNode != NULL); pNode = nextCityNameNode(pNode))
        {
                szName = gDLL->getText(pNode->m_data);
                if (isCityNameValid(szName, true))
                {
                        szName = pNode->m_data;
                        break;
                }
        }

        /* OOS-Fix: Role dice regardless if szName is empty or not. The emptyness of the string depends on the language!
         */

        if (szName.empty())
        {
                getCivilizationCityName(szName, getCivilizationType());
        }else{
                if (isBarbarian() || isMinorCiv())
                {
                        GC.getGameINLINE().getSorenRandNum(GC.getCivilizationInfo(getCivilizationType()).getNumCityNames(), "getNewCityName 1 (Player)");
                }
        }

        /* OOS-Fix: The following code free's the number of getSorenRandNum calls from the emptyness-condition of szName, too.
         * Thus, it will be languange independent.
         * numCityNameCalls defines the (maximal) number of getCivilizationCityName calls and exact number of getSorenRandNum
         * calls (in the isBarbarian() case).
         */

        int numCityNameCalls = std::min(5, GC.getNumCivilizationInfos());

        int iRandOffset = GC.getGameINLINE().getSorenRandNum(GC.getNumCivilizationInfos(), "getNewCityName 2 (Player)");
        if (szName.empty())
        {
                // Pick a name from another random civ
                for (iI = 0; iI < numCityNameCalls; iI++)
                {
                        int iLoopName = ((iI + iRandOffset) % GC.getNumCivilizationInfos());

                        getCivilizationCityName(szName, ((CivilizationTypes)iLoopName));

                        if (!szName.empty())
                        {
                                ++iI;
                                break;
                        }
                }
                for (iI; iI < numCityNameCalls; iI++){
                        if(isBarbarian() || isMinorCiv()){
                                int iLoopName = ((iI + iRandOffset) % GC.getNumCivilizationInfos());
                                GC.getGameINLINE().getSorenRandNum(GC.getCivilizationInfo(((CivilizationTypes)iLoopName)).getNumCityNames(), "getNewCityName 3A (Player)");
                        }
                }
        }else{
                for (iI = 0; iI < numCityNameCalls; iI++){
                        if(isBarbarian() || isMinorCiv()){
                                int iLoopName = ((iI + iRandOffset) % GC.getNumCivilizationInfos());
                                GC.getGameINLINE().getSorenRandNum(GC.getCivilizationInfo(((CivilizationTypes)iLoopName)).getNumCityNames(), "getNewCityName 3B (Player)");
                        }
                }
        }

        if (szName.empty())
        {
                szName = "TXT_KEY_CITY";
        }

        return szName;
}


void CvPlayer::getCivilizationCityName(CvWString& szBuffer, CivilizationTypes eCivilization) const
{
        int iRandOffset;
        int iLoopName;
        int iI;

/************************************************************************************************/
/* REVOLUTION_MOD                         02/29/08                                jdog5000      */
/*                                                                                              */
/* Minor Civs                                                                                   */
/************************************************************************************************/
/* original code
        if (isBarbarian() || isMinorCiv())
        {
                iRandOffset = GC.getGameINLINE().getSorenRandNum(GC.getCivilizationInfo(eCivilization).getNumCityNames(), "Place Units (Player)");
        }
        else
        {
                iRandOffset = 0;
        }
*/

        iRandOffset = 0;

        if( !GC.getGameINLINE().isOption(GAMEOPTION_NO_REVOLUTION) || !GC.getGameINLINE().isOption(GAMEOPTION_NO_BARBARIAN_CIV) )
        {
                if( isBarbarian() )
                {
                        iRandOffset = GC.getGameINLINE().getSorenRandNum(GC.getCivilizationInfo(eCivilization).getNumCityNames(), "Place Units (Player)");
                }
        }
        else
        {
                if (isBarbarian() || isMinorCiv())
                {
                        iRandOffset = GC.getGameINLINE().getSorenRandNum(GC.getCivilizationInfo(eCivilization).getNumCityNames(), "Place Units (Player)");
                }
        }
/************************************************************************************************/
/* REVOLUTION_MOD                          END                                                  */
/************************************************************************************************/

        for (iI = 0; iI < GC.getCivilizationInfo(eCivilization).getNumCityNames(); iI++)
        {
                iLoopName = ((iI + iRandOffset) % GC.getCivilizationInfo(eCivilization).getNumCityNames());

                CvWString szName = gDLL->getText(GC.getCivilizationInfo(eCivilization).getCityNames(iLoopName));

                if (isCityNameValid(szName, true))
                {
                        szBuffer = GC.getCivilizationInfo(eCivilization).getCityNames(iLoopName);
                        break;
                }
        }
}


bool CvPlayer::isCityNameValid(CvWString& szName, bool bTestDestroyed) const
{
        CvCity* pLoopCity;
        int iLoop = 0;

        if (bTestDestroyed)
        {
                if (GC.getGameINLINE().isDestroyedCityName(szName))
                {
                        return false;
                }

                for (int iPlayer = 0; iPlayer < MAX_PLAYERS; ++iPlayer)
                {
                        CvPlayer& kLoopPlayer = GET_PLAYER((PlayerTypes)iPlayer);
                        for (pLoopCity = kLoopPlayer.firstCity(&iLoop); pLoopCity != NULL; pLoopCity = kLoopPlayer.nextCity(&iLoop))
                        {
                                if (pLoopCity->getName() == szName)
                                {
                                        return false;
                                }
                        }
                }
        }
        else
        {
                for (pLoopCity = firstCity(&iLoop); pLoopCity != NULL; pLoopCity = nextCity(&iLoop))
                {
                        if (pLoopCity->getName() == szName)
                        {
                                return false;
                        }
                }
        }

        return true;
}

CvUnit* CvPlayer::getTempUnit(UnitTypes eUnit, int iX, int iY)
{
        if ( m_pTempUnit == NULL )
        {
                m_pTempUnit = initUnit(eUnit, iX, iY, NO_UNITAI, NO_DIRECTION, UNIT_BIRTHMARK_TEMP_UNIT);
                ((CvPlayerAI*)this)->AI_changeNumAIUnits(m_pTempUnit->AI_getUnitAIType(),-1);   //      This one doesn't count
                removeGroupCycle(m_pTempUnit->getGroup()->getID());
        }
        else
        {
                if ( m_pTempUnit->plot() != NULL )
                {
                        m_pTempUnit->setXY(INVALID_PLOT_COORD,INVALID_PLOT_COORD,true,false);
                }

                m_pTempUnit->changeIdentity(eUnit);
                m_pTempUnit->setXY(iX, iY, true, false);
        }

        //      Set an arbitrary automation type - just need it to be flagged as automated
        m_pTempUnit->getGroup()->setAutomateType(AUTOMATE_BUILD);

        return m_pTempUnit;
}

void CvPlayer::releaseTempUnit()
{
        m_pTempUnit->setXY(INVALID_PLOT_COORD,INVALID_PLOT_COORD,true,false);
}

CvUnit* CvPlayer::initUnit(UnitTypes eUnit, int iX, int iY, UnitAITypes eUnitAI, DirectionTypes eFacingDirection, int iBirthmark)
{
        PROFILE_FUNC();

        FAssertMsg(eUnit != NO_UNIT, "Unit is not assigned a valid value");

        CvUnit* pUnit = addUnit();
        FAssertMsg(pUnit != NULL, "Unit is not assigned a valid value");
        if (NULL != pUnit)
        {
                pUnit->init(pUnit->getID(), eUnit, ((eUnitAI == NO_UNITAI) ? ((UnitAITypes)(GC.getUnitInfo(eUnit).getDefaultUnitAIType())) : eUnitAI), getID(), iX, iY, eFacingDirection, iBirthmark);
/************************************************************************************************/
/* Afforess                       Start          02/27/10                      Coded By: KillMePlease   */
/*                                                                                              */
/* Great Commanders                                                                             */
/************************************************************************************************/
                if (pUnit->isCommander())
                {
                        Commanders.push_back(pUnit);
                }
/************************************************************************************************/
/* Afforess                          END                                                            */
/************************************************************************************************/
        }

        return pUnit;
}


void CvPlayer::disbandUnit(bool bAnnounce)
{
        CvUnit* pLoopUnit;
        CvUnit* pBestUnit;
        wchar szBuffer[1024];
        int iValue;
        int iBestValue;
        int iLoop = 0;

        iBestValue = MAX_INT;
        pBestUnit = NULL;

        for(pLoopUnit = firstUnit(&iLoop); pLoopUnit != NULL; pLoopUnit = nextUnit(&iLoop))
        {
                if (!(pLoopUnit->hasCargo()))
                {
                        if (!(pLoopUnit->isGoldenAge()))
                        {
                                if (pLoopUnit->getUnitInfo().getProductionCost() > 0)
                                {
                                        if (!(pLoopUnit->isMilitaryHappiness()) || !(pLoopUnit->plot()->isCity()) || (pLoopUnit->plot()->plotCount(PUF_isMilitaryHappiness, -1, -1, getID()) > 1))
                                        {
                                                iValue = (10000 + GC.getGameINLINE().getSorenRandNum(1000, "Disband Unit"));

                                                iValue += (pLoopUnit->getUnitInfo().getProductionCost() * 5);

                                                iValue += (pLoopUnit->getExperience() * 20);
                                                iValue += (pLoopUnit->getLevel() * 100);

                                                if (pLoopUnit->canDefend() && pLoopUnit->plot()->isCity())
                                                {
                                                        iValue *= 2;
                                                }

                                                if (pLoopUnit->plot()->getTeam() == pLoopUnit->getTeam())
                                                {
                                                        iValue *= 3;
                                                }
/************************************************************************************************/
/* Afforess                       Start          02/12/10                                               */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/
                                                if (pLoopUnit->plot()->getOwnerINLINE() == pLoopUnit->getOwnerINLINE())
                                                {
                                                        iValue /= 6;
                                                }
/************************************************************************************************/
/* Afforess                          END                                                            */
/************************************************************************************************/

                                                switch (pLoopUnit->AI_getUnitAIType())
                                                {
                                                case UNITAI_UNKNOWN:
                                                case UNITAI_ANIMAL:
                                                        break;

                                                case UNITAI_SUBDUED_ANIMAL:
                                                        iValue *= 3;
                                                        break;

                                                case UNITAI_HUNTER:
                                                        iValue *= 10;
                                                        break;

                                                case UNITAI_SETTLE:
                                                        iValue *= 20;
                                                        break;

                                                case UNITAI_WORKER:
                                                        iValue *= 10;
                                                        break;

                                                case UNITAI_ATTACK:
                                                case UNITAI_ATTACK_CITY:
                                                case UNITAI_COLLATERAL:
                                                case UNITAI_PILLAGE:
                                                case UNITAI_RESERVE:
                                                case UNITAI_COUNTER:
                                                case UNITAI_PILLAGE_COUNTER:
                                                        iValue *= 2;
                                                        break;

                                                case UNITAI_CITY_DEFENSE:
                                                case UNITAI_CITY_COUNTER:
                                                case UNITAI_CITY_SPECIAL:
                                                case UNITAI_PARADROP:
                                                        iValue *= 6;
                                                        break;

                                                case UNITAI_EXPLORE:
                                                        iValue *= 15;
                                                        break;

                                                case UNITAI_MISSIONARY:
                                                        iValue *= 8;
                                                        break;

                                                case UNITAI_PROPHET:
                                                case UNITAI_ARTIST:
                                                case UNITAI_SCIENTIST:
                                                case UNITAI_GENERAL:
                                                case UNITAI_MERCHANT:
                                                case UNITAI_ENGINEER:
                                                        break;

                                                case UNITAI_SPY:
                                                        iValue *= 12;
                                                        break;

                                                case UNITAI_ICBM:
                                                        iValue *= 4;
                                                        break;

                                                case UNITAI_WORKER_SEA:
                                                        iValue *= 18;
                                                        break;

                                                case UNITAI_ATTACK_SEA:
                                                case UNITAI_RESERVE_SEA:
                                                case UNITAI_ESCORT_SEA: