Python help Event to place units on a certain date.

1) Yes. This way is very poor for compatability. There are two or three ways you can make it better - check out how TheLopez sets it up (I know you hate it when people say that, but I haven't checked it out myself - I do something different...)

2) Game turn. Might be a function to turn year into game turn (gets messy with different game speeds).

3) Not sure there was one. Hold on, I'll sort one out for you...
 
Okies:
Code:
def onBeginGameTurn(self, argsList):
	iGameTurn, iPlayer = argsList
	
	unitType = gc.getInfoTypeForString("<Insert unit name as in XML here>")
	numUnits = <Insert num units here>
	
	if iPlayer == <Insert player number here>:
		if iGameTurn == <Insert the game turn here>:
			iPlotX = <Insert plot X co-ordinate here>
			iPlotY = <Insert plot X co-ordinate here>
			pPlot = CyMap().plot(iPlotX, iPlotY)
			
			bPlotValid = True
			
			for i in range(pPlot.getNumUnits()):
				if gc.getTeam(pPlot.getUnit(i).getTeam()).isAtWar(gc.getPlayer(iPlayer).getTeam()):
					bPlotValid = False
					break
					
			if bPlotValid:
				for i in range(numUnits):
					gc.getPlayer(iPlayer).initUnit(unitType, iPlotX, iPlotY, NO_UNITAI)
			else:
				validPlotList = []
				for iX in range(-1, 2):
					for iY in range(-1, 2):
						if iX == iY == 0:
							continue
						bPlotValid = True
						pPlot = CyMap().plot(iPlotX + iX, iPlotY + iY)
						if pPlot.getPlotType() == PlotTypes.PLOT_PEAK or (gc.getUnitInfo(unitType).getDomainType() == DomainTypes.DOMAIN_SEA and pPlot.getPlotType() == PlotTypes.PLOT_OCEAN)
							or (gc.getUnitInfo(unitType).getDomainType() == DomainTypes.DOMAIN_LAND and pPlot.getPlotType() == PlotTypes.PLOT_LAND):
							bPlotValid = False
						for i in range(pPlot.getNumUnits()):
							if gc.getTeam(pPlot.getUnit(i).getTeam()).isAtWar(gc.getPlayer(iPlayer).getTeam()):
								bPlotValid = False
								break
						if bPlotValid:
							validPlotList.append(pPlot)
				
				if len(validPlotList):
					rand = CyGame().getSorenRandNum(len(vaildPlotList), "Random unit plot")
					iPlotX = validPlotList[rand].getX()
					iPlotY = validPlotList[rand].getY()
					
					for i in range(numUnits):
						gc.getPlayer(iPlayer).initUnit(unitType, iPlotX, iPlotY, NO_UNITAI)
Now checks that the plot is valid for the unit (sea for water units, land for land units, and peak for no units.)

The more I write, the less chance it'll work first time. Gunner picked up one of my mistakes last time, but I don't know if there are any more in here now.
 
Uh... got an error on the line:

if pPlot.getPlotType() == PlotTypes.PLOT_PEAK or (gc.getUnitInfo(unitType).getDomainType() == DomainTypes.DOMAIN_SEA and pPlot.getPlotType() == PlotTypes.PLOT_OCEAN)
 
Hmmm. Try moving the next line to follow after it:
Code:
if pPlot.getPlotType() == PlotTypes.PLOT_PEAK or (gc.getUnitInfo(unitType).getDomainType() == DomainTypes.DOMAIN_SEA and pPlot.getPlotType() == PlotTypes.PLOT_OCEAN) or (gc.getUnitInfo(unitType).getDomainType() == DomainTypes.DOMAIN_LAND and pPlot.getPlotType() == PlotTypes.PLOT_LAND):
I probably moved it down so that I could see it all on my screen, but I'm pretty sure that isn't valid syntax.

I'm assuming it was a syntax error. It should have told you.
 
Okay, I made the recommended changes and after a bunch of testing and editing and more testing... I am still getting an error message in the PythonErr.log file, and no units are appearing. It makes me sad.....<g>. And even though experimenting and trying things out is fun and educational, since I am not making progress, its bumming me out.

