BTS Heroes (Wonder Units)

I've told ya how to do in xml (you have to spend production for the unit).

Without spending production, you'll need indeed python.
 
There is another xml possibility:

Make a second tech for an hero unit. Make that second tech require TECH_GERMANY AND other techs.

Then you can use firstfreeunitclass for that second tech - OR: Make the hero require that second tech.
 
There is another xml possibility:

Make a second tech for an hero unit. Make that second tech require TECH_GERMANY AND other techs.

Then you can use firstfreeunitclass for that second tech - OR: Make the hero require that second tech.

It seems that in XML it's rather complicated and probably won't work the way I like. So that why I posted the request here and in the thread for modcomp-requests.
 
note to you: every enabled python callback slows your game. I'm always doing it in xml when I don't need python.

you probably don't need a callback for your work

tech acquired?
1A. no --> do nothing
1B. yes --> by Germany?

2A. no --> do nothing
2B. yes --> Physics?

3A. no --> do nothing
3B. yes --> give a Red Baron to Germany

this should work. you will get the unit in your capital city. I don't know how to check for your empire, else I could do it for you.


//edit: you need to add a Help tag to the technology which gives you the unit. else you won't see it on the tech tree when using python.
 
note to you: every enabled python callback slows your game. I'm always doing it in xml when I don't need python.

you probably don't need a callback for your work



this should work. you will get the unit in your capital city. I don't know how to check for your empire, else I could do it for you.


//edit: you need to add a Help tag to the technology which gives you the unit. else you won't see it on the tech tree when using python.

That's probably the culprit. Isn't there a way in Python to compare the civ of the current player (human or AI) with i.e. CIVILIZATION_GERMANY
Maybe some Python command:

if GetInfoTypeForString(current_civ) = CIVILIZATION_WHATEVER then do this etc. ?

:dunno:
 
UnboundLocalError: local variable 'pPID' referenced before assignment
ERR: Python function onEvent failed, module CvEventInterface

Instead of pPID use pLoser.getOwner()



For the tech+civ:

PHP:
	def onTechAcquired(self, argsList):
		'Tech Acquired'
		iTechType, iTeam, iPlayer, bAnnounce = argsList
###this part here		
		if iTechType == gc.getInfoTypeForString("TECH_WHATEVER"):
		    		TheCivForTheUnit = gc.getInfoTypeForString("CIVILIZATION_WHATEVER")
		    		pPlayer = gc.getPlayer(iPlayer)
		    		myName = pPlayer.getCivilizationType ()
		    		if myName == TheCivForTheUnit:
		    		        pCity= pPlayer.getCapitalCity()
		    		        iX =pCity.getX()
		            		iY = pCity.getY()
		            		newUnit = pPlayer.initUnit(gc.getInfoTypeForString( 'UNIT_WHATEVER' ), iX, iY, UnitAITypes.UNITAI_GENERAL, DirectionTypes.NO_DIRECTION)


For the position, i just took the capital.
 
Instead of pPID use pLoser.getOwner()



For the tech+civ:

PHP:
	def onTechAcquired(self, argsList):
		'Tech Acquired'
		iTechType, iTeam, iPlayer, bAnnounce = argsList
###this part here		
		if iTechType == gc.getInfoTypeForString("TECH_WHATEVER"):
		    		TheCivForTheUnit = gc.getInfoTypeForString("CIVILIZATION_WHATEVER")
		    		pPlayer = gc.getPlayer(iPlayer)
		    		myName = pPlayer.getCivilizationType ()
		    		if myName == TheCivForTheUnit:
		    		        pCity= pPlayer.getCapitalCity()
		    		        iX =pCity.getX()
		            		iY = pCity.getY()
		            		newUnit = pPlayer.initUnit(gc.getInfoTypeForString( 'UNIT_WHATEVER' ), iX, iY, UnitAITypes.UNITAI_GENERAL, DirectionTypes.NO_DIRECTION)


For the position, i just took the capital.

Thanks J :goodjob:
With this code it's possible to spawn a Hero for a civ that researches the appropriate tech for it!
Just one minor question: how can I spawn two units? Just copy the last command?
 
