[MOD] More Naval AI

Assuming by "Rise" you meant Rise from Erebus, no, that would not be the reason; Nor does it have poor stability or AI at this point, thanks to Snarko.

It was dropped because we are tired of operating within the bounds of FfH; Much the same reason Ahwaric has chosen to work on Orbis 2 rather than Orbis, for example. We are working on one final release, which polishes the AI and fixes any stability issues we had. If you're interested in giving that release a try early, the beta is available.

http://forums.civfanatics.com/showth...5#post11249695

Ah, that's good to hear. I've been waiting quite some time for a new version from Rise from Erebus and was a bit dissapointed, when it was dropped.
I played it once at least a year ago, and it had great features but some serious stability and AI issues. If those will be fixed, I'll definitely give it a try. :)
 
I just want to add here that WM wasn't 'abandoned'. It's a very clean and finished build.
The AI could be a bit better in end game, but besides that, the mod is probably the most polished FFH2 sub-mod available.

I agree that WM is clean, finished, polished, etc... but it is also abandoned. Arkhan in another thread you told me I would have to PM Sephi to request the source code for WM. Also the only way I could download WM was through links provided by players who didn't even develop the game. In my opinion that counts as abandoned, and it is sad that such a finished mod was abandoned.

Sorry to go off topic. I won't use up any more space in this thread on WM. Long live More Naval AI! :king:

edit: I said I wouldn't use more space on WM, so I will respond to Aline (see below) right here. The link you provided is to Master of Mana not WildMana. I know MoM started out as WM 9, but it changed so many things that it became a different mod (as it should).
 
Woot:D Had barbarians dropping galleys full of axemen on my strategic resources!

Played 3 games so far, well started .. Erebus continents, medium sea level, medium cohesion, city ruins on ... whoops, gotta stop using that option on Monarch

I was next to Khazad who explored everything .. killing himself and me with spectre/wraiths once, and a couple ogres the next time.. third time the barbs start doing naval invasions on my backside :D

Love the work! I gotta stop playing sloppy now. :king:

ooh /edit

Did +1 happy get removed from god king ? Or was that one of my local edits.
 
There seems to be a bug with the Black Mirror (or equipment). Just had a stack of Svartalfar elves/tigers attack where they all had the black mirror promotion. I went into WB and had a quick look and it seems that this might be the only stack where that had happened.

They'd been at war with another side so perhaps when Svartalfar hero had died something buggy had happened? Earlier in the game I'd killed two Arthnenadains belonging to another side and captured a black mirror of my own (now I have enough to make a very interesting maze). So they'd managed to loose it previously.
 
I'm thinking of releasing a new version of MagisterModmod based on More Naval AI. I have merged my latest version with it and for the most part it seems to be working fine, but BugGameUtils.py seems to be preventing anything in CvGameUtils.py from being read. I've come across threads explaining how functions in CvGameUtils.py that were not in the default BtS version of the file can cause problems, but I don't understand why it seems to work fine in your version and not in mine. I made some changes to the file, but they were fairly minor. I did not add or remove any of your functions, only merged in things that worked perfectly without BUG.
 
I have been looking at the tech screen, it appears that when you click on a tech, the code that adds the number of turns to the label, is also recalculating the location of the label and changing it. That would narrow down where to look, if I knew where to look in the first place :)

My first guess is there is a hard coded value or variable name not changed when they made the wide tech window. I looked in TechWindowWide.py but my eyes bugged out after a few minutes. :eek:
 
v2.0, Great!

I have been looking at the tech screen, it appears that when you click on a tech, the code that adds the number of turns to the label, is also recalculating the location of the label and changing it. That would narrow down where to look, if I knew where to look in the first place :)

My first guess is there is a hard coded value or variable name not changed when they made the wide tech window. I looked in TechWindowWide.py but my eyes bugged out after a few minutes. :eek:

In Screens/CvTechChooser, I changed
Code:
screen.setTextAt( szTechID, sPanel, szTechString, CvUtil.FONT_LEFT_JUSTIFY, iX + 6 + X_INCREMENT, iY + 6, -0.1, FontTypes.SMALL_FONT, WidgetTypes.WIDGET_TECH_TREE, i, -1 )
to
Code:
#reset so that it offsets from the tech record's panel
iX = 6
iY = 6
screen.setTextAt( szTechID, szTechRecord, szTechString, CvUtil.FONT_LEFT_JUSTIFY, iX + 6 + X_INCREMENT, iY + 6, -0.1, FontTypes.SMALL_FONT, WidgetTypes.WIDGET_TECH_TREE, i, -1 )
That way it is done in line ~160
Now It seem to work

EDIT: Tholal said he fixed it. I'm not sure we meant the same thing, I will dowload the repository and check it
 
[*]BUG folders are not created.

Known issue. BUG wont create the directories. Apparently I need to do that with the installer.

[*]There is a typo in the Advanced Tactics option tooltip. It says "Adds new COmbat results..."

Fixed (rev 841).

[*]The tooltip of the Establish embassies option mentions espionage missions.

I decided to leave that in for now in case someone mods Espionage back in. I might remove it later.

[*]Shortcuts and Strategy Guides have no entries. Shortcuts should get the old page with small additions such as BUG or AIAutoPlay shortcuts. Strategy guides could be removed.

Strategy Guides section has been removed. Still cant seem to get Shortcuts to show up. I need to play around with it some more. I noticed last night that Items arent showing up in the Sevopedia at all, so I need to look into that also.

[*]The tech names are still appearing in the wrong place at the research advisor.

