[MODCOMP] Doviello Icehouse

I just had a CTD again, and this time I'm fairly sure it was from the Icehouse; it happened as soon as I cast "icehouse" in a size city that I had just made go into starvation by making none of its citizens work any tiles. The problem might be in the code you added to the SDK.

here is the code I added to CvUtils.py:
Code:
	def cannotGrow(self,argsList):
		pCity = argsList[0]
		if pCity.getNumRealBuilding(gc.getInfoTypeForString('BUILDING_ICEHOUSE')) > 0:
			if pCity.getNumBonuses(gc.getInfoTypeForString('BONUS_MANA_ICE')) *4 > pCity.getPopulation():
				return True
		return False
		
	def cannotStarve(self,argsList):
		pCity = argsList[0]
		if pCity.getNumRealBuilding(gc.getInfoTypeForString('BUILDING_ICEHOUSE')) > 0:
			if pCity.getNumBonuses(gc.getInfoTypeForString('BONUS_MANA_ICE')) > 4 * pCity.getPopulation():
				return True
		return False

Edit: It happened again as soon as casting the spell, this time when the city was not starving (it was 3 turns away from growing)
 
When you are testing for instability, you ought to go into the BtS Global Defines and set the Event Roll to an insanely high number to block out events, or to 2 to test for problems with them. Nice quick way to toggle them on/off. Just search for _ROLL twice and it hits you at the right entry :)
 
I don't get it. I commented out the only python code dealing with the Icehouse, and it still isn't working. I guess this means that veham is off the hook, his .dll doesn't seem relevant.


I don't get it. I copied the icehouse spell code (pure xml) from the another building granting spell that is working fine. Why does this spell cause a crash?

Edit: I found the problem. It is always something stupid, isn't it. I had changed the name of the building's art file without creating such a file (I copied the smokehouse xml, then replaced smokehouse with icehouse everywere I saw it). It is working fine now. It seems vehem's .dll did not cause the crash, now lets see if it actually works.
 
Edit: I found the problem. It is always something stupid, isn't it. I had changed the name of the building's art file without creating such a file

Heh - the sections of the code that handle the artwork are notoriously poor for their error-tolerance. If it gets anything that it doesn't expect, it just falls over without any indication of why. If I get a CtD, the artwork is always the first suspect.

XienWolf said:
While speaking of compilling the DLL though, where does it put the thing? As I read through Kael's post it sounded like it will place it right where the current DLL is, which would mean I sure better make a backup before I make my first attempt (and failure) at compiling my own.

Depending on the compiler, either you set the target directory yourself or it will default to a sub directory of where you have the source-code. In the case of CodeBlocks (assuming the source directory is \FFH030hSource) it puts it in \FFH30hSource\FinalRelease\.

Final Release is the build-type you want for the released DLL. You can also build Debug versions that include other "Debug Symbols" which may be useful for testing, though I haven't had to use those with FFH so far. "Final Release" is generally better optimized and so a smaller filesize/quicker performance.

==

The final DLL does have to replace the one in FFH\Assets though, so a backup is a good plan anyway. I've actually made a backup of the whole Patch-h directory so I can revert any given file to the official version. Also, if you can get it working, a source versioning package (like GIT) is pretty damned useful. Every change that you make to the mod is tracked, can be reverted or merged and the files involved are listed as .diffs (I used it to produce the DIFF's in my first post).
 

Attachments

  • GIT.jpg
    GIT.jpg
    83.4 KB · Views: 79
Could someone reupload this? And would anyone be willing to make this a standalone modcomp that can be integrated into BtS?

Which part of it are you after? The Python/XML components are erm... somewhere around here - just not anywhere I can lay hands on them quickly. The useful part though is the DLL changes and those are available in the other thread (though as part of a FFH DLL).

Also - what would the BtS modcomp do? This was specific to the FfH races and relied on terrain types. It is possible to limit the population increase/decrease using any set of factors that you can write python code to describe..
 
Those changes can be copied and pasted from within the spoilers on the first post into the appropriate python files and file in the uncompiled BtS dll
 
I was interested in making this a "national wonder" kind of building in my mod, so the python and SDK changes were the main thing I was after (and any changes that have to be made in the XML for all that to work with the assigned building).

As Magister said, if you can compile the DLL already, the changes are listed in the first post. The Python would need adjusting to refer to your National Wonder rather than "BUILDING_ICEHOUSE" and you can remove any reference to the terrain types.

If you can't compile the DLL, let me know and I'll either try to help you through it or can recompile a one off version with this change in it.
 
As Magister said, if you can compile the DLL already, the changes are listed in the first post. The Python would need adjusting to refer to your National Wonder rather than "BUILDING_ICEHOUSE" and you can remove any reference to the terrain types.
Well, I still want it to only work when there's tundra nearby. I've managed to get the SDK and python code inserted, thanks for pointing out the spoiler stuff. I don't suppose you would happen to know how to prevent the building from being built in the first place if the city isn't built within range of the tundra, would you?
 
I would probably just put a python block in the def cannotConstruct(self,argsList): define of CvGaneUtils.py, similar to how the Shrine of the Champion works, but of course with different requirements (checking the terrain type of pCity.plot(), and maybe other tiles nearby)
 
