Python code to delete cities/units or convert to another civ when a unit is killed

DireAussie

Chieftain
Joined
Nov 12, 2005
Messages
60
I wrote this code for someone else's mod

If you wanted to implement a leader unit and have all of the civ killed off when that leader is killed then this is the code for you :)

Put this in your CvEventManager class. Be sure to put in a "self.ignoreKill = false" entry in the init function of your CvEventManager class.

In the below code, units and cities are converted to barbarian when a maceman is killed. Currently no experience or promotions are carried over during unit conversion, but this could be added in.

Code:
	def onUnitKilled(self, argsList):

		#when inside the loop, calling loopUnit.kill(true, player.getID()) will then call this onUnitKilled method, then we get infinite loop.  So avoid this by not calling the function when killing units inside the loop
		if (self.ignoreKill == false):
        	
        		self.parent.onUnitKilled(self, argsList)

			unitInfo = []

        		#get info from args given to us
        		unit, iAttacker = argsList
			
        		#get player from unit
        		player = gc.getPlayer(unit.getOwner())
        		
			#get the attacking player (dont really need it for this)
        		attacker = gc.getPlayer(iAttacker)
      		
        		if (unit.getUnitType() == gc.getInfoTypeForString("UNIT_MACEMAN") and player.getID() != gc.getBARBARIAN_PLAYER()):
        			#loop through and store all info about the player's units
        			(loopUnit, iter) = player.firstUnit(false)

				
        			self.ignoreKill = true	#ignore onUnitKilled event while in loop
        			while (loopUnit):
	
        				if ( not loopUnit.isNone()): 
                				#store unit info
                				unitInfo.append((loopUnit.getUnitType(),loopUnit.getX(), loopUnit.getY()) )
                			
						#kill unit
                				loopUnit.kill(true, player.getID())

                			(loopUnit, iter) = player.nextUnit(iter, false)
        				CvUtil.pyPrint("did unitloop")
                
        			self.ignoreKill = false

        			#player.killUnits()  #this seems to crash the game

        			#now loop through all cities and convert to barbarian
        			(loopCity, iter) = player.firstCity(false)
        
        			while(loopCity):
        				if ( not loopCity.isNone()): 
        					#do conversion
        					gc.getPlayer(gc.getBARBARIAN_PLAYER()).acquireCity(loopCity, false, false)
        
        				(loopCity, iter) = player.nextCity(iter, false)
        				CvUtil.pyPrint("did cityloop")
                	
      	 			#now create new units for barbarian

				self.ignoreKill = true  #not tested but creating a unit on the same square as an enemy unit might kill the other unit 

        			for id, xpos, ypos in unitInfo:
					#NOTE- not fully tested - what if player is allied with someone and unit in an ally's city and then a barbarian unit is created?

					#CvUtil.pyPrint("creating unit as follows: id %d, xpos %d, ypos %d" % (id, xpos, ypos))
					#unitTypeNum = CvUtil.findInfoTypeNum(gc.getUnitInfo, gc.getNumUnitInfos(), "UNIT_MACEMAN")
									
        				gc.getPlayer(gc.getBARBARIAN_PLAYER()).initUnit(id, xpos, ypos, UnitAITypes.NO_UNITAI)
        				CvUtil.pyPrint("did barbunitloop")

				self.ignoreKill = false
 
Very useful! Good work.
 
Weasel Op said:
So this is a regicide mod?
Looks like it - when the king (or the maceman) dies, all your cities turn to barbarian cities - sounds cool to me!

Except the AI probably wouldn't protect his king so well...


EDIT: Just out of interest, how important is the API for coding in python - am I right in thinking that it is absolutely vital? I've just started playing with it, and I've constantly got the API open!

EDIT 2: And how would you go about carrying over promotions. I think I can work out experience, but I can't see any way of storing the promotion data before killing the unit.

EDIT 3: Oh, and the Rebellion mod by Trip (http://forums.civfanatics.com/showthread.php?t=137898), has some code to avoid unit clashes on foreign cities/units - you may want to check it out.
 
EDIT: Just out of interest, how important is the API for coding in python - am I right in thinking that it is absolutely vital? I've just started playing with it, and I've constantly got the API open!

For sure! The PyHelpers file is pretty much useless, but its good for learning how to do certain things. I always access the functions provided through CvPythonExtensions. I used pydocs (thanks to the civ4wiki for instructions) to make a web page out of it:

http://www.users.on.net/~dfidge/CvPythonExtensions.zip

EDIT 2: And how would you go about carrying over promotions. I think I can work out experience, but I can't see any way of storing the promotion data before killing the unit.

have a look at the file: civ4\assets\python\pyWB\CvWBDesc.py and search for "promotion".


I'm not familiar with that term - was this the name of a mod in civ 3 or something?
 
:D I already found answer to my quetion. To get sertain units like great general as a combat result you just have to mod Snaitf's "Unit Allegence mode" code.

Other stuff are only conditions - so now it is possible to make event to combat that you have chance to get some units what you like

Snaitf is genius!!! :D He made good option!
 
How could the code in the opening post be modified so that the remaining cities are split 50/50 between going barbarian and joing the regiciding civ?
 
If you want it more like regicide in civ3 you could use the following:

Code:
	def onUnitKilled(self, argsList):
		'Unit Killed'
		unit, iAttacker = argsList
		'determine owner of lost unit'
		player = PyPlayer(unit.getOwner())
		attacker = PyPlayer(iAttacker)
		'check if unit killed was a king'
		if unit.getUnitType() == gc.getInfoTypeForString("UNIT_KING"):
			'loop through cities and destroy each one'
			CityList = player.getCityList()
       	        	for City in CityList:
               	        	City.GetCy().kill()
		if (not self.__LOG_UNITKILLED):
			return

		CvUtil.pyPrint('Player %d Civilization %s Unit %s was killed by Player %d' 
			%(player.getID(), player.getCivilizationName(), PyInfo.UnitInfo(unit.getUnitType()).getDescription(), attacker.getID()))

This assumes you have created a unit called King, you could change this to gc.getInfoTypeForString("UNIT_SCOUT") for example.
 
Back
Top Bottom