예제 #1
0
/// Log chosen policy
void CvPolicyAI::LogPolicyChoice(PolicyTypes ePolicy)
{
	if(GC.getLogging() && GC.getAILogging())
	{
		CvString strOutBuf;
		CvString strBaseString;
		CvString strTemp;
		CvString playerName;
		CvString strDesc;

		// Find the name of this civ and city
		playerName = m_pCurrentPolicies->GetPlayer()->getCivilizationShortDescription();

		FILogFile* pLog;
		pLog = LOGFILEMGR.GetLog(GetLogFileName(playerName), FILogFile::kDontTimeStamp);

		// Get the leading info for this line
		strBaseString.Format("%03d, ", GC.getGame().getElapsedGameTurns());
		strBaseString += playerName + ", ";

		CvPolicyEntry* pPolicyEntry = GC.getPolicyInfo(ePolicy);
		const char* szPolicyType = (pPolicyEntry != NULL)? pPolicyEntry->GetType() : "Unknown";
		strTemp.Format("CHOSEN, %s", szPolicyType);

		strOutBuf = strBaseString + strTemp;
		pLog->Msg(strOutBuf);
	}
}
예제 #2
0
/// Logging function to write out info on Ideology choices
void CvPolicyAI::LogIdeologyChoice(CvString &decisionState, int iWeightFreedom, int iWeightAutocracy, int iWeightOrder)
{
	if(GC.getLogging() && GC.getAILogging())
	{
		CvString strOutBuf;
		CvString strBaseString;
		CvString strTemp;
		CvString playerName;

		// Find the name of this civ
		playerName = m_pCurrentPolicies->GetPlayer()->getCivilizationShortDescription();

		FILogFile* pLog;
		pLog = LOGFILEMGR.GetLog(GetLogFileName(playerName), FILogFile::kDontTimeStamp);

		// Get the leading info for this line
		strBaseString.Format("%03d, ", GC.getGame().getElapsedGameTurns());
		strBaseString += playerName + ", ";

		strTemp.Format("%s, Freedom: %d, Order: %d, Autocracy: %d", decisionState.c_str(), iWeightFreedom, iWeightOrder, iWeightAutocracy);

		strOutBuf = strBaseString + strTemp;
		pLog->Msg(strOutBuf);
	}
}
예제 #3
0
/// Log chosen policy
void CvPolicyAI::LogBranchChoice(PolicyBranchTypes eBranch)
{
	if(GC.getLogging() && GC.getAILogging())
	{
		CvString strOutBuf;
		CvString strBaseString;
		CvString strTemp;
		CvString playerName;
		CvString strDesc;

		// Find the name of this civ and city
		playerName = m_pCurrentPolicies->GetPlayer()->getCivilizationShortDescription();

		FILogFile* pLog;
		pLog = LOGFILEMGR.GetLog(GetLogFileName(playerName), FILogFile::kDontTimeStamp);

		// Get the leading info for this line
		strBaseString.Format("%03d, ", GC.getGame().getElapsedGameTurns());
		strBaseString += playerName + ", ";

		strTemp.Format("CHOSEN, Branch %d", eBranch);

		strOutBuf = strBaseString + strTemp;
		pLog->Msg(strOutBuf);
	}
}
예제 #4
0
/// Log GrandStrategy state: what are the Priorities and who is Active?
void CvGrandStrategyAI::LogGrandStrategies(const FStaticVector< int, 5, true, c_eCiv5GameplayDLL >& vModifiedGrandStrategyPriorities)
{
	if(GC.getLogging() && GC.getAILogging())
	{
		CvString strOutBuf;
		CvString strBaseString;
		CvString strTemp;
		CvString playerName;
		CvString strDesc;
		CvString strLogName;

		// Find the name of this civ and city
		playerName = GetPlayer()->getCivilizationShortDescription();

		// Open the log file
		if(GC.getPlayerAndCityAILogSplit())
		{
			strLogName = "GrandStrategyAI_Log_" + playerName + ".csv";
		}
		else
		{
			strLogName = "GrandStrategyAI_Log.csv";
		}

		FILogFile* pLog;
		pLog = LOGFILEMGR.GetLog(strLogName, FILogFile::kDontTimeStamp);

		AIGrandStrategyTypes eGrandStrategy;

		// Loop through Grand Strategies
		for(int iGrandStrategyLoop = 0; iGrandStrategyLoop < GC.getNumAIGrandStrategyInfos(); iGrandStrategyLoop++)
		{
			// Get the leading info for this line
			strBaseString.Format("%03d, ", GC.getGame().getElapsedGameTurns());
			strBaseString += playerName + ", ";

			eGrandStrategy = (AIGrandStrategyTypes) iGrandStrategyLoop;

			// GrandStrategy Info
			CvAIGrandStrategyXMLEntry* pEntry = GC.getAIGrandStrategyInfo(eGrandStrategy);
			const char* szAIGrandStrategyType = (pEntry != NULL)? pEntry->GetType() : "Unknown Type";

			if(GetActiveGrandStrategy() == eGrandStrategy)
			{
				strTemp.Format("*** %s, %d, %d", szAIGrandStrategyType, GetGrandStrategyPriority(eGrandStrategy), vModifiedGrandStrategyPriorities[eGrandStrategy]);
			}
			else
			{
				strTemp.Format("%s, %d, %d", szAIGrandStrategyType, GetGrandStrategyPriority(eGrandStrategy), vModifiedGrandStrategyPriorities[eGrandStrategy]);
			}
			strOutBuf = strBaseString + strTemp;
			pLog->Msg(strOutBuf);
		}
	}
}
예제 #5
0
void  CvLoggerCSV::WriteCSVLog(const char* strLogName, const char* strHeader)
	{

		FILogFile *pLog;

		pLog = LOGFILEMGR.GetLog(strLogName, FILogFile::kDontTimeStamp);

		CvAssert(pLog != NULL);

		pLog->Msg(strHeader);

	}
