Modders Guide to FfH2

@Kael:
2 patches now without your new SDK code for them being made available! :(

I hate recoding stuff I know is already out there ready to be cut'n'pasted ... well more or less. ;)
 
This is the API I use. There's also Zebra 9's API, which is updated for BtS. I haven't tried it.
 
Anyone know what the .thm files are used for? I got fixated on being able to open up and view every file in the Mod Folders, and so far I haven't found a viewer to let me open .Bik, but I know they are movie files, and I haven't figured out a way to access the .thm.

They are so small I doubt they are much more than some lines of text to set parameters, but I'd like to see them myself :)
 
@Kael:
2 patches now without your new SDK code for them being made available! :(

I hate recoding stuff I know is already out there ready to be cut'n'pasted ... well more or less. ;)

Sorry for the delay, the source code for version "h" is in the first post.
 
Sorry for the delay, the source code for version "h" is in the first post.
:goodjob:

Btw, any chance of 'converting' you into switching from using 4xSpace to 1xTAB for indentions? Currently your files (SDK, Python and XML) take up a total space several MBs more than they need to.

It would be fast and simple to convert - merely Find&Replace 4xSpace with 1xTAB (using UltraEdit myself for this but I can't imagine other programs not having similar functions).
 
I just gotta say I love this part:

"3. We will always make the source code available for those that would like to use it. We have no desire to try to hide the effort of our work, and we are flattered when we see it appear in other projects. If it makes your mod better, or even just saves you a little time you are free to use any part of FfH2."

Even though I've never tried the actual mod, I truly commend you for this. OS ftw! :)
 
Using python, how would I make a spell work only when a unit is fortified and get better based on how long the unit has been fortified?

Edit: I figured out how
 
Could someone please help tell me what I'm doing wrong here?:confused:
Spoiler :
Code:
def reqBarrage(caster):
	pPlayer = gc.getPlayer(caster.getOwner())
	eTeam = gc.getTeam(pPlayer.getTeam())
	iDamageLimit = caster.collateralDamageLimit()
	pPlot=caster.plot()
	bValid = False
	iX = caster.getX()
	iY = caster.getY()
	if pPlot.isCity() or pPlot.isHills or pPlot.getImprovementType() == gc.getInfoTypeForString('IMPROVEMENT_CITY_RUINS') or gc.getInfoTypeForString('IMPROVEMENT_TOWER') or gc.getInfoTypeForString('IMPROVEMENT_FORT') or gc.getInfoTypeForString('IMPROVEMENT_CASTLE') or gc.getInfoTypeForString('IMPROVEMENT_CITADEL'):
                for iiX in range(iX-1, iX+2, 1):
                        for iiY in range(iY-1, iY+2, 1):
                                pPlot = CyMap().plot(iiX,iiY)
                                if pPlot.getNumUnits() > 0:
                                        for i in range(pPlot.getNumUnits()):
                                                pUnit = pPlot.getUnit(i)
                                                e2Team = gc.getPlayer(pUnit.getOwner()).getTeam()
                                                if (eTeam.isAtWar(e2Team) and pUnit.getDamage() < iDamageLimit):
                                                        if caster.isMadeAttack() == False:
                                                                return True
	return False

def spellBarrage(caster):
	caster.setMadeAttack(True)
	iPlayer = caster.getOwner()
	pPlayer = gc.getPlayer(iPlayer)
	eTeam = gc.getTeam(pPlayer.getTeam())
	iDamageLimit = caster.collateralDamageLimit()
	iMaxUnits = 3 * caster.collateralDamageMaxUnits()
	pPlot=caster.plot()
	advantage = 1
	if pPlot.isCity():
		advantage = advantage *2.5
	if pPlot.getImprovementType() == gc.getInfoTypeForString('IMPROVEMENT_CITY_RUINS'):
		advantage = advantage *1.5
	if pPlot.getImprovementType() == gc.getInfoTypeForString('IMPROVEMENT_TOWER'):
		advantage = advantage *1.5
	if pPlot.getImprovementType() == gc.getInfoTypeForString('IMPROVEMENT_FORT'):
		advantage = advantage *1.5
	if pPlot.getImprovementType() == gc.getInfoTypeForString('IMPROVEMENT_CASTLE'):
		advantage = advantage *2
	if pPlot.getImprovementType() == gc.getInfoTypeForString('IMPROVEMENT_CITADEL'):
		advantage = advantage *2.5
	if pPlot.isHills() or pPlot.isPeak():
		advantage = advantage *1.5
	iX = caster.getX()
	iY = caster.getY()
	for iiX in range(iX-1, iX+2, 1):
		for iiY in range(iY-1, iY+2, 1):
			pPlot = CyMap().plot(iiX,iiY)
			if pPlot.getNumUnits() > 0:
				bHit = False
				for i in range(pPlot.getNumUnits()):
					pUnit = pPlot.getUnit(i)
					e2Team = gc.getPlayer(pUnit.getOwner()).getTeam()
					if (eTeam.isAtWar(e2Team) and pUnit.getDamage() < iDamageLimit and iMaxUnits > 0):
						iMaxUnits -= 1
						iDmg = advantage (CyUnit.firstStrikes() +1) * CyGame().getSorenRandNum(8 * caster.baseCombatStr(), "Barrage")
						iDmg -= 2 * pUnit.baseCombatStr()
						if iDmg < 1:
							iDmg = 1
						if iDmg + pUnit.getDamage() > iDamageLimit:
							iDmg = iDamageLimit - pUnit.getDamage()
						pUnit.changeDamage(iDmg, iPlayer)
						sMessage = PyHelpers.PyInfo.UnitInfo(pUnit.getUnitType()).getDescription() + " " + CyTranslator().getText("hit by a Barrage", (iDmg, ()))
						CyInterface().addMessage(iPlayer,True,25,sMessage,'AS2D_ARCHERY_BARRAGE',1,'Art/Interface/Buttons/Spells/Barrage.dds',ColorTypes(8),pUnit.getX(),pUnit.getY(),True,True)
						CyInterface().addMessage(pUnit.getOwner(),True,25,sMessage,'AS2D_ARCHERY_BARRAGE',1,'Art/Interface/Buttons/Spells/Barrage.dds',ColorTypes(7),pUnit.getX(),pUnit.getY(),True,True)
                                                #bHit == True
	#CyInterface().selectUnit(caster, true, true, true)
#	if caster.isHasPromotion(gc.getInfoTypeForString('PROMOTION_FLAMING_ARROWS')) and ((pPlot.getFeatureType() == gc.getInfoTypeForString('FEATURE_FOREST_ANCIENT') or pPlot.getFeatureType() == gc.getInfoTypeForString('FEATURE_FOREST') or pPlot.getFeatureType() == gc.getInfoTypeForString('FEATURE_JUNGLE'))):
#		if CyGame().getSorenRandNum(100, "Flames Spread") <= gc.getDefineINT('FLAMES_SPREAD_CHANCE'):
#			pPlot.setImprovementType(gc.getInfoTypeForString('IMPROVEMENT_SMOKE'))
 
Are you copying from my modmod? It look very similar to my code, but a little different (of course, I played around with mine a little to try to get it to work after I broke it)

The most obvious problem is the pPlot.getImprovementType() == gc.getInfoTypeForString('IMPROVEMENT_CITY_RUINS') or gc.getInfoTypeForString('IMPROVEMENT_TOWER'), etc. You can't set something equal to x and y and z..., you have to include the pPlot.getImprovementType() == part for each of them.
 
Sorry for butchering your code :lol: but I noticed that the barrage wasn't working so I looked in the python files and thought that it would be cool if archers where limited to where they could use barrage but that part didn't bring up any python exception errors it was the def spellbarrage part that didn't work. I wonder if it might have anything to do with all the python modcomps that I merged into Ffh?
 
Sorry for the cross posting, but I was hoping that perhaps one of you tech-savvy folk might be able to post a one-page Leader-only version of the FFH Editor in Excel 2003 format, rather than 2007? I've always like tinkering with the Diplomacy requirement and leader special ability settings in this mod (though I lack the skilss to do the alterations directly) and the switch to 2007 has thrown off my groove something fierce. I hope it's not too much to ask, I'm sure there are others out here who would still like to use the editor without upgrading to Office 2007....this is just the page that I find the most important.

Thanks to anyone that can help!:)
 
