Bulding cost in python

Joined
Jul 5, 2004
Messages
23,562
Location
Canberra, Australia
How do I get the cost of a building in python? I want to sort the buildings in the city screen by cost to build.

There is no getCost() on BuildingInfo. IE

Code:
g_BuildingList[i] = (gc.getBuildingInfo(eLoopBuilding).getDescription(), iBuilding)
works but
Code:
g_BuildingList[i] = (gc.getBuildingInfo(eLoopBuilding).getCost(), iBuilding)
gives the error
Code:
AttributeError: 'CvBuildingInfo' object has no attribute 'getCost'
 
You should use the API instead of guessing. See my signature for link.
 
You should use the API instead of guessing. See my signature for link.

I did. I guessed, based on logic. There is a cost field therefore there should be a getCost() method. I got an error so I then looked at the API and could not find a getCost in there. I could not even find any method that mentioned cost() - probably due to my dyslexia and tiredness when looking. So I asked.

Btw - I have managed to get a one unit prototype of barbarian spawn working, but need to do a few more specific units to figure out the generalisation possibilities. The client, C2C, kept wanting options ;)
 
I did. I guessed, based on logic. There is a cost field therefore there should be a getCost() method. I got an error so I then looked at the API and could not find a getCost in there. I could not even find any method that mentioned cost() - probably due to my dyslexia and tiredness when looking. So I asked.
Asking for advice is of course kosher, and good that you bothered to check with the API. But still, you can't make methods appear out of thin air by simply wishing they were there. That will always result in the exception that you posted. Because the API webpage is generated from parsing the actual SDK (C++) code. What-You-See-Is-What-You-Get, nothing more, nothing less.

But sure, sometimes the naming conventions of the methods (or the lack of) can be questioned.

One thing though, there are supposedly also global functions (not instance methods) available for Python scripting from the SDK. AFAIK there is no API for those... Could someone please write a script that generates a handy list of all such functions and their associated arguments? Pretty please, with sugar on top?

Alternatively, how would one identify the sections of code of interest here? And how to interpret said code as far as figuring out what the arguments are? Because otherwise I would probably write a Python script that parses all of the SDK code and writes this information into a .txt file myself. If I ever get around to it. :p
 
Could someone please write a script that generates a handy list of all such functions and their associated arguments? Pretty please, with sugar on top?

Not exactly what you asked for, but this is the relevant C+ code. I'm sure you can ignore the non-relevant stuff ;)

Spoiler :

Code:
	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)");
 
Where did you find those? :eek:
 
Asking for advice is of course kosher, and good that you bothered to check with the API. But still, you can't make methods appear out of thin air by simply wishing they were there. That will always result in the exception that you posted. Because the API webpage is generated from parsing the actual SDK (C++) code. What-You-See-Is-What-You-Get, nothing more, nothing less.

But good coding practice is to have a method exposed for each element on the data store. Even though I know of no project that has followed good coding practice I can hope.:p
 
Could someone please write a script that generates a handy list of all such functions and their associated arguments? Pretty please, with sugar on top?

In the page with the python API documentation that you link to, there is also a reference to the code which generated the documentation. It is probably possible for you to modify this code, to generate the additional documentation that you would like.
 
There actually is virtually no variables in the Dll that lacks methods for retrieving and changing it, though not all have been exposed to python (most of them have though). They were pretty consistent in that. In this case the method of course does exist, you just were looking under the wrong name :D.

As a C++ modder I'm fortunate enough to ignore the API and just use notepad++ to search the source code for whatever function I'm looking for. Even if you are just a python modder (and I don't know if that's the case), I actually suggest this to you as an alternative to the API if you have access to the source of the dll you are using. You can just search for the tag 'iCost' in CvInfos.cpp and see exactly what variable it's being saved to, then follow that variable to its 'get' function. That's how I do it anyway :). I can't stand pouring over an API looking for functions, and with no way of seeing what's really inside of them. But that's probably why I prefer modding directly in the Dll anyway :cool:.
 
There actually is virtually no variables in the Dll that lacks methods for retrieving and changing it, though not all have been exposed to python (most of them have though). They were pretty consistent in that. In this case the method of course does exist, you just were looking under the wrong name :D.

As a C++ modder I'm fortunate enough to ignore the API and just use notepad++ to search the source code for whatever function I'm looking for. Even if you are just a python modder (and I don't know if that's the case), I actually suggest this to you as an alternative to the API if you have access to the source of the dll you are using. You can just search for the tag 'iCost' in CvInfos.cpp and see exactly what variable it's being saved to, then follow that variable to its 'get' function. That's how I do it anyway :). I can't stand pouring over an API looking for functions, and with no way of seeing what's really inside of them. But that's probably why I prefer modding directly in the Dll anyway :cool:.

I have an aversion to C code. All stems from the trauma of writing a highly successful (complex and large) AI assistant and the politics involved. The maths was easy, it was just working with n-dimensional arrays where the number of dimensions and attributes varied while in use.
 
lol, I can only imagine. But I can also relate, as I avoid python like the plague myself. At least whenever I can. But that's mostly because of the modular nature of it for CIV, things are too spread out. With the Dll I know what's supposed to be there and where to find things, nothing to import, ahh....

Of course I can't always get away with it, I spent several hours today rewriting a piece of the DuneWars python. :mischief:
 
Back
Top Bottom