Svartalfar and kidnap

I know I once captured a city with several GP's, but other then that, yeah. Not so much use for this spell even if it would work.
 
The problem isn't just that it won't work because the AI doesn't like to settle, it is that in testing it against a city that DOES HAVE GREAT SPECIALISTS SETTLED, the spell still does nothing.

EDIT: And for Magister's gripe about how it is set up for a specific order in which the Specialists are captured (if it ever works), can we get it changed to the same type of Array setup that Planar Gates use? Thus you can get 1 randomly from among all those available.
 
That was what I was suggesting. You can have the same entry in the array multiple times, right? It should be more likely to kidnap the type of great people who are more prevalent in the city.
 
I was under the impression that it only worked to kidnap UN-settled Great People, and as such, was only very limitedly useful, considering you would have to be standing on top of the city when the GP popped to even have a chance of nabbing him/her before the AI settles/lightbulbs/Builds with him. Has anyone tried this, yet?
 
Tested it some more. Even though the code is clearly written to state it is for settled GP, I even tested it with some non-settled ones.

To get the spell to work, I had to replace the Python Requirement string with a simple return True entry, then I was able to cast the spell.

So I went back and left everything as is, but had it initialize the value "i" as "i = 1" instead of "i = 0." Again, this allowed me to begin casting the spell. The city I was in contained 4 settled Great Engineers and 4 settled Great Sages. However, the Python is failing to properly count them to allow the spell to be cast at all.


Now, when I am able to cast the spell it gets more vexing. Using a Hunter, base :strength: 4, I should have a 32% chance of success. However, in 15 castings of the spell I failed each time. It should be noted that he was killed roughly 50% of the time, and war was declared each time, so that works fine at least.

Using a Beastmaster I was able to get the spell to cast without any War Declaration, and instead encountered a Python Exception. It stated that the variable "iUnit" in line 1067 is referenced before assignment. That line would be:

newUnit = pPlayer.initUnit(iUnit, caster.getX(), caster.getY(), UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)


Which is supposed to give you the new Great Person.

Changing the spell to set "iUnit = 1" and "iSpec = 1" resulted in the spell working flawlessly and granting me The Dragon's Horde (Unit #1).


So the final answer is that there is a problem with the gc.getInfoTypeForString function (most likely). Or pCity.getSpecialistCount (will test after class)
 
Tested it by placing appropriate numbers in every gc.getInfoTypeForString function. No Luck.

Tried again replacing every pCity.getSpecialistCount with appropriate numbers. Spell works fine (and Hunter finally succeeded! So those 15 were just a bad run). So pCity.getSpecialistCount is not working. Possibly just because you don"t own the city?
 
Maybe the unit has to have the Investigate flag (or one of the other Espionag flags)set, so that it treats the city as one it can see? Possibly a hair-brained idea, but it makes sense if visibility of the city stats IS an issue....
 
Ok this is fixed with : (great people count as free Specialists and not specialists )

Spoiler :
Code:
def reqKidnap(caster):
	pCity = caster.plot().getPlotCity()
	if pCity.getTeam() == caster.getTeam():
		return False
	i = 0
	i = i + pCity.getFreeSpecialistCount(gc.getInfoTypeForString('SPECIALIST_GREAT_PRIEST'))
	i = i + pCity.getFreeSpecialistCount(gc.getInfoTypeForString('SPECIALIST_GREAT_ARTIST'))
	i = i + pCity.getFreeSpecialistCount(gc.getInfoTypeForString('SPECIALIST_GREAT_MERCHANT'))
	i = i + pCity.getFreeSpecialistCount(gc.getInfoTypeForString('SPECIALIST_GREAT_ENGINEER'))
	i = i + pCity.getFreeSpecialistCount(gc.getInfoTypeForString('SPECIALIST_GREAT_SCIENTIST'))

	if i == 0:
		return False
	return True