Instead of pPID use pLoser.getOwner()



For the tech+civ:

PHP:
	def onTechAcquired(self, argsList):
		'Tech Acquired'
		iTechType, iTeam, iPlayer, bAnnounce = argsList
###this part here		
		if iTechType == gc.getInfoTypeForString("TECH_WHATEVER"):
		    		TheCivForTheUnit = gc.getInfoTypeForString("CIVILIZATION_WHATEVER")
		    		pPlayer = gc.getPlayer(iPlayer)
		    		myName = pPlayer.getCivilizationType ()
		    		if myName == TheCivForTheUnit:
		    		        pCity= pPlayer.getCapitalCity()
		    		        iX =pCity.getX()
		            		iY = pCity.getY()
		            		newUnit = pPlayer.initUnit(gc.getInfoTypeForString( 'UNIT_WHATEVER' ), iX, iY, UnitAITypes.UNITAI_GENERAL, DirectionTypes.NO_DIRECTION)


For the position, i just took the capital.


I am sorry :blush:, i have NO idea where to put the info you have, or what to put where?
 
Do a search for "onTechAcquired", you will find this:

Code:
	def onTechAcquired(self, argsList):
		'Tech Acquired'
		iTechType, iTeam, iPlayer, bAnnounce = argsList
		# Note that iPlayer may be NULL (-1) and not a refer to a player object
	
		# Show tech splash when applicable
		if (iPlayer > -1 and bAnnounce and not CyInterface().noTechSplash()):
			if (gc.getGame().isFinalInitialized() and not gc.getGame().GetWorldBuilderMode()):
				if ((not gc.getGame().isNetworkMultiPlayer()) and (iPlayer == gc.getGame().getActivePlayer())):
					popupInfo = CyPopupInfo()
					popupInfo.setButtonPopupType(ButtonPopupTypes.BUTTONPOPUP_PYTHON_SCREEN)
					popupInfo.setData1(iTechType)
					popupInfo.setText(u"showTechSplash")
					popupInfo.addPopup(iPlayer)

replace this with

Code:
	def onTechAcquired(self, argsList):
		'Tech Acquired'
		iTechType, iTeam, iPlayer, bAnnounce = argsList
		# Note that iPlayer may be NULL (-1) and not a refer to a player object

### Hero Mod Start ##
     
       		if iTechType == gc.getInfoTypeForString("TECH_WHATEVER"):
			TheCivForTheUnit = gc.getInfoTypeForString("CIVILIZATION_WHATEVER")
			pPlayer = gc.getPlayer(iPlayer)
			myName = pPlayer.getCivilizationType ()
			if myName == TheCivForTheUnit:
				pCity= pPlayer.getCapitalCity()
				iX =pCity.getX()
				iY = pCity.getY()
				newUnit = pPlayer.initUnit(gc.getInfoTypeForString( 'UNIT_WHATEVER' ), iX, iY, UnitAITypes.UNITAI_GENERAL, DirectionTypes.NO_DIRECTION)

## Hero Mod End ##

		# Show tech splash when applicable
		if (iPlayer > -1 and bAnnounce and not CyInterface().noTechSplash()):
			if (gc.getGame().isFinalInitialized() and not gc.getGame().GetWorldBuilderMode()):
				if ((not gc.getGame().isNetworkMultiPlayer()) and (iPlayer == gc.getGame().getActivePlayer())):
					popupInfo = CyPopupInfo()
					popupInfo.setButtonPopupType(ButtonPopupTypes.BUTTONPOPUP_PYTHON_SCREEN)
					popupInfo.setData1(iTechType)
					popupInfo.setText(u"showTechSplash")
					popupInfo.addPopup(iPlayer)
 
Do a search for "onTechAcquired", you will find this:

