Tsentom1 Python Wonders

Sounds easy. I think I got it from here. Thanks for all your help.
 
Hi tsentom1,

I am having trouble getting the King Richard's Crusade wonder to work. I have added the Crusade Unit and the Python code to CvEventManager.py. However, the event just never seems to fire. I don't see anything in the logs and the Crusader unit never gets created. Any hints on how I might be mucking this up?

Cheers,
ripple01

Hi Ripple01

Just thought I's let you know that I've successfully merged King Richards Crusade into my own version of Hisytory in the making and it works like a charm so it must be something you're either doing wrong or some kind of conflict.

\Skodkim
 
I'll have you know, tsentom1, that the rush for the School of Confucius in my game has become a tactic on the level of the Liberalism race, Oracle, the Great Library, and the Pyramids.

And it's not because I think it is a broken wonder. Without a double production resource, you have to invest a significant amount of time to build it. It's just such a cool effect, and it comes at a reasonable tradeoff, like the Pyramids.

So, I'm posting another thanks for the wonder. You have an eye for filling in the gaps and adding content without making it overbearing.
 
I'll have you know, tsentom1, that the rush for the School of Confucius in my game has become a tactic on the level of the Liberalism race, Oracle, the Great Library, and the Pyramids.

And it's not because I think it is a broken wonder. Without a double production resource, you have to invest a significant amount of time to build it. It's just such a cool effect, and it comes at a reasonable tradeoff, like the Pyramids.

So, I'm posting another thanks for the wonder. You have an eye for filling in the gaps and adding content without making it overbearing.

Thanks, I'm glad to hear it. The School of Confucius, being the first wonder I released here, in particular has gone through quite a few balance edits so I'm glad it's reached a point where it nicely fits into your game.
 
I updated Trafalgar Square

I added additional code that now displays a message informing you of how much gold you've plundered and if you've captured an enemy ship.
 
Tom, as always great work.

I tried out the code for the trafalger square (I was looking to incorproate the Comendeer code for one of the "Heros"). Anyway, the message that tells you, you captured a ship fires whether you capture one or not.

Ah thanks, I probably left a typo in when I was testing to see if the message worked at all (so I set it to always fire). I'll fix it in a bit. Sorry about that.
 
Tom, as always great work.

I tried out the code for the trafalger square (I was looking to incorproate the Comendeer code for one of the "Heros"). Anyway, the message that tells you, you captured a ship fires whether you capture one or not.

Yeah I see what I did, I was testing if the message worked itself so it currently is:

Code:
						self.iNewPrivateerNumber = self.getRandomNumber( 4 )

						if self.iNewPrivateerNumber == 0:

							iPrivateer = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'UNIT_PRIVATEER')
							pClearPlot = self.findClearPlot(pLoser)

							if (pLoser.plot().getNumUnits() == 1 and pClearPlot != -1):
								pPlot = pLoser.plot()
								pLoser.setXY(pClearPlot.getX(), pClearPlot.getY(), false, true, true)
							else:
								pPlot = pWinner.plot()

							newUnit = pPlayer.initUnit(iPrivateer, pPlot.getX(), pPlot.getY(), UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_NORTH)
							pLoser.setDamage(75, False)
							newUnit.convert(pLoser)
							pLoser.setDamage(100, False)
							newUnit.finishMoves()

						iXa = pLoser.getX()
						iYa = pLoser.getY()

						CyInterface().addMessage(pPID,false,15,CyTranslator().getText("TXT_KEY_TRAFALGAR_CAPTURE_SUCCESS",()),'',0,',Art/Interface/Buttons/Units/ICBM.dds,Art/Interface/Buttons/Beyond_the_Sword_Atlas.dds,8,11',ColorTypes(44), iXa, iYa, True,True)

Where it should be:

Code:
						if self.iNewPrivateerNumber == 0:

							iPrivateer = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'UNIT_PRIVATEER')
							pClearPlot = self.findClearPlot(pLoser)

							if (pLoser.plot().getNumUnits() == 1 and pClearPlot != -1):
								pPlot = pLoser.plot()
								pLoser.setXY(pClearPlot.getX(), pClearPlot.getY(), false, true, true)
							else:
								pPlot = pWinner.plot()

							newUnit = pPlayer.initUnit(iPrivateer, pPlot.getX(), pPlot.getY(), UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_NORTH)
							pLoser.setDamage(75, False)
							newUnit.convert(pLoser)
							pLoser.setDamage(100, False)
							newUnit.finishMoves()
