Simple Python Things

I haven't tested the code yet, would this code work?

Nope, will not.

The problem is here:
PHP:
        for iLoopPlayer in range(gc.getMAX_CIV_PLAYERS()):
            LoopPlayerTeam = gc.getTeam(iLoopPlayer)

You're looping here over the players. So, with the max players, the loop goes normally from 0 to 17.
But then you're getting team instances. So first, you try to get team #0, then team #1, till team #17. But again, what if you have an alliance? Then there's no team #17.
You're looping over players, not over the teams. You can't just drag teams out of this loop, this doesn't make that much sense ;).
Just imagine: Player 1 and player 2 are in an alliance.
You loop over the players, you have the ID 1, and you say gc.getTeam(1), okay, that's fine. Player #1 is in team #1. But then, next round, with the ID 2, you say gc.getTeam(2)...wait...no...that is still team #1, but you have player #2. Player #2 is not in team #2, so using this command is logically wrong.
Same for your assignments of playerTeam and rivalTeam: You have player IDs, they are not necessarily the same as team IDs.

Right would be:
PHP:
        for iLoopPlayer in range(gc.getMAX_CIV_PLAYERS()):
            LoopPlayer = gc.getPlayer(iLoopPlayer)
            if LoopPlayer.getTeam() == iTeam or LoopPlayer.getTeam() == iRivalTeam:

This loops over the players, gets first the right player instances, and then compares their team ID to the given IDs.
That should work (hopefully, because i can't test it right now).
 
Thanks a lot :)
And another question.
Is it possible to check a plot to see if there's a bonus present?
I found this, but I doubt this is correct:
PHP:
if (pPlot.getBonusType(-1) != -1 ): ## more code...
The argument of getBonusType is TeamType, and -1 would mean no team.
Any ideas?
 
No, the whole thing is correct :).
If you give the function a team ID, the check will also only reveal to you what the team sees. e.g. there's a plot with uranium, and you give the function the team ID of a team which doesn't have physics, then it will appear as if there was no uranium (because the team can't see it).
If you check it with -1, then these restrictions do not apply.
So if you want to know if there's any resource on a plot, then this check you wrote there is correct.
 
Hello TJ,

A strange error is occuring in my mod A New Dawn with the Respawn-promo in onCombatResult(). I've never had this before.
Please take a look here. If you need additional info, please let me know. Thanks in advance :)
Here's the code:
PHP:
###respawn part 1 start###

		pPlayer = gc.getPlayer(pLoser.getOwner())
		pPID = pPlayer.getID()
		promotion = []
		promotion.append(gc.getInfoTypeForString('PROMOTION_LIVE2'))
		promotion.append(gc.getInfoTypeForString('PROMOTION_LIVE1'))
		
		if ((pLoser.isHasPromotion(gc.getInfoTypeForString('PROMOTION_LIVE1')))or(pLoser.isHasPromotion(gc.getInfoTypeForString('PROMOTION_LIVE2')))):
			iUnit = pLoser.getUnitType()                  
			pCity= pPlayer.getCapitalCity()
			iX =pCity.getX()
			iY = pCity.getY()
			if pLoser.getDomainType ()==gc.getInfoTypeForString('DOMAIN_SEA'):
				for iCity in range(pPlayer.getNumCities () ):
					ppCity = pPlayer.getCity(iCity)
					if ppCity.isNone():continue
					if ppCity.getOwner()<>pPID:continue
					pPlot = CyMap().plot(ppCity.getX(),ppCity.getY())
					if pPlot.isCoastalLand ():
						iX = ppCity.getX()
						iY = ppCity.getY()
						break                                

			newUnit = pPlayer.initUnit(iUnit, iX,iY, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_NORTH) ## CAUSES 'UNIDENTIFIABLE C++ ERROR' ###
			pLoser.setDamage(0, False)
			newUnit.convert(pLoser)
				
			newUnit.finishMoves()
			counter=0
			CyInterface().addMessage(pPID,false,15,CyTranslator().getText("TXT_KEY_REBORN",()),'',0,'Art/Interface/Buttons/Phoenix.dds',ColorTypes(44), iX, iY, True,True)
			for i in range(2):                                
				counter=counter+1
				newUnit.setHasPromotion(promotion[i], False)                                                
			for i in range(2):
				if pLoser.isHasPromotion(promotion[i]):
					if i==1:
						break
					newUnit.setHasPromotion(promotion[i+1], True)
			pLoser.setDamage(100, False)