Code:
	def onTechAcquired(self, argsList):
		'Tech Acquired'
		iTechType, iTeam, iPlayer, bAnnounce = argsList
		# Note that iPlayer may be NULL (-1) and not a refer to a player object
	
		# Show tech splash when applicable
		if (iPlayer > -1 and bAnnounce and not CyInterface().noTechSplash()):
			if (gc.getGame().isFinalInitialized() and not gc.getGame().GetWorldBuilderMode()):
				if ((not gc.getGame().isNetworkMultiPlayer()) and (iPlayer == gc.getGame().getActivePlayer())):
					popupInfo = CyPopupInfo()
					popupInfo.setButtonPopupType(ButtonPopupTypes.BUTTONPOPUP_PYTHON_SCREEN)
					popupInfo.setData1(iTechType)
					popupInfo.setText(u"showTechSplash")
					popupInfo.addPopup(iPlayer)

replace this with

Code:
	def onTechAcquired(self, argsList):
		'Tech Acquired'
		iTechType, iTeam, iPlayer, bAnnounce = argsList
		# Note that iPlayer may be NULL (-1) and not a refer to a player object

### Hero Mod Start ##
     
       		if iTechType == gc.getInfoTypeForString("TECH_WHATEVER"):
			TheCivForTheUnit = gc.getInfoTypeForString("CIVILIZATION_WHATEVER")
			pPlayer = gc.getPlayer(iPlayer)
			myName = pPlayer.getCivilizationType ()
			if myName == TheCivForTheUnit:
				pCity= pPlayer.getCapitalCity()
				iX =pCity.getX()
				iY = pCity.getY()
				newUnit = pPlayer.initUnit(gc.getInfoTypeForString( 'UNIT_WHATEVER' ), iX, iY, UnitAITypes.UNITAI_GENERAL, DirectionTypes.NO_DIRECTION)

## Hero Mod End ##

		# Show tech splash when applicable
		if (iPlayer > -1 and bAnnounce and not CyInterface().noTechSplash()):
			if (gc.getGame().isFinalInitialized() and not gc.getGame().GetWorldBuilderMode()):
				if ((not gc.getGame().isNetworkMultiPlayer()) and (iPlayer == gc.getGame().getActivePlayer())):
					popupInfo = CyPopupInfo()
					popupInfo.setButtonPopupType(ButtonPopupTypes.BUTTONPOPUP_PYTHON_SCREEN)
					popupInfo.setData1(iTechType)
					popupInfo.setText(u"showTechSplash")
					popupInfo.addPopup(iPlayer)


Thx but if i wanted ALL civs to receive this upon getting a coliseum (but only the first built one), then what?:crazyeye:
 
Got it working the way I want it to work, big thanks to the J :hatsoff:

Here's the example Pythoncode:

Code:
	def onTechAcquired(self, argsList):
		'Tech Acquired'
		iTechType, iTeam, iPlayer, bAnnounce = argsList
		# Note that iPlayer may be NULL (-1) and not a refer to a player object

### Hero Mod Start - code by The J##
     
		if iTechType == gc.getInfoTypeForString("TECH_BOATING"):
			TheCivForTheUnit = gc.getInfoTypeForString("CIVILIZATION_NETHERLANDS")
			pPlayer = gc.getPlayer(iPlayer)
			pPID = pPlayer.getID()
			myName = pPlayer.getCivilizationType ()
			if myName == TheCivForTheUnit:
				pCity= pPlayer.getCapitalCity()
				iX =pCity.getX()
				iY = pCity.getY()
				newUnit = pPlayer.initUnit(gc.getInfoTypeForString( 'UNIT_TANK' ), iX, iY, UnitAITypes.UNITAI_GENERAL, DirectionTypes.NO_DIRECTION)
				newUnit.setHasPromotion(gc.getInfoTypeForString( 'PROMOTION_HERO' ), true)
				newUnit.setHasPromotion(gc.getInfoTypeForString( 'PROMOTION_FREEUPGRADE' ), true)
				newUnit.setName("Tank the Terrible")

				## Display message
				CyInterface().addMessage(pPID,false,15,CyTranslator().getText("TXT_KEY_HERO_EMERGE_NETHERLANDS",()),'',0,'Art/Interface/Buttons/Units/HeroNetherlands.dds',ColorTypes(11), iX, iY, True,True)

## Hero Mod End ##

and here is how it looks ingame:

Spoiler :


The Hero has emerged!!



Log entry for the Hero!!



And the Hero Promotion!!
 
Just one minor question: how can I spawn two units? Just copy the last command?

