Version 2.62 released

Tholal

Emperor
Joined
May 19, 2009
Messages
1,676
Download link (not compatible with previous saves - sorry!)

This will probably be my final release (unless there is some major bug).

List of changes for this release follows:

Bugfixes
  • Units will no longer display positive damage messages when damaging themselves (example - moving onto a tile with a Blizzard)
  • fix for CivAlerts sending growth warning messages even though growth control is on
  • fix for a potential error in the Hell Terrain code
  • AI will now include AI_getPuppetAttitude() in its attitude value (bug find by Terkhen)
  • AI will now obey revealed limitations when choosing a city for a Trade Mission
  • fix for issues with Goblin Forts and Scorpion Clan Archers
  • fix for Illusionary units messing up the unit created count; Killing an Illusionary World unit should no longer trigger the global death message
  • AI players will no longer destroy lairs simply by moving on top of them
  • PuppetTradingCount will now be properly saved
  • fixes and code improvements to the Genesis spells
  • fix for a mis-coded variable loop (bug find by MC)
  • Heal spell will now work again (fix by fe79)
  • fix for infinite promotions when getFreePromotionPicks() is set to a neagtive number
  • Heal can no longer be cast on Magic Immune units
  • Frigates can now carry one Bird unit
  • new cities created by Barbarians will start with a technologically appropriate unit (re-aded some missing code)
  • Barbarians will create Acheron again

Features
  • Enhanced Worldbuilder - update to version 4.13b (thanks playpting and MC!)
  • UI - On the zoomed out Culture map, a player must have at least 20% culture on the plot before their player color will be shown on that plot (code taken from K-Mod)
  • Flavor Tweak - 10% of Forests will turn into Burnt Forest when plots change to Hell terrain; Volcanoes will sometimes erupt from long dormant mountains in Hell terrain
  • Sanctuary timer now displayed for casting civ
  • Game tweak - reducing the frequency, duration and severity of Blizzards
  • Game tweak - Hawks can now rebase to vassal and allied cities as well as carriers (code by fe79)
  • fix for Adept units not receiving free death promotions when the owner has multiple sources of death mana

AI
  • UNITAI_COUNTER units will now be assigned to GROUPFLAG_CONQUEST
  • tweak to how the AI decides to build Temples of the Hand
  • tweaks to Terraformer AI
  • AI should be more willing to found cities (and maybe a little smarter about it), especially during wartime
  • Allow the AI to cast Bloom (to help with potential terraformer AI loop)
  • AI should be more willing to upgrade their units (removed some hacked code I stuck in here a long time ago)

Code / UI
  • Version control handled via XML (code by Terkhen)
  • exposing incrementUnitCreatedCount, decrementUnitCreatedCountand decrementUnitClassCreatedCount to python
  • Blizzards will not move onto plots with temporary features (temporary workaround for a Blizzards bug)
  • re-adding the RevDCMOptionsTab in the BUG options (mostly used for debugging - probably still needs some cleanup)
  • getRealTerrainType() now being exposed to python
  • The following functions have all been changed so that they accept a Player ID rather than a Team ID as a variable (note: some mapscripts will need to be updated with this change)

    canHaveImprovement
    calculateNatureYield
    calculateBestNatureYield
    calculateTotalBestNatureYield
 
Just wanted to say, thanks for putting so much effort into this Tholal. I might not play FFH anymore, but I still love haunting this forum, and it wouldn't be anywhere near as active without all the work you do :) Gratz on getting another version out.
 
Thanks to Tholal :goodjob:,an incredible work of a mod of a mod,the fixaxis developers should of got you to do their original AI.Im currently getting griefed by lizard men,a great generals dropped-and he can bulb hunting :eek: I love it! you are :king:
 
Thanks Tholal!

I just wish you told me when you were going to release so I could look over the code and merge it with my modmod sooner. The problem with using a seperate thread to announce a new release is that we are not already subscribed to it and so can easily overlook updates.


So far I have found one minor bug, which causes temporary terrains to be displayed incorrectly so that it does not look like you are changing them even when you really are.

To fix it, change this
Spoiler :
Code:
	def placeTerrain(self):
		screen = CyGInterfaceScreen( "WBPlotScreen", CvScreenEnums.WB_PLOT)