###respawn part 1 end###
 
Okay, let's see:
- First, how did you merge the code? Did you adjust the python files to fit the BUG way of adding them? (can't download the mod, this PC has only 1 GB HDD space left)
- Sure that it is the initUnit line?
- I think i tested it, but i'm not sure anymore what happens if there's no capital left (because of...er..dead player, or other things). Maybe testwise adding
PHP:
if not pCity:return
after pCity= pPlayer.getCapitalCity() might help.

edit: And got your PM.
 
Okay, let's see:
1. First, how did you merge the code? Did you adjust the python files to fit the BUG way of adding them? (can't download the mod, this PC has only 1 GB HDD space left)
2. Sure that it is the initUnit line?
3. I think i tested it, but i'm not sure anymore what happens if there's no capital left (because of...er..dead player, or other things). Maybe testwise adding
PHP:
if not pCity:return
after pCity= pPlayer.getCapitalCity() might help.

edit: And got your PM.
This is the entire code block:
PHP:
	def onCombatResult(self, argsList):
		'Combat Result'
		pWinner,pLoser = argsList
		playerX = PyPlayer(pWinner.getOwner())
		unitX = PyInfo.UnitInfo(pWinner.getUnitType())
		playerY = PyPlayer(pLoser.getOwner())
		unitY = PyInfo.UnitInfo(pLoser.getUnitType())

###respawn part 1 start###

		pPlayer = gc.getPlayer(pLoser.getOwner())
		pPID = pPlayer.getID()
		promotion = []
		promotion.append(gc.getInfoTypeForString('PROMOTION_LIVE2'))
		promotion.append(gc.getInfoTypeForString('PROMOTION_LIVE1'))
		
		if ((pLoser.isHasPromotion(gc.getInfoTypeForString('PROMOTION_LIVE1')))or(pLoser.isHasPromotion(gc.getInfoTypeForString('PROMOTION_LIVE2')))):
			iUnit = pLoser.getUnitType()                  
			pCity= pPlayer.getCapitalCity()
			iX = pCity.getX()
			iY = pCity.getY()
			if pLoser.getDomainType ()==gc.getInfoTypeForString('DOMAIN_SEA'):
				for iCity in range(pPlayer.getNumCities () ):
					ppCity = pPlayer.getCity(iCity)
					if ppCity.isNone():continue
					if ppCity.getOwner()<>pPID:continue
					pPlot = CyMap().plot(ppCity.getX(),ppCity.getY())
					if pPlot.isCoastalLand ():
						iX = ppCity.getX()
						iY = ppCity.getY()
						break                                

			newUnit = pPlayer.initUnit(iUnit, iX,iY, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_NORTH)
			pLoser.setDamage(0, False)
			newUnit.convert(pLoser)
				
			newUnit.finishMoves()
			counter=0
			CyInterface().addMessage(pPID,false,15,CyTranslator().getText("TXT_KEY_REBORN",()),'',0,'Art/Interface/Buttons/Phoenix.dds',ColorTypes(44), iX, iY, True,True)
			for i in range(2):                                
				counter=counter+1
				newUnit.setHasPromotion(promotion[i], False)                                                
			for i in range(2):
				if pLoser.isHasPromotion(promotion[i]):
					if i==1:
						break
					newUnit.setHasPromotion(promotion[i+1], True)
			pLoser.setDamage(100, False)
###respawn part 1 end###

###more code###

		if (not self.__LOG_COMBAT):
			return
		if playerX and playerX and unitX and playerY:
			CvUtil.pyPrint('Player %d Civilization %s Unit %s has defeated Player %d Civilization %s Unit %s' 
				%(playerX.getID(), playerX.getCivilizationName(), unitX.getDescription(), 
				playerY.getID(), playerY.getCivilizationName(), unitY.getDescription()))
1. I never had this error before. I added 'Field Medic' and 'Trafalgar Square' in the same block and they seem to work correct.
2. 100% sure.
3. I'll try that. *** EDIT: DID NOT WORK ***
 
Did you check if the other 2 parts ('Field Medic' and 'Trafalgar Square') are really working, so did you observe an effect? Not, that there's just not yet been the occassion of the bug.

And i see you didn't merge it in the BUG way, so you let the code stay in the CvEventManager.py, right? That can AFAIK cause that type of bug. You should really take a look how to merge it here right (tutorial; i know you can do it ;)).
 
Did you check if the other 2 parts ('Field Medic' and 'Trafalgar Square') are really working, so did you observe an effect? Not, that there's just not yet been the occassion of the bug.

And i see you didn't merge it in the BUG way, so you let the code stay in the CvEventManager.py, right? That can AFAIK cause that type of bug. You should really take a look how to merge it here right (tutorial; i know you can do it ;)).
Trafalgar Square works fine. Didn't test Field Medic, but I suppose it's working correctly as I never had an error related to it (but that's no guarantee :p)
Anyway thanks, I'll have a look.

EDIT: attached CvEventManager.py
 

Attachments

Here's a question:

What happens if the unit was a sea domain unit but the owning player doesn't have a coastal city anymore?

There may be an issue with trying to spawn a ship in a non-coastal capital.
 
Might be, but i can't really see a reason why :dunno:.
Maybe the automatic unit ai :think:?
But that could easily be fixed by adding an "else: return" after the loop block.

Trafalgar Square works fine. Didn't test Field Medic, but I suppose it's working correctly as I never had an error related to it (but that's no guarantee :p)
Anyway thanks, I'll have a look.

EDIT: attached CvEventManager.py

Looks itself okay :dunno:.
But not correclty merged into BUG, like said above, and i'd definitively say you should have a look on how to do it right.
 
Here's a question:

What happens if the unit was a sea domain unit but the owning player doesn't have a coastal city anymore?

There may be an issue with trying to spawn a ship in a non-coastal capital.
The error occured on a Great Plains map, no ocean present.
Another possibility is that this:

iUnit = pLoser.getUnitType()

returns -1, causing the error with 'initUnit'.

But not correclty merged into BUG, like said above, and i'd definitively say you should have a look on how to do it right.
Well, I did but haven't yet figured out how to do it :(
 
The error occured on a Great Plains map, no ocean present.
Another possibility is that this:

iUnit = pLoser.getUnitType()

returns -1, causing the error with 'initUnit'.

I don't think you can have a unit without unit type (NOT unit combat).

Well, I did but haven't yet figured out how to do it :(

Dummy explanation:
- Take the whole def onCombatResult (without everything after "if (not self.__LOG_COMBAT):")
- Put that code into a single .py file (name it whatever you like)
- Put on the top of the .py file the following:
PHP:
from CvPythonExtensions import *
import BugUtil
gc = CyGlobalContext()
- Put that .py file into your mods Python\Contrib folder
- Remove the "self" from the def onCombatResult(self, argsList): line.
- Put every line one backspace/tab back
- Create an XML file in your mods Assets\config folder
- Name of the XML file = exactly the same as the python file
- content of the XML file
PHP:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!--
    blablablaSomeComment
-->
<mod id="PutHereNameOfThePythonFileWithoutPyEnding" module="PutHereNameOfThePythonFileWithoutPyEnding">
    <event type="combatResult" function="onCombatResult"/>
</mod>
- add to config\init.xml at the end
PHP:
<load mod="PutHereNameOfThePythonFileWithoutPyEnding"/>

I remember from the BUG description that not everything has to be exactly like that (especially names), but this is the very easy description, which i use myself when i don't have the time to think about it and to test it.
 
I don't think you can have a unit without unit type (NOT unit combat).



Dummy explanation:
- Take the whole def onCombatResult (without everything after "if (not self.__LOG_COMBAT):")
- Put that code into a single .py file (name it whatever you like)
- Put on the top of the .py file the following:
PHP:
from CvPythonExtensions import *
import BugUtil
gc = CyGlobalContext()
- Put that .py file into your mods Python\Contrib folder
- Remove the "self" from the def onCombatResult(self, argsList): line.
- Put every line one backspace/tab back
- Create an XML file in your mods Assets\config folder
- Name of the XML file = exactly the same as the python file
- content of the XML file
PHP:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!--
    blablablaSomeComment
-->
<mod id="PutHereNameOfThePythonFileWithoutPyEnding" module="PutHereNameOfThePythonFileWithoutPyEnding">
    <event type="combatResult" function="onCombatResult"/>
</mod>
- add to config\init.xml at the end
PHP:
<load mod="PutHereNameOfThePythonFileWithoutPyEnding"/>

I remember from the BUG description that not everything has to be exactly like that (especially names), but this is the very easy description, which i use myself when i don't have the time to think about it and to test it.

@Arian:

Best thing to do is take a look at the C2C mod for using all kinds of BUG extra content, that is why i asked you if you were changing the CvEventManager, cause it does cause problems with the BUG mod.
 
I think I solved the Respawn-bug, I hope.
I tested some Barbs with Respawn-promos and the ''Unidentifiable C++ error" showed up. Did some recoding and this code works fine (I tested this with some Barbs with Respawn-promos):
PHP:
###respawn part 1 start###

		pPlayer = gc.getPlayer(pLoser.getOwner())
		pPID = pPlayer.getID()
		promotion = []
		promotion.append(gc.getInfoTypeForString('PROMOTION_LIVE2'))
		promotion.append(gc.getInfoTypeForString('PROMOTION_LIVE1'))
		
		if ((pLoser.isHasPromotion(gc.getInfoTypeForString('PROMOTION_LIVE1')))or(pLoser.isHasPromotion(gc.getInfoTypeForString('PROMOTION_LIVE2')))):
			iUnit = pLoser.getUnitType()
			if iUnit == -1: return
			pCity = pPlayer.getCapitalCity()
			if pCity:
				if pPlayer.isBarbarian() == false:
					iX = pCity.getX()
					iY = pCity.getY()
					if pLoser.getDomainType ()==gc.getInfoTypeForString('DOMAIN_SEA'):
						for iCity in range(pPlayer.getNumCities () ):
							ppCity = pPlayer.getCity(iCity)
							if ppCity.isNone():continue
							if ppCity.getOwner()<>pPID:continue
							pPlot = CyMap().plot(ppCity.getX(),ppCity.getY())
							if pPlot.isCoastalLand ():
								iX = ppCity.getX()
								iY = ppCity.getY()
								break                                

					newUnit = pPlayer.initUnit(iUnit, iX,iY, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_NORTH)
					pLoser.setDamage(0, False)
					newUnit.convert(pLoser)
					
					newUnit.finishMoves()
					counter=0
					CyInterface().addMessage(pPID,false,15,CyTranslator().getText("TXT_KEY_REBORN",()),'',0,'Art/Interface/Buttons/Phoenix.dds',ColorTypes(44), iX, iY, True,True)
					for i in range(2):                                
						counter=counter+1
						newUnit.setHasPromotion(promotion[i], False)                                                
					for i in range(2):
						if pLoser.isHasPromotion(promotion[i]):
							if i==1:
								break
							newUnit.setHasPromotion(promotion[i+1], True)
					pLoser.setDamage(100, False)
###respawn part 1 end###
I hope you find this useful.
 
this is referring to the Circus Hagenbeck you did

platyping and I are looking into adding the Olympics to my TTT - MA mod, and we want to do something similar to this. One thing i was wondering is how did you get it to do 1890 on the dot? did you do it by number of turns? or by the actual year? Also does it go international?
 
One thing i was wondering is how did you get it to do 1890 on the dot? did you do it by number of turns? or by the actual year?

The first code line shows it directly ;):
PHP:
if (CyGame().getTurnYear(iGameTurn)>=1890)

But you shouldn't use an exact check for the year ( == ), because whatever date you choose might not actually appear ingame.
(edit: That advice doesn't really make sense here, since the effect should appear later than 1890, not exactly at that date)

Also does it go international?

Yes :yup:, goes international, but could sure also be restricted to only one nation.
 
The first code line shows it directly ;):
PHP:
if (CyGame().getTurnYear(iGameTurn)>=1890)

But you shouldn't use an exact check for the year ( == ), because whatever date you choose might not actually appear ingame.
(edit: That advice doesn't really make sense here, since the effect should appear later than 1890, not exactly at that date)
It would be for my modern mod, and since it starts at 1900, we would just put it at 1900, so that would work perfectly im sure

Yes :yup:, goes international, but could sure also be restricted to only one nation.
We want it international:goodjob:

We were thinking of ways to do this for a while and this fits what we wanted almost exactly (beside the benefits it provides of course). To avoid platyping from having to spend time on it i (who has no expirience w/ python) will attempt to do it. The benefits i could edit via xml no problem, but theres two things i need help with. Is there a way it sends an alert saying "The olympics have been chosen to be in CITY this year" to all players? Also a way that it adds free building classes to just that city. Also it would trigger golden age which ik how to do, but anyway almost a mini golden age for jsut that city? More happiness gold hammer etc for just 10 turns?
 
Back
Top Bottom