Yes, that will do it.

Thx but if i wanted ALL civs to receive this upon getting a coliseum (but only the first built one), then what?:crazyeye:

The first colloseum, which is built, should spawn a unit?
This needs some changes...

PHP:
	def onBuildingBuilt(self, argsList):
		'Building Completed'
		pCity, iBuildingType = argsList
		game = gc.getGame()
###from here###
        thisBuilding = gc.getBuildingInfo(iBuildingType)
        BuildingClass = thisBuilding.getBuildingClassType ()
        if BuildingClass == gc.getInfoTypeForString("BUILDINGCLASS_COLOSSEUM"):
            if game.getBuildingClassCreatedCount(BuildingClass)==1:                
				iX = pCity.getX()
				iY = pCity.getY()
				newUnit = pPlayer.initUnit(gc.getInfoTypeForString( 'UNIT_WHATEVER' ), iX, iY, UnitAITypes.UNITAI_GENERAL, DirectionTypes.NO_DIRECTION)
####to here###	

		
		if ((not gc.getGame().isNetworkMultiPlayer()) and (pCity.getOwner() == gc.getGame().getActivePlayer()) and isWorldWonderClass(gc.getBuildingInfo(iBuildingType).getBuildingClassType())):
			# If this is a wonder...
			popupInfo = CyPopupInfo()
			popupInfo.setButtonPopupType(ButtonPopupTypes.BUTTONPOPUP_PYTHON_SCREEN)
			popupInfo.setData1(iBuildingType)
			popupInfo.setData2(pCity.getID())
			popupInfo.setData3(0)
			popupInfo.setText(u"showWonderMovie")
			popupInfo.addPopup(pCity.getOwner())

		CvAdvisorUtils.buildingBuiltFeats(pCity, iBuildingType)

		if (not self.__LOG_BUILDING):
			return
		CvUtil.pyPrint('%s was finished by Player %d Civilization %s' 
			%(PyInfo.BuildingInfo(iBuildingType).getDescription(), pCity.getOwner(), gc.getPlayer(pCity.getOwner()).getCivilizationDescription(0)))

Got it working the way I want it to work, big thanks to the J :hatsoff:

Here's the example Pythoncode:

:cool: nice to see it.
 
Yes, that will do it.



The first colloseum, which is built, should spawn a unit?
This needs some changes...

Spoiler :
PHP:
	def onBuildingBuilt(self, argsList):
		'Building Completed'
		pCity, iBuildingType = argsList
		game = gc.getGame()
###from here###
        thisBuilding = gc.getBuildingInfo(iBuildingType)
        BuildingClass = thisBuilding.getBuildingClassType ()
        if BuildingClass == gc.getInfoTypeForString("BUILDINGCLASS_COLOSSEUM"):
            if game.getBuildingClassCreatedCount(BuildingClass)==1:                
				iX = pCity.getX()
				iY = pCity.getY()
				newUnit = pPlayer.initUnit(gc.getInfoTypeForString( 'UNIT_WHATEVER' ), iX, iY, UnitAITypes.UNITAI_GENERAL, DirectionTypes.NO_DIRECTION)
####to here###	

		
		if ((not gc.getGame().isNetworkMultiPlayer()) and (pCity.getOwner() == gc.getGame().getActivePlayer()) and isWorldWonderClass(gc.getBuildingInfo(iBuildingType).getBuildingClassType())):
			# If this is a wonder...
			popupInfo = CyPopupInfo()
			popupInfo.setButtonPopupType(ButtonPopupTypes.BUTTONPOPUP_PYTHON_SCREEN)
			popupInfo.setData1(iBuildingType)
			popupInfo.setData2(pCity.getID())
			popupInfo.setData3(0)
			popupInfo.setText(u"showWonderMovie")
			popupInfo.addPopup(pCity.getOwner())

		CvAdvisorUtils.buildingBuiltFeats(pCity, iBuildingType)
[/SPOILER]
		if (not self.__LOG_BUILDING):
			return
		CvUtil.pyPrint('%s was finished by Player %d Civilization %s' 
			%(PyInfo.BuildingInfo(iBuildingType).getDescription(), pCity.getOwner(), gc.getPlayer(pCity.getOwner()).getCivilizationDescription(0)))



