davidlallen
Deity
So far, except for a few tweaks by koma13, the python for Dune Wars is controlled and maintained by me. This thread is to explain how you can tweak some things in the python. I will try to keep it up to date, but if there are later rewrites, it may be that the instructions are slightly out of date.
At this time (1.5.3 release, mid-September 2009), 95% of the python changes are in one file, assets/python/DuneWars.py. There are some small hooks in CvGameUtils.py, Screens/CvMainInterface.py, and EntryPoints/CvRandomEventInterface.py. Koma13 has also added the homeworld advisor screen, which involves larger changes in CvMainInterface.py, new file MercenaryUtils.py, and a few lines in DuneWars.py. I will not try to describe those, but he may.
General architecture
DuneWars.py is built on top of the BUG event manager. So there are no changes in CvEventManager.py. Instead, DuneWars::__init__ calls BUG functions to register event handlers; see lines like "customEM.addEventHandler("improvementBuilt", self.onImprovementBuilt)".
One key event is onEndGameTurn. A lot of things happen within the python at the end of the turn. See the code for the latest information, but in general I have tried to make high level entry points with comprehensible names. Here is the current code.
Hopefully you can sort of guess from the names what is happening, and then go into the related function.
Sandworms and sandstorms
One easy python change is to make sandworms and sandstorms more or less frequent, or maybe remove them altogether. See routines WormAdd and StormAddSubtract. They are similar. Both maintain a relatively constant number of worms or storms. If worms or storms are killed or deleted for whatever reason, then these routines will add more to make sure the right number is maintained. You can change the goal number of worms or storms.
In WormAdd, find the line "iWormWant = (iUnowned / (3 * iUTPGA)) - iWormCount". This says the goal number of worms is the number of unowned tiles, divided by three times the handicap value, UnownedTilesPerGameAnimal. If you want more worms, make 3 a smaller number or edit the handicap xml file to decrease UTPGA. If you want no worms, edit this line to set iWormWant to zero.
In StormAddSubtract, find the line "iStormWant = (xmax * ymax / 400) - len(lStorms)". This says that the number of storms is equal to the number of plots on the map, divided by 400. If you want more storms, make 400 a smaller number. If you want less, make 400 a larger number. If you want none, set iStormWant to 0.
Spice frequency and decay
You may want to increase or decrease the amount of spice. You can make spice blows more or less frequent by editing function BlowAdd. Find the line "iBlowWant = (xmax * ymax / 50) - (iSpiceCount / 8)". Each tile of existing spice counts as 1/8 of a spice blow, and we want roughly one spice blow for every 50 tiles on the map. If you want more spice, make 50 a smaller number. If you want less spice, make 50 a larger number.
To change the spice decay rate, see function SpiceDecay. This function is a little more complicated. Basically it sets the decay rate to either 0.2% (plot is owned by a civilization following the spice industry civic), 2% (if there is a spice harvester) or 0.5% (default). This is the chance that a given spice tile will be removed, per turn.
Fresh water
Suppose you want to add/change which improvements spread fresh water. Today certain improvements and city buildings spread fresh water in adjacent plots. One building, the Reservoir of Liet, spreads fresh water in all the plots of the city BFC. (This particular part is not released yet, but planned for 1.5.3.)
To add or subtract an improvement, which spreads fresh water, edit the list dFreshI which is defined in the Init routine:
Basically, just add another line with your improvement, or delete an improvement line if you don't want it to spread fresh water. You can see how this gets used in the event function onImprovementBuilt. It adds an invisible feature called WINDTRAP_WATER. This feature is basically a copy of the oasis feature from vanilla, but the art for it has fScale 0.001, which makes it really tiny and effectively invisible. So when an improvement is built, this invisible feature is added; when an improvement is destroyed or overbuilt, the invisible feature is removed.
At this time (1.5.3 release, mid-September 2009), 95% of the python changes are in one file, assets/python/DuneWars.py. There are some small hooks in CvGameUtils.py, Screens/CvMainInterface.py, and EntryPoints/CvRandomEventInterface.py. Koma13 has also added the homeworld advisor screen, which involves larger changes in CvMainInterface.py, new file MercenaryUtils.py, and a few lines in DuneWars.py. I will not try to describe those, but he may.
General architecture
DuneWars.py is built on top of the BUG event manager. So there are no changes in CvEventManager.py. Instead, DuneWars::__init__ calls BUG functions to register event handlers; see lines like "customEM.addEventHandler("improvementBuilt", self.onImprovementBuilt)".
One key event is onEndGameTurn. A lot of things happen within the python at the end of the turn. See the code for the latest information, but in general I have tried to make high level entry points with comprehensible names. Here is the current code.
Spoiler :
Code:
def onEndGameTurn(self, argsList):
self.Initialize()
iGameTurn = argsList[0]
self.Dequeue() # results of AI actions
(iUnowned, iWormCount, iSpiceCount, iMaxStr) = self.Count()
self.BlowAdd(iSpiceCount, false)
self.SpiceDecay()
self.SpiceBlow()
self.WormAdd(iUnowned, iWormCount, iMaxStr)
self.StormRun()
self.AtreidesDraft()
self.UnitLoop()
self.PlagueCities()
self.Terraform()
self.Dequeue() # results of end of turn actions
Hopefully you can sort of guess from the names what is happening, and then go into the related function.
Sandworms and sandstorms
One easy python change is to make sandworms and sandstorms more or less frequent, or maybe remove them altogether. See routines WormAdd and StormAddSubtract. They are similar. Both maintain a relatively constant number of worms or storms. If worms or storms are killed or deleted for whatever reason, then these routines will add more to make sure the right number is maintained. You can change the goal number of worms or storms.
In WormAdd, find the line "iWormWant = (iUnowned / (3 * iUTPGA)) - iWormCount". This says the goal number of worms is the number of unowned tiles, divided by three times the handicap value, UnownedTilesPerGameAnimal. If you want more worms, make 3 a smaller number or edit the handicap xml file to decrease UTPGA. If you want no worms, edit this line to set iWormWant to zero.
In StormAddSubtract, find the line "iStormWant = (xmax * ymax / 400) - len(lStorms)". This says that the number of storms is equal to the number of plots on the map, divided by 400. If you want more storms, make 400 a smaller number. If you want less, make 400 a larger number. If you want none, set iStormWant to 0.
Spice frequency and decay
You may want to increase or decrease the amount of spice. You can make spice blows more or less frequent by editing function BlowAdd. Find the line "iBlowWant = (xmax * ymax / 50) - (iSpiceCount / 8)". Each tile of existing spice counts as 1/8 of a spice blow, and we want roughly one spice blow for every 50 tiles on the map. If you want more spice, make 50 a smaller number. If you want less spice, make 50 a larger number.
To change the spice decay rate, see function SpiceDecay. This function is a little more complicated. Basically it sets the decay rate to either 0.2% (plot is owned by a civilization following the spice industry civic), 2% (if there is a spice harvester) or 0.5% (default). This is the chance that a given spice tile will be removed, per turn.
Fresh water
Suppose you want to add/change which improvements spread fresh water. Today certain improvements and city buildings spread fresh water in adjacent plots. One building, the Reservoir of Liet, spreads fresh water in all the plots of the city BFC. (This particular part is not released yet, but planned for 1.5.3.)
To add or subtract an improvement, which spreads fresh water, edit the list dFreshI which is defined in the Init routine:
Spoiler :
Code:
self.dFreshI = {
self.GetCheckInfo("IMPROVEMENT_WINDTRAP") : 1,
self.GetCheckInfo("IMPROVEMENT_AQUABORE") : 1,
self.GetCheckInfo("IMPROVEMENT_SHALLOW_WELL") : 1,
self.GetCheckInfo("IMPROVEMENT_DEEP_WELL") : 1
}