Well, I still want it to only work when there's tundra nearby. I've managed to get the SDK and python code inserted, thanks for pointing out the spoiler stuff. I don't suppose you would happen to know how to prevent the building from being built in the first place if the city isn't built within range of the tundra, would you?

As Magister said - "CannotConstruct" is the easiest way and already exists in Python. You can make it such that you must have Tundra in the city square (quite cheap processorwise) or a do a search over nearby tiles (which is more expensive given the code is run a fair bit).
 
I'm trying to model this after the Machu Picchu mod, but I'm having trouble finding the correct function of pPlot to use. I've highlighted the part that I'm pretty sure I have wrong.
Code:
		if ( eBuilding == gc.getInfoTypeForString("BUILDING_ICEHOUSE") ):

			### find taiga within the city radius controlled by your team ###
			pPlayer = gc.getPlayer(pCity.plot().getOwner())
			iPID = pPlayer.getID()
			iTID = pPlayer.getTeam()
			iX = pCity.getX()
			iY = pCity.getY()
			for iXLoop in range(iX - 2, iX + 3, 1):
				for iYLoop in range(iY - 2, iY + 3, 1):
					pPlot = CyMap().plot(iXLoop, iYLoop)
					if ( pPlot.isPlayerCityRadius(iPID)==true ):
						if ( pPlot.getTeam()==iTID ):
							if ( pPlot.[b]isTundra()[/b]==true  ):
								return False
			return True
 
I'm trying to model this after the Machu Picchu mod, but I'm having trouble finding the correct function of pPlot to use. I've highlighted the part that I'm pretty sure I have wrong.
Code:
		if ( eBuilding == gc.getInfoTypeForString("BUILDING_ICEHOUSE") ):

			### find taiga within the city radius controlled by your team ###
			pPlayer = gc.getPlayer(pCity.plot().getOwner())
			iPID = pPlayer.getID()
			iTID = pPlayer.getTeam()
			iX = pCity.getX()
			iY = pCity.getY()
			for iXLoop in range(iX - 2, iX + 3, 1):
				for iYLoop in range(iY - 2, iY + 3, 1):
					pPlot = CyMap().plot(iXLoop, iYLoop)
					if ( pPlot.isPlayerCityRadius(iPID)==true ):
						if ( pPlot.getTeam()==iTID ):
							if ( pPlot.[b]isTundra()[/b]==true  ):
								return False
			return True


pPlot.getTerrainType() == gc.getInfoTypeForString('TERRAIN_TUNDRA')

getTerrainType returns an integer value that represents the Terrain Type.
getInfoTypeForString finds the integer value that has been assigned to the "Info" with the XML-name "TERRAIN_TUNDRA".

If they're the same, the plot is TERRAIN_TUNDRA.

====

The same is true of pPlot.getFeatureType() and pPlot.getImprovementType() (gc.getInfoTypeForString('FEATURE_FOREST') and gc.getInfoTypeForString('IMPROVEMENT_FARM') respectively).

====

The only "isSomething" methods that pPlot has (related to the actual map rather than the game) are
Code:
bool isWater ()
bool isFlatlands ()
bool isHills ()
bool isPeak ()
 
Ah, Ok. So, using that, would I be correct with this code?
Code:
		if ( eBuilding == gc.getInfoTypeForString("BUILDING_ICEHOUSE") ):

			### find taiga within the city radius controlled by your team ###
			pPlayer = gc.getPlayer(pCity.plot().getOwner())
			iPID = pPlayer.getID()
			iTID = pPlayer.getTeam()
			iX = pCity.getX()
			iY = pCity.getY()
			for iXLoop in range(iX - 2, iX + 3, 1):
				for iYLoop in range(iY - 2, iY + 3, 1):
					pPlot = CyMap().plot(iXLoop, iYLoop)
					if ( pPlot.isPlayerCityRadius(iPID)==true ):
						if ( pPlot.getTeam()==iTID ):
							if ( pPlot.getTerrainType() == gc.getInfoTypeForString('TERRAIN_TUNDRA'  ):
								return False
			return True

And thanks for all the assistance you've been providing. :)
 
Ah, Ok. So, using that, would I be correct with this code?

And thanks for all the assistance you've been providing. :)

Looks like it should work, though I'd be tempted to use
Code:
if (pCity.canWork(pPlot)):
instead of
Code:
if ( pPlot.isPlayerCityRadius(iPID)==true ):
	if ( pPlot.getTeam()==iTID ):

as if I remember correctly, "canWork()" requires that it be (a) in the city radius and (b) accessible to your team. I suspect either would work fine.

EDIT: Hmm - seems that "canWork()" may also rely on not being under siege by an enemy. The original way may be better depending on how you want it to behave.
 
Damn, it seems my code causes an OOS error in multiplayer. Any idea how to get around this?

Whereabouts is it placed? In CannotBuild()? If so, I'm not really sure how it can be causing a problem as all it does is check a set of conditions and returns True/False (doesn't change the gamestate itself).

The only thing that may be an issue is when pPlot is not a valid plot (the iX or iY that it's checking is too high/low for the map), but I'd expect that to be a Python error rather than a OoS.

EDIT: Or is this part of your CannotStarve() function?
 
Top Bottom