Python: What value does pNukeUnit have?

The_J

Say No 2 Net Validations
Administrator
Supporter
Joined
Oct 22, 2008
Messages
40,951
Location
DE/NL/FR
Hi :).

You see my question:
What value does pNukeUnit have?

Why the question:
I've added an effect to onNukeExplosion, but, after several crashes, i've found out, that onNukeExplosion is also triggered when there's a meltdown in a city, but i only want the effect to be triggered when a ICBM explodes.

So i tried

Code:
	def onNukeExplosion(self, argsList):
		'Nuke Explosion'
		pPlot, pNukeUnit = argsList
		
		CvUtil.pyPrint('Nuke detonated at %d, %d'
			%(pPlot.getX(), pPlot.getY()))
                
		if (pNukeUnit == gc.getInfoTypeForString('UNIT_ICBM')):

but that doesn't work, the value is never true.
I've also tried it with UNITCLASS_ and only ICBM, and it's also not a boolean-value.

To find it out i've also tried CvUtil.pyPrint('%s' %pNukeUnit), but it seems, that the Print-statements doesn't work here.

And there's also no error.


I hope someone here can help me :).
 
There's no error because Python will happily compare apples to oranges (with a False result).

pNukeUnit is a CyUnit object with functions like getUnitType(). You probably want to first compare it to the special Python value "None" to see if it's a real unit. Then test if it's the type you want.

Code:
	def onNukeExplosion(self, argsList):
		'Nuke Explosion'
		pPlot, pNukeUnit = argsList
		
		CvUtil.pyPrint('Nuke detonated at %d, %d'
			%(pPlot.getX(), pPlot.getY()))
                
		if (pNukeUnit is not None and pNukeUnit.getUnitType() == gc.getInfoTypeForString('UNIT_ICBM')):
			# boom

Note that by testing unit type instead of class, this code will fail if a civ has a UU ICBM replacement. For that you can use CyUnit.getUnitClassType() and ÜNITCLASS_...".
 
There's no error because Python will happily compare apples to oranges (with a False result).

pNukeUnit is a CyUnit object with functions like getUnitType(). You probably want to first compare it to the special Python value "None" to see if it's a real unit. Then test if it's the type you want.

Code:
	def onNukeExplosion(self, argsList):
		'Nuke Explosion'
		pPlot, pNukeUnit = argsList
		
		CvUtil.pyPrint('Nuke detonated at %d, %d'
			%(pPlot.getX(), pPlot.getY()))
                
		if (pNukeUnit is not None and pNukeUnit.getUnitType() == gc.getInfoTypeForString('UNIT_ICBM')):
			# boom

Note that by testing unit type instead of class, this code will fail if a civ has a UU ICBM replacement. For that you can use CyUnit.getUnitClassType() and ÜNITCLASS_...".

I tried this and can't get it to work. If eather of you have done it could you tell me how?
I wanted one effect for ICBM and another for the MRBM.
 
Nope, I've never tried to do this, but the principle is the same as with other checks. How exactly doesn't it work? Post the contents of the file Logs/PythonErr.log from your My Games BTS folder after launching a nuke.

Edit: Post your code snippet as well.
 
I tried this and can't get it to work. If eather of you have done it could you tell me how?
I wanted one effect for ICBM and another for the MRBM.

What do you exactly mean?
I don't mean "effect" as an graphical effect, i've attached a terraforming-effect to that.
 
What do you exactly mean?
I don't mean "effect" as an graphical effect, i've attached a terraforming-effect to that.

