View Full Version : [PYTHON MODCOMP] zActions


Zebra 9
Apr 25, 2007, 11:39 AM
This allows any person who has a knowledge of Civ Python to add new actions that can range from ranged bombardment to planting forests.

Limitations include units that use all of their moves don't end their turn and there is no AI.:(

I have included a sample that allows any worker (including fast workers) to plant forests and gives seige units the ability to bombard a 2 plot range damaging any enemy unit on the targeted plot.

Some of the code I copied from the spellDemo MOD COMP Thingy.

Usage Tutorial;)
The first step in adding an action using zActions is desiding what the action will be called, what it will do, when it will be able to be preformed, and what units can use it.
Once you have all the information above we need to convert it into python in the form of functions. Now because zActions requires you to create 6 functions I have created a system by which we can list all 6, and some other information, in one spot. The code for this goes in zActionsActions.py, so example code is blow:
zActionInfos.addZAction (
"Bombard City", ## Name
"art/interface/buttons/actions/bombard.dds", ## Button
getDistRangeFuncSquare(2), ## Plots it can hit
canBombard, ## Tells if the action can be done
canEverBombard, ## Tells if it can do action now
canBombardOnPlot, ## Tells if action can be done on plot
shouldBombard, ## Tells if action is recommended
bombard, ## Does Action
2 ## Range
)
Now the line that reads "Rand Bombard" tells python that the action is to be called [i]Rand Bombard[/] (I couldn't think of anything else).
Now the line that reads "art/interface/buttons/actions/bombard.dds" tells python what button to use for the action.
Now the line that reads getDistRangeFuncSquare(2) tells python how to find the plots that can be bombarded, this code tells python that the most distant plot can not be more than 2 plots away from the active unit.
Now the line that reads canBombard tells python if the action can be preformed, it calls a function in zActionsFuncs.py.
Now the line that reads canEverBombard tells python if the active unit can preform the action, it calls a function in zActionsFuncs.py.
Now the line that reads canBombardOnPlot tells python if the action can be preform on a certain plot, it calls a function in zActionsFuncs.py.
Now the line that reads shouldBombard tells python if the action is recommended, it calls a function in zActionsFuncs.py.
Now the line that reads bombard tells python how to do the action, it calls a function in zActionsFuncs.py.

Next we need to create the nessicary functions in zActionsFuncs.py. First we will make the function canBombard, it looks like:
def canBombard(unit, action):
if unit.getMoves() == unit.baseMoves() * 60:
return False
return True
Then we need to make canEverBombard, this function looks like:
def canEverBombard(unit, action):
plot = unit.plot()
if unit.getUnitCombatType() == gc.getInfoTypeForString("UNITCOMBAT_SIEGE"):
return True
return False
Next let's create canBombardOnPlot:
def canBombardOnPlot(unit, plot, action):
if plot.getNumDefenders(-1) > 0:
if plot.getBestDefender(-1, unit.getOwner(), unit, True, True, True).isNone() == False:
return True
return False
We will next make shouldBombard, it looks like:
def shouldBombard(unit, action):
return False
Lastly, but most important, we will make bombard, it looks like:
def bombard(unit, plot, action):
yUnit = plot.getBestDefender(-1, unit.getOwner(), unit, True, True, True)

rand = CyGame().getSorenRandNum(90, 'Zebra9') + 10

dmg = yUnit.getDamage()
yUnit.setDamage(dmg + rand, -1)

unit.setMoves(unit.getMoves() + 60)
unit.setMadeAttack(True)
All of the arguments for the functions are pretty much self explanitory, but so you know action is an instance of the action that is currently being worked with. Now because zActions require a more in depth knowledge I havn't gone indepth explaining how everything works. This is just supposed to show the basic steps and give some information on how zActions works.

Download Here (http://forums.civfanatics.com/downloads.php?do=file&id=4680)
Enjoy:cool:

MatzeHH
Apr 25, 2007, 02:42 PM
Why use Python for that? It's much more simply with XML.

Matze

Gerikes
Apr 25, 2007, 04:57 PM
Why use Python for that? It's much more simply with XML.

Matze

I don't think you can do that stuff with just XML...

Caesium
Apr 25, 2007, 05:03 PM
Most of these stuff is "triggerable" via xml
There exists an early mod called something like "Plant Forest Mod"
Also the terraforming mod is triggered via xml, only the events are handled via python.

ClassicThunder
Apr 25, 2007, 06:39 PM
add new actions

This can't be done with XML or Python until Zebra. However, the lack of AI is a major put off to me.

strategyonly
Apr 27, 2007, 11:36 PM
Do you have a guide/tutorial/readme here, so some of US non-python people can do certain things here with this??

RogerBacon
Apr 28, 2007, 02:10 PM
This bears a STONG resemblence to the SpellDemo mod including an identical comment on line 1416 of your CVMainInterface.py that says "for some reason if I put this all on 1 line it gives me a MemoryError or an "unidentifiable c++ exception". Not nice to use someone else's work without giving them credit. :(

Roger Bacon

Zebra 9
May 01, 2007, 11:32 AM
Oh, I forgot to mention that bI did copy some of the spell demo code over. Sorry about that.

This can't be done with XML or Python until Zebra. However, the lack of AI is a major put off to me.
Weel AI could be implementedx by going through an AI's units at the bginning of their turn.

Grave
May 05, 2007, 07:57 PM
I'd like to see a python script that would allow artillery bombardment (or aircraft bombing missions) to have a user-defined percentage to randomly destroy a building in the attacked city.

Something that could be used as a stand-alone, or compatable with those of us who use Dale's Ranged Bombardment.


Think you could do something like that? :)

Zebra 9
May 07, 2007, 11:22 AM
Yes that would be possible. I will see if I put that as an example script in the tut I will release this week (I'll post it for you as soon as possible).

Grave
May 08, 2007, 05:03 PM
Yes that would be possible. I will see if I put that as an example script in the tut I will release this week (I'll post it for you as soon as possible).

Sweet... thank you! I could never understand why Firaxis left destroying buildings via bombardment out of the game. It's a great way to cripple an enemy city.

I look forward to seeing your tutorial. :goodjob:

Zebra 9
May 09, 2007, 10:45 AM
In the file zActionsActions.py put the below code:

zActionInfos.addZAction (
"Rand Bombard", ## Name
"art/interface/buttons/actions/bombard.dds", ## Button
getDistRangeFuncSquare(2), ## Plots it can hit
canRandBombard, ## Tells if the action can be done
canEverRandBombard, ## Tells if it can do action now
canRandBombardOnPlot, ## Tells if action can be done on plot
shouldRandBombard, ## Tells if action is recommended
doRandBombard, ## Does Action
2 ## Range
)

This tells python what to use to preform the action as well as give it some infomation about the action. Some thing you should know is that if you change the 2s to a different number it will change the range to that number. So if you set it to 3, any unit trying to preform the action will have a square around them that is 7 plots wide by 7 plots high (3 plots to it's left, right, back, and front, along with the plot it is standing on). Next put this code in the file titled zActionsFuncs.py:

def canEverRandBombard(unit, action):
plot = unit.plot()
if unit.getUnitCombatType() == gc.getInfoTypeForString("UNITCOMBAT_SIEGE") or unit.getDomainType() == gc.getInfoTypeForString("DOMAIN_AIR"):
return True
return False

def canRandBombard(unit, action):
if unit.getMoves() == unit.baseMoves() * 60:
return False
return True

def canRandBombardOnPlot(unit, plot, action):
if plot.getNumDefenders(-1) > 0:
if plot.getBestDefender(-1, unit.getOwner(), unit, True, True, True).isNone() == False:
return True
elif plot.isCity() and (plot.getPlotCity().getNumBuildings() > 0 or plot.getPlotCity().getPopulation() > 1) and gc.getTeam(unit.getTeam()).isAtWar(plot.getPlotCit y().getTeam()):
return True
return False

def doRandBombard(unit, plot, action):
hitUnit = CyGame().getSorenRandNum(100, 'Zebra9') + 1
if plot.getBestDefender(-1, unit.getOwner(), unit, True, True, True).isNone() == False and hitUnit <= 25:
yUnit = plot.getBestDefender(-1, unit.getOwner(), unit, True, True, True)

rand = CyGame().getSorenRandNum(90, 'Zebra9') + 10

dmg = yUnit.getDamage()
yUnit.setDamage(dmg + rand, -1)

hitCity = CyGame().getSorenRandNum(100, 'Zebra9') + 1
if plot.isCity() and gc.getTeam(unit.getTeam()).isAtWar(plot.getPlotCit y().getTeam()) and hitCity <= 25:
if plot.getPlotCity().getNumBuildings() > 0:
for iBuilding in range(gc.getNumBuildingInfos()):
if gc.getBuildingInfo(iBuilding).isNukeImmune() or plot.getPlotCity().isHasRealBuilding(iBuilding) == False:
continue
if CyGame().getSorenRandNum(100, 'Zebra9') + 1 <= 25:
plot.getPlotCity().setHasRealBuilding(iBuilding, False)
if plot.getPlotCity().getPopulation() > 1:
if CyGame().getSorenRandNum(100, 'Zebra9') + 1 <= 25:
plot.getPlotCity().setPopulation(plot.getPlotCity( ).getPopulation() - CyGame().getSorenRandNum(int(plot.getPlotCity().ge tPopulation() / 2), 'Zebra9'))
unit.setMoves(unit.getMoves() + 60)
unit.setMadeAttack(True)


def shouldRandBombard(unit, action):
return False

Now if you copy that code over you should be able to use aircraft and seige units to do major damage to cities and units. Now the draw backs are that the AI has no clue about the action and your aircraft can't be intercepted or shot at by sam infantry or aircraft on air patrol.

This would add a no AI action using zActions. Now I am trying to see if I could hyjack an action (say bombard) from the SDK and add my own little event with it. This would allow a person to bombard a city, the city would suffer the usual damage and it would also lose some buildings or what ever. I'm realy hoping to be able to do this.:goodjob:

Zebra 9
Jun 04, 2007, 11:01 AM
Added Usage Tutorial. :thumbsup:

Jeckel
Jun 26, 2008, 12:58 PM
Nice one Zebra. Have you had any luck getting flying help text for your added ActionButtons?

Zebra 9
Jun 27, 2008, 08:51 PM
Not sure what you mean Jeckel?