Python and cvcity.cpp functions

Duke176

Warlord
Joined
Oct 19, 2006
Messages
241
Location
Turin - Italy
how do I recall in python file a function that is inserted inside cvcity.cpp (CvCity::xxxxxxx)?

I need this to insert inside one of the advisors screen the value that this function return to know if it works.
thx
 
I've taken a look to the guide,
My problem how to recall, I mean:

to get a function in CvPlayer for ex. you write
gold = gc.playergetgold()
or something similar.

I mean really the base...
 
it's CvCity::getOilConsumptionPerBuilding()
it's a function I've created i'll add the file cvcity.cpp

Code:
// OIL TOTAL CONSUMPTION + OIL CONSUMPTION FROM ALL BUILDINGS
int CvCity::getOilTotalConsumption()
{
	return m_iOilTotalConsumption;
}


void CvCity::setOilTotalConsumption (int iNewValue)
{
	m_iOilTotalConsumption = iNewValue;
}


void CvCity::changeOilTotalConsumption(int iChange)
{
	setOilTotalConsumption(getOilTotalConsumption() + iChange);
}


//get buildings oil consumption per turn
int CvCity::OilConsumptionPerBuildings()
{

//	int iAirportCons = 0;
//	int iDryDockCons = 0;
//	int iHospitalCons = 0;
//	int iHydroplantCons = 0;
//	int iNuclearPlantCons = 0;
//	int iRecyclingCenterCons = 0;

	int iTotalConsumption = 0;
// basic city consumptio BCC from Define INT
	int iBCC = 0;
//	int iMedCitiesConsumption = 0;
//	int iBigCitiesConsumption = 0;
//	int iEnormousCitiesConsumption = 0;


//	if (hasActiveBuilding((BuildingTypes)GC.getInfoTypeForString("BUILDING_AIRPORT")))
//	{
//		iAirportCons = GC.getBuildingInfo(BuildingTypes (GC.getInfoTypeForString("BUILDING_AIRPORT"))).getOilConsumption();
//	}
//	return iAirportCons;

//	if (Building((BuildingTypes)GC.getInfoTypeForString("BUILDING_DRYDOCK")))
//	{
//		iDryDockCons = GC.getBuildingInfo(BuildingTypes (GC.getInfoTypeForString("BUILDING_DRYDOCK"))).getOilConsumption();
//	}
//	return iDryDockCons;

//	if (hasActiveBuilding((BuildingTypes)GC.getInfoTypeForString("BUILDING_HOSPITAL")))
//	{
//		iHospitalCons = GC.getBuildingInfo(BuildingTypes (GC.getInfoTypeForString("BUILDING_HOSPITAL"))).getOilConsumption();
//	}
//	return iHospitalCons;

//	if (hasActiveBuilding((BuildingTypes)GC.getInfoTypeForString("BUILDING_HYDROPLANT")))
//	{
//		iHydroplantCons = GC.getBuildingInfo(BuildingTypes (GC.getInfoTypeForString("BUILDING_HYDROPLANT"))).getOilConsumption();
//	}
//	return iHydroplantCons;

//	if (hasActiveBuilding((BuildingTypes)GC.getInfoTypeForString("BUILDING_NUCLEAR_PLANT")))
//	{
//		iNuclearPlantCons = GC.getBuildingInfo(BuildingTypes (GC.getInfoTypeForString("BUILDING_NUCLEAR_PLANT"))).getOilConsumption();
//	}
//	return iNuclearPlantCons;

//	if (hasActiveBuilding((BuildingTypes)GC.getInfoTypeForString("BUILDING_RECYCLING_CENTER")))
//	{
//		iRecyclingCenterCons = GC.getBuildingInfo(BuildingTypes (GC.getInfoTypeForString("BUILDING_RECYCLING_CENTER"))).getOilConsumption();
//	}
//	return iRecyclingCenterCons;

// let's go for population
	if ((getPopulation() >= 1) && (getPopulation() <= 5))
	{
		iBCC = (GC.getDefineINT("LITTLE_CITIES_CONSUMPTION"));
	}
	else if ((getPopulation() >= 6) && (getPopulation() <= 10))
	{
		iBCC = (GC.getDefineINT("MED_CITIES_CONSUMPTION"));
	}
	else if ((getPopulation() >= 11) && (getPopulation() <= 15))
	{
		iBCC = (GC.getDefineINT("BIG_CITIES_CONSUMPTION"));
	}
	else if (getPopulation() >= 16)
	{
		iBCC = (GC.getDefineINT("ENORMOUS_CITIES_CONSUMPTION"));
	}
	return iBCC;
	
int iI;


// Loop through all the buildings. If the player has that building in their city,
// then add the oil consumption to the accumulating "iSum" variable.
// getOilConsumption is the new function you created after following Kael's guide.
for (iI = 0; iI < GC.getNumBuildingInfos(); iI++)
{
	if (getNumActiveBuilding((BuildingTypes)iI))
	{
		iTotalConsumption +=  ((iBCC * getPopulation()) + ((iBCC * (GC.getBuildingInfo((BuildingTypes) iI).getOilConsumption())) / 1));
	}
}

//	iTotalConsumption = ((iBCC * getPopulation()) + ((iBCC * iAirportCons) / 100) + ((iBCC * iDryDockCons) / 100) + ((iBCC * iHospitalCons) / 100) + ((iBCC * iHydroplantCons) / 100) + ((iBCC * iNuclearPlantCons) / 100) + ((iBCC * iRecyclingCenterCons) / 100));


	return iTotalConsumption;

}
// END
 
