def onBuildingBuilt(self, argsList):
		city, iBuildingType = argsList
		iOwner = city.getOwner()
		tCity = (city.getX(), city.getY())
		
		vic.onBuildingBuilt(iOwner, iBuildingType)
		self.rel.onBuildingBuilt(city, iOwner, iBuildingType)
		
		if iOwner < iNumPlayers:
			self.com.onBuildingBuilt(iOwner, iBuildingType, city)
		
		if isWorldWonderClass(gc.getBuildingInfo(iBuildingType).getBuildingClassType()):
			sta.onWonderBuilt(iOwner, iBuildingType)
			
		if iBuildingType == iPalace:
			sta.onPalaceMoved(iOwner)
			dc.onPalaceMoved(iOwner)
			
			if city.isHasRealBuilding(iAdministrativeCenter): city.setHasRealBuilding(iAdministrativeCenter, False)
			
			# Leoreth: in case human Phoenicia moves palace to Carthage
			if iOwner == iCarthage and tCity == (58, 39):
				utils.setReborn(iCarthage, True)

		# Leoreth: update trade routes when Porcelain Tower is built to start its effect
		if iBuildingType == iPorcelainTower:
			gc.getPlayer(iOwner).updateTradeRoutes()

		# Leoreth/Voyhkah: Empire State Building
		if iBuildingType == iEmpireStateBuilding:
			iPop = city.getPopulation()
			city.setBuildingCommerceChange(gc.getInfoTypeForString("BUILDINGCLASS_EMPIRE_STATE_BUILDING"), 0, iPop)
			
		# Leoreth: Machu Picchu
		if iBuildingType == iMachuPicchu:
			iNumPeaks = 0
			for i in range(21):
				if city.getCityIndexPlot(i).isPeak():
					iNumPeaks += 1
			city.setBuildingCommerceChange(gc.getInfoTypeForString("BUILDINGCLASS_MACHU_PICCHU"), 0, iNumPeaks * 2)
			
		# Leoreth: Great Wall
		if iBuildingType == iGreatWall:
			for iPlot in range(gc.getMap().numPlots()):
				plot = gc.getMap().plotByIndex(iPlot)
				if plot.getOwner() == iOwner and not plot.isWater():
					plot.setWithinGreatWall(True)
					
		# Leoreth: La Mezquita
		if iBuildingType == iMezquita:
			lGPList = [0, 0, 0, 0, 0, 0, 0]
			for city in utils.getCityList(iOwner):
				for i in range(7):
					iSpecialistUnit = utils.getUniqueUnit(iOwner, iGreatProphet + i)
					lGPList[i] += city.getGreatPeopleUnitProgress(iSpecialistUnit)
			iGPType = utils.getUniqueUnit(iOwner, iGreatProphet + utils.getHighestIndex(lGPList))
			utils.makeUnit(iGPType, iOwner, tCity, 1)
			CyInterface().addMessage(iOwner, False, iDuration, CyTranslator().getText("TXT_KEY_MEZQUITA_FREE_GP", (gc.getUnitInfo(iGPType).getText(), city.getName())), "", InterfaceMessageTypes.MESSAGE_TYPE_MINOR_EVENT, gc.getUnitInfo(iGPType).getButton(), ColorTypes(iWhite), city.getX(), city.getY(), True, True)
	def canadianUP(self, city):
		iPopulation = 5 * city.getPopulation() / 2
		
		lProgress = []
		bAllZero = True
		for iSpecialist in [iGreatProphet, iGreatArtist, iGreatScientist, iGreatMerchant, iGreatEngineer, iGreatStatesman]:
			iProgress = city.getGreatPeopleUnitProgress(utils.getUniqueUnit(city.getOwner(), iSpecialist))
			if iProgress > 0: bAllZero = False
			lProgress.append(iProgress)
			
		if bAllZero:
			iGreatPerson = utils.getRandomEntry([iGreatProphet, iGreatArtist, iGreatScientist, iGreatMerchant, iGreatEngineer, iGreatStatesman])
		else:
			iGreatPerson = utils.getHighestIndex(lProgress) + iGreatProphet
			
		iGreatPerson = utils.getUniqueUnit(city.getOwner(), iGreatPerson)
		
		city.changeGreatPeopleProgress(iPopulation)
		city.changeGreatPeopleUnitProgress(iGreatPerson, iPopulation)
		
		if utils.getHumanID() == city.getOwner():
			CyInterface().addMessage(city.getOwner(), False, iDuration, CyTranslator().getText("TXT_KEY_UP_MULTICULTURALISM", (city.getName(), gc.getUnitInfo(iGreatPerson).getText(), iPopulation)), "", InterfaceMessageTypes.MESSAGE_TYPE_MINOR_EVENT, gc.getUnitInfo(iGreatPerson).getButton(), ColorTypes(iGreen), city.getX(), city.getY(), True, True)
	def canadianUP(self, city):
		iPopulation = 5 * city.getPopulation() / 2
		
		lProgress = []
		bAllZero = True
		for iSpecialist in [iGreatProphet, iGreatArtist, iGreatScientist, iGreatMerchant, iGreatEngineer, iGreatStatesman]:
			iProgress = city.getGreatPeopleUnitProgress(utils.getUniqueUnit(city.getOwner(), iSpecialist))
			if iProgress > 0: bAllZero = False
			lProgress.append(iProgress)
			
		if bAllZero:
			iGreatPerson = utils.getRandomEntry([iGreatProphet, iGreatArtist, iGreatScientist, iGreatMerchant, iGreatEngineer, iGreatStatesman])
		else:
			iGreatPerson = utils.getHighestIndex(lProgress) + iGreatProphet
			
		iGreatPerson = utils.getUniqueUnit(city.getOwner(), iGreatPerson)
		
		city.changeGreatPeopleProgress(iPopulation)
		city.changeGreatPeopleUnitProgress(iGreatPerson, iPopulation)
		
		if utils.getHumanID() == city.getOwner():
			CyInterface().addMessage(city.getOwner(), False, iDuration, CyTranslator().getText("TXT_KEY_UP_MULTICULTURALISM", (city.getName(), gc.getUnitInfo(iGreatPerson).getText(), iPopulation)), "", InterfaceMessageTypes.MESSAGE_TYPE_MINOR_EVENT, gc.getUnitInfo(iGreatPerson).getButton(), ColorTypes(iGreen), city.getX(), city.getY(), True, True)
    def determineTargetPlayer(self, iPlayer):
        pPlayer = gc.getPlayer(iPlayer)
        tPlayer = gc.getTeam(pPlayer.getTeam())
        lPotentialTargets = []
        lTargetValues = [0 for i in range(iNumPlayers)]

        # determine potential targets
        for iLoopPlayer in self.possibleTargets(iPlayer):
            pLoopPlayer = gc.getPlayer(iLoopPlayer)
            tLoopPlayer = gc.getTeam(pLoopPlayer.getTeam())

            if iLoopPlayer == iPlayer: continue

            # requires live civ and past contact
            if not pLoopPlayer.isAlive(): continue
            if not tPlayer.isHasMet(iLoopPlayer): continue

            # no masters or vassals
            if tPlayer.isVassal(iLoopPlayer): continue
            if tLoopPlayer.isVassal(iPlayer): continue

            # not already at war
            if tPlayer.isAtWar(iLoopPlayer): continue

            lPotentialTargets.append(iLoopPlayer)

        if not lPotentialTargets: return -1

        # iterate the map for all potential targets
        for i in range(iWorldX):
            for j in range(iWorldY):
                iOwner = gc.getMap().plot(i, j).getOwner()
                if iOwner in lPotentialTargets:
                    lTargetValues[iOwner] += pPlayer.getWarValue(i, j)

        # hard to attack with lost contact
        for iLoopPlayer in lPotentialTargets:
            lTargetValues[iLoopPlayer] /= 8

        # normalization
        iMaxValue = utils.getHighestEntry(lTargetValues)
        if iMaxValue == 0: return -1

        for iLoopPlayer in lPotentialTargets:
            lTargetValues[iLoopPlayer] *= 500
            lTargetValues[iLoopPlayer] /= iMaxValue

        for iLoopPlayer in lPotentialTargets:

            # randomization
            if lTargetValues[iLoopPlayer] <= iThreshold:
                lTargetValues[iLoopPlayer] += gc.getGame().getSorenRandNum(
                    100, 'random modifier')
            else:
                lTargetValues[iLoopPlayer] += gc.getGame().getSorenRandNum(
                    300, 'random modifier')

            # balanced by attitude
            iAttitude = pPlayer.AI_getAttitude(iLoopPlayer) - 2
            if iAttitude > 0:
                lTargetValues[iLoopPlayer] /= 2 * iAttitude

            # exploit plague
            if data.players[iLoopPlayer].iPlagueCountdown > 0 or data.players[
                    iLoopPlayer].iPlagueCountdown < -10:
                if gc.getGame().getGameTurn() > getTurnForYear(
                        tBirth[iLoopPlayer]) + utils.getTurns(20):
                    lTargetValues[iLoopPlayer] *= 3
                    lTargetValues[iLoopPlayer] /= 2

            # determine master
            iMaster = -1
            for iLoopMaster in range(iNumPlayers):
                if tLoopPlayer.isVassal(iLoopMaster):
                    iMaster = iLoopMaster
                    break

            # master attitudes
            if iMaster >= 0:
                iAttitude = gc.getPlayer(iMaster).AI_getAttitude(iLoopPlayer)
                if iAttitude > 0:
                    lTargetValues[iLoopPlayer] /= 2 * iAttitude

            # peace counter
            if not tPlayer.isAtWar(iLoopPlayer):
                iCounter = min(
                    7, max(1, tPlayer.AI_getAtPeaceCounter(iLoopPlayer)))
                if iCounter <= 7:
                    lTargetValues[iLoopPlayer] *= 20 + 10 * iCounter
                    lTargetValues[iLoopPlayer] /= 100

            # defensive pact
            if tPlayer.isDefensivePact(iLoopPlayer):
                lTargetValues[iLoopPlayer] /= 4

            # consider power
            iOurPower = tPlayer.getPower(True)
            iTheirPower = gc.getTeam(iLoopPlayer).getPower(True)
            if iOurPower > 2 * iTheirPower:
                lTargetValues[iLoopPlayer] *= 2
            elif 2 * iOurPower < iTheirPower:
                lTargetValues[iLoopPlayer] /= 2

            # spare smallish civs
            if iLoopPlayer in [iNetherlands, iPortugal, iItaly]:
                lTargetValues[iLoopPlayer] *= 4
                lTargetValues[iLoopPlayer] /= 5

            # no suicide
            if iPlayer == iNetherlands:
                if iLoopPlayer in [iFrance, iHolyRome, iGermany]:
                    lTargetValues[iLoopPlayer] /= 2
            elif iPlayer == iPortugal:
                if iLoopPlayer == iSpain:
                    lTargetValues[iLoopPlayer] /= 2
            elif iPlayer == iItaly:
                if iLoopPlayer in [iFrance, iHolyRome, iGermany]:
                    lTargetValues[iLoopPlayer] /= 2

        return utils.getHighestIndex(lTargetValues)
	def determineTargetPlayer(self, iPlayer):
		pPlayer = gc.getPlayer(iPlayer)
		tPlayer = gc.getTeam(pPlayer.getTeam())
		lPotentialTargets = []
		lTargetValues = [0 for i in range(iNumPlayers)]

		# determine potential targets
		for iLoopPlayer in range(iNumPlayers):
			pLoopPlayer = gc.getPlayer(iLoopPlayer)
			tLoopPlayer = gc.getTeam(pLoopPlayer.getTeam())
			
			# requires live civ and past contact
			if not pLoopPlayer.isAlive(): continue
			if not tPlayer.isHasMet(iLoopPlayer): continue
			
			# no masters or vassals
			if tPlayer.isVassal(iLoopPlayer): continue
			if tLoopPlayer.isVassal(iPlayer): continue
			
			# not already at war
			if tPlayer.isAtWar(iLoopPlayer): continue
			
			lPotentialTargets.append(iLoopPlayer)
			
		if not lPotentialTargets: return -1
			
		# iterate the map for all potential targets
		for i in range(124):
			for j in range(68):
				iOwner = gc.getMap().plot(i,j).getOwner()
				if iOwner in lPotentialTargets:
					lTargetValues[iOwner] += pPlayer.getWarValue(i, j)
					
		# hard to attack with lost contact
		for iLoopPlayer in lPotentialTargets:
			lTargetValues[iLoopPlayer] /= 8
			
		# normalization
		iMaxValue = utils.getHighestEntry(lTargetValues)
		if iMaxValue == 0: return -1
		
		for iLoopPlayer in lPotentialTargets:
			lTargetValues[iLoopPlayer] *= 500
			lTargetValues[iLoopPlayer] /= iMaxValue
			
		for iLoopPlayer in lPotentialTargets:
		
			# randomization
			if lTargetValues[iLoopPlayer] <= iThreshold:
				lTargetValues[iLoopPlayer] += gc.getGame().getSorenRandNum(100, 'random modifier')
			else:
				lTargetValues[iLoopPlayer] += gc.getGame().getSorenRandNum(300, 'random modifier')
			
			# balanced by attitude
			iAttitude = pPlayer.AI_getAttitude(iLoopPlayer) - 2
			if iAttitude > 0:
				lTargetValues[iLoopPlayer] /= 2 * iAttitude
				
			# exploit plague
			if data.players[iLoopPlayer].iPlagueCountdown > 0 or data.players[iLoopPlayer].iPlagueCountdown < -10:
				if gc.getGame().getGameTurn() > getTurnForYear(tBirth[iLoopPlayer]) + utils.getTurns(20):
					lTargetValues[iLoopPlayer] *= 3
					lTargetValues[iLoopPlayer] /= 2
		
			# determine master
			iMaster = -1
			for iLoopMaster in range(iNumPlayers):
				if tLoopPlayer.isVassal(iLoopMaster):
					iMaster = iLoopMaster
					break
					
			# master attitudes
			if iMaster >= 0:
				iAttitude = gc.getPlayer(iMaster).AI_getAttitude(iLoopPlayer)
				if iAttitude > 0:
					lTargetValues[iLoopPlayer] /= 2 * iAttitude
			
			# peace counter
			if not tPlayer.isAtWar(iLoopPlayer):
				iCounter = min(7, max(1, tPlayer.AI_getAtPeaceCounter(iLoopPlayer)))
				if iCounter <= 7:
					lTargetValues[iLoopPlayer] *= 20 + 10 * iCounter
					lTargetValues[iLoopPlayer] /= 100
					
			# defensive pact
			if tPlayer.isDefensivePact(iLoopPlayer):
				lTargetValues[iLoopPlayer] /= 4
				
			# consider power
			iOurPower = tPlayer.getPower(True)
			iTheirPower = gc.getTeam(iLoopPlayer).getPower(True)
			if iOurPower > 2 * iTheirPower:
				lTargetValues[iLoopPlayer] *= 2
			elif 2 * iOurPower < iTheirPower:
				lTargetValues[iLoopPlayer] /= 2
				
			# spare smallish civs
			if iLoopPlayer in [iNetherlands, iPortugal, iItaly]:
				lTargetValues[iLoopPlayer] *= 4
				lTargetValues[iLoopPlayer] /= 5
				
			# no suicide
			if iPlayer == iNetherlands:
				if iLoopPlayer in [iFrance, iHolyRome, iGermany]:
					lTargetValues[iLoopPlayer] /= 2
			elif iPlayer == iPortugal:
				if iLoopPlayer == iSpain:
					lTargetValues[iLoopPlayer] /= 2
			elif iPlayer == iItaly:
				if iLoopPlayer in [iFrance, iHolyRome, iGermany]:
					lTargetValues[iLoopPlayer] /= 2
					
		return utils.getHighestIndex(lTargetValues)