def spellKidnap(caster):
	pCity = caster.plot().getPlotCity()
	if pCity.getFreeSpecialistCount(gc.getInfoTypeForString('SPECIALIST_GREAT_PRIEST')) > 0:
		iUnit = gc.getInfoTypeForString('UNIT_PROPHET')
		iSpec = gc.getInfoTypeForString('SPECIALIST_GREAT_PRIEST')
	if pCity.getFreeSpecialistCount(gc.getInfoTypeForString('SPECIALIST_GREAT_ARTIST')) > 0:
		iUnit = gc.getInfoTypeForString('UNIT_ARTIST')
		iSpec = gc.getInfoTypeForString('SPECIALIST_GREAT_ARTIST')
	if pCity.getFreeSpecialistCount(gc.getInfoTypeForString('SPECIALIST_GREAT_MERCHANT')) > 0:
		iUnit = gc.getInfoTypeForString('UNIT_MERCHANT')
		iSpec = gc.getInfoTypeForString('SPECIALIST_GREAT_MERCHANT')
	if pCity.getFreeSpecialistCount(gc.getInfoTypeForString('SPECIALIST_GREAT_ENGINEER')) > 0:
		iUnit = gc.getInfoTypeForString('UNIT_ENGINEER')
		iSpec = gc.getInfoTypeForString('SPECIALIST_GREAT_ENGINEER')
	if pCity.getFreeSpecialistCount(gc.getInfoTypeForString('SPECIALIST_GREAT_SCIENTIST')) > 0:
		iUnit = gc.getInfoTypeForString('UNIT_SCIENTIST')
		iSpec = gc.getInfoTypeForString('SPECIALIST_GREAT_SCIENTIST')
	iChance = caster.baseCombatStr() * 8
	pPlayer = gc.getPlayer(caster.getOwner())
	if CyGame().getSorenRandNum(100, "Kidnap") <= iChance:
		newUnit = pPlayer.initUnit(iUnit, caster.getX(), caster.getY(), UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)
		pCity.changeFreeSpecialistCount(iSpec, -1)
	else:
		if CyGame().getSorenRandNum(100, "Kidnap") <= 50:
			caster.setXY(pPlayer.getCapitalCity().getX(), pPlayer.getCapitalCity().getY(), false, true, true)
		else:
			caster.kill(True, 0)
		startWar(caster.getOwner(), pCity.getOwner())

Tcho !
 
Now that Sto has it working, I decided to implement the changes people mentioned in here.

  1. Chances are now Base :strength: * 8 + current XP.
    • Reduced the maximum chance to 80% instead of Kael's 95% since you can now get a higher chance much easier
    • Value would be better stored as a Global Define for ease of changing to balance out precisely what should be used though
  2. You can now get any Great specialist randomly selected from those which the city has settled, and it is weighted by how many they have.

Spoiler code :
Code:
def reqKidnap(caster):
	pCity = caster.plot().getPlotCity()
	if pCity.getTeam() == caster.getTeam():
		return False
	i = 0
	i = i + pCity.getFreeSpecialistCount(gc.getInfoTypeForString('SPECIALIST_GREAT_PRIEST'))
	i = i + pCity.getFreeSpecialistCount(gc.getInfoTypeForString('SPECIALIST_GREAT_ARTIST'))
	i = i + pCity.getFreeSpecialistCount(gc.getInfoTypeForString('SPECIALIST_GREAT_MERCHANT'))
	i = i + pCity.getFreeSpecialistCount(gc.getInfoTypeForString('SPECIALIST_GREAT_ENGINEER'))
	i = i + pCity.getFreeSpecialistCount(gc.getInfoTypeForString('SPECIALIST_GREAT_SCIENTIST'))
	if i == 0:
		return False
	return True