[B]
							iXa = pLoser.getX()
							iYa = pLoser.getY()

							CyInterface().addMessage(pPID,false,15,CyTranslator().getText("TXT_KEY_TRAFALGAR_CAPTURE_SUCCESS",()),'',0,',Art/Interface/Buttons/Units/ICBM.dds,Art/Interface/Buttons/Beyond_the_Sword_Atlas.dds,8,11',ColorTypes(44), iXa, iYa, True,True)[/B]

The last three lines just need to be indented (TAB) onced each. Anyway, I updated the download.
 
Tom, as always great work.

I tried out the code for the trafalger square (I was looking to incorproate the Comendeer code for one of the "Heros"). Anyway, the message that tells you, you captured a ship fires whether you capture one or not.

Currently it's set to give you a privateer when you capture a ship. It's a simple change of one line if you want the captured ship to be the same unit class instead of always a privateer.

Code:
				iPrivateer = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'UNIT_PRIVATEER')
				pClearPlot = self.findClearPlot(pLoser)

Is what's currently there (after the get random number stuff which determines the chance). Just change it to:

Code:
				iPrivateer = pLoser.getUnitType()
				pClearPlot = self.findClearPlot(pLoser)

In case you were looking for this as the ability instead of always the privateer.
 
Thanks for the heads up. I have been expirimenting with Python since I came back from my Civ Sabatical.

My biggest issure right now is removing the building requirement. Ideally I would like: If Owner has Unit A, you get Unit B 20% chance.

Basically the same thing as the wonder only its unit specific instead of building specific.
 
Thanks for the heads up. I have been expirimenting with Python since I came back from my Civ Sabatical.

My biggest issure right now is removing the building requirement. Ideally I would like: If Owner has Unit A, you get Unit B 20% chance.

Basically the same thing as the wonder only its unit specific instead of building specific.

Oh that's easy, I actually originally wrote the code for JustATourist who wanted it to always fire for Privateers. I only adapted it in wonder form after to release here.

Anyway:

This is the edit to the onCombatResult Section (the bold I explain at the end):
Spoiler :

Code:
	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())


## Privateer Edit Start ##

		if pWinner.getUnitClassType() == gc.getInfoTypeForString('UNITCLASS_PRIVATEER'):

			pPlayer = gc.getPlayer(pWinner.getOwner())

			[B]iGold = playerY.getGold( )
			iGoldStolen = ( iGold//50 )
			message = 0

			if playerY.getGold( ) >= 2500:
				playerY.changeGold( -50 )
			elif playerY.getGold( ) >= 100:
				playerY.changeGold( -iGoldStolen )
			elif (playerY.getGold( ) >= 2) and (playerY.getGold( ) < 100):
				playerY.changeGold( -2 )

			iGold2 = playerX.getGold( )
			if playerY.getGold( ) >= 2500:
				playerX.changeGold( +50 )
				message = 1
			elif playerY.getGold( ) >= 100:
				playerX.changeGold( +iGoldStolen )
				message = 2
			else:
				playerX.changeGold( +2 )
				message = 3
[/B]


			pPID = pPlayer.getID()
[B]			iX = pWinner.getX()
			iY = pWinner.getY()
			szName = pPlayer.getName()[/B]

[B]			## This only controls the text, all actual gold amounts are done above:
			iGoldStolenMax = ( 2500//50 )
			iGoldStolenMin = ( 100//50 )

			if ( message == 1 ):
				CyInterface().addMessage(pPID,false,15,CyTranslator().getText("TXT_KEY_TRAFALGAR_GOLD1",(szName,iGoldStolenMax)),'',0,',Art/Interface/Buttons/TechTree/Banking.dds,Art/Interface/Buttons/TechTree_Atlas.dds,8,1',ColorTypes(44), iX, iY, True,True)
				### message: %s1 has plundered %d2 [ICON_GOLD]!###
			if ( message == 2 ):
				CyInterface().addMessage(pPID,false,15,CyTranslator().getText("TXT_KEY_TRAFALGAR_GOLD2",(szName,iGoldStolen)),'',0,',Art/Interface/Buttons/TechTree/Banking.dds,Art/Interface/Buttons/TechTree_Atlas.dds,8,1',ColorTypes(44), iX, iY, True,True)
				### message: %s1 has plundered %d2 [ICON_GOLD]!###
			if ( message == 3 ):
				CyInterface().addMessage(pPID,false,15,CyTranslator().getText("TXT_KEY_TRAFALGAR_GOLD3",(szName,iGoldStolenMin)),'',0,',Art/Interface/Buttons/TechTree/Banking.dds,Art/Interface/Buttons/TechTree_Atlas.dds,8,1',ColorTypes(44), iX, iY, True,True)
				### message: %s1 has plundered %d2 [ICON_GOLD]!###[/B]



			self.iNewPrivateerNumber = self.getRandomNumber( 9 )

			if self.iNewPrivateerNumber == 0:

				iPrivateer = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'UNIT_PRIVATEER')
				pClearPlot = self.findClearPlot(pLoser)

				if (pLoser.plot().getNumUnits() == 1 and pClearPlot != -1):
					pPlot = pLoser.plot()
					pLoser.setXY(pClearPlot.getX(), pClearPlot.getY(), false, true, true)
				else:
					pPlot = pWinner.plot()

				newUnit = pPlayer.initUnit(iPrivateer, pPlot.getX(), pPlot.getY(), UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_NORTH)
				pLoser.setDamage(75, False)
				newUnit.convert(pLoser)
				pLoser.setDamage(100, False)
				newUnit.finishMoves()

				iXa = pLoser.getX()
				iYa = pLoser.getY()

				CyInterface().addMessage(pPID,false,15,CyTranslator().getText("TXT_KEY_TRAFALGAR_CAPTURE_SUCCESS",()),'',0,',Art/Interface/Buttons/Units/ICBM.dds,Art/Interface/Buttons/Beyond_the_Sword_Atlas.dds,8,11',ColorTypes(44), iXa, iYa, True,True)

## Privateer Edit End ##

		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()))