:cool: nice to see it.
Spoiler :


Do i copy all the spoiler under def onBuildingBuilt(self, argsList):? exactly like you have it?

You do know this belongs to the Spartacus HEROES part right??
 
Do i copy all the spoiler under def onBuildingBuilt(self, argsList):? exactly like you have it?

All, what is after "####to here###" and before "###from here### "should already be somewhere there, so you don't need that part.


You do know this belongs to the Spartacus HEROES part right??

No, i didn't know that, but i guessed it.
 
All, what is after "####to here###" and before "###from here### "should already be somewhere there, so you don't need that part.

Nope its no where, Heroes did not have that stuff anyplace, here is the code he made:

Spoiler :
Code:
## BTS HEROS - Spartacus Capture Event Start ##

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

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

            ## Capture % Random # 0 to 3 or 25% ##
			self.iNewGladiatorNumber = self.getRandomNumber( 3 )

			if self.iNewGladiatorNumber == 0:

				iGladiator = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'UNIT_GLADIATOR')
				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(iGladiator, 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_SPARTACUS_CAPTURE_SUCCESS",()),'',0,',Art/Interface/Buttons/Units/ICBM.dds,Art/Interface/Buttons/Warlords_Atlas_1.dds,3,11',ColorTypes(44), iXa, iYa, True,True)

## BTS HEROS - Spartacus Capture End ##

thats all.
 
You don't have to place the code in that section, you have to place it in CvEventManager after onBuildingBuilt (you see that in the code).

I am still confused cause you said that it should ALREADY be there and its not.

Here's what i have:

Code:
def onBuildingBuilt(self, argsList):
		'Building Completed'
		pCity, iBuildingType = argsList
		game = gc.getGame()
###water start part 3####
then a BUNCH your codes from alot of YOUR stuff.


But none of the stuff your have written, thats all i am saying???

Spoiler :
Code:
###from here###
        thisBuilding = gc.getBuildingInfo(iBuildingType)
        BuildingClass = thisBuilding.getBuildingClassType ()
        if BuildingClass == gc.getInfoTypeForString("BUILDINGCLASS_COLOSSEUM"):
            if game.getBuildingClassCreatedCount(BuildingClass)==1:                
                iX = pCity.getX()
                iY = pCity.getY()
                newUnit = pPlayer.initUnit(gc.getInfoTypeForString( 'UNIT_WHATEVER' ), iX, iY, UnitAITypes.UNITAI_GENERAL, DirectionTypes.NO_DIRECTION)
####to here###    

        
        if ((not gc.getGame().isNetworkMultiPlayer()) and (pCity.getOwner() == gc.getGame().getActivePlayer()) and isWorldWonderClass(gc.getBuildingInfo(iBuildingType).getBuildingClassType())):
Code:
# If this is a wonder...
            popupInfo = CyPopupInfo()
            popupInfo.setButtonPopupType(ButtonPopupTypes.BUTTONPOPUP_PYTHON_SCREEN)
            popupInfo.setData1(iBuildingType)
            popupInfo.setData2(pCity.getID())
            popupInfo.setData3(0)
            popupInfo.setText(u"showWonderMovie")
            popupInfo.addPopup(pCity.getOwner())

        CvAdvisorUtils.buildingBuiltFeats(pCity, iBuildingType)
 
@Strat:
I like the concept of giving a unit to the first civ that builds a certain building i.e. first civ that builds a colosseum receives Spartacus.
I'm quite sure the AI is totally oblivious of this. How do you intend to get the AIs actively going after building, in this case, the first colosseum?
Otherwise human players can easily exploit this :rolleyes:
 
@Strat:
I like the concept of giving a unit to the first civ that builds a certain building i.e. first civ that builds a colosseum receives Spartacus.
I'm quite sure the AI is totally oblivious of this. How do you intend to get the AIs actively going after building, in this case, the first colosseum?
Otherwise human players can easily exploit this :rolleyes:

As far as i know, its done with CIV4EventTriggerInfos and CIV4EventInfos.
 
Top Bottom