I've also seen the problem with the display of names in the Tech tree. They were initially displayed normally but when I clicked on one, the positioning of the name got messed up as Terken had shown earlier.

I have been looking at the tech screen, it appears that when you click on a tech, the code that adds the number of turns to the label, is also recalculating the location of the label and changing it.

Yep. It was related to selecting a tech on the tech screen. I had made each tech tab slightly wider to accommodate techs that had lots of icons but the width was hardcoded in more that one spot. Fixed (rev 840)

We spotted a bug with the new "capture siege equipment" feature. If the attacker is on a peak (for example, Abashi), the captured siege equipment will appear on the peak too.

Fixed (rev 842)

There seems to be a bug with the Black Mirror (or equipment). Just had a stack of Svartalfar elves/tigers attack where they all had the black mirror promotion. I went into WB and had a quick look and it seems that this might be the only stack where that had happened.

Strange. I played around with the Black Mirror in all sorts of situations and couldn't get it to duplicate. Anyone have any idea how this is happening or have a save game from right before it happens?

Stasis continues after the Illians are destroyed, I can't remember if this happened before.

But Stasis still goes away after X number of turns correct? If so, I would say it's by design. World Spells are powerful magic. Once started, there is no turning back.

I'm thinking of releasing a new version of MagisterModmod based on More Naval AI. I have merged my latest version with it and for the most part it seems to be working fine, but BugGameUtils.py seems to be preventing anything in CvGameUtils.py from being read. I've come across threads explaining how functions in CvGameUtils.py that were not in the default BtS version of the file can cause problems, but I don't understand why it seems to work fine in your version and not in mine. I made some changes to the file, but they were fairly minor. I did not add or remove any of your functions, only merged in things that worked perfectly without BUG.


I had lots of issue with this as well. I ended up having to dump CvGameInterfaceFile.py and that seemed to fix things. Never did figure out what was going wrong.
 
Spoiler :
Civ4ScreenShot0047.jpg


Should he realy be telling everyone about this?
 
I has a save game close to the point when it was happening and played through a few turns again. It looks like a hidden nationality Alazkan is duplicating both himself and the mirror, then when the illusion ends the duplicated mirror is left behind.

Alazkan is around the Svaltfar city of Zbulob, their northern most city. In the first save there are two Alazkans and one worker in a square just north of the city. The next turn Alazkan has moved into the city and the worker now has the black mirror promotion.

I'm playing as Banor and thir empire is south of mine. I used the Erubus continent map script to generate the map.

Interestingly later on in the game one of the AIs actually asked me to make peace with a different AI. I don't think I've ever seen that happen before, in any version of the game I've played (including BTS and the BAT mod).
 

Attachments

No matter what I do, including random suicide combats to disrupt the random numbers, when OO is founded on turn 323, no matter where the zealot appears, the holy city is put in Innsmouth.

This is my second game with this setup, where I had extra cities and it founded in the capital, I am not normally that lucky so I tested it a bit from this save.

Bah humbug, shouldn't have bought all those lottery tickets today either! :cry:

I downloaded it on Sunday, the CRC-32 is 415BBB06 but I can't see where the build number is.

I also noticed that in diplo chat with someone following CoE, the CoE icon is next to their name. I thought no one was supposed to be able to see if you had CoE for a state religion?
 

Attachments

I see that when you establish a puppet state that they get the techs of the original owner and as a vassal they are quite happy to trade them away. Would it be better to either give them the tech s of the conqueror or to treat them as unable to trade those techs? Otherwise it seems like there is an option to pick up on some quite cheaply when the original civ won't trade them. It might just be a bonus for the warmongers...

Also I see that great generals can't be combined with disciple units. Is this intentional?

[Edit] My hidden nationality shadow just captured a catapult. I may be misremembering things but I thought hidden nationality couldn't capture?
 
Spoiler :
I had lots of issue with this as well. I ended up having to dump CvGameInterfaceFile.py and that seemed to fix things. Never did figure out what was going wrong.
Obviously since you deleted that file before I merged your mod with mine I couldn't just delete it from my mod to fix the problem. However, I just remembered that in order to get those error messages about not finding the right ini files to disappear I ran the installer for the full BUG mod. Rather than installing in the Mods folder, its files were placed in BtS's CustomAssets folder. I found the file you mention there, and changed its extension to disable it.

This does seem to have stopped the problem of not loading CvGameUtils.py, as evidenced by the fact that I can no longer build the Shrine of the Champion on the first turn. This leaves me rather confused though, as the unaltered version of your modmod works the same with or without that file in CustomAssets.

Also, it might just be a coincidence, but the mod seemed stable with that file yet crashed to the desktop on about the 8th turn in my first game without it.

Edit: my first game after re-enabling the file crashed around the same time, so I guess that file was not the cause.


Every game of my modmod starts with a "BugInit - init 'UnitUtil' failed" error. Could you help me figure out how to fix that?

The start of every game also showed errors based undefined TXT_KEYs for various units and a unitcombat (I added UNITCOMBAT_CIVILIAN for workers and great people, so they could benefit from spells like Haste), but I fixed those rather easily.


Whenever a unit is killed I the message "Error in unitKilled event handler <bound methd BugEventManager.onUnitKilled of <BugEventManager.BugEventManager instance at 0x0F3D8B20>>" and when one is created (at least from a free tech, not worldbuilder or upon map generation) I get the message "error in unitCreated event handler <bound method BugeventManager.onUnitCreated of <BugEventManager.BugEventManager instance at 0x0F57FAF8>>"do you know what could be causing those?

Edit: I got rid of the error in onUnitCreated by deleting a short section of code that attempted to call applyBuildEffects if the unit happened to have been initialized inside a city.