This just goes at the very end of the EventManager:

Spoiler :
Code:
## Privateer Edit Start ##

    def findClearPlot(self, pUnit):
        BestPlot = -1
        iBestPlot = 0
        pOldPlot = pUnit.plot()
        iX = pOldPlot.getX()
        iY = pOldPlot.getY()
        for iiX in range(iX-1, iX+2, 1):
            for iiY in range(iY-1, iY+2, 1):
                iCurrentPlot = 0
                pPlot = CyMap().plot(iiX,iiY)
                if pPlot.getNumUnits() == 0:
                    iCurrentPlot = iCurrentPlot + 5
                if iCurrentPlot >= 1:
                    iCurrentPlot = iCurrentPlot + CyGame().getSorenRandNum(5, "findClearPlot")
                    if iCurrentPlot >= iBestPlot:
                        BestPlot = pPlot
                        iBestPlot = iCurrentPlot
        return BestPlot

    def getRandomNumber(self, int):
        return CyGame().getSorenRandNum(int, "Gods")

## Privateer Edit End ##

And these are the text files it calls in the python (the capture gold and ship messages):

Spoiler :
Code:
	<TEXT>
		<Tag>TXT_KEY_TRAFALGAR_GOLD1</Tag>
		<English>[COLOR_SELECTED_TEXT]%s1 has plundered %d2 [ICON_GOLD]![COLOR_REVERT]</English>
		<French>[COLOR_SELECTED_TEXT]%s1 has plundered %d2 [ICON_GOLD]![COLOR_REVERT]</French>
		<German>[COLOR_SELECTED_TEXT]%s1 has plundered %d2 [ICON_GOLD]![COLOR_REVERT]</German>
		<Italian>[COLOR_SELECTED_TEXT]%s1 has plundered %d2 [ICON_GOLD]![COLOR_REVERT]</Italian>
		<Spanish>[COLOR_SELECTED_TEXT]%s1 has plundered %d2 [ICON_GOLD]![COLOR_REVERT]</Spanish>
	</TEXT>
	<TEXT>
		<Tag>TXT_KEY_TRAFALGAR_GOLD2</Tag>
		<English>[COLOR_SELECTED_TEXT]%s1 has plundered %d2 [ICON_GOLD]![COLOR_REVERT]</English>
		<French>[COLOR_SELECTED_TEXT]%s1 has plundered %d2 [ICON_GOLD]![COLOR_REVERT]</French>
		<German>[COLOR_SELECTED_TEXT]%s1 has plundered %d2 [ICON_GOLD]![COLOR_REVERT]</German>
		<Italian>[COLOR_SELECTED_TEXT]%s1 has plundered %d2 [ICON_GOLD]![COLOR_REVERT]</Italian>
		<Spanish>[COLOR_SELECTED_TEXT]%s1 has plundered %d2 [ICON_GOLD]![COLOR_REVERT]</Spanish>
	</TEXT>
	<TEXT>
		<Tag>TXT_KEY_TRAFALGAR_GOLD3</Tag>
		<English>[COLOR_SELECTED_TEXT]%s1 has plundered %d2 [ICON_GOLD]![COLOR_REVERT]</English>
		<French>[COLOR_SELECTED_TEXT]%s1 has plundered %d2 [ICON_GOLD]![COLOR_REVERT]</French>
		<German>[COLOR_SELECTED_TEXT]%s1 has plundered %d2 [ICON_GOLD]![COLOR_REVERT]</German>
		<Italian>[COLOR_SELECTED_TEXT]%s1 has plundered %d2 [ICON_GOLD]![COLOR_REVERT]</Italian>
		<Spanish>[COLOR_SELECTED_TEXT]%s1 has plundered %d2 [ICON_GOLD]![COLOR_REVERT]</Spanish>
	</TEXT>
	<TEXT>
		<Tag>TXT_KEY_TRAFALGAR_CAPTURE_SUCCESS</Tag>
		<English>[COLOR_SELECTED_TEXT]You have captured an enemy vessel![COLOR_REVERT]</English>
		<French>[COLOR_SELECTED_TEXT]You have captured an enemy vessel![COLOR_REVERT]</French>
		<German>[COLOR_SELECTED_TEXT]You have captured an enemy vessel![COLOR_REVERT]</German>
		<Italian>[COLOR_SELECTED_TEXT]You have captured an enemy vessel![COLOR_REVERT]</Italian>
		<Spanish>[COLOR_SELECTED_TEXT]You have captured an enemy vessel![COLOR_REVERT]</Spanish>
	</TEXT>

