REQUESTING HELP on a Python Wonder...

Alright, but I should put the:

Code:
				BugUtil.debug("found Topkapi")

Under each if line?

So if my code looks like this originally:

Code:
	def onUnitBuilt(self, argsList):
		'Unit Completed'
		city = argsList[0]
		unit = argsList[1]
		player = PyPlayer(city.getOwner())

## Topkapi Palace Start ##

		pCity = argsList[0]
		pUnit = argsList[1]
		pPlayer = gc.getPlayer(pUnit.getOwner())
		iUnitType = pUnit.getUnitType()

		b_BUILDING_TOPKAPI = gc.getInfoTypeForString("BUILDING_FLAVIAN")
		obsoleteTech = gc.getBuildingInfo(b_BUILDING_TOPKAPI).getObsoleteTech()
		if ( gc.getTeam(pPlayer.getTeam()).isHasTech(obsoleteTech) == false or obsoleteTech == -1 ):
			topkapi = false
			for iCity in range(pPlayer.getNumCities()):
				if topkapi == false:
					ppCity = pPlayer.getCity(iCity)
					if ppCity.getNumActiveBuilding(b_BUILDING_TOPKAPI) == true:
						topkapi = true
			if ( topkapi == true ):
				iTeam = pPlayer.getTeam()
				pTeam = gc.getTeam(iTeam)
				l_vassalUB = []
				for iPlayer in range(gc.getMAX_PLAYERS()):
					ppPlayer = gc.getPlayer(iPlayer)
					if ( (ppPlayer.isAlive()==true) and (ppPlayer.isBarbarian()==false) ):
						if ( (gc.getTeam(ppPlayer.getTeam()).isHasMet(iTeam)) and (ppPlayer.isAlive()==true) and (ppPlayer.isBarbarian()==false) ):
							civ_type = gc.getPlayer(iPlayer).getCivilizationType()
							for iUnit in range(gc.getNumUnitClassInfos()):
								iUniqueUnit = gc.getCivilizationInfo(civ_type).getCivilizationUnits(iUnit);
								iDefaultUnit = gc.getUnitClassInfo(iUnit).getDefaultUnitIndex();
								if (iDefaultUnit > -1 and iUniqueUnit > -1 and iDefaultUnit != iUniqueUnit):
									if ( iUnitType == iDefaultUnit ):
										l_vassalUB.append(iUniqueUnit)
				if ( len(l_vassalUB) >= 1 ):
					self.iVassalUUChance = self.getRandomNumber( 4 )
					if self.iVassalUUChance == 0:
						chance = CyGame().getSorenRandNum(len(l_vassalUB), "Random for UB")
						iX = pUnit.getX()
						iY = pUnit.getY()
						pNewUnit = pPlayer.initUnit( l_vassalUB[chance], iX, iY, UnitAITypes.NO_UNITAI, DirectionTypes.NO_DIRECTION )
						pNewUnit.convert(pUnit)


## Topkapi Palace End ##

It should now look like this?

Code:
	def onUnitBuilt(self, argsList):
		'Unit Completed'
		city = argsList[0]
		unit = argsList[1]
		player = PyPlayer(city.getOwner())