I did make a fair number of changes within onUnitCreated and onUnitKilled, so perhaps you don't. These changes include letting Mokka's Cauldron function as a piece of equipment (either promotion or unit) instead of only as a building in a city, making The Soul Forge process the souls of units belonging to its owner rather than of units that happen to be nearby, and creating Sluagh units to store information of dead heroes so that my resurrection spells can bring them back with their promotions, levels, and xp intact. I also tried moving this to onUnitLost, to avoid problems with resurrection in cases where a hero was lost without combat, but got the same kind of error there.

I believe I had tried that before merging with your mod but found that onUnitLost did not seem to be called in normal FfH. I had assumed you had activated it because of the Treant code you had placed there. I thought I had read that treants in your mod were supposed to leave new forests behind when their duration ran out, but that does not seem to be the case when I tested it in any version. I'm not sure that the code there works at all, or at least not any better than if it were in onUnitKilled.


Edit: The onUnitKilled error goes away if I remove all the Sluagh code. I guess that means the problem is in here somewhere
Spoiler :
Note that bSoul was set to true at the top of the define, and then false if the unit was processed by the soul forge. This code comes before angels and manes are gifted, which only happens if bSoul remains true.
Code:
if bSoul:

				if unit.getUnitType() == gc.getInfoTypeForString('UNIT_DONAL'):
					newUnit= bPlayer.initUnit(gc.getInfoTypeForString('UNIT_SLUAGH_DONAL'), 0,0, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)
					newUnit.setLevel(unit.getLevel())
					newUnit.setExperience(unit.getExperience(), -1)
					newUnit.setName(unit.getNameNoDesc())
					for iCount in range(gc.getNumPromotionInfos()):
						if (unit.isHasPromotion(iCount)) and not gc.getPromotionInfo(iCount).isEquipment():
							newUnit.setHasPromotion(iCount, True)

					bSoul = False
				elif unit.getUnitType() == gc.getInfoTypeForString('UNIT_TEUTORIX'):
					newUnit= bPlayer.initUnit(gc.getInfoTypeForString('UNIT_SLUAGH_TEUTORIX'), 0,0, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)
					newUnit.setLevel(unit.getLevel())
					newUnit.setExperience(unit.getExperience(), -1)
					newUnit.setName(unit.getNameNoDesc())
					for iCount in range(gc.getNumPromotionInfos()):
						if (unit.isHasPromotion(iCount)) and not gc.getPromotionInfo(iCount).isEquipment():
							newUnit.setHasPromotion(iCount, True)
					bSoul = False
				elif unit.getUnitType() == gc.getInfoTypeForString('UNIT_CORLINDALE'):
					newUnit= bPlayer.initUnit(gc.getInfoTypeForString('UNIT_SLUAGH_CORLINDALE'), 0,0, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)
					newUnit.setLevel(unit.getLevel())
					newUnit.setExperience(unit.getExperience(), -1)
					newUnit.setName(unit.getNameNoDesc())
					for iCount in range(gc.getNumPromotionInfos()):
						if (unit.isHasPromotion(iCount)) and not gc.getPromotionInfo(iCount).isEquipment():
							newUnit.setHasPromotion(iCount, True)
					bSoul = False
				elif unit.getUnitType() == gc.getInfoTypeForString('UNIT_GUYBRUSH'):
					newUnit= bPlayer.initUnit(gc.getInfoTypeForString('UNIT_SLUAGH_GUYBRUSH'), 0,0, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)
					newUnit.setLevel(unit.getLevel())
					newUnit.setExperience(unit.getExperience(), -1)
					newUnit.setName(unit.getNameNoDesc())
					for iCount in range(gc.getNumPromotionInfos()):
						if (unit.isHasPromotion(iCount)) and not gc.getPromotionInfo(iCount).isEquipment():
							newUnit.setHasPromotion(iCount, True)
					bSoul = False
				elif unit.getUnitType() == gc.getInfoTypeForString('UNIT_HERNE'):
					newUnit= bPlayer.initUnit(gc.getInfoTypeForString('UNIT_SLUAGH_HERNE'), 0,0, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)
					newUnit.setLevel(unit.getLevel())
					newUnit.setExperience(unit.getExperience(), -1)
					newUnit.setName(unit.getNameNoDesc())
					for iCount in range(gc.getNumPromotionInfos()):
						if (unit.isHasPromotion(iCount)) and not gc.getPromotionInfo(iCount).isEquipment():
							newUnit.setHasPromotion(iCount, True)
					bSoul = False
				elif unit.getUnitType() == gc.getInfoTypeForString('UNIT_GILDEN'):
					newUnit= bPlayer.initUnit(gc.getInfoTypeForString('UNIT_SLUAGH_GILDEN'), 0,0, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)
					newUnit.setLevel(unit.getLevel())
					newUnit.setExperience(unit.getExperience(), -1)
					newUnit.setName(unit.getNameNoDesc())
					for iCount in range(gc.getNumPromotionInfos()):
						if (unit.isHasPromotion(iCount)) and not gc.getPromotionInfo(iCount).isEquipment():
							newUnit.setHasPromotion(iCount, True)
					bSoul = False
				elif unit.getUnitType() == gc.getInfoTypeForString('UNIT_MAROS'):
					newUnit= bPlayer.initUnit(gc.getInfoTypeForString('UNIT_SLUAGH_MAROS'), 0,0, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)
					newUnit.setLevel(unit.getLevel())
					newUnit.setExperience(unit.getExperience(), -1)
					newUnit.setName(unit.getNameNoDesc())
					for iCount in range(gc.getNumPromotionInfos()):
						if (unit.isHasPromotion(iCount)) and not gc.getPromotionInfo(iCount).isEquipment():
							newUnit.setHasPromotion(iCount, True)
					bSoul = False
				elif unit.getUnitType() == gc.getInfoTypeForString('UNIT_MAGNADINE'):
					newUnit= bPlayer.initUnit(gc.getInfoTypeForString('UNIT_SLUAGH_MAGNADINE'), 0,0, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)
					newUnit.setLevel(unit.getLevel())
					newUnit.setExperience(unit.getExperience(), -1)
					newUnit.setName(unit.getNameNoDesc())
					for iCount in range(gc.getNumPromotionInfos()):
						if (unit.isHasPromotion(iCount)) and not gc.getPromotionInfo(iCount).isEquipment():
							newUnit.setHasPromotion(iCount, True)
					bSoul = False
				elif unit.getUnitType() == gc.getInfoTypeForString('UNIT_GOVANNON'):
					newUnit= bPlayer.initUnit(gc.getInfoTypeForString('UNIT_SLUAGH_GOVANNON'), 0,0, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)
					newUnit.setLevel(unit.getLevel())
					newUnit.setExperience(unit.getExperience(), -1)
					newUnit.setName(unit.getNameNoDesc())
					for iCount in range(gc.getNumPromotionInfos()):
						if (unit.isHasPromotion(iCount)) and not gc.getPromotionInfo(iCount).isEquipment():
							newUnit.setHasPromotion(iCount, True)
					bSoul = False
				elif unit.getUnitType() == gc.getInfoTypeForString('UNIT_LOKI'):
					newUnit= bPlayer.initUnit(gc.getInfoTypeForString('UNIT_SLUAGH_LOKI'), 0,0, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)
					newUnit.setLevel(unit.getLevel())
					newUnit.setExperience(unit.getExperience(), -1)
					newUnit.setName(unit.getNameNoDesc())
					for iCount in range(gc.getNumPromotionInfos()):
						if (unit.isHasPromotion(iCount)) and not gc.getPromotionInfo(iCount).isEquipment():
							newUnit.setHasPromotion(iCount, True)
					bSoul = False
				elif unit.getUnitType() == gc.getInfoTypeForString('UNIT_RANTINE'):
					newUnit= bPlayer.initUnit(gc.getInfoTypeForString('UNIT_SLUAGH_RANTINE'), 0,0, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)
					newUnit.setLevel(unit.getLevel())
					newUnit.setExperience(unit.getExperience(), -1)
					newUnit.setName(unit.getNameNoDesc())
					for iCount in range(gc.getNumPromotionInfos()):
						if (unit.isHasPromotion(iCount)) and not gc.getPromotionInfo(iCount).isEquipment():
							newUnit.setHasPromotion(iCount, True)
					bSoul = False
				elif unit.getUnitType() == gc.getInfoTypeForString('UNIT_ALAZKAN'):
					newUnit= bPlayer.initUnit(gc.getInfoTypeForString('UNIT_SLUAGH_ALAZKAN'), 0,0, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)
					newUnit.setLevel(unit.getLevel())
					newUnit.setExperience(unit.getExperience(), -1)
					newUnit.setName(unit.getNameNoDesc())
					for iCount in range(gc.getNumPromotionInfos()):
						if (unit.isHasPromotion(iCount)) and not gc.getPromotionInfo(iCount).isEquipment():
							newUnit.setHasPromotion(iCount, True)
					bSoul = False
				elif unit.getUnitType() == gc.getInfoTypeForString('UNIT_LOSHA'):
					newUnit= bPlayer.initUnit(gc.getInfoTypeForString('UNIT_SLUAGH_LOSHA'), 0,0, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)
					newUnit.setLevel(unit.getLevel())
					newUnit.setExperience(unit.getExperience(), -1)
					newUnit.setName(unit.getNameNoDesc())
					for iCount in range(gc.getNumPromotionInfos()):
						if (unit.isHasPromotion(iCount)) and not gc.getPromotionInfo(iCount).isEquipment():
							newUnit.setHasPromotion(iCount, True)
					bSoul = False
				elif unit.getUnitType() == gc.getInfoTypeForString('UNIT_GOSEA'):
					newUnit= bPlayer.initUnit(gc.getInfoTypeForString('UNIT_SLUAGH_GOSEA'), 0,0, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)
					newUnit.setLevel(unit.getLevel())
					newUnit.setExperience(unit.getExperience(), -1)
					newUnit.setName(unit.getNameNoDesc())
					for iCount in range(gc.getNumPromotionInfos()):
						if (unit.isHasPromotion(iCount)) and not gc.getPromotionInfo(iCount).isEquipment():
							newUnit.setHasPromotion(iCount, True)
					bSoul = False
				elif unit.getUnitType() == gc.getInfoTypeForString('UNIT_RATHUS'):
					newUnit= bPlayer.initUnit(gc.getInfoTypeForString('UNIT_SLUAGH_RATHUS'), 0,0, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)
					newUnit.setLevel(unit.getLevel())
					newUnit.setExperience(unit.getExperience(), -1)
					newUnit.setName(unit.getNameNoDesc())
					for iCount in range(gc.getNumPromotionInfos()):
						if (unit.isHasPromotion(iCount)) and not gc.getPromotionInfo(iCount).isEquipment():
							newUnit.setHasPromotion(iCount, True)
					bSoul = False
				elif unit.getUnitType() == gc.getInfoTypeForString('UNIT_AURIC'):
					newUnit= bPlayer.initUnit(gc.getInfoTypeForString('UNIT_SLUAGH_AURIC'), 0,0, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)
					newUnit.setLevel(unit.getLevel())
					newUnit.setExperience(unit.getExperience(), -1)
					newUnit.setName(unit.getNameNoDesc())
					for iCount in range(gc.getNumPromotionInfos()):
						if (unit.isHasPromotion(iCount)) and not gc.getPromotionInfo(iCount).isEquipment():
							newUnit.setHasPromotion(iCount, True)
					bSoul = False
				if unit.isHasPromotion(gc.getInfoTypeForString('PROMOTION_ADVENTURER')):
					newUnit= bPlayer.initUnit(gc.getInfoTypeForString('UNIT_SLUAGH_ADVENTURER'), 0,0, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)
					newUnit.setLevel(unit.getLevel())
					newUnit.setExperience(unit.getExperience(), -1)
					newUnit.setName(unit.getNameNoDesc())
					for iCount in range(gc.getNumPromotionInfos()):
						if (unit.isHasPromotion(iCount)) and not gc.getPromotionInfo(iCount).isEquipment():
							newUnit.setHasPromotion(iCount, True)
					bSoul = False
				elif unit.getUnitType() == gc.getInfoTypeForString('UNIT_DUIN'):
					newUnit= bPlayer.initUnit(gc.getInfoTypeForString('UNIT_SLUAGH_DUIN'), 0,0, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)
					newUnit.setLevel(unit.getLevel())
					newUnit.setExperience(unit.getExperience(), -1)
					newUnit.setName(unit.getNameNoDesc())
					for iCount in range(gc.getNumPromotionInfos()):
						if (unit.isHasPromotion(iCount)) and not gc.getPromotionInfo(iCount).isEquipment():
							newUnit.setHasPromotion(iCount, True)
					bSoul = False
				elif unit.getUnitType() == gc.getInfoTypeForString('UNIT_MARY'):
					newUnit= bPlayer.initUnit(gc.getInfoTypeForString('UNIT_SLUAGH_MARY'), 0,0, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)
					newUnit.setLevel(unit.getLevel())
					newUnit.setExperience(unit.getExperience(), -1)
					newUnit.setName(unit.getNameNoDesc())
					for iCount in range(gc.getNumPromotionInfos()):
						if (unit.isHasPromotion(iCount)) and not gc.getPromotionInfo(iCount).isEquipment():
							newUnit.setHasPromotion(iCount, True)
					bSoul = False
				elif unit.getUnitType() == gc.getInfoTypeForString('UNIT_ROSIER'):
					newUnit= bPlayer.initUnit(gc.getInfoTypeForString('UNIT_SLUAGH_ROSIER'), 0,0, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)
					newUnit.setLevel(unit.getLevel())
					newUnit.setExperience(unit.getExperience(), -1)
					newUnit.setName(unit.getNameNoDesc())
					for iCount in range(gc.getNumPromotionInfos()):
						if (unit.isHasPromotion(iCount)) and not gc.getPromotionInfo(iCount).isEquipment():
							newUnit.setHasPromotion(iCount, True)
					bSoul = False
				elif unit.getUnitType() == gc.getInfoTypeForString('UNIT_VALIN'):
					newUnit= bPlayer.initUnit(gc.getInfoTypeForString('UNIT_SLUAGH_VALIN'), 0,0, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)
					newUnit.setLevel(unit.getLevel())
					newUnit.setExperience(unit.getExperience(), -1)
					newUnit.setName(unit.getNameNoDesc())
					for iCount in range(gc.getNumPromotionInfos()):
						if (unit.isHasPromotion(iCount)) and not gc.getPromotionInfo(iCount).isEquipment():
							newUnit.setHasPromotion(iCount, True)
					bSoul = False
				elif unit.getUnitType() == gc.getInfoTypeForString('UNIT_BAMBUR'):
					newUnit= bPlayer.initUnit(gc.getInfoTypeForString('UNIT_SLUAGH_BAMBUR'), 0,0, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)
					newUnit.setLevel(unit.getLevel())
					newUnit.setExperience(unit.getExperience(), -1)
					newUnit.setName(unit.getNameNoDesc())
					for iCount in range(gc.getNumPromotionInfos()):
						if (unit.isHasPromotion(iCount)) and not gc.getPromotionInfo(iCount).isEquipment():
							newUnit.setHasPromotion(iCount, True)
					bSoul = False
				elif unit.getUnitType() == gc.getInfoTypeForString('UNIT_HEMAH'):
					newUnit= bPlayer.initUnit(gc.getInfoTypeForString('UNIT_SLUAGH_HEMAH'), 0,0, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)
					newUnit.setLevel(unit.getLevel())
					newUnit.setExperience(unit.getExperience(), -1)
					newUnit.setName(unit.getNameNoDesc())
					for iCount in range(gc.getNumPromotionInfos()):
						if (unit.isHasPromotion(iCount)) and not gc.getPromotionInfo(iCount).isEquipment():
							newUnit.setHasPromotion(iCount, True)
					bSoul = False
				elif unit.getUnitType() == gc.getInfoTypeForString('UNIT_MOKKA'):
					newUnit= bPlayer.initUnit(gc.getInfoTypeForString('UNIT_SLUAGH_MOKKA'), 0,0, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)
					newUnit.setLevel(unit.getLevel())
					newUnit.setExperience(unit.getExperience(), -1)
					newUnit.setName(unit.getNameNoDesc())
					for iCount in range(gc.getNumPromotionInfos()):
						if (unit.isHasPromotion(iCount)) and not gc.getPromotionInfo(iCount).isEquipment():
							newUnit.setHasPromotion(iCount, True)
					bSoul = False
				elif unit.getUnitType() == gc.getInfoTypeForString('UNIT_TUMTUM'):
					newUnit= bPlayer.initUnit(gc.getInfoTypeForString('UNIT_SLUAGH_TUMTUM'), 0,0, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)
					newUnit.setLevel(unit.getLevel())
					newUnit.setExperience(unit.getExperience(), -1)
					newUnit.setName(unit.getNameNoDesc())
					for iCount in range(gc.getNumPromotionInfos()):
						if (unit.isHasPromotion(iCount)) and not gc.getPromotionInfo(iCount).isEquipment():
							newUnit.setHasPromotion(iCount, True)
					bSoul = False
				elif unit.getUnitType() == gc.getInfoTypeForString('UNIT_LUCIAN'):
					newUnit= bPlayer.initUnit(gc.getInfoTypeForString('UNIT_SLUAGH_LUCIAN'), 0,0, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)
					newUnit.setLevel(unit.getLevel())
					newUnit.setExperience(unit.getExperience(), -1)
					newUnit.setName(unit.getNameNoDesc())
					for iCount in range(gc.getNumPromotionInfos()):
						if (unit.isHasPromotion(iCount)) and not gc.getPromotionInfo(iCount).isEquipment():
							newUnit.setHasPromotion(iCount, True)
					bSoul = False
				elif unit.getUnitType() == gc.getInfoTypeForString('UNIT_GAELAN'):
					newUnit= bPlayer.initUnit(gc.getInfoTypeForString('UNIT_SLUAGH_GAELAN'), 0,0, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)
					newUnit.setLevel(unit.getLevel())
					newUnit.setExperience(unit.getExperience(), -1)
					newUnit.setName(unit.getNameNoDesc())
					for iCount in range(gc.getNumPromotionInfos()):
						if (unit.isHasPromotion(iCount)) and not gc.getPromotionInfo(iCount).isEquipment():
							newUnit.setHasPromotion(iCount, True)
					bSoul = False
				elif unit.getUnitType() == gc.getInfoTypeForString('UNIT_WILBOMAN'):
					newUnit= bPlayer.initUnit(gc.getInfoTypeForString('UNIT_SLUAGH_WILBOMAN'), 0,0, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)
					newUnit.setLevel(unit.getLevel())
					newUnit.setExperience(unit.getExperience(), -1)
					newUnit.setName(unit.getNameNoDesc())
					for iCount in range(gc.getNumPromotionInfos()):
						if (unit.isHasPromotion(iCount)) and not gc.getPromotionInfo(iCount).isEquipment():
							newUnit.setHasPromotion(iCount, True)
					bSoul = False
				elif unit.getUnitType() == gc.getInfoTypeForString('UNIT_CHALID'):
					newUnit= bPlayer.initUnit(gc.getInfoTypeForString('UNIT_SLUAGH_CHALID'), 0,0, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)
					newUnit.setLevel(unit.getLevel())
					newUnit.setExperience(unit.getExperience(), -1)
					newUnit.setName(unit.getNameNoDesc())
					for iCount in range(gc.getNumPromotionInfos()):
						if (unit.isHasPromotion(iCount)) and not gc.getPromotionInfo(iCount).isEquipment():
							newUnit.setHasPromotion(iCount, True)
					bSoul = False
				elif unit.getUnitType() == gc.getInfoTypeForString('UNIT_GIBBON'):
					newUnit= bPlayer.initUnit(gc.getInfoTypeForString('UNIT_SLUAGH_GIBBON'), 0,0, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)
					newUnit.setLevel(unit.getLevel())
					newUnit.setExperience(unit.getExperience(), -1)
					newUnit.setName(unit.getNameNoDesc())
					for iCount in range(gc.getNumPromotionInfos()):
						if (unit.isHasPromotion(iCount)) and not gc.getPromotionInfo(iCount).isEquipment():
							newUnit.setHasPromotion(iCount, True)
					bSoul = False
				elif unit.getUnitType() == gc.getInfoTypeForString('UNIT_ORTHUS'):
					newUnit= bPlayer.initUnit(gc.getInfoTypeForString('UNIT_SLUAGH_ORTHUS'), 0,0, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)
					newUnit.setLevel(unit.getLevel())
					newUnit.setExperience(unit.getExperience(), -1)
					newUnit.setName(unit.getNameNoDesc())
					for iCount in range(gc.getNumPromotionInfos()):
						if (unit.isHasPromotion(iCount)) and not gc.getPromotionInfo(iCount).isEquipment():
							newUnit.setHasPromotion(iCount, True)
					bSoul = False
				elif unit.getUnitType() == gc.getInfoTypeForString('UNIT_YVAIN'):
					newUnit= bPlayer.initUnit(gc.getInfoTypeForString('UNIT_SLUAGH_YVAIN'), 0,0, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)
					newUnit.setLevel(unit.getLevel())
					newUnit.setExperience(unit.getExperience(), -1)
					newUnit.setName(unit.getNameNoDesc())
					for iCount in range(gc.getNumPromotionInfos()):
						if (unit.isHasPromotion(iCount)) and not gc.getPromotionInfo(iCount).isEquipment():
							newUnit.setHasPromotion(iCount, True)
					bSoul = False
				elif unit.getUnitType() == gc.getInfoTypeForString('UNIT_KITHRA'):
					newUnit= bPlayer.initUnit(gc.getInfoTypeForString('UNIT_SLUAGH_KITHRA'), 0,0, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)
					newUnit.setLevel(unit.getLevel())
					newUnit.setExperience(unit.getExperience(), -1)
					newUnit.setName(unit.getNameNoDesc())
					for iCount in range(gc.getNumPromotionInfos()):
						if (unit.isHasPromotion(iCount)) and not gc.getPromotionInfo(iCount).isEquipment():
							newUnit.setHasPromotion(iCount, True)
					bSoul = False
				elif unit.getUnitType() == gc.getInfoTypeForString('UNIT_ARTHENDAIN'):
					newUnit= bPlayer.initUnit(gc.getInfoTypeForString('UNIT_SLUAGH_ARTHENDAIN'), 0,0, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)
					newUnit.setLevel(unit.getLevel())
					newUnit.setExperience(unit.getExperience(), -1)
					newUnit.setName(unit.getNameNoDesc())
					for iCount in range(gc.getNumPromotionInfos()):
						if (unit.isHasPromotion(iCount)) and not gc.getPromotionInfo(iCount).isEquipment():
							newUnit.setHasPromotion(iCount, True)
					bSoul = False
				elif unit.getUnitType() == gc.getInfoTypeForString('UNIT_SAVEROUS'):
					newUnit= bPlayer.initUnit(gc.getInfoTypeForString('UNIT_SLUAGH_SAVEROUS'), 0,0, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)
					newUnit.setLevel(unit.getLevel())
					newUnit.setExperience(unit.getExperience(), -1)
					newUnit.setName(unit.getNameNoDesc())
					for iCount in range(gc.getNumPromotionInfos()):
						if (unit.isHasPromotion(iCount)) and not gc.getPromotionInfo(iCount).isEquipment():
							newUnit.setHasPromotion(iCount, True)
					bSoul = False
				elif unit.getUnitType() == gc.getInfoTypeForString('UNIT_MARDERO'):
					newUnit= bPlayer.initUnit(gc.getInfoTypeForString('UNIT_SLUAGH_MARDERO'), 0,0, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)
					newUnit.setLevel(unit.getLevel())
					newUnit.setExperience(unit.getExperience(), -1)
					newUnit.setName(unit.getNameNoDesc())
					for iCount in range(gc.getNumPromotionInfos()):
						if (unit.isHasPromotion(iCount)) and not gc.getPromotionInfo(iCount).isEquipment():
							newUnit.setHasPromotion(iCount, True)
					bSoul = False


				elif unit.getUnitType() == gc.getInfoTypeForString('UNIT_HYBOREM'):
					newUnit= bPlayer.initUnit(gc.getInfoTypeForString('UNIT_SLUAGH_HYBOREM'), 0,0, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)
					newUnit.setLevel(unit.getLevel())
					newUnit.setExperience(unit.getExperience(), -1)
					newUnit.setName(unit.getNameNoDesc())
					for iCount in range(gc.getNumPromotionInfos()):
						if (unit.isHasPromotion(iCount)) and not gc.getPromotionInfo(iCount).isEquipment():
							newUnit.setHasPromotion(iCount, True)
					bSoul = False
				elif unit.getUnitType() == gc.getInfoTypeForString('UNIT_LETHE'):
					newUnit= bPlayer.initUnit(gc.getInfoTypeForString('UNIT_SLUAGH_LETHE'), 0,0, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)
					newUnit.setLevel(unit.getLevel())
					newUnit.setExperience(unit.getExperience(), -1)
					newUnit.setName(unit.getNameNoDesc())
					for iCount in range(gc.getNumPromotionInfos()):
						if (unit.isHasPromotion(iCount)) and not gc.getPromotionInfo(iCount).isEquipment():
							newUnit.setHasPromotion(iCount, True)
					bSoul = False
				elif unit.getUnitType() == gc.getInfoTypeForString('UNIT_JUDECCA'):
					newUnit= bPlayer.initUnit(gc.getInfoTypeForString('UNIT_SLUAGH_JUDECCA'), 0,0, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)
					newUnit.setLevel(unit.getLevel())
					newUnit.setExperience(unit.getExperience(), -1)
					newUnit.setName(unit.getNameNoDesc())
					for iCount in range(gc.getNumPromotionInfos()):
						if (unit.isHasPromotion(iCount)) and not gc.getPromotionInfo(iCount).isEquipment():
							newUnit.setHasPromotion(iCount, True)
					bSoul = False
				elif unit.getUnitType() == gc.getInfoTypeForString('UNIT_OUZZA'):
					newUnit= bPlayer.initUnit(gc.getInfoTypeForString('UNIT_SLUAGH_OUZZA'), 0,0, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)
					newUnit.setLevel(unit.getLevel())
					newUnit.setExperience(unit.getExperience(), -1)
					newUnit.setName(unit.getNameNoDesc())
					for iCount in range(gc.getNumPromotionInfos()):
						if (unit.isHasPromotion(iCount)) and not gc.getPromotionInfo(iCount).isEquipment():
							newUnit.setHasPromotion(iCount, True)
					bSoul = False
				elif unit.getUnitType() == gc.getInfoTypeForString('UNIT_MERESIN'):
					newUnit= bPlayer.initUnit(gc.getInfoTypeForString('UNIT_SLUAGH_MERESIN'), 0,0, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)
					newUnit.setLevel(unit.getLevel())
					newUnit.setExperience(unit.getExperience(), -1)
					newUnit.setName(unit.getNameNoDesc())
					for iCount in range(gc.getNumPromotionInfos()):
						if (unit.isHasPromotion(iCount)) and not gc.getPromotionInfo(iCount).isEquipment():
							newUnit.setHasPromotion(iCount, True)
					bSoul = False
				elif unit.getUnitType() == gc.getInfoTypeForString('UNIT_SALLOS'):
					newUnit= bPlayer.initUnit(gc.getInfoTypeForString('UNIT_SLUAGH_SALLOS'), 0,0, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)
					newUnit.setLevel(unit.getLevel())
					newUnit.setExperience(unit.getExperience(), -1)
					newUnit.setName(unit.getNameNoDesc())
					for iCount in range(gc.getNumPromotionInfos()):
						if (unit.isHasPromotion(iCount)) and not gc.getPromotionInfo(iCount).isEquipment():
							newUnit.setHasPromotion(iCount, True)
					bSoul = False
				elif unit.getUnitType() == gc.getInfoTypeForString('UNIT_STATIUS'):
					newUnit= bPlayer.initUnit(gc.getInfoTypeForString('UNIT_SLUAGH_STATIUS'), 0,0, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)
					newUnit.setLevel(unit.getLevel())
					newUnit.setExperience(unit.getExperience(), -1)
					newUnit.setName(unit.getNameNoDesc())
					for iCount in range(gc.getNumPromotionInfos()):
						if (unit.isHasPromotion(iCount)) and not gc.getPromotionInfo(iCount).isEquipment():
							newUnit.setHasPromotion(iCount, True)
					bSoul = False



				elif unit.getLevel() > 12 or unit.isHasPromotion(gc.getInfoTypeForString('PROMOTION_LAROTH_LEGIONNAIRE')) or unit.isHasPromotion(gc.getInfoTypeForString('PROMOTION_VINCULUS_VINDEX')):
					newUnit= bPlayer.initUnit(gc.getInfoTypeForString('UNIT_SLUAGH'), 0,0, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)
					newUnit.setLevel(unit.getLevel())
					newUnit.setExperience(unit.getExperience(), -1)
					newUnit.setName(unit.getNameNoDesc())
					for iCount in range(gc.getNumPromotionInfos()):
						if (unit.isHasPromotion(iCount)) and not gc.getPromotionInfo(iCount).isEquipment():
							newUnit.setHasPromotion(iCount, True)
					bSoul = False
