Requesting following features

does that would function() think work!? I thought that would be impossible!!!

Looks good (I presume you will continue to develop it?), you have to do the same for the penalties... I am about to test the isDate() function :p
 
does that would function() think work!? I thought that would be impossible!!!
:D I originally saw this in some of the external code used in the RFC mod. Its pretty mind-boggling, eh? :crazyeye:

The prerequisite for this to work is, of course, that all those names are defined. In this case; defined as functions.

Looks good (I presume you will continue to develop it?), you have to do the same for the penalties... I am about to test the isDate() function :p
I'm thinking that we get one of these beast working first - then its just a matter of adapting the what works to other areas. Otherwise we'll end up updating multiple systems simultaneously, which is pretty sub-optimal. We get the code design we want first, only then we use it universally.
 
right exception from your fix :p

Traceback (most recent call last):

File "CvEventInterface", line 23, in onEvent

File "CvEventManager", line 188, in handleEvent

File "CvEventManager", line 385, in onBeginGameTurn

File "ModEvents", line 41, in eventSpartacus

File "Helpers", line 35, in isDate

IndexError: list index out of range
ERR: Python function onEvent failed, module CvEventInterface

line: iMonthDate = int(lDate[0]) * 12 + int(lDate[2]) - 1
 
fixed! I did a test in idle...

>>> date = "395:2"
>>> lDate = date.split(":")
>>> print lDate
['395', '2']

there is no [2] as the : is omitted
 
Thinking about this further, we don't even need a separate "apply punishment" function. Instead, we can make generic function for applying both reward and punishment. Lets call it the randSenateOutcome() function:
Code:
def getWeighSpan():
        iCount = 0
        for iWeigh in (tValues[2] for tValues in lRewards):
                iCount += iWeigh
        return iCount

def randSenateOutcome(lData):
        iRand = getRandNum(getWeighSpan(lData)) + 1
        iCount = 0
        for tValues in lData:
                function, iArgument, iWeigh = tValues
                iCount += iWeigh
                if iCount => iRand:
                        if iArgument == None:
                                function()
                        else:
                                function(iArgument)
                        return
So if we wanna grant rewards, we call:
Code:
randSenateOutcome(lRewards)
I adhere to a reductionist programming philosophy, where repetition of code is prohibited by principle. :D
 
Nice work! :goodjob: My confidence in your ability to carry on development after I ride off into the sunset is pretty rock-solid. :king:
 
why didn't I think of that :rolleyes: (then again I started this back when I was new :p)