## Topkapi Palace Start ##

		pCity = argsList[0]
		pUnit = argsList[1]
		pPlayer = gc.getPlayer(pUnit.getOwner())
		iUnitType = pUnit.getUnitType()

		b_BUILDING_TOPKAPI = gc.getInfoTypeForString("BUILDING_FLAVIAN")
		obsoleteTech = gc.getBuildingInfo(b_BUILDING_TOPKAPI).getObsoleteTech()
		if ( gc.getTeam(pPlayer.getTeam()).isHasTech(obsoleteTech) == false or obsoleteTech == -1 ):
			BugUtil.debug("found Topkapi")        
			topkapi = false
			for iCity in range(pPlayer.getNumCities()):
				if topkapi == false:
					ppCity = pPlayer.getCity(iCity)
					if ppCity.getNumActiveBuilding(b_BUILDING_TOPKAPI) == true:
						topkapi = true
			if ( topkapi == true ):
				BugUtil.debug("found Topkapi")            
				iTeam = pPlayer.getTeam()
				pTeam = gc.getTeam(iTeam)
				l_vassalUB = []
				for iPlayer in range(gc.getMAX_PLAYERS()):
					ppPlayer = gc.getPlayer(iPlayer)
					if ( (ppPlayer.isAlive()==true) and (ppPlayer.isBarbarian()==false) ):
					BugUtil.debug("found Topkapi")                    
						if ( (gc.getTeam(ppPlayer.getTeam()).isHasMet(iTeam)) and (ppPlayer.isAlive()==true) and (ppPlayer.isBarbarian()==false) ):
							BugUtil.debug("found Topkapi")                        
							civ_type = gc.getPlayer(iPlayer).getCivilizationType()
							for iUnit in range(gc.getNumUnitClassInfos()):
								iUniqueUnit = gc.getCivilizationInfo(civ_type).getCivilizationUnits(iUnit);
								iDefaultUnit = gc.getUnitClassInfo(iUnit).getDefaultUnitIndex();
								if (iDefaultUnit > -1 and iUniqueUnit > -1 and iDefaultUnit != iUniqueUnit):
									BugUtil.debug("found Topkapi")                                
									if ( iUnitType == iDefaultUnit ):
										BugUtil.debug("found Topkapi")                                    
										l_vassalUB.append(iUniqueUnit)
				if ( len(l_vassalUB) >= 1 ):
					BugUtil.debug("found Topkapi")                
					self.iVassalUUChance = self.getRandomNumber( 4 )
					if self.iVassalUUChance == 0:
						chance = CyGame().getSorenRandNum(len(l_vassalUB), "Random for UB")
						iX = pUnit.getX()
						iY = pUnit.getY()
						pNewUnit = pPlayer.initUnit( l_vassalUB[chance], iX, iY, UnitAITypes.NO_UNITAI, DirectionTypes.NO_DIRECTION )
						pNewUnit.convert(pUnit)


## Topkapi Palace End ##

Is that right?
 
Yes, but typically you want to put in a message that makes sense for where you are in the code. For example:

  • Found building
  • Found building in city
  • Checking player X
etc. You can build messages from variables using standard Python notation

Code:
BugUtil.debug("Checking player " + iPlayer)

inside the for() loop. You can look at the BUG code using your editor's find in files to find places that make more advanced usage of BugUtil.debug(), but for now the above should be sufficient.

The important thing is that all these messages will be dumped out to the log. You will not be able to make sense of this:

Code:
found Topkapi
found Topkapi
found Topkapi
found Topkapi
found Topkapi
found Topkapi
found Topkapi
found Topkapi
found Topkapi
found Topkapi

:lol: Better to see something like this

Code:
building is not obsolete
found building in a city
getting UUs for player 0
...
getting UUs for player 1
...

But what I'm looking for first is that your function is being called at all. Without that, the rest is moot. Look for your module and function name in the logs. You should see BugEventManager saying that it's calling your function for the unitBuilt event.
 
Alright, I'll try this out again if I have time before I go to work this morning.

Just to make sure, this has to be set to 1, correct?

Code:
	<Define>
		<DefineName>USE_ON_UNIT_CREATED_CALLBACK</DefineName>
		<iDefineIntVal>1</iDefineIntVal>
	</Define>
 
Then it looks like your code isn't getting past this line:

Code:
		if ( gc.getTeam(pPlayer.getTeam()).isHasTech(obsoleteTech) == false or obsoleteTech == -1 ):

I would comment that part out, remove the if statement so it always loops through the cities, and then add the debug message creation inside the loop where its setting topkapi to true.

If that works, then you need to look into the above if statement to see why it's not functioning correctly.
 