A effect in terms that the ICBM acts as a Alpha centaury planet buster, clearing the square of all things and reverting it to base. And the MRBM explodes like a regular nuke.
So I need something that goes like this:
(this is C#)
OnNukeExplode:
If(Unit = ICBM)
#effect 1 (anihilate all)
else
#effect 2 (just a big boom)

I don't get any error. The thing just newer trigeres. As if the part of the function after the IF does not exist.
 
The code needs to be in Python, not C#. I don't know how to kill every unit on the plot, but the code I posted above would let you check the type of unit.
 
A effect in terms that the ICBM acts as a Alpha centaury planet buster, clearing the square of all things and reverting it to base. And the MRBM explodes like a regular nuke.
So I need something that goes like this:
(this is C#)
OnNukeExplode:
If(Unit = ICBM)
#effect 1 (anihilate all)
else
#effect 2 (just a big boom)

I don't get any error. The thing just newer trigeres. As if the part of the function after the IF does not exist.

I've done exactly that :D.

PHP:
	def onNukeExplosion(self, argsList):
		'Nuke Explosion'
		pPlot, pNukeUnit = argsList
		
		CvUtil.pyPrint('Nuke detonated at %d, %d'
			%(pPlot.getX(), pPlot.getY()))
		if (pNukeUnit is not None and pNukeUnit.getUnitType() == gc.getInfoTypeForString('UNIT_ICBM')):

                        
            iX = pPlot.getX()
            iY = pPlot.getY()
            tt_desert = gc.getInfoTypeForString( 'TERRAIN_DESERT' )
			tt_plain = gc.getInfoTypeForString( 'TERRAIN_PLAINS' )
			tt_grass = gc.getInfoTypeForString( 'TERRAIN_GRASS' )
			tt_tundra = gc.getInfoTypeForString( 'TERRAIN_TUNDRA' )
			tt_snow = gc.getInfoTypeForString( 'TERRAIN_SNOW' )
			tt_ocean = gc.getInfoTypeForString( 'TERRAIN_OCEAN' )
			for iXLoop in range(iX - 1, iX + 2, 1):
				for iYLoop in range(iY - 1, iY + 2, 1):
						pPlot = CyMap().plot(iXLoop, iYLoop)
			
   						if ( pPlot.getTerrainType()==tt_grass ):
   						    	pPlot.setTerrainType(gc.getInfoTypeForString( "TERRAIN_COAST" ), 1, 1)
   						        
			   			elif ( pPlot.getTerrainType()==tt_plain ):
								   										pPlot.setTerrainType(gc.getInfoTypeForString( "TERRAIN_COAST" ), 1, 1)
						elif ( pPlot.getTerrainType()==tt_tundra ):
								 			pPlot.setTerrainType(gc.getInfoTypeForString( "TERRAIN_COAST" ), 1, 1)
						elif ( pPlot.getTerrainType()==tt_snow ):
									pPlot.setTerrainType(gc.getInfoTypeForString( "TERRAIN_COAST" ), 1, 1)
						elif ( pPlot.getTerrainType()==tt_ocean ):
									pPlot.setTerrainType(gc.getInfoTypeForString( "TERRAIN_COAST" ), 1, 1)
						elif ( pPlot.getTerrainType()==tt_desert ):
									pPlot.setTerrainType(gc.getInfoTypeForString( "TERRAIN_COAST" ), 1, 1)

Yes, i know, that the code is totally stupid and some parts redundant at the moment, but it works.
Credits for this code go to tsentom1, i've stolen it all from his eden-project, and got his help :).
If it's badly needed, i could maybe release it tomorrow, or so (time, time is lacking).

edit: This code terminates really all on the plot (units, improvements, etc) and the surrounding plots, including cities.
Can easily be changed, that it doesn't destroy cities.
 
It kills everything (boats too?) by turning all the plots into water (coast), so you'll need to take a different approach to killing everything if you don't want to modify the terrain.

You need to loop through the units on the plot and kill them (pUnit->kill()), but I don't know what that will do to your loop (modifying the plot list while looping through it).
 
The code needs to be in Python, not C#. I don't know how to kill every unit on the plot, but the code I posted above would let you check the type of unit.

I know. But since I know C# I thought that it would have been easier to explain what I want with it and avoid confusion.

And The_J, I tried your code and it changed apsolutely nothing.
 
It kills everything (boats too?) by turning all the plots into water (coast), so you'll need to take a different approach to killing everything if you don't want to modify the terrain.

You need to loop through the units on the plot and kill them (pUnit->kill()), but I don't know what that will do to your loop (modifying the plot list while looping through it).

Haven't tried it out with ships, but i've added hovercrafts, which are DOMAIN_LAND, but can also move on water, and they are destroyed.

Uh, thought, the terrain should be changed (->AC-Planetbuster), didn't see, that he only want's it to be cleared.
I would just terraform the terrain back after the change to water. This would totally clear it.
(yes, the idea is not very intelligent)

When you loope through the units, a while-loop has to be used, or am i wrong? Using a for-loop wouldn't work.


I know. But since I know C# I thought that it would have been easier to explain what I want with it and avoid confusion.

And The_J, I tried your code and it changed apsolutely nothing.

What :confused:? I've tried it out after reading this, and it works fine in my mod :confused:.
Do you have python-exceptions enabled?
 
When things don't work, 1) post the code and 2) post the file Logs/PythonErr.log. Otherwise there's nothing we have to go on to help you.
 
When things don't work, 1) post the code and 2) post the file Logs/PythonErr.log. Otherwise there's nothing we have to go on to help you.

I am not getting any pyton errors.
I simply copied the code J posted to replace the default onNukeExplosion function.
There is no code edit other than that, but it simply ignores the code and acts as if it is a normal nuke (vanila civ). Note that other than the code change mentioned the entire test mod is 100% vanila.
 
Change the debug print line

Code:
CvUtil.pyPrint('Nuke detonated at %d, %d'

to this

Code:
CvUtil.pyPrint('OMG a nuke was detonated at %d, %d'

Then test your mod. If you still see the old print in the log file, then you aren't running your mod or you're modifying the wrong file.
 
Assets\Python\CvEventManager.py
That is the right file, right?

It is almost as if the game is not detecting the code at all. I am getting the vanila mesage: "Purple has launched a nuke and it explodes."
 
Yes, but where is that file? Are you modifying the core Civ4 files, or have you created a folder in the Mods folder?

What does changing the debug line do? Do you see the new message in Lods/PythonDbg.log?
 
I created a new mod with only that 1 file for the purpose of testing it.

The entire mod literaly looks like this:
Mod1\Assets\Python\CvEventManager.py
And there is nothing else in it.
And it still don't work.

where is the debug line located in what file?
 
where is the debug line?

it's near the top of the onNukeExplosion(...) function that The_J posted.

The entire mod literaly looks like this:
Mod1\Assets\Python\CvEventManager.py
And there is nothing else in it.

That looks correct. The log file will show up in your My Games BTS Logs folder.
 
I edited the line, and I am still getting the same resault. The vanila civ default mesage: "Player name has launched a nuke and it explodes."
It is as if the game is compleatly ignoring the code that I wrote.

Here is what I get:
PythonErr2.log said:
sys.path = ['..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\email', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\encodings', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\build', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\lib', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\locale', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\py', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\tools', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\lib\\colourchooser', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\lib\\editor', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\lib\\floatcanvas', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\lib\\masked', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\lib\\mixins', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\lib\\ogl', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\locale\\af', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\locale\\ca', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\locale\\cs', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\locale\\da', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\locale\\de', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\locale\\el', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\locale\\es', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\locale\\eu', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\locale\\fi', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\locale\\fr', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\locale\\hi', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\locale\\hu', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\locale\\id', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\locale\\it', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\locale\\ja', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\locale\\lv', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\locale\\nb', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\locale\\nl', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\locale\\pl', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\locale\\pt_BR', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\locale\\ru', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\locale\\sl', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\locale\\sv', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\locale\\tr', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\locale\\uk', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\locale\\zh_CN', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\locale\\zh_TW', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\locale\\af\\LC_MESSAGES', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\locale\\ca\\LC_MESSAGES', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\locale\\cs\\LC_MESSAGES', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\locale\\da\\LC_MESSAGES', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\locale\\de\\LC_MESSAGES', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\locale\\el\\LC_MESSAGES', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\locale\\es\\LC_MESSAGES', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\locale\\eu\\LC_MESSAGES', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\locale\\fi\\LC_MESSAGES', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\locale\\fr\\LC_MESSAGES', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\locale\\hi\\LC_MESSAGES', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\locale\\hu\\LC_MESSAGES', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\locale\\id\\LC_MESSAGES', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\locale\\it\\LC_MESSAGES', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\locale\\ja\\LC_MESSAGES', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\locale\\lv\\LC_MESSAGES', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\locale\\nb\\LC_MESSAGES', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\locale\\nl\\LC_MESSAGES', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\locale\\pl\\LC_MESSAGES', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\locale\\pt_BR\\LC_MESSAGES', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\locale\\ru\\LC_MESSAGES', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\locale\\sl\\LC_MESSAGES', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\locale\\sv\\LC_MESSAGES', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\locale\\tr\\LC_MESSAGES', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\locale\\uk\\LC_MESSAGES', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\locale\\zh_CN\\LC_MESSAGES', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\locale\\zh_TW\\LC_MESSAGES', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\py\\tests', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\tools\\XRCed', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM\\wx\\tools\\XRCed\\src-images', '..\\WARLORDS\\ASSETS\\PYTHON\\SYSTEM']

sys.modules = {'zipimport': <module 'zipimport' (built-in)>, 'signal': <module 'signal' (built-in)>, '__builtin__': <module '__builtin__' (built-in)>, 'sys': <module 'sys' (built-in)>, '__main__': <module '__main__' (built-in)>, 'exceptions': <module 'exceptions' (built-in)>, 'CvPythonExtensions': <module 'CvPythonExtensions' (built-in)>}

sys.builtin_module_names = ('CvPythonExtensions', '__builtin__', '__main__', '_bisect', '_codecs', '_codecs_cn', '_codecs_hk', '_codecs_iso2022', '_codecs_jp', '_codecs_kr', '_codecs_tw', '_csv', '_heapq', '_hotshot', '_locale', '_multibytecodec', '_random', '_sre', '_subprocess', '_symtable', '_weakref', '_winreg', 'array', 'audioop', 'binascii', 'cPickle', 'cStringIO', 'cmath', 'collections', 'datetime', 'errno', 'exceptions', 'gc', 'imageop', 'imp', 'itertools', 'marshal', 'math', 'md5', 'mmap', 'msvcrt', 'nt', 'operator', 'parser', 'regex', 'rgbimg', 'sha', 'signal', 'strop', 'struct', 'sys', 'thread', 'time', 'xxsubtype', 'zipimport')
load_module CvEventInterface
load_module CvUtil
load_module traceback
load_module CvEventManager
Traceback (most recent call last):
File "<string>", line 1, in ?
File "<string>", line 52, in load_module
File "CvEventInterface", line 13, in ?
File "<string>", line 35, in load_module
File "<string>", line 13, in _get_code
File "CvEventManager", line 490
def onNukeExplosion(self, argsList):
^
IndentationError: unindent does not match any outer indentation level
load_module CvAppInterface
 
Top Bottom