Modders Guide to FfH2

The AI does occasionally use ships in ways that surprise you though. A couple days ago I was shocked when I saw Tumtum attack and conquer a poorly defended coastal city from The Sailor's Dirge.
 
General modding question: how do I make a variable global? I need this variable to be remembered and accessible as I jump in and out of subroutines. I don't really need it to be retained with save game, although that would be OK too.
 
General modding question: how do I make a variable global? I need this variable to be remembered and accessible as I jump in and out of subroutines. I don't really need it to be retained with save game, although that would be OK too.

In python, or in SDK?

In python, you can put the "self." modifier in front of the variable when you declare it (such as in the def _init_ or whatever of a class), and it can then be used by anything in that class.

If you want it to be used throughout the entire file, declare it at the very top of the file (like they do for "gc", gc = CyGlobalContext(). That way you don't have to say CyGlobalContext().getInfoTypeForString, but merely gc.getInfoTypeForString.

Not sure about the SDK, I haven't messed with it, I just started learning how to mod it.
 
My main interest would be in improving the AI (mostly naval ability). Before I get too far into looking into how to do this however, I would like to ask a few questions.

1) Is there a reason the naval AI in FFH is so poor (not sending settlers to other continents, no real continent to continent naval battles)?

2) What tools/files (if any) do I need to get started?

3) Is this a realistic goal for a first time civ modder?

Most AI work needs to be done in the DLL, which is not quite the best location to start for a first time modder, unless you have some programming experience with an object oriented language. There are enough guides out there however that it is reasonable for anyone to start with anything in modding :)

To mod in Civ, you just need Notepad for 75% of it, except Notepad++ works a lot better, and it is free so I would advise you get it. To mod in the DLL you need Codeblocks or Visual Studio, both can be obtained free and require somewhat extensive setup, but there are guides to help with that. To mod graphics, you need NifSkope, Blender, and the KFMKonverter, all free, or 3DSMax I hear works nice as well, but isn't free. To mod icons/buttons you need Gimp (I think) which is free, or Photoshop, which is bloody expensive but you might already have for other reasons, I also hear there is something called Photoshop Elements which is either free or real cheap and works fairly well.


Personally what I translated to be the main issue which the AI had with settling through oceans was an inability to find escort ships of sufficient quality, and inability to transport as many units as it wanted to in one move (cargo space). Combined those cripple it.
 
Primarily because of the ability to turn religions off in gameoptions, I was wondering if it's necessary to do anything with the python to add a seventh (and eighth, and ninth etc) religion.

Also, what do the alignment settings in religion do exactly?
 
Extra religions are possible. The gameoptions aren't required for being able to disable them, but if you wanted to have them that would require DLL work. If you add numerous additional religions you need to modify the City Screen to display them a bit better or it gets too cluttered. The religion screen can also do with some modification after adding a couple more religions.
 
Ok. What controls whether units will have a religion? Is it something generic that will just apply to any new religions I might add, or does that have to be specified in python?

I think I've found the python bits where killed "evil" units create manes, and the part that sets the town art by religion, and I'm hoping that's all I'll need to do. Besides the display aspects, that is.
 
Well, first, eligious UUs (priests, religious heroes, units like Radiant Guards and Crusaders) have their religions defined in the <ReligionType> field in the CIV4UnitInfos.xml. If a unit has a religion in the xml, it is not eligible for getting a random religion.

Random religions are assigned to living units based on what religions are present in the city that built them. (Note that non-living units will never get a random religion, nor will any units acquired by other means than building them, like summons or units from events.) This is handled in the DLL. I know it was formerly supposed to be a 20% change per religion but was written in a way that actually biased it based on the order the religions were defined in the xml. I know that FF makes it more likely for a unit to take your state religion, but I don't think FfH does.


I'm pretty sure the system would work for an arbitrary number of religions, but it may or may not still be written so that at the bottom (or maybe top) would have very little chance to be assigned if too many religions are present in the city that built the unit. It could become very likely that a unit would get a random religion before it gets that far down the list and would preempt it from having a chance to get a latter one or that the first assigned religions would be overwritten by assigning later ones.


You can also use python to change a unit's religion. I think the functions are pretty self explanatory.

iReligion = pUnit.getReligion()

pUnit.setReligion(iReligion)


In my version, I always change it so that Angels/Manes keep the religion they had in life, and I give some of the high level angels access to diving magic.
 
The art for your improvements is set by changing your Era, so if you want to have special improvement art, you have to MAKE that art, and then also add more eras to the game. There is a piece in python which sets your era on religion change.
 
The art for your improvements is set by changing your Era, so if you want to have special improvement art, you have to MAKE that art, and then also add more eras to the game. There is a piece in python which sets your era on religion change.

Yep, figured that. Saw the era stuff in the python while I was hunting around for references to the religions to see what I'd need to do. That's a real neat trick! I'm figuring you could have full on religious artstyles, for units and cities as well?