Attached is a .zip file containing the CvEventsInterface from Vanilla civ (there doesn't seem to be such a file in Warlords), also included is the CvEventManager from my Testmod\Python folder where the testmod is. The PythonErr.log file is there, and the Testmod.WarlordsWBSave file too.

To save you the unzipping, here is module from CvEventManager.py

def onBeginGameTurn(self, argsList):
'Called at the beginning of the end of each turn'
iGameTurn,iPlayer = argsList
CvTopCivs.CvTopCivs().turnChecker(iGameTurn)

###added stuff
unitType = gc.getInfoTypeForString("UNITCLASS_PIKEMAN")
numUnits = 3

if iPlayer == 0:
if iGameTurn == 333:
iPlotX = 28
iPlotY = 9
pPlot = CyMap().plot(iPlotX, iPlotY)

bPlotValid = True

for i in range(pPlot.getNumUnits()):
if gc.getTeam(pPlot.getUnit(i).getTeam()).isAtWar(gc.getPlayer(iPlayer).getTeam()):
bPlotValid = False
break

if bPlotValid:
for i in range(numUnits):
gc.getPlayer(iPlayer).initUnit(unitType, iPlotX, iPlotY, NO_UNITAI)
else:
validPlotList = []
for iX in range(-1, 2):
for iY in range(-1, 2):
if iX == iY == 0:
continue
bPlotValid = True
pPlot = CyMap().plot(iPlotX + iX, iPlotY + iY)
if pPlot.getPlotType() == PlotTypes.PLOT_PEAK or (gc.getUnitInfo(unitType).getDomainType() == DomainTypes.DOMAIN_SEA and pPlot.getPlotType() == PlotTypes.PLOT_OCEAN) or (gc.getUnitInfo(unitType).getDomainType() == DomainTypes.DOMAIN_LAND and pPlot.getPlotType() == PlotTypes.PLOT_LAND):
bPlotValid = False
for i in range(pPlot.getNumUnits()):
if gc.getTeam(pPlot.getUnit(i).getTeam()).isAtWar(gc.getPlayer(iPlayer).getTeam()):
bPlotValid = False
break
if bPlotValid:
validPlotList.append(pPlot)

if len(validPlotList):
rand = CyGame().getSorenRandNum(len(vaildPlotList), "Random unit plot")
iPlotX = validPlotList[rand].getX()
iPlotY = validPlotList[rand].getY()

for i in range(numUnits):
gc.getPlayer(iPlayer).initUnit(unitType, iPlotX, iPlotY, NO_UNITAI)
###

...and the PythonErr.log file says:

Traceback (most recent call last):

File "CvEventInterface", line 23, in onEvent

File "CvEventManager", line 172, in handleEvent

File "CvEventManager", line 324, in onBeginGameTurn

ValueError: need more than 1 value to unpack
ERR: Python function onEvent failed, module CvEventInterface
Traceback (most recent call last):

File "CvEventInterface", line 23, in onEvent

File "CvEventManager", line 172, in handleEvent

File "CvEventManager", line 324, in onBeginGameTurn

ValueError: need more than 1 value to unpack
ERR: Python function onEvent failed, module CvEventInterface
Traceback (most recent call last):

File "CvEventInterface", line 23, in onEvent

File "CvEventManager", line 172, in handleEvent

File "CvEventManager", line 324, in onBeginGameTurn

ValueError: need more than 1 value to unpack
ERR: Python function onEvent failed, module CvEventInterface

....and how the heck do you get the quotes to indent properly?
 
Default (and what I wrote) is:
iGameTurn, iPlayer = argsList

What you have (on line 324) is:
iGameTurn,iPlayer = argsList

I'm pretty sure (though not certain) that's your problem.

To indent properly use [code]<text>[/code]. It also makes it quotable, which is useful.

EDIT: Also, instead of UNITCLASS_PIKEMAN you need UNIT_PIKEMAN.
 
Wow, TGA, that is fast.

I do not think the space is the problem, I tried it with and without the space, same error.
 
I replaced the line

iGameTurn = argsList[0]

with

iGameTurn, iPlayer = argsList

Would that have anything to do with it?
 
Oh. Ooops. Should be onBeginPlayerTurn not onBeginGameTurn. Thought that space wouldn't have mattered, but it was the only thing I could see.
 
Queue the intro music!

It worked perfectly. Here is the amended and fully correct code.

Code:
	def onBeginPlayerTurn(self, argsList):
		'Called at the beginning of a players turn'
		iGameTurn, iPlayer = argsList
		
###added stuff 
		unitType = gc.getInfoTypeForString("UNIT_PIKEMAN")
		numUnits = 3
		
		if iPlayer == 0:
			if iGameTurn == 333:
				iPlotX = 28
				iPlotY = 9
				pPlot = CyMap().plot(iPlotX, iPlotY)
				
				bPlotValid = True
				
				for i in range(pPlot.getNumUnits()):
					if gc.getTeam(pPlot.getUnit(i).getTeam()).isAtWar(gc.getPlayer(iPlayer).getTeam()):
						bPlotValid = False
						break
						
				if bPlotValid:
					for i in range(numUnits):
						gc.getPlayer(iPlayer).initUnit(unitType, iPlotX, iPlotY, UnitAITypes.NO_UNITAI)
				else:
					validPlotList = []
					for iX in range(-1, 2):
						for iY in range(-1, 2):
							if iX == iY == 0:
								continue
							bPlotValid = True
							pPlot = CyMap().plot(iPlotX + iX, iPlotY + iY)
							if pPlot.getPlotType() == PlotTypes.PLOT_PEAK or (gc.getUnitInfo(unitType).getDomainType() == DomainTypes.DOMAIN_SEA and pPlot.getPlotType() == PlotTypes.PLOT_OCEAN) or (gc.getUnitInfo(unitType).getDomainType() == DomainTypes.DOMAIN_LAND and pPlot.getPlotType() == PlotTypes.PLOT_LAND):
								bPlotValid = False
							for i in range(pPlot.getNumUnits()):
								if gc.getTeam(pPlot.getUnit(i).getTeam()).isAtWar(gc.getPlayer(iPlayer).getTeam()):
									bPlotValid = False
									break
							if bPlotValid:
								validPlotList.append(pPlot)
					
					if len(validPlotList):
						rand = CyGame().getSorenRandNum(len(vaildPlotList), "Random unit plot")
						iPlotX = validPlotList[rand].getX()
						iPlotY = validPlotList[rand].getY()
						
						for i in range(numUnits):
							gc.getPlayer(iPlayer).initUnit(unitType, iPlotX, iPlotY, UnitAITypes.NO_UNITAI)
###

What it does. It puts unit(s) you specify on a location you specify on a gameturn you specify, without any other modules required.

One word was missing from the NO_UNITAI, it wanted the UnitAITypes.NO_UNITAI instead.

And yes, I did go look at other examples to see what the error code was telling me. See, I can be taught.... for the most part...:D
 
Okay, one more question and I SWEAR, I won't ask another one... for days, perhaps a week!

What if I wanted to put 3 ENEMY units at a certain area on a certain game turn?

...uh, and with a popup box telling me they are there.

No more questions... I mean it..... really.... for a while... maybe a week.... at least a few days..... seriously.... I mean it....
 
What do you mean by enemy? If I understand you correctly enemy units should be able to be done with the above code.

Popups... urrrgh. I hate popups. I'm going to annoy you by suggesting you look at Kael's tutorial in the tutorials forum... which I just see you have already posted on.
 
Yep, I figured I would spread the love around so I asked about popups on the popup thread.... though I have come to love that Zulu "Wrong Forum" message.

My vague question was.... well I see how it places MY (the human) units on the map, but what line would place say.... player 2's units on the map.

Is it that last two lines:

Code:
for i in range(numUnits):
		gc.getPlayer(iPlayer).initUnit(unitType, iPlotX, iPlotY, UnitAITypes.NO_UNITAI)
 
Hmmm. Good question.

You'd probably have to iterate through all the player's to find the one with the right Civ:
Code:
iCivPlayer = -1

for i in range(gc.getMAX_CIV_PLAYERS()):
	if gc.getPlayer(i).getCivilizationType() == gc.getInfoTypeForString("<Insert civ name>"):
		iCivPlayer = i
		break
 
Thanks TGA.

Oh and forgive me if this is wrong, but shouldn't it be gc.getPlayer(i).getCivilizationType() instead of gc.getPlayer(iPlayer).getCivilizationType()? With the thing you have up there it doesn't look like you are using the i range value anywhere.
 
Back
Top Bottom