예제 #6
0
/// Log all possible policy choices
void CvPolicyAI::LogPossiblePolicies()
{
    if(GC.getLogging() && GC.getAILogging())
    {
        CvString strOutBuf;
        CvString strBaseString;
        CvString strTemp;
        CvString playerName;
        CvString strDesc;

        // Find the name of this civ and city
        playerName = m_pCurrentPolicies->GetPlayer()->getCivilizationShortDescription();

        FILogFile* pLog;
        pLog = LOGFILEMGR.GetLog(GetLogFileName(playerName), FILogFile::kDontTimeStamp);

        // Get the leading info for this line
        strBaseString.Format("%03d, ", GC.getGame().getElapsedGameTurns());
        strBaseString += playerName + ", ";

        int iNumBranches = GC.getNumPolicyBranchInfos();

        // Dump out the weight of each possible policy
        for(int iI = 0; iI < m_AdoptablePolicies.size(); iI++)
        {
            int iWeight = m_AdoptablePolicies.GetWeight(iI);

            if(m_AdoptablePolicies.GetElement(iI) < iNumBranches)
            {
                strTemp.Format("Branch %d, %d", m_AdoptablePolicies.GetElement(iI), iWeight);
            }
            else
            {

                PolicyTypes ePolicy = (PolicyTypes)(m_AdoptablePolicies.GetElement(iI) - iNumBranches);
                CvPolicyEntry* pPolicyEntry = GC.getPolicyInfo(ePolicy);
                const char* szPolicyType = (pPolicyEntry != NULL)? pPolicyEntry->GetType() : "Unknown";
                strTemp.Format("%s, %d", szPolicyType, iWeight);
            }
            strOutBuf = strBaseString + strTemp;
            pLog->Msg(strOutBuf);
        }
    }
}
예제 #7
0
unsigned long CvRandom::get(unsigned long ulNum, const char* pszLog)
{
	if(!gDLL->IsGameCoreThread() && gDLL->IsGameCoreExecuting() && m_bSynchronous)
	{
		OutputDebugString("Warning: GUI is accessing the synchronous random number generator while the game core is running.");
	}

	m_ulCallCount++;

	unsigned long long ullNewSeed = ((RANDOM_A * m_ullRandomSeed) + RANDOM_C);
	unsigned long ul = ((unsigned long)((((ullNewSeed >> RANDOM_SHIFT) & MAX_UNSIGNED_INT) * (ulNum)) / (MAX_UNSIGNED_INT + 1LL)));

	if(GC.getLogging())
	{
		int iRandLogging = GC.getRandLogging();
		if(iRandLogging > 0 && (m_bSynchronous || (iRandLogging & RAND_LOGGING_ASYNCHRONOUS_FLAG) != 0))
		{
			CvGame& kGame = GC.getGame();
			if(kGame.getTurnSlice() > 0 || ((iRandLogging & RAND_LOGGING_PREGAME_FLAG) != 0))
			{
				FILogFile* pLog = LOGFILEMGR.GetLog("RandCalls.csv", FILogFile::kDontTimeStamp, "Game Turn, Turn Slice, Range, Value, Seed, Instance, Type, Location\n");
				if(pLog)
				{
					char szOut[1024] = {0};
					sprintf_s(szOut, "%d, %d, %u, %u, %I64u, %8x, %s, %s\n", kGame.getGameTurn(), kGame.getTurnSlice(), 
						ulNum, ul, m_ullRandomSeed, (void*)this, m_bSynchronous?"sync":"async", (pszLog != NULL)?pszLog:"Unknown");
					pLog->Msg(szOut);

#if defined(MOD_CORE_DEBUGGING)
					if(MOD_CORE_DEBUGGING)
					{
						//gStackWalker.SetLog(pLog);
						//gStackWalker.ShowCallstack();
					}
#endif
				}
			}
		}
	}

	m_ullRandomSeed = ullNewSeed;
	return ul;
}
예제 #8
0
/// Log all potential builds
void CvProjectProductionAI::LogPossibleBuilds()
{
	if(GC.getLogging() && GC.getAILogging())
	{
		CvString strOutBuf;
		CvString strBaseString;
		CvString strTemp;
		CvString playerName;
		CvString cityName;
		CvString strDesc;
		CvString strLogName;

		CvAssert(m_pCity);
		if(!m_pCity) return;

		// Find the name of this civ and city
		playerName = GET_PLAYER(m_pCity->getOwner()).getCivilizationShortDescription();
		cityName = m_pCity->getName();

		// Open the log file
		FILogFile* pLog;
		pLog = LOGFILEMGR.GetLog(m_pCity->GetCityStrategyAI()->GetLogFileName(playerName, cityName), FILogFile::kDontTimeStamp);
		CvAssert(pLog);
		if(!pLog) return;

		// Get the leading info for this line
		strBaseString.Format("%03d, ", GC.getGame().getElapsedGameTurns());
		strBaseString += playerName + ", " + cityName + ", ";

		// Dump out the weight of each buildable item
		for(int iI = 0; iI < m_Buildables.size(); iI++)
		{
			CvProjectEntry* pProjectEntry = GC.GetGameProjects()->GetEntry(m_Buildables.GetElement(iI));

			strDesc = (pProjectEntry != NULL)? pProjectEntry->GetDescription() : "Unknown";
			strTemp.Format("Project, %s, %d", strDesc.GetCString(), m_Buildables.GetWeight(iI));
			strOutBuf = strBaseString + strTemp;
			pLog->Msg(strOutBuf);
		}
	}
}
예제 #9
0
// TODO Make this function more useful.
void CvPlayerAI::AI_LogEvent(int iEvent, int iOption)
{
	if(GC.getLogging() && GC.getAILogging())
	{
		CvString strOutBuf;
		CvString strBaseString;
		CvString playerName;
		CvString strDesc;
		CvString strLogName;
		CvString strTemp;

		// Find the name of this civ and city
		playerName = getCivilizationShortDescription();

		// Open the log file
		if(GC.getPlayerAndCityAILogSplit())
		{
			strLogName = "EventAILog_" + playerName + ".csv";
		}
		else
		{
			strLogName = "EventAILog.csv";
		}

		FILogFile* pLog;
		pLog = LOGFILEMGR.GetLog(strLogName, FILogFile::kDontTimeStamp);

		// Get the leading info for this line
		strBaseString.Format("%03d, EVENT, ", GC.getGame().getElapsedGameTurns());
		strBaseString += playerName;

		strTemp.Format("%d, %d", iEvent, iOption);

		strOutBuf = strBaseString + ", " + strTemp;

		pLog->Msg(strOutBuf);
	}
}
예제 #10
0
/// Log our guess as to other Players' Active Grand Strategy
void CvGrandStrategyAI::LogGuessOtherPlayerGrandStrategy(const FStaticVector< int, 5, true, c_eCiv5GameplayDLL >& vGrandStrategyPriorities, PlayerTypes ePlayer)
{
	if(GC.getLogging() && GC.getAILogging())
	{
		CvString strOutBuf;
		CvString strBaseString;
		CvString strTemp;
		CvString playerName;
		CvString otherPlayerName;
		CvString strDesc;
		CvString strLogName;

		// Find the name of this civ and city
		playerName = GetPlayer()->getCivilizationShortDescription();

		// Open the log file
		if(GC.getPlayerAndCityAILogSplit())
		{
			strLogName = "GrandStrategyAI_Guess_Log_" + playerName + ".csv";
		}
		else
		{
			strLogName = "GrandStrategyAI_Guess_Log.csv";
		}

		FILogFile* pLog;
		pLog = LOGFILEMGR.GetLog(strLogName, FILogFile::kDontTimeStamp);

		AIGrandStrategyTypes eGrandStrategy;
		int iPriority;

		// Loop through Grand Strategies
		for(int iGrandStrategyLoop = 0; iGrandStrategyLoop < GC.getNumAIGrandStrategyInfos(); iGrandStrategyLoop++)
		{
			// Get the leading info for this line
			strBaseString.Format("%03d, ", GC.getGame().getElapsedGameTurns());
			strBaseString += playerName + ", ";

			eGrandStrategy = (AIGrandStrategyTypes) iGrandStrategyLoop;
			iPriority = vGrandStrategyPriorities[iGrandStrategyLoop];

			CvAIGrandStrategyXMLEntry* pEntry = GC.getAIGrandStrategyInfo(eGrandStrategy);
			const char* szGrandStrategyType = (pEntry != NULL)? pEntry->GetType() : "Unknown Strategy";

			// GrandStrategy Info
			if(GetActiveGrandStrategy() == eGrandStrategy)
			{
				strTemp.Format("*** %s, %d", szGrandStrategyType, iPriority);
			}
			else
			{
				strTemp.Format("%s, %d", szGrandStrategyType, iPriority);
			}
			otherPlayerName = GET_PLAYER(ePlayer).getCivilizationShortDescription();
			strOutBuf = strBaseString + otherPlayerName + ", " + strTemp;

			if(GetGuessOtherPlayerActiveGrandStrategy(ePlayer) == eGrandStrategy)
			{
				// Confidence in our guess
				switch(GetGuessOtherPlayerActiveGrandStrategyConfidence(ePlayer))
				{
				case GUESS_CONFIDENCE_POSITIVE:
					strTemp.Format("Positive");
					break;
				case GUESS_CONFIDENCE_LIKELY:
					strTemp.Format("Likely");
					break;
				case GUESS_CONFIDENCE_UNSURE:
					strTemp.Format("Unsure");
					break;
				default:
					strTemp.Format("XXX");
					break;
				}

				strOutBuf += ", " + strTemp;
			}

			pLog->Msg(strOutBuf);
		}

		// One more entry for NO GRAND STRATEGY
		// Get the leading info for this line
		strBaseString.Format("%03d, ", GC.getGame().getElapsedGameTurns());
		strBaseString += playerName + ", ";

		iPriority = vGrandStrategyPriorities[GC.getNumAIGrandStrategyInfos()];

		// GrandStrategy Info
		strTemp.Format("NO_GRAND_STRATEGY, %d", iPriority);
		otherPlayerName = GET_PLAYER(ePlayer).getCivilizationShortDescription();
		strOutBuf = strBaseString + otherPlayerName + ", " + strTemp;
		pLog->Msg(strOutBuf);
	}
}
예제 #11
0
void CvCityAI::AI_chooseProduction(bool bInterruptWonders)
{
	VALIDATE_OBJECT
	CvPlayerAI& kOwner = GET_PLAYER(getOwner());
	CvCitySpecializationAI* pSpecializationAI = kOwner.GetCitySpecializationAI();
	bool bBuildWonder = false;

	// See if this is the one AI city that is supposed to be building wonders
	if(pSpecializationAI->GetWonderBuildCity() == this)
	{
		// Is it still working on that wonder and we don't want to interrupt it?
		if(!bInterruptWonders)
		{
			const BuildingTypes eBuilding = getProductionBuilding();
			CvBuildingEntry* pkBuilding = (eBuilding != NO_BUILDING)? GC.getBuildingInfo(eBuilding) : NULL;
			if(pkBuilding && kOwner.GetWonderProductionAI()->IsWonder(*pkBuilding))
			{
				return;  // Stay the course
			}
		}

		// So we're the wonder building city but it is not underway yet...

		// Has the designated wonder been poached by another civ?
		BuildingTypes eNextWonder = pSpecializationAI->GetNextWonderDesired();
		if(!canConstruct(eNextWonder))
		{
			// Reset city specialization
			kOwner.GetCitySpecializationAI()->SetSpecializationsDirty(SPECIALIZATION_UPDATE_WONDER_BUILT_BY_RIVAL);
		}
		else
		{
			// to prevent us from continuously locking into building wonders in one city when there are other high priority items to build
			int iFlavorWonder = kOwner.GetGrandStrategyAI()->GetPersonalityAndGrandStrategy((FlavorTypes)GC.getInfoTypeForString("FLAVOR_WONDER"));
			int iFlavorGP = kOwner.GetGrandStrategyAI()->GetPersonalityAndGrandStrategy((FlavorTypes)GC.getInfoTypeForString("FLAVOR_GREAT_PEOPLE"));
			int iFlavor = (iFlavorWonder > iFlavorGP ) ? iFlavorWonder : iFlavorGP;
			if (GC.getGame().getJonRandNum(11, "Random roll for whether to continue building wonders") <= iFlavor)
				bBuildWonder = true;
		}
	}

	if(bBuildWonder)
	{
		CvCityBuildable buildable;
		buildable.m_eBuildableType = CITY_BUILDABLE_BUILDING;
		buildable.m_iIndex = pSpecializationAI->GetNextWonderDesired();
		buildable.m_iTurnsToConstruct = getProductionTurnsLeft((BuildingTypes)buildable.m_eBuildableType, 0);
		pushOrder(ORDER_CONSTRUCT, buildable.m_iIndex, -1, false, false, false, false);

		if(GC.getLogging() && GC.getAILogging())
		{
			CvString playerName;
			FILogFile* pLog;
			CvString strBaseString;
			CvString strOutBuf;

			m_pCityStrategyAI->LogCityProduction(buildable, false);

			playerName = kOwner.getCivilizationShortDescription();
			pLog = LOGFILEMGR.GetLog(kOwner.GetCitySpecializationAI()->GetLogFileName(playerName), FILogFile::kDontTimeStamp);
			strBaseString.Format("%03d, ", GC.getGame().getElapsedGameTurns());
			strBaseString += playerName + ", ";
			strOutBuf.Format("%s, WONDER - Started %s, Turns: %d", getName().GetCString(), GC.getBuildingInfo((BuildingTypes)buildable.m_iIndex)->GetDescription(), buildable.m_iTurnsToConstruct);
			strBaseString += strOutBuf;
			pLog->Msg(strBaseString);
		}
	}

	else
	{
		m_pCityStrategyAI->ChooseProduction(false);
		AI_setChooseProductionDirty(false);
	}

	return;
}
예제 #12
0
unsigned short CvRandom::get(unsigned short usNum, const char* pszLog)
{
	recordCallStack();
	m_ulCallCount++;

	unsigned long ulNewSeed = ((RANDOM_A * m_ulRandomSeed) + RANDOM_C);
	unsigned short us = ((unsigned short)((((ulNewSeed >> RANDOM_SHIFT) & MAX_UNSIGNED_SHORT) * ((unsigned long)usNum)) / (MAX_UNSIGNED_SHORT + 1)));

	if(GC.getLogging())
	{
		int iRandLogging = GC.getRandLogging();
		if(iRandLogging > 0 && (m_bSynchronous || (iRandLogging & RAND_LOGGING_ASYNCHRONOUS_FLAG) != 0))
		{
#if !defined(FINAL_RELEASE)
			if(!gDLL->IsGameCoreThread() && gDLL->IsGameCoreExecuting() && m_bSynchronous)
			{
				CvAssertMsg(0, "App side is accessing the synchronous random number generator while the game core is running.");
			}
#endif
			CvGame& kGame = GC.getGame();
			if(kGame.getTurnSlice() > 0 || ((iRandLogging & RAND_LOGGING_PREGAME_FLAG) != 0))
			{
				FILogFile* pLog = LOGFILEMGR.GetLog("RandCalls.csv", FILogFile::kDontTimeStamp, "Game Turn, Turn Slice, Range, Value, Seed, Instance, Type, Location\n");
				if(pLog)
				{
					char szOut[1024] = {0};
					sprintf_s(szOut, "%d, %d, %u, %u, %u, %8x, %s, %s\n", kGame.getGameTurn(), kGame.getTurnSlice(), (uint)usNum, (uint)us, getSeed(), (uint)this, m_bSynchronous?"sync":"async", (pszLog != NULL)?pszLog:"Unknown");
					pLog->Msg(szOut);

#if !defined(FINAL_RELEASE)
					if((iRandLogging & RAND_LOGGING_CALLSTACK_FLAG) != 0)
					{
#ifdef _DEBUG
						if(m_bExtendedCallStackDebugging)
						{
							// Use the callstack from the extended callstack debugging system
							const FCallStack& callStack = m_kCallStacks.back();
							std::string stackTrace = callStack.toString(true, 6);
							pLog->Msg(stackTrace.c_str());
						}
						else
#endif
						{
#ifdef WIN32
							// Get callstack directly
							FCallStack callStack;
							FDebugHelper::GetInstance().GetCallStack(&callStack, 0, 8);
							std::string stackTrace = callStack.toString(true, 6);
							pLog->Msg(stackTrace.c_str());
#endif
						}
					}
#endif
				}
			}
		}
	}

	m_ulRandomSeed = ulNewSeed;
	return us;
}
예제 #13
0
void CvTreasury::LogExpenditure(CvString strExpenditure, int iAmount, int iColumn)
{
	if(!(GC.getLogging() && GC.getAILogging()))
	{
		return;
	}

	// don't log minor civs for now
	if(m_pPlayer->isMinorCiv())
	{
		return;
	}

	static bool bFirstRun = true;
	bool bBuildHeader = false;
	CvString strHeader;
	if(bFirstRun)
	{
		bFirstRun = false;
		bBuildHeader = true;
	}

	CvString strLog;

	// Find the name of this civ and city
	CvString strPlayerName;
	strPlayerName = m_pPlayer->getCivilizationShortDescription();
	CvString strLogName;

	// Open the log file
	if(GC.getPlayerAndCityAILogSplit())
	{
		strLogName = "ExpenditureLog_" + strPlayerName + ".csv";
	}
	else
	{
		strLogName = "ExpenditureLog.csv";
	}


	FILogFile* pLog;
	pLog = LOGFILEMGR.GetLog(strLogName, FILogFile::kDontTimeStamp);

	CvString str;

	// civ name
	TreasuryHelpers::AppendToLog(strHeader, strLog, "Civ Name", strPlayerName);

	// turn
	TreasuryHelpers::AppendToLog(strHeader, strLog, "Turn", GC.getGame().getGameTurn());

	// treasury at turn start
	TreasuryHelpers::AppendToLog(strHeader, strLog, "Treasury Before Purchase", m_pPlayer->GetTreasury()->GetGold());
	
	// Cost of Plot
	if (iColumn == 1){
		TreasuryHelpers::AppendToLog(strHeader, strLog, "Cost of Plot:", iAmount);
	}
	else{
		TreasuryHelpers::AppendToLog(strHeader, strLog, "Cost of Plot:", 0);
	}
	
	// City Expenditure and Amount
	if (iColumn == 2){
		TreasuryHelpers::AppendToLog(strHeader, strLog, "City Bought:", strExpenditure);
		TreasuryHelpers::AppendToLog(strHeader, strLog, "City Spent:", iAmount);
	}
	else{
		TreasuryHelpers::AppendToLog(strHeader, strLog, "City Bought:", "");
		TreasuryHelpers::AppendToLog(strHeader, strLog, "City Spent:", 0);
	}
	
	// Unit Upgrade and cost
	if (iColumn == 3){
		TreasuryHelpers::AppendToLog(strHeader, strLog, "Unit Upgraded:", strExpenditure);
		TreasuryHelpers::AppendToLog(strHeader, strLog, "Spent on Upgrade:", iAmount);
	}
	else{
		TreasuryHelpers::AppendToLog(strHeader, strLog, "Unit Upgrade:", "");
		TreasuryHelpers::AppendToLog(strHeader, strLog, "Spent on Upgrade:", 0);
	}

	// City State Gifted and Amount
	if (iColumn == 4){
		TreasuryHelpers::AppendToLog(strHeader, strLog, "City State Gold Gifted:", strExpenditure);
		TreasuryHelpers::AppendToLog(strHeader, strLog, "Gold Gift Amount:", iAmount);
	}
	else{
		TreasuryHelpers::AppendToLog(strHeader, strLog, "City State Gold Gifted:", "");
		TreasuryHelpers::AppendToLog(strHeader, strLog, "Gold Gift Amount:", 0);
	}
	
	// City State Improved and Amount
	if (iColumn == 5){
		TreasuryHelpers::AppendToLog(strHeader, strLog, "City State Improved:", strExpenditure);
		TreasuryHelpers::AppendToLog(strHeader, strLog, "Gold for Improvement Amount:", iAmount);
	}
	else{
		TreasuryHelpers::AppendToLog(strHeader, strLog, "City State Improved:", "");
		TreasuryHelpers::AppendToLog(strHeader, strLog, "Gold for Improvement Amount:", 0);
	}

	// City State Bought and Amount
	if (iColumn == 6){
		TreasuryHelpers::AppendToLog(strHeader, strLog, "City State Bought:", strExpenditure);
		TreasuryHelpers::AppendToLog(strHeader, strLog, "Bought for:", iAmount);
	}
	else{
		TreasuryHelpers::AppendToLog(strHeader, strLog, "City State Bought:", "");
		TreasuryHelpers::AppendToLog(strHeader, strLog, "Bought for:", 0);
	}
	
	// Emergency City Expenditure Unit and Amount
	if (iColumn == 7){
		TreasuryHelpers::AppendToLog(strHeader, strLog, "Emergency Unit:", strExpenditure);
		TreasuryHelpers::AppendToLog(strHeader, strLog, "Emergency Unit Cost:", iAmount);
	}
	else{
		TreasuryHelpers::AppendToLog(strHeader, strLog, "Emergency Unit:", "");
		TreasuryHelpers::AppendToLog(strHeader, strLog, "Emergency Unit Cost:", 0);
	}
	
	// Emergency City Expenditure Unit and Amount
	if (iColumn == 8){
		TreasuryHelpers::AppendToLog(strHeader, strLog, "Emergency Building:", strExpenditure);
		TreasuryHelpers::AppendToLog(strHeader, strLog, "Emergency Building Cost:", iAmount);
	}
	else{
		TreasuryHelpers::AppendToLog(strHeader, strLog, "Emergency Building:", "");
		TreasuryHelpers::AppendToLog(strHeader, strLog, "Emergency Building Cost:", 0);
	}

	// Research Agreement and Amount
	if (iColumn == 9){
		TreasuryHelpers::AppendToLog(strHeader, strLog, "Research Agreement with:", strExpenditure);
		TreasuryHelpers::AppendToLog(strHeader, strLog, "Research Agreement Cost:", iAmount);
	}
	else{
		TreasuryHelpers::AppendToLog(strHeader, strLog, "Research Agreement with:", "");
		TreasuryHelpers::AppendToLog(strHeader, strLog, "Research Agreement Cost:", 0);
	}

	if(bBuildHeader)
	{
		pLog->Msg(strHeader);
	}
	pLog->Msg(strLog);
}