It seems seems odd that any of this could matter, as no unit created that early in a test game could have met these if statements. Maybe the way I rename the units interferes with BUG's unit naming scheme?

Edit: Strangely, it seems that the code works perfectly fine if I move it all to CustomFunctions.py and call cf.Sluagh(unit) instead of trying to do it within def onUnitKilled. This is better for me anyway, as it makes it easier when units are killed by spells.



In a game I just started as the Sidar I got an error about a missing icon in the great person bar, probably because in my modmod the Sidar have an Elder Council UB that grants GPP towards Shades. I also noticed it looking really odd when I had earned great Commander points, probably because I am using different gamefonts than you. Mine are FfH2 gamefonts modified to include to accommodate icons for new types of mana, a new religions, and having the main religions reorganized from most good to most evil. I guess the best way to make the commander GPP show up right would be to include my edits in a new GameFont_75.tga based on yours, but I'm not sure what to do about Shade GPP.

Edit: I went ahead and created said GameFont_75.tga, and also edited GPUtil.py so that Shades appear as (CyGame().getSymbolID(FontSymbols.GREAT_GENERAL_CHAR)+3), a grey face with a flat line for a mouth.
Edit: I managed to fix everything but the "BugInit - init 'UnitUtil' failed" error on my own, and it doesn't seem to be causing problems.
 