Just replace that first edited line:

Code:
if pWinner.getUnitClassType() == gc.getInfoTypeForString('UNITCLASS_PRIVATEER'):

To the unit you are using and it will fire for that unit. Removing the bolded text will remove the capture gold function (which is basically the whole top except the two lines where I define PID and pPlayer--which of course if you remove you don't need the three Gold XML files, though still the last one).
 

The Lubyanka (KGB):


KGB2.jpg


A rather simple wonder (code wise), still I thought it was a cool effect.

The Lubyanka, a.k.a. the headquarters of the KGB, it basically functions as an 'evil' Taj Mahal where, once built, it will place all rival civs into anarchy. The length of anarchy is equal to half a golden age (so it scales with game speed). Spiritual leaders are immune to the effect (as are team mates / vassals). It also increases espionage throughout your empire by 20%.

XML, python, wonder movie: me (tsentom1)
Building: asioasioasio
 
Yay, another new wonder :).

I love the idea... A wonder that has a direct (negative) effect on your opponents... which results in making you come out stronger. There should be more of those!
 
Thanks everyone!

Yeah I sort of like the idea of negative wonders that hurt your opponents rather then helping you. I'm going to keep that thinking in mid for future wonders possibly.

Anyway, in regards to the KGB download I actually just updated it and added a line of code to take into account if a rival civ is in a Golden Age (as that was a situation I didn't think of when I wrote the code).

It's just adding a line:

if (not ppPlayer.isGoldenAge()):

Before the anarchy trigger, although I guess this is optional. Without it, it would cancel a rival's golden age if they were in one when the KGB triggers, so up to you if you want to include it.
 
Hey tsentom1,

Lets say one wanted to implement a handful of these mods into the base game. Have you posted any instructions on how to do so?
I'm assuming its really a matter of cruching out all the merges in all the files that come with each zipped wonder, right?
 
Hey tsentom1,

Lets say one wanted to implement a handful of these mods into the base game. Have you posted any instructions on how to do so?
I'm assuming its really a matter of cruching out all the merges in all the files that come with each zipped wonder, right?

Yeah, it's just merging all the files, and as such all the downloads only include the bare minimum files that need to be merged.

I wish I could make them modular, but the problem is half the python can't be made modular and I've found in the past making half the files modular while the other half aren't in a download confuses people more.

I tried to be consistent with where the changes are in the files. So all the python changes are labeled (usually searching for the mods name will find the changes, though the exact search 'word' is always listed in the downloads page). For the XML the changes for the most part are at the bottom of the file. The only exception is special XML files like the ones used for Troyes and Public Works where the new process could be in the middle.

Regardless, downloading the program called Winmerge can be an enormous help. Since I edited only base BTS files if you open and compare the modcomp's file with the same named file from standard BTS you'll be to see all the changes outright.

As always, if you're just adding them to the base game, and not a mod, it's not recommended to change base game files. Instead combine them with each other to make it one big mod.
 
Back
Top Bottom