Simple Python addition problem

Thanks, man. I bookmarked that, but once I get this done, I will probably not make own Python. I'll have others write the Python and then modularize them into BUG. therefore, this process that I am doing right now, while irritating you all, is very important to me, since I learn such a lot in the process.

Your solution did it and the GetType thing is cleared. The next error that comes up is this one on Line 20. The last self is not defined...

Spoiler :

PHP:
Traceback (most recent call last):
  File "BugEventManager", line 362, in _handleDefaultEvent
  File "Baddykill", line 20, in onUnitKilled
NameError: global name 'self' is not defined
 
Yes! That did it.

The game just freezes though after I kill the bad guy and the vicotry screen isn't shown. But that probably has to do with me trying to force the Conquest victory like this. I should create a new victory type.

Thanks, gentlemen. Medals to you!

 
If you haven't defined a new victory type

Code:
gc.getInfoTypeForString("VICTORY_BADDYKILL")

evaluates to -1 which is VICTORY_NONE to the game. You definitely need to define this victory type or supply a different type such as VICTORY_CONQUEST.
 
I have now rewritten the Python and not used onUnitKilled, but onCombatResult instead, and it required quite a bit of work and I wouldn't have done it without all the things I learned here from Phungus and EmperorFool, and from the other thread with The_J and SaibotLieh. This fixes the problem with the freezing game after victory is announced. I am really proud of myself, because the below code is something that I actually put together myself! Watch it, lads! I'm the next great Python programmer in the making, I believe! :crazyeye:


Spoiler :
PHP:
# Baddykill
# Kill the Bad Guy, win the game!

from CvPythonExtensions import *
import BugUtil
import PyHelpers

gc = CyGlobalContext()
PyPlayer = PyHelpers.PyPlayer
PyInfo = PyHelpers.PyInfo

def onCombatResult(argsList):
	'Combat Result'
	pWinner,pLoser = argsList
	playerX = PyPlayer(pWinner.getOwner())
	unitX = PyInfo.UnitInfo(pWinner.getUnitType())
	playerY = PyPlayer(pLoser.getOwner())
	unitY = PyInfo.UnitInfo(pLoser.getUnitType())
	unit, iAttacker = argsList
	iBaddy = gc.getInfoTypeForString("UNITCLASS_DEMON_KING")
	if (pLoser.getUnitClassType() == iBaddy):
		CyGame().setWinner(pWinner.getTeam(), gc.getInfoTypeForString("VICTORY_CONQUEST"))
 
Congrats! :goodjob:

Looking over your code it seems you can trim some unnecessary lines. You aren't using playerX/Y, unitX/Y, unit, or iAttacker and can remove all five of those lines. They were probably leftover from your old code. Plus you are only using the PyHelper classes in those lines to delete, allowing you to cut out three more lines. Finally, you're not using BugUtil anymore--probably had some debugging messages in there, eh?

You can simplify your code to this:

Code:
# Baddykill
# Kill the Bad Guy, win the game!

from CvPythonExtensions import *

gc = CyGlobalContext()

def onCombatResult(argsList):
    'Combat Result'
    pWinner,pLoser = argsList
    iBaddy = gc.getInfoTypeForString("UNITCLASS_DEMON_KING")
    if (pLoser.getUnitClassType() == iBaddy):
        CyGame().setWinner(pWinner.getTeam(), gc.getInfoTypeForString("VICTORY_CONQUEST"))

As this function is called only when combat ends, it won't get called thousands of times a turn. However, it's a good example on how to speed up your code easily using one of BUG's key features: module initialization functions.

What we want to do is avoid the call to getInfoTypeForString() every time we need the value because that value never changes after the game loads. For that we can ask BUG to call a function once when the game starts and store the result of the function in a variable to use inside the function.

1. Create the variable and function.

Code:
gc = CyGlobalContext()

[COLOR="Green"][B]# This will be set once by init(). ALL_CAPS typically denotes a constant value in a module
BADDY_UNIT_CLASS = None

def init():
    global BADDY_UNIT_CLASS
    BADDY_UNIT_CLASS = gc.getInfoTypeForString("UNITCLASS_DEMON_KING")[/B][/COLOR]

def onCombatResult(argsList):

2. Use the variable in your onCombatResult().

Note that you only need to use "global <variable>" in a function if you are going to assign it a value with =. You don't need "global" below to to use BADDY_UNIT_CLASS in the "if (...)" test.

Code:
def onCombatResult(argsList):
    'Combat Result'
    pWinner,pLoser = argsList
    [B][COLOR="Red"][s]iBaddy = gc.getInfoTypeForString("UNITCLASS_DEMON_KING")[/s][/COLOR][/B]
    if (pLoser.getUnitClassType() == [B][COLOR="Green"]BADDY_UNIT_CLASS[/COLOR][/B]):
        CyGame().setWinner(pWinner.getTeam(), gc.getInfoTypeForString("VICTORY_CONQUEST"))

3. Tell BUG to call init().

Add this line to your module's configuration XML file:

Code:
<mod ...>
    ...
    [B][COLOR="Green"]<init module="Baddykill"/>[/COLOR][/B]
    ...
</mod>

This assumes the above Python file is called "Baddykill.py". Since <init>s are normally called after all modules have been loaded, it doesn't matter so much where you place it in your <mod> element as long as it is inside it.

Why didn't I do the same thing with VICTORY_CONQUEST? Mostly because I'm lazy. ;) This value will only be needed when the bad guy is killed--once per game--so it hardly seemed worth it. It would make a good exercise for the reader, though. :D
 
Yes! Thanks. I supposed there were leftovers that I didn't need anymore, because it looked unnecessarily long.

I have it working now, at last! Yeyyy! I'm so happy I need yet another cup of coffee :crazyeye:

Thanks for all the help.
 
Top Bottom