Any way of detecting current game month?

Baldyr

"Hit It"
Joined
Dec 5, 2009
Messages
5,530
Location
Sweden
I realize that the calendars in the game really work with months and not years, but at the same time there is no way of getting the actual month value, only the year that is calculated from the month. Right?

But looking at the API I see MonthTypes. It would be helpful if there was a method that returned one of those... :rolleyes:

Is there? Or would I have to make it myself? Or do I need to do this with C++?

What are my options for getting around this limitation in the Python API? Like checking the year of previous and subsequent turns with CyGame.getGameYear() and comparing the returned values. Then figure out how many turns that are within that year interval, and calculate how many months one game turn really is. And then figure out which month would be the current one. (Although it would be obvious for the player - as the date is right there in the game interface. Is it possible to capture the displayed value (string?) and use that instead?)
 
It's getTurnMonthForGame in CvGameCoreUtils, but it has to be exposed to Python. Deja vu? :confused:

For second part, there's getGameSpeedInfo(eSpeed) in CvInfos which can be used to retrieve all the calendar info.
 
That's in the SDK, right?

I was wondering about a possible work-around to adding a custom DLL file, actually. Because that doens't work for me.
 
I think we're editing our posts while the other one is replying, so I'll just post a new one:

What is CvInfos and where does it reside?
 
getTurnMonthForGame - yes, but I said I can expose it in the RFCM DLL.

getGameSpeedInfo is available in Python, with further get* methods for every tag in the XML, basically.
EDIT: gc.getGameSpeedInfo... normal stuff.
 
getTurnMonthForGame - yes, but I said I can expose it in the RFCM DLL.
And I thank you for your offer. I sadly can't add a custom DLL to my own project, but if you ever update yours you could always add that. Because it would be most helpful.

Until then I'm looking for a work-around - in Python only.

getGameSpeedInfo is available in Python, with further get* methods for every tag in the XML, basically.
EDIT: gc.getGameSpeedInfo... normal stuff.
What do I do with it then? How does it help me retrieve the current game month? :confused:
 
It won't help with that (at least not directly)... well, it could, but calculating the calendar in Python is an overkill. It was just for the second part of question, i.e. how to retrieve current number of months per turn etc.

Those are of interest I guess: getNumTurnIncrements() / getGameTurnInfo(int).iYearIncrement / getGameTurnInfo(int).iNumGameTurnsPerIncrement
 
Thanks! :goodjob:

I don't actually understand what I'm seeing here. So I guess I use getGameTurnInfo() which returns the GameTurnInfo class? (An instance of that class?) But how do I retrieve the attribute values? And what are they exactly?

iNumGameTurnsPerIncrement and iYearIncrement - are they the current values or do they refer to how the calendar is setup? (The default calendar would have varied turn/year increments, right?)

This is all new stuff for me.

edit: I guess you already answered my question(s)?
 
Ok, so I can figure out how many game turns say the year AD 1989 is on Marathon speed, then. But how do I know which of those turns is the current one?

Confusing stuff...
 
The current turn is always gc.getGame().getGameTurn(), though you probably mean something else - the DLL functions just iterate through all the turns and stop when they find the correct turn.

getNumTurnIncrements and getGameTurnInfo correspond to tags in the XML. Using them you can go turn by turn and get exact month for every one (this is getTurnMonthForGame w/ Default calendar):

Code:
		iTurnCount = 0;

		for (iI = 0; iI < GC.getGameSpeedInfo(eSpeed).getNumTurnIncrements(); iI++)
		{
			if (iGameTurn > (iTurnCount + GC.getGameSpeedInfo(eSpeed).getGameTurnInfo(iI).iNumGameTurnsPerIncrement))
			{
				iTurnMonth += (GC.getGameSpeedInfo(eSpeed).getGameTurnInfo(iI).iMonthIncrement * GC.getGameSpeedInfo(eSpeed).getGameTurnInfo(iI).iNumGameTurnsPerIncrement);
				iTurnCount += GC.getGameSpeedInfo(eSpeed).getGameTurnInfo(iI).iNumGameTurnsPerIncrement;
			}
			else
			{
				iTurnMonth += (GC.getGameSpeedInfo(eSpeed).getGameTurnInfo(iI).iMonthIncrement * (iGameTurn - iTurnCount));
				iTurnCount += (iGameTurn - iTurnCount);
				break;
			}
		}

		if (iGameTurn > iTurnCount)
		{
			iTurnMonth += (GC.getGameSpeedInfo(eSpeed).getGameTurnInfo(GC.getGameSpeedInfo(eSpeed).getNumTurnIncrements() - 1).iMonthIncrement * (iGameTurn - iTurnCount));
		}

