Tsentom1 Python Promotions

I'm playtesting it now to see what happens. I can just see somebody attaching a Great General to a tank and letting all hell break lose on a weaker Civ to get this awesome unit...
 
I'm playtesting it now to see what happens. I can just see somebody attaching a Great General to a tank and letting all hell break lose on a weaker Civ to get this awesome unit...

Haha, but that's why you'll notice I didn't actually set Armor units to be able to receive the promotion (at least in the default download; you can do whatever you want), simply because tanks start with blitz.

Though, Skirmisher + Blitz + Commando does = Fun.
 
I didn't check that. I have made some adjustments (increased the survival and heal chances to 20%, for example).

I do have a recommendation for the Marauder promotion. Is there any way to add an announcement at the top of the screen that tells you how much gold your troops stole? For some reason, I think I am exceeding your 20 gold per unit theft cap.
 
I didn't check that. I have made some adjustments (increased the survival and heal chances to 20%, for example).

I do have a recommendation for the Marauder promotion. Is there any way to add an announcement at the top of the screen that tells you how much gold your troops stole? For some reason, I think I am exceeding your 20 gold per unit theft cap.

JustATourist also requested the gold stolen announcement and I'm working on it, but it's proving more difficult to code than I thought. But hopefully I'll have it figured out soon.

It shouldn't be possible to exceed the max but in all honesty I could have made a typo in the python (or more accurately a typo that would cause it to fire twice). I'll check it later tonight.

edit:


Just looking at the code, I don't have time to test it in game at the moment, if it is double firing you can probably change all the second "if"s to"elif"s in the gold section which would just act as a double check for the double fire. I'll of course take a closer look when I get time later.

Spoiler :
Code:
			if playerY.getGold( ) >= 500:
				playerY.changeGold( -20 )
			elif playerY.getGold( ) >= 25:
				playerY.changeGold( -iGoldStolen )
			elif (playerY.getGold( ) >= 1) and (playerY.getGold( ) < 25):
				playerY.changeGold( -1 )

			iGold2 = playerX.getGold( )
			if playerY.getGold( ) >= 500:
				playerX.changeGold( +20 )
			elif playerY.getGold( ) >= 25:
				playerX.changeGold( +iGoldStolen )
			else:
				playerX.changeGold( +1 )
 
You would think, with several semesters of programming and I don't know how many hours of MATLAB debugging, I would have caught that. That's definitely the reason why I got 44 gold out of a single battle.

I know the programming frustrations, though...currently, I'm struggling with getting events to trigger properly. I've done 23 and they work perfectly, but for some reason my last 3 are just utter failures. And don't get me started on my hackneyed attempts at Python. ;)
 
You would think, with several semesters of programming and I don't know how many hours of MATLAB debugging, I would have caught that. That's definitely the reason why I got 44 gold out of a single battle.

I know the programming frustrations, though...currently, I'm struggling with getting events to trigger properly. I've done 23 and they work perfectly, but for some reason my last 3 are just utter failures. And don't get me started on my hackneyed attempts at Python. ;)

Yeah, I should have caught it earlier as well. Blah, all the code just starts looking the same after a while :lol:

I updated the promotion's code in the download.
 
To my understanding, if your unit was "destroyed", the combat ends with your unit at 10% strength in the same tile, and the victorious unit stays put, with any experience gained from the combat.

EDIT: I should warn you this function operates on the defense, not offense.
 
To my understanding, if your unit was "destroyed", the combat ends with your unit at 10% strength in the same tile, and the victorious unit stays put, with any experience gained from the combat.

EDIT: I should warn you this function operates on the defense, not offense.

Thanks. That makes more sense to me now.
 
Yes, the survival promotion is sort of like the defensive version of withdrawal chance (since withdrawal only works if you are attacking).

Actually, it's completely independent of existing combat odds. Technically, if your unit is killed in combat then it rolls a die, if positive it re-creates the unit in the same spot. So it works as a second check after combat.

In the python:

self.iResistance = self.getRandomNumber( 9 )

Sets the chance of survival. 9 is a 10% chance since the game includes 0 in the random number. So making it call 4 instead of 9 would raise it to a 20% chance, calling 1 would be a 50% chance, etc.

pLoser.setDamage(90, False)

Sets how much damage the surviving unit has (so the survival chance and the surviving damage is completely independent of each other and can be set to anything you want). In the download I have it set to the surviving unit only having 10% health if it survives (90% damage). Using a 0 instead of a 90 would make the unit spawn with full life, etc.