def spellKidnap(caster):
	pCity = caster.plot().getPlotCity()
	listUnits = []
	listSpecs = []
	if pCity.getFreeSpecialistCount(gc.getInfoTypeForString('SPECIALIST_GREAT_PRIEST')) > 0:
		for i in range(pCity.getFreeSpecialistCount(gc.getInfoTypeForString('SPECIALIST_GREAT_PRIEST'))):
			listUnits.append(gc.getInfoTypeForString('UNIT_PROPHET'))
			listSpecs.append(gc.getInfoTypeForString('SPECIALIST_GREAT_PRIEST'))
	if pCity.getFreeSpecialistCount(gc.getInfoTypeForString('SPECIALIST_GREAT_ARTIST')) > 0:
		for i in range(pCity.getFreeSpecialistCount(gc.getInfoTypeForString('SPECIALIST_GREAT_ARTIST'))):
			listUnits.append(gc.getInfoTypeForString('UNIT_ARTIST'))
			listSpecs.append(gc.getInfoTypeForString('SPECIALIST_GREAT_ARTIST'))
	if pCity.getFreeSpecialistCount(gc.getInfoTypeForString('SPECIALIST_GREAT_MERCHANT')) > 0:
		for i in range(pCity.getFreeSpecialistCount(gc.getInfoTypeForString('SPECIALIST_GREAT_MERCHANT'))):
			listUnits.append(gc.getInfoTypeForString('UNIT_MERCHANT'))
			listSpecs.append(gc.getInfoTypeForString('SPECIALIST_GREAT_MERCHANT'))
	if pCity.getFreeSpecialistCount(gc.getInfoTypeForString('SPECIALIST_GREAT_ENGINEER')) > 0:
		for i in range(pCity.getFreeSpecialistCount(gc.getInfoTypeForString('SPECIALIST_GREAT_ENGINEER'))):
			listUnits.append(gc.getInfoTypeForString('UNIT_ENGINEER'))
			listSpecs.append(gc.getInfoTypeForString('SPECIALIST_GREAT_ENGINEER'))
	if pCity.getFreeSpecialistCount(gc.getInfoTypeForString('SPECIALIST_GREAT_SCIENTIST')) > 0:
		for i in range(pCity.getFreeSpecialistCount(gc.getInfoTypeForString('SPECIALIST_GREAT_SCIENTIST'))):
			listUnits.append(gc.getInfoTypeForString('UNIT_SCIENTIST'))
			listSpecs.append(gc.getInfoTypeForString('SPECIALIST_GREAT_SCIENTIST'))
	iChance = caster.baseCombatStr() * 8
	iChance = iChance + caster.getExperience()
	if iChance > 80:
		iChance = 80
	pPlayer = gc.getPlayer(caster.getOwner())
	if CyGame().getSorenRandNum(100, "Kidnap") <= iChance:
		i = CyGame().getSorenRandNum(len(listUnits), "Bob")
		newUnit = pPlayer.initUnit(listUnits[i], caster.getX(), caster.getY(), UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)
		pCity.changeFreeSpecialistCount(listSpecs[i], -1)
	else:
		if CyGame().getSorenRandNum(100, "Kidnap") <= 50:
			caster.setXY(pPlayer.getCapitalCity().getX(), pPlayer.getCapitalCity().getY(), false, true, true)
		else:
			caster.kill(True, 0)
		startWar(caster.getOwner(), pCity.getOwner())
 
The same for the fun :) :

Spoiler :
Code:
def spellKidnap(caster):
	pCity = caster.plot().getPlotCity()
	listUnits = [gc.getInfoTypeForString(item) for item in ['UNIT_PROPHET', 'UNIT_ARTIST', 'UNIT_MERCHANT', 'UNIT_ENGINEER', 'UNIT_SCIENTIST']]
	listSpecs = [gc.getInfoTypeForString(item) for item in ['SPECIALIST_GREAT_PRIEST', 'SPECIALIST_GREAT_ARTIST', 'SPECIALIST_GREAT_MERCHANT', 'SPECIALIST_GREAT_ENGINEER', 'SPECIALIST_GREAT_SCIENTIST']]
	listSpecsChance = []
	for iSpe in listSpecs :
                for j in range(pCity.getFreeSpecialistCount(iSpe)) : # range(0) = []
                        listSpecsChance.append(iSpe)

	iChance = caster.baseCombatStr() * 8
	iChance = iChance + caster.getExperience()
	if iChance > 80:
		iChance = 80
	pPlayer = gc.getPlayer(caster.getOwner())
	if CyGame().getSorenRandNum(100, "Kidnap") <= iChance:
		iSpecialist = listSpecsChance[CyGame().getSorenRandNum(len(listSpecsChance), "FfH : Specialist Choice")]
		newUnit = pPlayer.initUnit(listUnits[listSpecs.index(iSpecialist)], caster.getX(), caster.getY(), UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)
		pCity.changeFreeSpecialistCount(iSpecialist, -1)
	else:
		if CyGame().getSorenRandNum(100, "Kidnap") <= 50:
			caster.setXY(pPlayer.getCapitalCity().getX(), pPlayer.getCapitalCity().getY(), false, true, true)
		else:
			caster.kill(True, 0)
		startWar(caster.getOwner(), pCity.getOwner())

Tcho !
 
Back
Top Bottom