You could technically make a copy of it in Python to avoid the DLL, but it'd be much slower. Maybe it can be used to get the next month interval though I don't really know how to get to the correct GameTurnInfo without iterating all turns.
 
Perhaps it would be possible to create a index of all game turns and their respective years/montsh at initialization? Then access that for quick calls.
 
I'll just have to figure out how to do this... But its just another programming problem - love those! :king:

I wonder what my turn entries will end up being, then. Months? Integer year and integer month?

Any other ideas for this, anybody?
 
So this is the code for printing out all game turns with their associated dates - year and month - for any game speed:
Code:
from CvPythonExtensions import CyGlobalContext
gc = CyGlobalContext()
eGameSpeed = gc.getGame().getGameSpeedType()
speedInfo = gc.getGameSpeedInfo(eGameSpeed)
iGameYear = gc.getGame().getStartYear()
iGameTurn, increment = 0, 0
while increment < speedInfo.getNumTurnIncrements():
        turnInfo = speedInfo.getGameTurnInfo(increment)
        iNumTurns = turnInfo.iNumGameTurnsPerIncrement
        iNumMonths = turnInfo.iMonthIncrement
        for iTurn in range(iNumTurns):
                iCurrentTurn = iGameTurn + iTurn
                currentYear = iGameYear + iTurn * iNumMonths / 12.0
                iCurrentYear = int(currentYear)
                iCurrentMonth = int((currentYear % iCurrentYear) * 12)
                [COLOR="DarkRed"]print (iCurrentTurn, iCurrentYear, iCurrentMonth)[/COLOR]
        iGameTurn += iNumTurns
        iGameYear += iNumTurns * iNumMonths / 12
        increment += 1
Instead of printing out iCurrentYear and iCurrenMonth I could put both of these values in a tuple and store it in a list.
Code:
                lCalendarIndex.append((iCurrentYear, iCurrentMonth))
Then access the data by indexing with iGameTurn and assigning the tuple values to iYear and iMonth:
Code:
iYear, iMonth = lCalendarIndex[iGameTurn]
And wrap the call into a set of functions:
Code:
def getDateForTurn(iGameTurn):
        return lCalendarIndex[iGameTurn]

def getYearForTurn(iGameTurn):
        return getDateForTurn(iGameTurn)[0]

def getMonthForTurn(iGameTurn):
        return getDateForTurn(iGameTurn)[1]

def getMonthDateForTurn(iGameTurn):
        iYear, iMonth = getDateForTurn(iGameTurn)
        return iYear * 12 + iMonth
Problem solved, I think. :D But it will cause some delay on initialization... :p

Oh, boy. This kind of thing is what I call clean programming fun! :D
 
:goodjob:

It takes fraction of a second in C++, in Python it shouldn't take more than 1-2 seconds, it'd only be a problem if done every turn, with every trigger etc.; on init only it won't be noticeable.
 
I ended up converting all dates to "game date" values which correspond to the month:
Code:
class GameDate:

        index = [iStartYear * 12]

        def __init__(self, eGameSpeed):
                pSpeedInfo = gc.getGameSpeedInfo(eGameSpeed)
                iGameMonth = iStartYear * 12
                iIncrement = 0
                while iIncrement < pSpeedInfo.getNumTurnIncrements():
                        pTurnInfo = pSpeedInfo.getGameTurnInfo(iIncrement)
                        iTurn = 0
                        while iTurn < pTurnInfo.iNumGameTurnsPerIncrement:
                                iGameMonth += pTurnInfo.iMonthIncrement
                                self.index.append(iGameMonth)
                                iTurn += 1
                        iIncrement += 1
On initialization the GameDate constructor is called once but not assigned to any variable. This causes the class variable index (list) be populated with game date entries. And the index is accessed simply with:
Code:
GameDate.index[iGameTurn]
So it won't be necessary to get the current month which I originally requested. Move along, nothing more to see. :p
 
I haven't checked this: what is returned by CyGameTextMgr.getDateStr(INT iGameTurn, BOOL bSave, CalendarType eCalendar, INT iStartYear, GameSpeedType eSpeed)?
 
Aargh! I was looking for something like that myself, but never realized there was such a thing as CyGameTextMgr... :rolleyes:
 
It also has a getTimeStr(INT iGameTurn, BOOL bSave), which I also don't know what it returns (it is used to produce the "founded date" text on the religion screen, but I don't remember what that actually looks like) .
 
Top Bottom