It looks like a hidden nationality Alazkan is duplicating both himself and the mirror, then when the illusion ends the duplicated mirror is left behind.

That's the info I was looking for! Fixed (rev 843). Thanks!

Interestingly later on in the game one of the AIs actually asked me to make peace with a different AI. I don't think I've ever seen that happen before, in any version of the game I've played (including BTS and the BAT mod).

Think that code came with Advanced Diplomacy.
 
No matter what I do, including random suicide combats to disrupt the random numbers, when OO is founded on turn 323, no matter where the zealot appears, the holy city is put in Innsmouth.

This is part of base FFH. If you found a religion that is your civ's favorite religion, it's founded in your capitol.

Should he realy be telling everyone about this?

I also noticed that in diplo chat with someone following CoE, the CoE icon is next to their name. I thought no one was supposed to be able to see if you had CoE for a state religion?

CoE is kind of a weird religion. It's supposed to be a secret, but gameplay mechanics just don't support that idea. Though I could make it so that all references to your religion type are suppressed when following CoE, it would be purely aesthetic and not change gameplay at all, so I'm not sure that it's worth the trouble.


I see that when you establish a puppet state that they get the techs of the original owner and as a vassal they are quite happy to trade them away.

Good catch. I'll have to work on that.


Also I see that great generals can't be combined with disciple units. Is this intentional?

Unintentional. Will be fixed.

My hidden nationality shadow just captured a catapult. I may be misremembering things but I thought hidden nationality couldn't capture?

Probably via the new War Prizes code. I'll fix it.



Edit: I managed to fix everything but the "BugInit - init 'UnitUtil' failed" error on my own, and it doesn't seem to be causing problems.

Glad that you were able to fix all those issues. I dont really know about the BUG error. I never found their error messages very useful. Maybe dig around in the BUG subforum for clues.
 
This is part of base FFH. If you found a religion that is your civ's favorite religion, it's founded in your capitol.

Weird, been playing FFH2 for quite a while, and never noticed this behavior before I updated on Sunday the 12th. Not unwelcome! Possibly you fixed something that no one knew was broken :goodjob:
 
Back
Top Bottom