#Magister Start
##		iX = screen.getXResolution() /5 + 10
##		iY = self.iTable_Y
##		iHeight = (screen.getYResolution()/2 - 32 - iY) /24 * 24 + 2
##		iTerrain = pPlot.getTerrainType()

		iX = screen.getXResolution() *3/5 + 10
		iY = iPlotType_Y
		iHeight = (screen.getYResolution() - 52 - iY) /24 * 24 + 2
		iTerrain = pPlot.getTerrainType()

		if bReal:
			iTerrain = pPlot.getRealTerrainType()#This function is not exposed yet as it is supposed to be

			iHeight -= 20
			iY2 = iY + iHeight
			screen.setButtonGFC("TerrainTempTimerPlus", "", "", iX, iY2, 24, 24, WidgetTypes.WIDGET_PYTHON, 1030, -1, ButtonStyles.BUTTON_STYLE_CITY_PLUS)
			screen.setButtonGFC("TerrainTempTimerMinus", "", "", iX + 25, iY2, 24, 24, WidgetTypes.WIDGET_PYTHON, 1031, -1, ButtonStyles.BUTTON_STYLE_CITY_MINUS)
			sText = CyTranslator().getText("TXT_KEY_WB_TEMP_TIMER", (pPlot.getTempTerrainTimer(),))
			screen.setLabel("TerrainTempTimerText", "Background", "<font=3>" + sText + "</font>", CvUtil.FONT_LEFT_JUSTIFY, iX + 50, iY2, -0.1, FontTypes.TITLE_FONT, WidgetTypes.WIDGET_GENERAL, -1, -1)
		else:
			screen.hide("TerrainTempTimerPlus")
			screen.hide("TerrainTempTimerMinus")
			screen.hide("TerrainTempTimerText")
#Magister Stop

		iTerrain = pPlot.getTerrainType()
		sText = gc.getTerrainInfo(iTerrain).getDescription()
		screen.setLabel("TerrainHeader", "Background", "<font=3b>" + sText + "</font>", CvUtil.FONT_CENTER_JUSTIFY, iX + screen.getXResolution()/10 - 10, iY - 30, -0.1, FontTypes.GAME_FONT, WidgetTypes.WIDGET_GENERAL, -1, -1)
		screen.addTableControlGFC("WBPlotTerrain", 1, iX, iY, iWidth, iHeight, False, False, 24, 24, TableStyles.TABLE_STYLE_STANDARD)
		screen.setTableColumnHeader("WBPlotTerrain", 0, "", iWidth)

		if bReal:
			sColor = CyTranslator().getText("[COLOR_WARNING_TEXT]", ())
			iRow = screen.appendTableRow("WBPlotTerrain")
			screen.setTableText("WBPlotTerrain", 0, 0, "<font=3>" + sColor + CyTranslator().getText("TXT_KEY_CULTURELEVEL_NONE", ()) + "</font></color>", CyArtFileMgr().getInterfaceArtInfo("INTERFACE_BUTTONS_CANCEL").getPath(), WidgetTypes.WIDGET_PYTHON, 7875, -1, CvUtil.FONT_LEFT_JUSTIFY )

		for i in xrange(gc.getNumTerrainInfos()):
			TerrainInfo = gc.getTerrainInfo(i)
			if TerrainInfo.isGraphicalOnly(): continue
			if TerrainInfo.isWater() != pPlot.isWater(): continue
			iRow = screen.appendTableRow("WBPlotTerrain")
			sColor = CyTranslator().getText("[COLOR_WARNING_TEXT]", ())
			if iTerrain == i:
				sColor = CyTranslator().getText("[COLOR_POSITIVE_TEXT]", ())
			sText = "<font=3>" + sColor + TerrainInfo.getDescription() + "</font></color>"
			screen.setTableText("WBPlotTerrain", 0, iRow, sText, TerrainInfo.getButton(), WidgetTypes.WIDGET_PYTHON, 7875, i, CvUtil.FONT_LEFT_JUSTIFY)
to this
Spoiler :
Code:
	def placeTerrain(self):
		screen = CyGInterfaceScreen( "WBPlotScreen", CvScreenEnums.WB_PLOT)