Can a terrain improvement require a specific feature, or only a feature in general? I had assumed that it would require the feature found in <FeatureMakesValids>, but when I added one feature that should require forests and another that should require flames I've seen the flame improvement built on forests.
 
Is there a way to set a temporary feature like you set a temporary terrain in the thaw mechanic? If not, really think you should add one. It would help me get a couple of spells to work the way I want them to, and it would be cool if with this game option much of the world's seas started covered with ice, which would then thaw along with the rest of the world.

Edit: I just looked in the SDK, and I see there isn't one. I stil think there should be (If I was planning to compile my own .dll this time, instead of using that vehem did for me, I would add it my self)

Also, I'd like to know what happens if you use pPlot.setTempTerrainType(iTerrain, iTime) twice on the same tile at the same time. Can you, for example, set it to Tundra for 30 turns then set it to snow for 5 to make it be snow for five then tundra for 25?
 
Could you add terrain impassible and feature impassible to promotions to CIV4PromotionInfos.xml (the same as are already in CIV4UnitInfos.xml) in the next real version?

It would would help with some ideas for my modmod, and would allow several people who want to create a coastal-only-water walking type promotion the ability to do so.

(In general I would prefer it if essentially all the tags in CIV4UnitInfos.xml had an equivalent in CIV4PromotionInfos.xml, and vice versa. Of course this makes no sense for some of the tags, but prereq civics, prereq alignments, impassible terrains, no/extra upkeep, tags to change a units workrate, tags to allowing building certain improvements (could be an interesting alternative implementation for a few spells), tags to create/convert units on combat, tags to change the chances for such creation, tags to change collateral damage limits, and perhaps most importantly the tags that call python functions once perturn/on victory/on defeat would be very useful in both places)
 