I fear the day the sunset comes :(
 
Further, the grantGold() function would also work for punishments - with a negative argument. The same probably goes for happiness/unhappiness, and so on.
 
why didn't I think of that :rolleyes: (then again I started this back when I was new :p)
Yeah, I realize you had great fun drafting up those if-trees of yours. I'm sure it was a great learning experience, and I apologize for trampling on those sand-castles you built but never got to watch being swallowed up by the tides. Or something equally, eh... poetic. ;)
 
oh dear.... um...

Traceback (most recent call last):

File "CvEventInterface", line 23, in onEvent

File "CvEventManager", line 188, in handleEvent

File "CvEventManager", line 385, in onBeginGameTurn

File "ModEvents", line 41, in eventSpartacus

File "Helpers", line 37, in isDate

File "Helpers", line 30, in getDateForTurn

NameError: global name 'getTurnMonthForGame' is not defined
ERR: Python function onEvent failed, module CvEventInterface
 
Oops! I was kinda fearful of this eventuality, actually.

This could potentially mean that the getTurnMonthForGame() function in the SDK isn't exposed to Python by default. So you'd need to ask Asaf to add this to the Python API for you. :p

Sorry about that!
 
I fear the day the sunset comes :(
No need. Firstly; you don't need training-wheels forever. And, secondly; I will still be visiting these boards on a more or less daily basis after I become free of domestic duties. Even if I may not be able to test code in-game myself, I will surely take every opportunity to flex my scripting muscles. Because otherwise they will inevitable become weak over time. So drafting up some sample code will still be an option.
 
Now that I actually bothered to look-up CyGameCoreUtilsInterface, it turns out that the function is missing:
Spoiler :
Code:
//
// Python interface for CvgameCoreUtils.h.
//

void CyGameCoreUtilsPythonInterface()
{
	OutputDebugString("Python Extension Module - CyGameCoreUtilsPythonInterface\n");

	python::def("cyIntRange", cyIntRange,"int (int iNum, int iLow, int iHigh)");
	python::def("cyFloatRange", cyFloatRange,"float (float fNum, float fLow, float fHigh)");
	python::def("dxWrap", cyDxWrap,"int (int iDX)");
	python::def("dyWrap", cyDyWrap,"int (int iDY)");
	python::def("plotDistance", cyPlotDistance,"int (int iX1, int iY1, int iX2, int iY2)");
	python::def("stepDistance", cyStepDistance,"int (int iX1, int iY1, int iX2, int iY2)");
	python::def("plotDirection", cyPlotDirection, python::return_value_policy<python::manage_new_object>(), "CyPlot* (int iX, int iY, DirectionTypes eDirection)");
	python::def("plotCardinalDirection", cyPlotCardinalDirection, python::return_value_policy<python::manage_new_object>(), "CyPlot* (int iX, int iY, CardinalDirectionTypes eCardDirection)");
	python::def("splotCardinalDirection", cysPlotCardinalDirection, python::return_value_policy<python::reference_existing_object>(), "CyPlot* (int iX, int iY, CardinalDirectionTypes eCardDirection)");
	python::def("plotXY", cyPlotXY, python::return_value_policy<python::manage_new_object>(), "CyPlot* (int iX, int iY, int iDX, int iDY)");
	python::def("splotXY", cysPlotXY, python::return_value_policy<python::reference_existing_object>(), "CyPlot* (int iX, int iY, int iDX, int iDY)");
	python::def("directionXY", cyDirectionXYFromInt,"DirectionTypes (int iDX, int iDY)");
	python::def("directionXYFromPlot", cyDirectionXYFromPlot,"DirectionTypes (CyPlot* pFromPlot, CyPlot* pToPlot)");
	python::def("plotCity", cyPlotCity, python::return_value_policy<python::manage_new_object>(), "CyPlot* (int iX, int iY, int iIndex)");
	python::def("plotCityXY", cyPlotCityXYFromInt,"int (int iDX, int iDY)");
	python::def("plotCityXYFromCity", cyPlotCityXYFromCity,"int (CyCity* pCity, CyPlot* pPlot)");
	python::def("getOppositeCardinalDirection", cyGetOppositeCardinalDirection,"CardinalDirectionTypes (CardinalDirectionTypes eDir)");
	python::def("cardinalDirectionToDirection", cyCardinalDirectionToDirection, "DirectionTypes (CardinalDirectionTypes eDir) - converts a CardinalDirectionType to the corresponding DirectionType");

	python::def("isCardinalDirection", cyIsCardinalDirection,"bool (DirectionTypes eDirection)");
	python::def("estimateDirection", cyEstimateDirection, "DirectionTypes (int iDX, int iDY)");

	python::def("atWar", cyAtWar,"bool (int eTeamA, int eTeamB)");
	python::def("isPotentialEnemy", cyIsPotentialEnemy,"bool (int eOurTeam, int eTheirTeam)");

	python::def("getCity", cyGetCity, python::return_value_policy<python::manage_new_object>(), "CyPlot* (IDInfo city)");
	python::def("getUnit", cyGetUnit, python::return_value_policy<python::manage_new_object>(), "CyUnit* (IDInfo unit)");

	python::def("isPromotionValid", cyIsPromotionValid, "bool (int /*PromotionTypes*/ ePromotion, int /*UnitTypes*/ eUnit, bool bLeader)");
	python::def("getPopulationAsset", cyGetPopulationAsset, "int (int iPopulation)");
	python::def("getLandPlotsAsset", cyGetLandPlotsAsset, "int (int iLandPlots)");
	python::def("getPopulationPower", cyGetPopulationPower, "int (int iPopulation)");
	python::def("getPopulationScore", cyGetPopulationScore, "int (int iPopulation)");
	python::def("getLandPlotsScore", cyGetLandPlotsScore, "int (int iPopulation)");
	python::def("getTechScore", cyGetTechScore, "int (int /*TechTypes*/ eTech)");
	python::def("getWonderScore", cyGetWonderScore, "int (int /*BuildingClassTypes*/ eWonderClass)");
	python::def("finalImprovementUpgrade", cyFinalImprovementUpgrade, "int /*ImprovementTypes*/ (int /*ImprovementTypes*/ eImprovement, int iCount)");

	python::def("getWorldSizeMaxConscript", cyGetWorldSizeMaxConscript, "int (int /*CivicTypes*/ eCivic)");
	python::def("isReligionTech", cyIsReligionTech, "int (int /*TechTypes*/ eTech)");

	python::def("isTechRequiredForUnit", cyIsTechRequiredForUnit, "bool (int /*TechTypes*/ eTech, int /*UnitTypes*/ eUnit)");
	python::def("isTechRequiredForBuilding", cyIsTechRequiredForBuilding, "bool (int /*TechTypes*/ eTech, int /*BuildingTypes*/ eBuilding)");
	python::def("isTechRequiredForProject", cyIsTechRequiredForProject, "bool (int /*TechTypes*/ eTech, int /*ProjectTypes*/ eProject)");
	python::def("isWorldUnitClass", cyIsWorldUnitClass, "bool (int /*UnitClassTypes*/ eUnitClass)");
	python::def("isTeamUnitClass", cyIsTeamUnitClass, "bool (int /*UnitClassTypes*/ eUnitClass)");
	python::def("isNationalUnitClass", cyIsNationalUnitClass, "bool (int /*UnitClassTypes*/ eUnitClass)");
	python::def("isLimitedUnitClass", cyIsLimitedUnitClass, "bool (int /*UnitClassTypes*/ eUnitClass)");
	python::def("isWorldWonderClass", cyIsWorldWonderClass, "bool (int /*BuildingClassTypes*/ eBuildingClass)");
	python::def("isTeamWonderClass", cyIsTeamWonderClass, "bool (int /*BuildingClassTypes*/ eBuildingClass)");
	python::def("isNationalWonderClass", cyIsNationalWonderClass, "bool (int /*BuildingClassTypes*/ eBuildingClass)");
	python::def("isLimitedWonderClass", cyIsLimitedWonderClass, "bool (int /*BuildingClassTypes*/ eBuildingClass)");
	python::def("isWorldProject", cyIsWorldProject, "bool (int /*ProjectTypes*/ eProject)");
	python::def("isTeamProject", cyIsTeamProject, "bool (int /*ProjectTypes*/ eProject)");
	python::def("isLimitedProject", cyIsLimitedProject, "bool (int /*ProjectTypes*/ eProject)");
	python::def("getCombatOdds", cyGetCombatOdds, "int (CyUnit* pAttacker, CyUnit* pDefender)");
	python::def("getEspionageModifier", cyGetEspionageModifier, "int (int /*TeamTypes*/ iOurTeam, int /*TeamTypes*/ iTargetTeam)");
}
The good news is that it should be very easy to expose the function to Python. Its the bloody compilation of the DLL that is in the way. :p
 
I would do it myself, but the DLL is way too painful (and if asaf does work for us again it could cause problems)... I don't suppose simple standalone C++ code could do the job? :lol:

edit: why didn't they expose everything to python in the first place? :lol:
 
Until Asaf fixes your DLL... The getTurnMonthForGame function in CvGameCoreUtils.cpp is pretty short and not very complicated, so you should be able to just do the same thing in Python. I don't think it itself uses anything not exposed to Python.
 
This:
Spoiler :
Code:
int getTurnMonthForGame(int iGameTurn, int iStartYear, CalendarTypes eCalendar, GameSpeedTypes eSpeed)
{
	int iTurnMonth;
	int iTurnCount;
	int iI;

	iTurnMonth = iStartYear * GC.getNumMonthInfos();

	switch (eCalendar)
	{
	case CALENDAR_DEFAULT:
		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));
		}
		break;

	case CALENDAR_BI_YEARLY:
		iTurnMonth += (2 * iGameTurn * GC.getNumMonthInfos());
		break;

	case CALENDAR_YEARS:
	case CALENDAR_TURNS:
		iTurnMonth += iGameTurn * GC.getNumMonthInfos();
		break;

	case CALENDAR_SEASONS:
		iTurnMonth += (iGameTurn * GC.getNumMonthInfos()) / GC.getNumSeasonInfos();
		break;

	case CALENDAR_MONTHS:
		iTurnMonth += iGameTurn;
		break;

	case CALENDAR_WEEKS:
		iTurnMonth += iGameTurn / GC.getDefineINT("WEEKS_PER_MONTHS");
		break;

	default:
		FAssert(false);
	}

	return iTurnMonth;
}
This makes me think I actually did this once, in Python. :p I wonder if the code is still available, somewhere... (If I remember correctly I had PyScenario do all the math at startup and set up an array for the months. Then the actual function would simply index that array at run-time.)

edit: Found it :D More on this tonight
 
Great! so until we get the faster C++ method we can use yours (very helpful!)

Why aren't all methods exposed to python by default? is it to make us feel bad or because it causes lag?
 
I guess it wouldn't make sense to make everything available, so it would always be a question of judgment. So things are simply more useful than others, and making something that is entirely useless for Python scripting would only confuse things.
 
Back
Top Bottom