I don't see that your event handler was registered in the log. Make sure you have a configuration XML file, it uses <event> or <events>, and that file is loaded by init.xml. Before you try to fix your code you need to make sure you code is even being run by BUG.
 
I don't see that your event handler was registered in the log. Make sure you have a configuration XML file, it uses <event> or <events>, and that file is loaded by init.xml. Before you try to fix your code you need to make sure you code is even being run by BUG.

I'm an idiot...

I think this is the problem:

Code:
class DiplomacyEventManager:
	def __init__(self, eventManager):
		eventManager.addEventHandler("GameStart", self.onGameStart)
		eventManager.addEventHandler("OnLoad", self.onLoadGame)
		eventManager.addEventHandler("GameStart", self.onGameStart)
		eventManager.addEventHandler("BeginGameTurn", self.onBeginGameTurn)
		eventManager.addEventHandler("combatResult", self.onCombatResult)        
		eventManager.addEventHandler("cityRazed", self.onCityRazed)
		eventManager.addEventHandler("cityAcquired", self.onCityAcquired)        
		eventManager.addEventHandler("cityAcquiredAndKept", self.onCityAcquiredAndKept)        
		eventManager.addEventHandler("cityDoTurn", self.onCityDoTurn)
		eventManager.addEventHandler("unitBuilt", [COLOR="Red"]self.onCityDoTurn[/COLOR])        
		eventManager.addEventHandler("buildingBuilt", self.onBuildingBuilt)

Right?

EDIT: Which probably also explains why it kept referencing an error in that line 239.
 
Man, I feel like a complete idiot right now. I have been going on and on about this in two different threads and it was such a simple mistake. It definitely works now:

attachment.php

But I suppose I have another question while I've started this thread. It is sort of out-of-nowhere when the unit is created. Is there any way I could get an alert that says something to the effect of "The Ludus/Flavian Amphitheatre in [Madrid] has trained a [Holkan] [Spearman]!" ?
 

Attachments

  • SpanishHolkan.jpg
    SpanishHolkan.jpg
    71.8 KB · Views: 1,095
Sure, lookup CyInterface().addMessage() in the Python API. Contrib/Civ4lerts has examples on using it. You can give it a tile x/y location and an icon that shows in the little pointer flag on the map. You can give it a sound, too.
 
Sure, lookup CyInterface().addMessage() in the Python API. Contrib/Civ4lerts has examples on using it. You can give it a tile x/y location and an icon that shows in the little pointer flag on the map. You can give it a sound, too.

So you are saying I could have that little circle with the arrow thing show up (showing the icon of the unit made I guess) and have an alert with the Colosseum sound playing?

Cool. Now what is the Python API?
 
So you are saying I could have that little circle with the arrow thing show up (showing the icon of the unit made I guess) and have an alert with the Colosseum sound playing?

Cool. Now what is the Python API?

If I understand right what you mean, yes you can.
This is the Python API. It has (nearly) all possible python calls you can use.
 
That's why I suggested looking at the top of BUG's Civ4lerts.py module. It uses the very call I pointed out and has a few examples of its use.
 
That's why I suggested looking at the top of BUG's Civ4lerts.py module. It uses the very call I pointed out and has a few examples of its use.

Alright, I'm checking it out right now.

So I'll just take a random example from it:

Code:
	def _getPendingAlertMessageIcon(self, city, passes):
		if (passes):
			BugUtil.warn("%s passed pending occupation test, ignoring", city.getName())
			return (None, None)
		else:
			return (localText.getText("TXT_KEY_CIV4LERTS_ON_CITY_PENDING_PACIFIED", (city.getName(), )),
					HAPPY_ICON)

This is basically saying that this city will be pacified on the next turn. Right?

So how do I get an alert to show up for a unit being created with the wonder? I can't really see how this works.
 
That is just getting the message and icon to be used for a particular alert. Look near the top of the file where there are four functions like addMessageNoIcon() and addMessageIcon() or something similar. Better, search for "CyInterface().addMessage" since that's what those functions will call.
 
Back
Top Bottom