As far as the units' religion, more religions won't be a problem because I'm planning to disable some of the original ones. I had initially planned to replace some of the current ones, but disentangling them from the python proved too difficult, so I am just disabling them with tech_never.
 
Need more help with a general Python question above. I'll try to explain in more detail. Sorry if this is a stupid question.

I have a value, let's call it purpledragonfarts, that I need to use in many different places, including CustomFunctions.py, CvEventManager.py, CvMainInterface.py, CvSpellInterface. It's computationally expensive to calculate purpledragonfarts and I only need to do it once per turn. Currently, I caluculate purpledragonfarts in a custom function that may get called many times in a turn (which is an unnecessary slow down). Instead, I'd like to calculate purpledragonfarts once per turn and then have that value "global" so that any function can see it and possibly change it (sorry if I'm misusing the term "global"... I'm not a programer).

If I understand TC01's post above, I should be able to define it at the top of CvEventManager.py like so:
Code:
class CvEventManager:
	def __init__(self):

		self.purpledragonfarts = 0
So now, can I change purpledragonfarts in CvEventManager by "self. purpledragonfarts = x"? Can I read it in any other python function (in CustomFunctions.py, CvEventManager.py, CvMainInterface.py, or CvSpellInterface) using self.purpledragonfarts?
 
To have unique art for each religion on units you would have to slightly modify the DLL to allow you more Era based Art defines. Right now you only get Early, Mid & Late, which are defined by splitting the eras into chunks, not even sized as I recall either. SO you could do by alignment if you lined things up just right with the current setup, or make the small tweak (there is a modcomp which does it already) and have it specifically set per religion, even setting only 1 or 2 of them to be special and leaving all the rest as default.


For your purpledragonfarts, I believe the appropriate method would be to calculate it in CustomFunctions.py with a call made from CvEventManager.py's onBeginGameTurn, and store it as a self.purpledragonfarts within CustomFunctions. Then from CustomFunctions you refer to it as self.purpledragonfarts, but from all other locations you refer to it as cf.purpledragonfarts (with cf being defined as CustomFunctions() earlier in most files already)
 
Thanks xienwolf! Would I have to define it at the top of CustomFunctions with a "def __init__(self):" entry? (I only see these lines in CvEventManager, not in CustomFunctions or other python files.)

Alternatively, if I define it in CvEventManager, do I refer to it as self.purpledragonfarts in CvEventManager and (?) gc.pupledragonfarts in CustomFunctions?
 
I'm not sure how you would have to do it in python. I am relatively certain you can define an initial value right at the top where the other globals are defined, like gc = ... and whatnot. Yes on the second one, mostly, you refer to it as self. within the file it was defined for, and refer to it as thatfile. in all other files. I do not believe that gc. refers to CvEventManager, it ought to refer to GameCore, which should be a DLL piece, not python at all.
 
Actually, gc. refers to CyGlobalContext(), according to the header of every python file. (this may in fact be GameCore, I don't know, I'm just learning SDK modding right now).

Code:
gc = CyGlobalContext()

To define something in CustomFunctions, you'd simply need to add your function somewhere in class CustomFunctions. That's all you'd need to do.

You need to make sure that the file the variable is in is imported by the other python file you want to use the variable. CustomFunctions is, I think, defined in every python file, but the Event Manager is not.

So first you'd have to import the EventManager, like this, under the other imports at the top of a python file.

Code:
import CvEventManager

Then, at the top, below where they define globals (like cf = CustomFunctions.CustomFunctions()) you'd need to add this:

Code:
EventManager = CvEventManager.CvEventManager()
Then, you could refer to it in CustomFunctions as EventManager., or in any other file you did this to. (It's not necessary if it's already done).

But there's no reason to import from the Event Mananger or any existing python file. You should really be doing stuff like that in your custom python file (CustomFunctions) and importing it into the existing python files where needed.
 
Ah! I think I understand now.

Does this code in EventManager
Code:
	def __init__(self):
				
		self.bCtrl = False
		self.bShift = False
		self.bAlt = False
		self.bAllowCheats = False
do nothing except give these variables an initial value? In other words, could "self.bCtrl = False" have occured for the first time in any defined function without any "__init__(self)" function?
 
Yes, that's what it does.

You want to always reset your variables to 0 (int), false (bool), "" (string), [] (list), etc. depending on what type of variable they are, at the beginning of the file.
 
Is it possible to add additional scenarios to the Scenario Menu, and if so, what file would need to be edited to add additional scenarios?
 
The CvEspionageAdvisor in /python/screens. Lutefisk Mafia modded it a bit for his Dungeon Adventure (the Khazad one) so if you ask him nicely or try to figure out what he did by comparing the normal with his you should get it.
 
Back
Top Bottom