Looking for some help in setting Event Triggers.

If I want to make it so you are required to have multiple buildings of a type in your Civ (Like 6 Libraries for the Great Library), how do I set the flags?

I have tried
Code:
            <iNumBuildings>4</iNumBuildings>
            <iNumBuildingsGlobal>0</iNumBuildingsGlobal>

And also
Code:
            <iNumBuildings>1</iNumBuildings>
            <iNumBuildingsGlobal>4</iNumBuildingsGlobal>

And then even
Code:
            <iNumBuildings>0</iNumBuildings>
            <iNumBuildingsGlobal>4</iNumBuildingsGlobal>

But each time I can get the event to happen with just 1 of the building in my Civ!
 
The problem is that you have probably define pickCity . In this case , the requirement of the number of buildings is not taken in count , the event just choose a city with the desired building . If you don't pick a city , initTriggeredData will check if you have the desired number of buildings .

<iNumBuildingsGlobal> is always checked , but this is for the number of buildings built for all players .

I think you should add a python function "canDoEvent" , where you check if the player have the desired number of buildings .

Tcho !
 
Anyone know what the .thm files are used for? I got fixated on being able to open up and view every file in the Mod Folders, and so far I haven't found a viewer to let me open .Bik, but I know they are movie files, and I haven't figured out a way to access the .thm.

They are so small I doubt they are much more than some lines of text to set parameters, but I'd like to see them myself :)

Erm... Open them in a text editor. Any text editor... They are just text.
 
And on to why I came into this thread. I'm attaching a screenshot of a Python error I got while trying to port the BUG's Great People Bar to FfH. I'm guessing that FfH changed the getGreatPeopleUnitProgress function, but I have little to no clue what to do to fix this.

Or is there some sort of numerical order to the types of great people? I messed around a bit with that...
 

Attachments

  • Civ4ScreenShot0000.gif
    Civ4ScreenShot0000.gif
    54.9 KB · Views: 126
Top Bottom