#Magister Start
##		iX = screen.getXResolution() /5 + 10
##		iY = self.iTable_Y
##		iHeight = (screen.getYResolution()/2 - 32 - iY) /24 * 24 + 2
##		iTerrain = pPlot.getTerrainType()

		iX = screen.getXResolution() *3/5 + 10
		iY = iPlotType_Y
		iHeight = (screen.getYResolution() - 52 - iY) /24 * 24 + 2
		iTerrain = pPlot.getTerrainType()

		if bReal:
			iTerrain = pPlot.getRealTerrainType()
			iHeight -= 20
			iY2 = iY + iHeight
			screen.setButtonGFC("TerrainTempTimerPlus", "", "", iX, iY2, 24, 24, WidgetTypes.WIDGET_PYTHON, 1030, -1, ButtonStyles.BUTTON_STYLE_CITY_PLUS)
			screen.setButtonGFC("TerrainTempTimerMinus", "", "", iX + 25, iY2, 24, 24, WidgetTypes.WIDGET_PYTHON, 1031, -1, ButtonStyles.BUTTON_STYLE_CITY_MINUS)
			sText = CyTranslator().getText("TXT_KEY_WB_TEMP_TIMER", (pPlot.getTempTerrainTimer(),))
			screen.setLabel("TerrainTempTimerText", "Background", "<font=3>" + sText + "</font>", CvUtil.FONT_LEFT_JUSTIFY, iX + 50, iY2, -0.1, FontTypes.TITLE_FONT, WidgetTypes.WIDGET_GENERAL, -1, -1)
		else:
			screen.hide("TerrainTempTimerPlus")
			screen.hide("TerrainTempTimerMinus")
			screen.hide("TerrainTempTimerText")

[COLOR="Red"]		sText = CyTranslator().getText("TXT_KEY_CULTURELEVEL_NONE", ())
		sColor = CyTranslator().getText("[COLOR_POSITIVE_TEXT]", ())
		if iTerrain  > -1:
			sText = gc.getTerrainInfo(iTerrain).getDescription()
			sColor = CyTranslator().getText("[COLOR_WARNING_TEXT]", ())[/COLOR]

#Magister Stop
		screen.setLabel("TerrainHeader", "Background", "<font=3b>" + sText + "</font>", CvUtil.FONT_CENTER_JUSTIFY, iX + screen.getXResolution()/10 - 10, iY - 30, -0.1, FontTypes.GAME_FONT, WidgetTypes.WIDGET_GENERAL, -1, -1)
		screen.addTableControlGFC("WBPlotTerrain", 1, iX, iY, iWidth, iHeight, False, False, 24, 24, TableStyles.TABLE_STYLE_STANDARD)
		screen.setTableColumnHeader("WBPlotTerrain", 0, "", iWidth)

		if bReal:
			sColor = CyTranslator().getText("[COLOR_WARNING_TEXT]", ())
			iRow = screen.appendTableRow("WBPlotTerrain")
			screen.setTableText("WBPlotTerrain", 0, 0, "<font=3>" + sColor + CyTranslator().getText("TXT_KEY_CULTURELEVEL_NONE", ()) + "</font></color>", CyArtFileMgr().getInterfaceArtInfo("INTERFACE_BUTTONS_CANCEL").getPath(), WidgetTypes.WIDGET_PYTHON, 7875, -1, CvUtil.FONT_LEFT_JUSTIFY )

		for i in xrange(gc.getNumTerrainInfos()):
			TerrainInfo = gc.getTerrainInfo(i)
			if TerrainInfo.isGraphicalOnly(): continue
			if TerrainInfo.isWater() != pPlot.isWater(): continue
			iRow = screen.appendTableRow("WBPlotTerrain")
			sColor = CyTranslator().getText("[COLOR_WARNING_TEXT]", ())
			if iTerrain == i:
				sColor = CyTranslator().getText("[COLOR_POSITIVE_TEXT]", ())
			sText = "<font=3>" + sColor + TerrainInfo.getDescription() + "</font></color>"
			screen.setTableText("WBPlotTerrain", 0, iRow, sText, TerrainInfo.getButton(), WidgetTypes.WIDGET_PYTHON, 7875, i, CvUtil.FONT_LEFT_JUSTIFY)

edit: Why are ordinary units like adepts and disciples able to research technologies? Not only that, but they seem to be completing even advanced techs which would normally take multiple great persons to learn. This needs addressing.
 
I was suprised by the above as well. Seems like a pretty major change.
 
I dont know if this change was intended,but I like it,it speeds up the pace of the game,but I think their should be a cut off point you cant bulb past-sorcery maybe for the adepts- bieng able to bulb past this point sought of nullifys building the tower of divination.What I did notice is that the AIs dont seem to take advantage of this.This means you can easily get a monopoly on techs like priesthood and with trade you can create massive leverage-bribing AIs to war etc.
 
I think I found the commit in which the issue was originally introduced. I'm going to link to my repository instead of the More Naval AI repository because sourceforge is "temporarily in static offline mode", but it is a More Naval AI commit.