how do I recall in python file a function that is inserted inside cvcity.cpp (CvCity::xxxxxxx)?

I need this to insert inside one of the advisors screen the value that this function return to know if it works.
thx
Since it's your own code that you added you need to expose it to python which involves adding it to a few extra files. Take a look at the Cy (not Cv) files, in particular the Cy???Interface.cpp files. In general the Cv version of files are 'internal' code for the DLL while the Cy files handle the python functions.
 
thx.
done added
CyCity::getOilConsumptionPerBuildings()

both in CyCity.cpp and CyCity.h

than how to recall that in python?
 
You'll need to add the python definition in one of the interface.cpp files, find the other city related code and it should be easy enough to drop yours in.
 
sorry seven05, I haven't been so clear.
I've added the code everywhere I found other city related similar codes, my problem is that I dunno how manually use that function in the python.

I mean this:
I have the function working in cpp? dunno I have to check, so I use financial advisor window and I add to gold (the total treasury ammount) my oil function.
I did it already once, but last time was easier becuase my other function (was for the total oil extracted by bonuses) was inside player.cpp so once exposed I simply use the code (in python) already implemented simply changing GOLD with OIL.

so there is was gc.player.... (function from civplayer.cpp I guess) but my prb here is that, in financial advisor window, there's not a "city functions" directly use so I dunno how to tell the program to look inside CvCity.cpp functions and find the one I called CvCity::OilConsumptionPerBuildings.

I mean I dunno how should I write it in python because in cpp you use: for ex.
gc.getImprovementInfo(....)...
or
gc.getCityInfo....


so on, and there I know the program will look inside Imrpovements/CvCity functions to find the value I need...

Hope I haven't been so much confusing. :p
 
Assuming you wrote them just like the Firaxis code you'd call them the same way, for instance:

pCity.getOilTotalConsumption() or pCity.setOilTotalConsumption (x)

That would use the city 'pCity' which should be available depending on where you're calling it. If you don't know 'pCity' you can get it easily enough, for instance here is an example of iterating over the list of the current player's cities:
Code:
	kTriggeredData = argsList[0]
	player = gc.getPlayer(kTriggeredData.ePlayer)
	(loopCity, iter) = player.firstCity(false)

	while(loopCity):

		if (loopCity.getPopulation() >= 5):
			if (loopCity.canConstruct(iBuilding, false, false, true)):
				loopCity.setNumRealBuilding(iBuilding, 1)
				
		(loopCity, iter) = player.nextCity(iter, false)

So kTriggeredData is the args passed to the function, ePlayer (enum, not object) is one of those args which you convert to the player 'object' so you can use it to call the player methods like firstCity() which returns a city 'object' which can than be used to call city methods on itself.

The exact process may change depending on your desired effect but the process should be similar. So you'll have an enum passed to your python function (ePlayer) which you can use to find the object using the GC functions (player = gc.getPlayer(ePlayer)) and form there you can grab additional objects associated with that object (city = player.firstCity()) and then call your own methods on the final object (city.getOilTotalConsumption()).

Remember, python ALWAYS passes the object 'self' so if you're working in a python function called by a city you don't need to specify the object, just call the method directly like 'getOilTotalConsumption()' and you're done.

Fun isn't it? Have I mentioned that I hate python? :)

Anyway, you can probably hook into your own methods by inserting your codes in an existing python function that is already working with a specific city object, or at the very least a player object. Look in the CvRandomEventInterface.py file for some great examples of iterating over players & cities (that's where my example came from).
 
And If I want just to see which one is the resoult of function I have in cpp?
So in mine, program should check into the city wich building has "oilConsumption" attribute (XML) and how big is the city, than make a calculation with those elements and return the resoult.

How can I show the resoult, so how can I check on my screen the reosult of the function simply telling game to run the function (without rewriting it in Python) and show me the integer resoult?

(Anyway the last post is really really usefull to me for another part of my mod :))
 
Hmmm... displaying that data on the interface is something I haven't tried myself. I imagine it's not much different and you should be able to copy & modifiy existing code that does somethign similar.

But to answer your other question, yes your DLL code should do 99% of the work and python should just grab the final output of that work.
 
exactly what I was looking for;
for gold it uses
for CvFinanceAdvisor.py (screen directory)


player = gc.getPlayer(self.iActiveLeader)
gold = player.getGold()

how for cities?
 
Ok, after looking there since it uses the player you should add a method to the player class to get the total oil consumption for all cities, expose that method to python and then call it like they already do for maintenance:

totalMaintenance = player.getTotalMaintenance()

You method would then iterate through all cities, get the total oil cunmption per city and then return the sum of those totals which the advisor could then display.
 
As an alternative that would be quite slow you could simply write a python function to iterate through the cities for you. For performance reason though that would definately be better in the DLL.
 
Back
Top Bottom