I figured it was best to have it set to a low amount of suriving health. A) it makes sense. B) keep in mind that if you're defending a city it's still now a whole another unit to get through that wouldn' be there. C) even if the unit dies again, it will still then have the survival chance to re-survive a second time. This is kinda overpowered if you'd have to figth through all the units health again.
 
I bumped it up to 20% in my mod, and I'm considering 25%. Same with the Field Medic promo...if you are going to invest a large amount of XP into that promotion (you typically require at least 2 promotions to be able to select the new one) instead of taking +25% against a particular unit type or another base 10% combat strength, I figure it should have a decent chance of triggering.

You've also inspired me to create my own version of Encirclement from the Genghis Khan mod. Two additional first strike chances for mounted units. :D
 
If I was just updating my current (read: already merged) promotion so that I receive the message, what all do I have to do? I figure there is an XML entry and then something in python pointing to the message to be displayed...

EDIT: Never mind, it's pretty obvious when you look at the Python code what has changed. Thanks for the good commenting on the code! :)
 
If I was just updating my current (read: already merged) promotion so that I receive the message, what all do I have to do? I figure there is an XML entry and then something in python pointing to the message to be displayed...

EDIT: Never mind, it's pretty obvious when you look at the Python code what has changed. Thanks for the good commenting on the code! :)

Actually, well, its not as well commented as it could be as there are three lines in the old code that I had to add and can be easily missed (namely all the lines that are message = 0, message = 1, etc). Besides that it's everything under playerX.changeGold( +1 ).

Anyway, whatever is in bold below were the changes:

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

		if pWinner.isHasPromotion(gc.getInfoTypeForString('PROMOTION_MARAUDER')):

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

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

			iGoldStolen = ( iGold//25 )

			if playerY.getGold( ) >= 500:
				playerY.changeGold( -20 )
			elif playerY.getGold( ) >= 25:
				playerY.changeGold( -iGoldStolen )
			elif (playerY.getGold( ) >= 1) and (playerY.getGold( ) < 25):
				playerY.changeGold( -1 )

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

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

			## This only controls the text, all actual gold amounts are done above:
			iGoldStolenMax = ( 500//25 )
			iGoldStolenMin = ( 25//25 )

			if ( message == 1 ):
				CyInterface().addMessage(pPID,false,15,CyTranslator().getText("TXT_KEY_MARAUDER_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_MARAUDER_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_MARAUDER_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]

The xml are the three ones added to the bottom of the file. They have names like Gold1, Gold2, Gold3.
 
Good, I got the message lines added as well. Thanks for the update--you are one of the wizards of Python on this forum. :)
 
I'm not sure I've really understood how the code works. So if:

"self.iResistance = self.getRandomNumber( 9 )
Sets the chance of survival. 9 is a 10% chance since the game includes 0 in the random number. So making it call 4 instead of 9 would raise it to a 20% chance, calling 1 would be a 50% chance, etc."

Why 4 set a 20% chance? How these accounts works?
And what value should be set to determine a 25% chance of survival, or a 35%, or a 70% chance, for example?
 
I'm not sure I've really understood how the code works. So if:

"self.iResistance = self.getRandomNumber( 9 )
Sets the chance of survival. 9 is a 10% chance since the game includes 0 in the random number. So making it call 4 instead of 9 would raise it to a 20% chance, calling 1 would be a 50% chance, etc."

Why 4 set a 20% chance? How these accounts works?
And what value should be set to determine a 25% chance of survival, or a 35%, or a 70% chance, for example?

If the game is getting a random number up to 9 and includes 0 in that list, there is exactly a 1 in 10 chance (10%) it will choose any given number (0,1,2,3,4,5,6,7,8,9).

So calling 4, or more accurately 0 to 4, there is a 1 in 5 chance for a number to be picked (hence 20%).

For a 1 in 4 chance or (25%), you want it to only call 4 numbers. So self.iResistance = self.getRandomNumber( 3 ), aka 0,1,2,3.
 
Why 4 set a 20% chance? How these accounts works?
And what value should be set to determine a 25% chance of survival, or a 35%, or a 70% chance, for example?

To anwer the second part of your question, it is a lot more difficult to make a non-fractional (as in, not 1 / integer) chance happen. The easiest way I can think of is to conduct two checks that add up to the desired percentage, and if either passes you return a true.

As in, if you want 40%, you could hack it together with two 20% throws, which is a 1/5 shot. Not perfect, but better than nothing.
 
Top Bottom