https://bitbucket.org/Terkhen/extramodmod/commits/82b344bd2e66e8dc761301731be0e438637806f6

In the int CvUnit::getDiscoverResearch(TechTypes eTech) code change, it seems that the intention was to prevent calculating research if the unit has casted a spell (as in that case the value will always be zero). The calculation itself has also been changed to the following:

Code:
int iResearch;
if (eTech != NO_TECH)
{
	iResearch = std::min(GET_TEAM(getTeam()).getResearchLeft(eTech), iResearch);
}
else
{
	iResearch = (m_pUnitInfo->getBaseDiscover() + (m_pUnitInfo->getDiscoverMultiplier() * GET_TEAM(getTeam()).getTotalPopulation()));
	iResearch *= GC.getGameSpeedInfo(GC.getGameINLINE().getGameSpeedType()).getUnitDiscoverPercent();
	iResearch /= 100;
}

return std::max(0, iResearch);

The key is the std::min line. At that point, iResearch is not initialized. Therefore, if iResearch happens to have a positive value, this method will return a positive research value and CvUnit::canDiscover will return true.
 
I just found out that the Lightbringer unit for Malakim can also used to get tech. Just want to report that here.
 
All units with a <FlavorType> set in CIV4UnitInfos.xml are subject to this bug. This includes mostly all arcane and disciple units, but other seemingly random units (such as Acheron) are affected too. They are not able to lightbulb all the time, as it depends on the value of a random memory position.

Tholal seems to be away, so I went ahead and prepared a hotfix dll for More Naval AI 2.62. I have checked all affected units and they seem to be working correctly now. To install the hotfix, first backup your <Fall from Heaven 2 mod folder>\Assets\CvGameCoreDLL.dll file. Then download and unzip the CvGameCoreDLL.dll.zip file attached to this post. Paste the resulting file in your <Fall from Heaven 2 mod folder>\Assets folder, overwriting the file that you should have backed up earlier.

Tholal: Sourceforge is still offline, so instead of creating an issue in your repository I'm attaching the modified source code to this post.

While fixing this issue, I found another place for performance improvements. At CvUnit::canDiscover, the game will check getDiscoveryTech before checking getDiscoverResearch. getDiscoveryTech is very expensive to evaluate and is checked for all units, while getDiscoverResearch is called later, it is faster and in most cases it will return zero. getDiscoverResearch only used the TechTypes parameter to make sure it does not return a value greater than the research required for the technology. Since at canDiscover it only needs to know if the unit can make any research at all, I have switched the order in which getDiscoverResearch and getDiscoveryTech are called. This change is included along with the fix in the attached CvUnit.cpp file.
 

Attachments

  • CvUnit.cpp.zip
    96.6 KB · Views: 208
  • CvGameCoreDLL.dll.zip
    1.8 MB · Views: 207
All units with a <FlavorType> set in CIV4UnitInfos.xml are subject to this bug. This includes mostly all arcane and disciple units, but other seemingly random units (such as Acheron) are affected too. They are not able to lightbulb all the time, as it depends on the value of a random memory position.

Tholal seems to be away, so I went ahead and prepared a hotfix dll for More Naval AI 2.62. I have checked all affected units and they seem to be working correctly now. To install the hotfix, first backup your <Fall from Heaven 2 mod folder>\Assets\CvGameCoreDLL.dll file. Then download and unzip the CvGameCoreDLL.dll.zip file attached to this post. Paste the resulting file in your <Fall from Heaven 2 mod folder>\Assets folder, overwriting the file that you should have backed up earlier.

Tholal: Sourceforge is still offline, so instead of creating an issue in your repository I'm attaching the modified source code to this post.

While fixing this issue, I found another place for performance improvements. At CvUnit::canDiscover, the game will check getDiscoveryTech before checking getDiscoverResearch. getDiscoveryTech is very expensive to evaluate and is checked for all units, while getDiscoverResearch is called later, it is faster and in most cases it will return zero. getDiscoverResearch only used the TechTypes parameter to make sure it does not return a value greater than the research required for the technology. Since at canDiscover it only needs to know if the unit can make any research at all, I have switched the order in which getDiscoverResearch and getDiscoveryTech are called. This change is included along with the fix in the attached CvUnit.cpp file.

Where exactly do we put the Cvunit.cpp file. I looked in a ton of folders and while I see files that start with Cv, I do not see a Cvunit.pp file that already exist.
 
Top Bottom