1. We have added the ability to collapse/expand forum categories and widgets on forum home.
    Dismiss Notice
  2. All Civ avatars are brought back and available for selection in the Avatar Gallery! There are 945 avatars total.
    Dismiss Notice
  3. To make the site more secure, we have installed SSL certificates and enabled HTTPS for both the main site and forums.
    Dismiss Notice
  4. Civ6 is released! Order now! (Amazon US | Amazon UK | Amazon CA | Amazon DE | Amazon FR)
    Dismiss Notice
  5. Dismiss Notice
  6. Forum account upgrades are available for ad-free browsing.
    Dismiss Notice

Modders Guide to FfH2

Discussion in 'Civ4 - Fall from Heaven' started by Kael, Aug 14, 2007.

  1. Sephi

    Sephi Chieftain

    Joined:
    Jan 25, 2009
    Messages:
    2,908
    http://forums.civfanatics.com/showthread.php?t=331912
     
  2. Aurelazza

    Aurelazza Chieftain

    Joined:
    Oct 4, 2012
    Messages:
    58
    Thank you, Sephi. Much appreciated.

    As someone whose only modding experience comes from the new generation of Pokemon games, coming into the world of Civ IV modding makes me feel like a high schooler walking in on a P.H.D. level lecture. I'll doubtlessly be flooding this thread with questions... :blush:
     
  3. Aurelazza

    Aurelazza Chieftain

    Joined:
    Oct 4, 2012
    Messages:
    58
    Several more queries from a humbly grateful newbie:

    - Where/how would I code a specific plot (with no improvements) to spawn barbarians every few (say, 4 or 5) turns.

    - Is it possible to randomize which sort of barb unit appears, within 3 or 4 different choices?

    - Could different numbers of Barbarians show up depending upon the unit type selected? (For example, equal odds of getting 8 Drown, 4 Stygian Guard or 1 Kraken?)

    - Can I control when they show up during the turn cycle? End of the Barbarian turn, beginning of my turn, etc?

    - Does "Damage=" refer to health missing, health remaining, or a percentage? (i.e. Would Damage=10 on a Kraken make it spawn at 7/17, 10/17, 1.7/17 or 15.3/17 hit points?)

    - I was poking around the Radiant Guard scenario for answers to some of these questions, and I came across the "UNITAI_ATTACK_CITY_LEMMING" AI script. How do I set which city they make their kamikaze run for? And would I need to reveal the entire map to the enemy in question to prevent them from wandering around searching for alternate routes to said city if I've blocked it off at a chokepoint with units?

    - If I were to want to move a unit unique to a certain mod into another one, where would I find all the various files regarding the unit (animation, texture, sounds, statistics, special abilities, etc.)? Would this simply require XML, or Python / SDK as well? For what it's worth, the unit in question is the Frozen Mulyalfar Elf.

    I also have several questions relating to premade map / custom scenario design and playability. I'm posting them here to avoid clogging the board with threads of mine, but by all means I can move them elsewhere if they're not quite relevant here.

    - On a slightly different tack, as someone with no premade map / custom scenario design experience, might any gentlefolk offer some suggestions for a scenario that's more or less "Auric and his outnumbered allies defend themselves against the hordes of righteousness until he becomes a god and wrecks shop"?

    - Would you recommend having the good and evil forces "checkerboarded" with each Civ more or less surrounded by enemies, ala "Wages of Sin", or would it be more interesting if it was along the lines of "one side of the map vs. the other"?

    - Would having Auric's 3 little helper priests be teammates / vassals skew the research rate? I've found that large teams simply speed through the tech tree, but at the same time if I can't tell my allies what to research / where to attack, optimal decisions do not get made. At all.

    - Going out on a limb here, but what might be a good ratio of Illian/Doviello to "Good Guy" civs, given a roughly equal number of starting cities and units? Dare I enable Basium? I'm looking to combine the multi-faction struggle of "Wages of Sin" with the desperate survival element of "Against the Wall". As it stands I'm 5v9 with "Compact Enforced" on a Large map.

    Many thanks!

    Edit: Running the Improved Naval AI mod, would an entirely island-based Lanun empire be a threat in this scenario, or does the AI really need a land route for its armies?
     
  4. MagisterCultuum

    MagisterCultuum Great Sage

    Joined:
    Feb 14, 2007
    Messages:
    15,546
    Location:
    Kael's head
    Spawning units on any given plot is easy in python, particularly if want to hard code it to a specific x and y coordinate. The difficulty is making it so that it does not always do that on random maps where it is inappropriate. The various scenario game options allow that, but there is only one extra option available for scenario makers. You can use if gc.getGame().isOption(GameOptionTypes.GAMEOPTION_WB_EXTRA): for such special behavior in one scenario, but making additional game options like it for multiple scenarios would require compiling a new DLL or re-purposing one of the game options from another scenario if you don't care to play that one anymore. (Also, note that in my modmod I use that game option to disable the Children of the One religion.)


    The following code would spawn the units as you wanted.
    Code:
    		if pPlayer.isBarbarian():
    			bPlayer = gc.getPlayer(gc.getBARBARIAN_PLAYER())
    			listUnitType = ['UNIT_DROWN','UNIT_STYGIAN_GUARD','UNIT_KRAKEN']
    			listUnitNumber = [8,4,1]
    			index = CyGame().getSorenRandNum(len(listUnitType), "Pick Spawn")
    			iUnit = gc.getInfoTypeForString(listUnitType[index])
    			iNum = listUnitNumber[index]
    			iX = 1
    			iY = 1
    			for i in range(iNum):
    				pNewUnit = bPlayer.initUnit(iUnit, iX, iY, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_NORTH)
    
    Originally I tried doing it with a list of tuples to keep the number of units and unit types together, but I could not get it to work that way. This way is easier and works fine so long as the two lists are of equal length. You could add as many different types of unit to the list as you like, but be sure to specify the number of each.


    I tested it where the units were set t spawn at the start of the barbarian player's turn. It was just the quoted code placed under def onBeginPlayerTurn(self, argsList):, with the conditional if pPlayer.isBarbarian(): being what assures it happens at the barbarian's turn as opposed to someone else's.

    You could use if pPlayer.isHuman(): if you want it to happen on the human player's turn, but keep in mind that in multiplayer games it would happen more often.

    You could also place this code under def onEndPlayerTurn(self, argsList): without changing anything else.


    It would probably be best to move it to def onBeginGameTurn(self, argsList): though, and get rid of that conditional. Having that many unit spawn every turn seems a bit much, so it might be better to place it within a conditional that uses a random number generator to decide whether to spawn anything that turn.
    I think that damage is the percent of health missing.
    I don't think that there is a way to set what city a unit will target manually in python. Such AI behavior is in the SDK, I believe.

    Edit: unless maybe the pUnit.attack(pPlot, False) used in the taunt spell woould work as you wish?
    Borrowing a unit would probably only require modifying a few xml files and copying the artwork files into the art folder. The only change you would definitely need in is CIV4UnitInfos.xml. If the unit does not share an existing unitclass you would also need to add its unitclass to CIV4UnitClassInfos.xml. If you want to assign it to a civ as a unique unit or make it unavailable to some civs than you would need to modify CIV4CivilizationInfos.xml. If the unit had different art then you need to modify CIV4ArtDefines_Unit.xml. The unit's art define in that file points to the location where its model and animations are found. Follow that path, and copy that whole folder (models typically rely on textures found in the same folder) to the destination mod. Note that art might be held within a .fpk file, in which case you may need to unpack it.

    Most units don't depend on python at all, but some do have <PythonPostCombatWon> or <PythonPostCombatLost> callbacks. If that is the case for the unit you are borrowing, than that piece of code needs to be copied from one mod's CvSpellInferface.py to the other's.

    That scenario idea sounds rather similar to Mulcarn Reborn, but with the human playing on the opposite side of the conflict. I was actually thinking changing that myself so that you can play on either side.


    You can easily tell your allies and vassals what to research. When you open up the diplomacy window with them, select "Let's discuss something else..." and then "We would like you to Research..." and then select from the lists of the technologies that that player is capable of researching. (If you are permanent allies it should generally be the same techs available to you, but there are exceptions like Cassiel being unable to research religion founding techs or a player without the Fol State religion being able to research Hidden Paths.) I've never seen an AI refuse research whatever I told it to research.

    You can also select "Why don't you attack..." and then select one of the cities belonging to a player with whom you are both at war (barbarian cities are excluded though). That actually only requires a mutual enemy, not a permanent alliance or vassalage agreement. It does not seem like this actually changes the AI's behavior in any way though.


    There does not seem to be any way to stop the AI from making most stupid decisions though, including annoying things like trying to build wonders or heroes in cities with very little production when you would otherwise be able to finish them much faster in your cities. (The Splintered Court partially gets around this by forbidding non-human members of either alliance from building the civ's hero.)
     
  5. Aurelazza

    Aurelazza Chieftain

    Joined:
    Oct 4, 2012
    Messages:
    58
    Grateful as ever, MC. This barbarian spawning is my first ever time touching Python. So Woo!

    I'm kinda assuming that it would go under Assets/Python/CustomFunctions, and there'd be no problem with it being the very first definition. I have yet to find a solid guide on the order that all the lines in a single command go in, and how many spaces before each line, so here's my shot in the dark at implementing what you suggested.

    Code:
    def onBeginGameTurn(self, argsList):
    	if gc.getGame(My Scenario's Name).isOption(GameOptionTypes.GAMEOPTION_W B_EXTRA)and if iRandNum < iPropability:
    		bPlayer = gc.getPlayer(gc.getBARBARIAN_PLAYER())
                            iRandNum = cyGame.getSorenRandNum(100, "OOBarbs")
                            iPropability = 20
    			listUnitType = ['UNIT_DROWN','UNIT_STYGIAN_GUARD','UNIT_KRAKEN']
    			listUnitNumber = [8,4,1]
    			index = CyGame().getSorenRandNum(len(listUnitType), "Pick Spawn")
    			iUnit = gc.getInfoTypeForString(listUnitType[index])
    			iNum = listUnitNumber[index]
    			iX = 12
    			iY = 31
    			for i in range(iNum):
    			    pNewUnit = bPlayer.initUnit(iUnit, iX, iY, UnitAITypes.UNITAI_ATTACK_SEA, DirectionTypes.DIRECTION_EAST)
    Aiming for a 20% chance per turn of them showing up at the 12,31 coordinates with the ATTACK_SEA unitAI and facing their prey towards the East.
     
  6. MagisterCultuum

    MagisterCultuum Great Sage

    Joined:
    Feb 14, 2007
    Messages:
    15,546
    Location:
    Kael's head
    I don't think that the order of each def function within a file really matters. Each define is practically treated like a separate file. They don't interact unless one specifically calls another. Variables within one function are not accessible from others.

    Assets/Python/CustomFunctions.py is not the file you ought to be editing. The code should be placed either in Assets/Python/CvEventManager.py or in Assets/Python/ScenarioFunctions.py. It does not really matter which one, but if the code is specific to a scenario then it seems more logical to use the latter. I'm pretty sure that the DLL only calls the def onBeginGameTurn(self, argsList): function in CvEventManager.py, which in turn calls ScenarioFunctions.py. If you want to place it in CustomFunctions.py then you would have to edit CvEventManager.py to call it from that file too.


    There are no parameters in gc.getGame(). You cannot identify the game by your scenario's name, but rather only by the game option. The apostrophe you used is read is an quotation mark that marks the beginning of a string, and since it is unmatched everyting after it is taken to be text instead of code.There should not be a space within the name of the game options (that error was introduced by this forum parsing it poorly). You should not use another if after an and. You cannot call the variables like iRandNum or iPropability before you define them, and in this case there is little reason to define since they are each only used once. Capitalization matters in python, so you need to use CyGame instead of cyGame. You shouldn't mix spaces and tabs. It won't necessarily break things, but make it really easy to accidentally do so. You can use spaces for indentation and the number you use doesn't matter much, so long as you are consistent within any block of code. Personally I prefer to play it save only only use tabs though. You need to indent the things within each define, if statement, for loop, while loop, etc, and should never indent some lines more at random. (Indentation doesn't seem to matter within lists, and I think using a / within a function lets you extend things to the next line to make things easier to read, but is is probably safer for a newbie to ignore that.)


    Edit: I just realized that the function in ScenarioFunctions.py called by the def onBeginGameTurn(self, argsList): function in CvEventManager.py is not called def onBeginGameTurn(self, argsList): but rather def doTurn(self):. This is set up to call separate functions for each scenario like self.doTurnLordOfTheBalors(), but there is no reason why the whole code could not be placed within that define itself. Be sure to place the code within doTurn rather than making a duplicate function of the same name, as that could prevent the game from reading the original function used for all the other scenarios.

    I'd recommend using this code in Assets/Python/ScenarioFunctions.py
    Code:
    	def doTurn(self):
    
    
    
    		if gc.getGame().isOption(GameOptionTypes.GAMEOPTION_WB_EXTRA):
    			if CyGame.getSorenRandNum(100, "OOBarbs") <= 20:
    				bPlayer = gc.getPlayer(gc.getBARBARIAN_PLAYER())
    				listUnitType = ['UNIT_DROWN','UNIT_STYGIAN_GUARD','UNIT_KRAKEN']
    				listUnitNumber = [8,4,1]
    				index = CyGame().getSorenRandNum(len(listUnitType), "Pick Spawn")
    				iUnit = gc.getInfoTypeForString(listUnitType[index])
    				iNum = listUnitNumber[index]
    				iX = 12
    				iY = 31
    				for i in range(iNum):
    					pNewUnit = bPlayer.initUnit(iUnit, iX, iY, UnitAITypes.UNITAI_ATTACK_SEA, DirectionTypes.DIRECTION_EAST)
    
     
  7. Aurelazza

    Aurelazza Chieftain

    Joined:
    Oct 4, 2012
    Messages:
    58
    Awesome. Now I'm a little sketchy on which folders you can tinker with and have them only affect a custom scenario and not the rest of the game. Are there folders where the command line "if gc.getGame().isOption(GameOptionTypes.GAMEOPTION_WB_EXTRA):" wouldn't work?

    Few other queries about my "Auric Ascends" scenario, as well.

    - Acheron's Wyrmhold causes -5 happiness in the city should a Temple of the Hand be built. I assume that setting iConquestProb to 0 on Acheron's Wyrmhold would cause it to automatically be destroyed when captured, solving the problem, but as I understand it this would apply to all games played and not just the scenario. Solutions?

    - What's the easiest way to have an NPC city refuse to accept its Civ's state religion? Falamar has a little problem with squidloving loonies spreading throughout his empire, but he's tolerating none of that baloney in his own capitol.

    - Where might I find the folder governing the opening text / illustration that pops up at the beginning of any regular scenario?

    - Can Python change several specific plots/terrains/landmark captions at once? What I'm aiming for here is a tropical valley in the frozen northlands, walled-off by mountains and kept warm by Bhall's blessings / numerous Fire Nodes. What I'd love to do is have a Jungle Altar captioned "Tribute Unto Bhall" that, when taken, switches captions to "Tribute Unto Mulcarn" and changes all the jungle/grasslands into snowy trees/tundra. A short text popup would be an added bonus. Too ambitious?

    - Edit: With Cassiel murdered at Auric's hands, the remaining Grigori have rallied behind Minister Koun to join the forces seeking to prevent a 2nd Age of Ice. I was surprised as any when Koun suddenly converted to the White Hand. Note that this is in a mod where Cassiel lacks the Agnostic trait, and some other mechanism prevents the Grigori from going religious. Any idea why this might have happened? Or are the Grigori now Ice-Worshippers in name only, unable to receive any of the benefits?

    - AI units with the AI_ CITYDEFENSE script will still conjure forth permanent summons, correct? So an Illian Barnaxus controlled by the AI would sit safe and sound in the capitol while cranking out Ice Golems that would rush forth?

    Cheers! :)
     
  8. MagisterCultuum

    MagisterCultuum Great Sage

    Joined:
    Feb 14, 2007
    Messages:
    15,546
    Location:
    Kael's head
    It should work in pretty much any python file.

    The call is actually "if CyGlobalContext().getGame().isOption(GameOptionTypes.GAMEOPTION_WB_EXTRA):", but since CyGlobalContext() is called so often in many files Kael set gc = CyGlobalContext() at the top of them. If you want to use this conditional in a file where it is not defined so then you must either write it out every time or add that line near the top.


    It seems a lot easier to keep track of scenario-specific things if you keep them all in ScenarioFunctions.py though.
    The easiest way would be to use the game option to disable Acheron, but you probably don't want to disable Drifa in the process.


    You could place this under def onCityAcquired(self, iPreviousOwner, iNewOwner, pCity, bConquest, bTrade):
    Code:
    		if gc.getGame().isOption(GameOptionTypes.GAMEOPTION_WB_EXTRA):
    			if pCity.getNumRealBuilding(gc.getInfoTypeForString('BUILDING_WYRMHOLD_ACHERON')) > 0:
    				pCity.setNumRealBuilding(gc.getInfoTypeForString('BUILDING_WYRMHOLD_ACHERON'), 0)
    That would remove the wonder whenever a new player captures the city. You could also add another conditional if you wanted that to only be the case for the Illians, players following the White Hand religion, etc.



    I don't know about blocking the spread of the religion, but it would be simple enough to remove the religion from his capital every turn.

    In ScenarioFunctions.py, under def doTurn(self): (or a scenario specific doTurn function called from there, if the code gets complicated and you want it to be organized like all the other scenarios)

    Code:
    
    		elif gc.getGame().isOption(GameOptionTypes.GAMEOPTION_WB_EXTRA):
    			iFalamarPlayer = cf.getLeader(gc.getInfoTypeForString('LEADER_FALAMAR'))
    			pCity = gc.getPlayer(iFalamarPlayer).getCapitalCity()
    			iOverlords = gc.getInfoTypeForString('RELIGION_OCTOPUS_OVERLORDS')
    			pCity.setHasReligion(iOverlords, False, True, True)
    			for i in range(gc.getNumBuildingInfos()):
    				if pCity.getNumBuilding(i) > 0:
    					if gc.getBuildingInfo(i).getPrereqReligion() == iOverlords:
    						if not isWorldWonderClass(gc.getBuildingInfo(i).getBuildingClassType()):
    							pCity.setNumRealBuilding(i, 0)
    

    Edit: You could also add this code to def onReligionSpread(self, argsList): in CvEventManager.py to remove the religion whenever it spreads to Falamar's Capital. There is not yet an equivalent call in ScenarioFunctions.py though, so if you want to keep the scenario-specific things together you would have to create one and edit CvEventManager.py to make it be called.
    Code:
    		iOverlords = gc.getInfoTypeForString('RELIGION_OCTOPUS_OVERLORDS')
    		if gc.getGame().isOption(GameOptionTypes.GAMEOPTION_WB_EXTRA):
    			if pSpreadCity.isCapital():
    				if pPlayer.getLeaderType() == gc.getInfoTypeForString('LEADER_FALAMAR'):
    					if iReligion == iOverlords:
    						pSpreadCity.setHasReligion(iOverlords, False, True, True)
    
    
    The code that controls those popups is found in ScenarioFunctions.py under def gameStart(self):
    Code:
    		if gc.getGame().isOption(GameOptionTypes.GAMEOPTION_WB_AGAINST_THE_GREY):
    			pPlayer = gc.getPlayer(0)
    			if pPlayer.isHuman():
    				gc.getPlayer(0).setAlignment(gc.getInfoTypeForString('ALIGNMENT_GOOD'))
    				self.addPopupWB(CyTranslator().getText("TXT_KEY_WB_AGAINST_THE_GREY_INTRO_MALAKIM",()), 'art/interface/popups/Against the Grey.dds')
    			else:
    				gc.getPlayer(1).setAlignment(gc.getInfoTypeForString('ALIGNMENT_EVIL'))
    				self.addPopupWB(CyTranslator().getText("TXT_KEY_WB_AGAINST_THE_GREY_INTRO_CALABIM",()), 'art/interface/popups/Against the Grey.dds')
    
    The TXT_KEY's are can be defined in pretty much any of the files found in the Assets\XML\Text folder. Kael put everything in one file called CIV4GameText_FFH2.xml, which is huge. I placed all of my changed in Magister_CIV4GameText_FFH2.xml, which is sill pretty big. Tholal put the various TXT_KEY's requires for More Naval AI in 71 different much smaller .xml files, many of them borrowed directly from modcomps he merged into his modmod.

    I'm not sure of the exact order the game reads these things in. I think it goes in alphabetical order, with whatever it reads last overriding what it read before. I know that there are many TXT_KEY's in CIV4GameText_FFH2.xml ad Magister_CIV4GameText_FFH2.xml that share the same name, and that the ones in Magister_CIV4GameText_FFH2.xml are what are used in the game.

    You could include all the TXT_KEY's used in your scenario in one new xml file in that folder. You could also just write out the text you want displayed within those quotation marks and not bother with TXT_KEY's, if you don't mind the same words being used in ll languages. The code could be rather unwieldy if you include a long string of text that way though.

    The path of the artwork in this case is 'art/interface/popups/Against the Grey.dds', but you would presumably want to change that. You could ass your own artwork, or reuse the artwork from another scenario like Return of Winter, Blood of the Angels, or Mulcarn Reborn. I was about to suggest using the popup for the Auric Ascended unit, but I'm thinking now that its lower resolution might stop it from working with self.addPopupWB(). (It would work with cf.addPopup, but then the popup window would be smaller and off to the side like an event rather than an opening screen.)

    It does not sound too ambitious, or even particularly difficult.

    You can set the initial signs in the scenario file. The original versions of the scenarios had these set for the various unique improvements, but I removed those. You can still see plenty of examples at the bottom of KE huge ICE Empires v1.1 for MagisterModmod.CivBeyondSwordWBSave though.
    Code:
    BeginSign
    	plotX=13
    	plotY=21
    	playerType=-1
    	caption=Tomb of Sucellus
    EndSign
    The plotX and plotY obviously refer to the coordinates of the tile that bears the caption, and the caption is what you want it to say. (Note: If the caption is too long it will get truncated. I don't think the captions you want are too long, but I'm not sure what the limit is other than that "Guardian of the Pristinus Pass" won't all fit.)

    When playerType is set to -1 then it is a landmark, in black, visible to everyone, and unable to be removed without resorting to python. If you set it to a particular player's index then it will be placed in that player's colors, be visible only to that player's team, and that player will be able to remove it just like the signs he might add himself using alt + s.



    For the change in signs and the popup, you can look for examples in ScenarioFunction.py under def onMoveWarningPost(self, pCaster, pPlot):, elif gc.getGame().isOption(GameOptionTypes.GAMEOPTION_WB_LORD_OF_THE_BALORS):, around line 2329 in my modmod.
    Code:
    		elif gc.getGame().isOption(GameOptionTypes.GAMEOPTION_WB_LORD_OF_THE_BALORS):
    			iPlayer = pCaster.getOwner()
    			pPlayer = gc.getPlayer(iPlayer)
    			if pPlayer.isHuman():
    				if pPlot.at(33,14):
    					pPlot.setImprovementType(-1)
    					CyEngine().addLandmark(pPlot, "The Conquerers' Pass")
    					szText = CyTranslator().getText("TXT_KEY_WB_LORD_OF_THE_BALORS_CONQUERERS_PASS",())
    					if pPlayer.getLeaderType() == gc.getInfoTypeForString('LEADER_KEELYN'):
    						szText = CyTranslator().getText("TXT_KEY_WB_LORD_OF_THE_BALORS_CONQUERERS_PASS_KEELYN",())
    					cf.addPlayerPopup(szText, iPlayer)
    
    If there is already a landmark in place, I believe that you would have to include the line CyEngine().removeLandmark(pPlot) before CyEngine().addLandmark(pPlot, "The Conquerers' Pass")

    If you want the captions be be only for a specific player, then you can use CyEngine().removeSign(pPlot, iPlayer) before CyEngine().addSign(pPlot, iPlayer, "Tribute Unto Mulcarn") instead.

    As you can see, the code already shows a text popup to the player whose unit entered the plot and changed the signs.


    You can place this code under def onMoveJungleAltar(self, pCaster, pPlot): just as easily as under def onMoveWarningPost(self, pCaster, pPlot):.


    The hardest part of the terraforming would be deciding what tiles needs to change. You could change the whole map, you could change only specific hard coded tiles, or you could loop through tiles nearby. I'm going to assume you want the later, and to make things easier I'll assume that the area to be terraformed is a square with the jungle altar at its center.

    You could just place this code right below the code that changes the landmarks:
    Code:
    					iSnow = gc.getInfoTypeForString('TERRAIN_SNOW')
    					iGlacier = gc.getInfoTypeForString('TERRAIN_GLACIER')
    					iFlames = gc.getInfoTypeForString('FEATURE_FLAMES')
    					iFloodPlains = gc.getInfoTypeForString('FEATURE_FLOOD_PLAINS')
    					iForest = gc.getInfoTypeForString('FEATURE_FOREST')
    					iJungle = gc.getInfoTypeForString('FEATURE_JUNGLE')
    					iScrub = gc.getInfoTypeForString('FEATURE_SCRUB')
    					iSmoke = gc.getInfoTypeForString('IMPROVEMENT_SMOKE')
    					iNodeFire = gc.getInfoTypeForString('IMPROVEMENT_MANA_FIRE')
    					iBonusFire = gc.getInfoTypeForString('BONUS_MANA_FIRE')
    					iNodeIce = gc.getInfoTypeForString('IMPROVEMENT_MANA_ICE')
    					iBonusIce = gc.getInfoTypeForString('BONUS_MANA_ICE')
    
    					iX = pPlot.getX()
    					iY = pPlot.getY()
    					for iiX in range(iX-3, iX+4, 1):
    						for iiY in range(iY-3, iY+4, 1):
    							pLoopPlot = CyMap().plot(iiX,iiY)
    							if not pLoopPlot.isNone():
    								if not pLoopPlot.isWater():
    									if not pLoopPlot.getTerrainType() == iSnow and not pLoopPlot.getTerrainType() == iGlacier:
    										pLoopPlot.setTerrainType(iSnow)
    										if pLoopPlot.getImprovementType() == iSmoke:
    											pLoopPlot.setImprovementType(-1)
    										if pLoopPlot.getImprovementType() == iNodeFire:
    											pLoopPlot.setImprovementType(iNodeIce)
    										if pPlot.getBonusType(-1) == iBonusFire:
    											pPlot.setBonusType(iBonusIce)
    										iFeature = pLoopPlot.getFeatureType()
    										if iFeature == iForest:
    											pLoopPlot.setFeatureType(iForest, 2)
    										if iFeature == iJungle:
    											pLoopPlot.setFeatureType(iForest, 2)
    										if iFeature == iFlames:
    											pLoopPlot.setFeatureType(-1, -1)
    										if iFeature == iFloodPlains:
    											pLoopPlot.setFeatureType(-1, -1)
    										if iFeature == iScrub:
    											pLoopPlot.setFeatureType(-1, -1)
    
    Cassiel is prevented from adopting a religion because he has a -100 religion weight modifier towards every religion. The Grigori civilization also has all the religion founding techs, all religious buildings except the holy shrines, and all of the religious units except for the Luonnotar disabled in its CIV4CivilizationInfos.xml defines.

    Grigori leader that follows the White Hand wouldn't really receive any benefits, but would still become forced vassals of Auric Ulvin once he completes The Draw.

    Koun does have a -100 religion weight modifier to The White Hand (all leaders but those of the Illian and Doviello civilizations do), which should stop him from ever adopting it.

    Are you using the Random Personalities game option? If so, he could have been set to have an Illian or Doviello leader's personality, including the religion preferences.

    Was Koun generated through a revolution? The revolution code currently assigns a state religion to players it generates, and does not take religion weight modifiers into account. I've been trying to fix that, but without much luck so far. I just tried a new approach which I think will work better, but have not tested it yet. I mentioned the issue to Tholal and he agreed to change the code himself though, so if I cannot figure how to stop rebel civs from taking a blocked religion on my own I should be fine once I merge my modmod with the next release of More Naval AI.

    I'm not really sure. AI questions should be directed towards Tholal.

    I would guess this is the case though. Acheron has UNITAI_CITY_DEFENSE by default, and it my modmod he summons plenty of Fireballs with his Breath Fire ability. I don't imagine that permanent summons like Ice Golems would be treated much differently.
     
  9. Aurelazza

    Aurelazza Chieftain

    Joined:
    Oct 4, 2012
    Messages:
    58
    Okay. I got most, if not all of that, and I'll put it to the test as soon as I get the chance.

    As for the White Hand Grigori issue, I didn't activate random personalities, though I did allow unrestricted leaders if that has anything to do with it. I'd like to chalk this one up to a freak occurrence - if it's an ongoing problem then it's bound to pop up again during playtesting.

    One thing I forgot - You helped me set up the spawning of OO Barbarians to make sure that the player maintains a strong coastal defense. Should these defenses prove too strong, however, the Barbs might turn on the neighboring Lanun. What's the best way around this, short of giving Falamar the Barbarian trait or using Ice to trap them in an area where they're funneled into attacking the player's fortified harbor?

    And this last bit goes out to anyone who might know someone with map/scenario design experience. My current map/scenario seems to suffer from a key problem. If anyone is interested in offering some advice, I'd be happy to upload the map as it currently stands.
     
  10. WilliamOfOrange

    WilliamOfOrange Chieftain

    Joined:
    Jul 17, 2003
    Messages:
    998
    Location:
    Lincolnshire, UK
    Sorry if this has been asked before, but this is a massive thread.

    How easy/hard would it be to import the spell system from FfH or Orbis or RiFE into a mod such as C2C?

    How do I go about finding all the files with the relevant code to copy into the dll fiels of the other mod?
     
  11. arcticnightwolf

    arcticnightwolf Chieftain

    Joined:
    Jun 8, 2008
    Messages:
    1,301
    Location:
    Prague, Czech Republic
    in theory, all you have to do is track down all occurrences of "//FfH Spell System" in the dll source files (it's harder than it sounds)
    but that's assuming the ffh-dev team was thorough with this comment-convention
     
  12. Aurelazza

    Aurelazza Chieftain

    Joined:
    Oct 4, 2012
    Messages:
    58
    Is there any way to make a civ's state religion influence plot yields? Suppose I wanted to give Doviello who've adopted the White Hand 1 :food: on all snow tiles, or a (non-Infernal) civ extra commerce on hell terrain.

    Failing that, could religious buildings change plot yields on tiles aside from ocean/coast/riverside?
     
  13. Kiech

    Kiech Chieftain

    Joined:
    Oct 1, 2002
    Messages:
    987
    Leevys affect land tiles, so part 2 of your question should be yes. I don't know about the rest.
     
  14. Aurelazza

    Aurelazza Chieftain

    Joined:
    Oct 4, 2012
    Messages:
    58
    Actually, I could only seem to find options to make a building change the plot yield of water tiles (coast/great lighthouse) and riverside tiles (which would be in place because of levies).
     
  15. MagisterCultuum

    MagisterCultuum Great Sage

    Joined:
    Feb 14, 2007
    Messages:
    15,546
    Location:
    Kael's head
    I don't think that the game has the functionality that you would like, although it seems like it would be a good idea to add it. Perhaps we could convince Tholal to include it in a future version of More Naval AI. (That is generally considered the successor of the standard FfH2, since Kael has moved on to professional game development with Stardock and no longer his any time to be involved in the project. Tholal and his team seem a bit more amenable to adding requested functionality for modmoders than Kael was anyway. )
     
  16. Aurelazza

    Aurelazza Chieftain

    Joined:
    Oct 4, 2012
    Messages:
    58
    I wasn't aware that Tholal was so receptive to suggestions from modmodders. Glad to hear it.

    I'm currently trying to figure out ways to make a unit's iGroupSize or fScale correspond directly to its level or promotions. I'm all rather new at this, so it's easy to let the imagination run wild and envision the difficult/impossible, but one certainly couldn't deny the appeal of a unit of righteous Crusaders swelling with new recruits as it wins battle after battle, or a Pit Beast growing larger and more grotesque as it feasts upon the slain.

    I suppose it would make sense to write in multiple copies of the same unit, albeit at different sizes, and have Python automatically upgrade the unit in question when it hits the desired level. Has anything like this been done before? And would it be possible for Tholal and Co. to somehow streamline this so that it could become a common feature shared by a great number of different units?
     
  17. MagisterCultuum

    MagisterCultuum Great Sage

    Joined:
    Feb 14, 2007
    Messages:
    15,546
    Location:
    Kael's head
    I believe those things are handled mostly by the graphics engine, which modders have no way of changing.

    BtS did however introduce the ability for promotions to change art styles. (FfH2 uses this for race specific graphics.)

    Rather than using python to convert one unit to another, you try using it just to swap out some dummy promotions based on level. Those dummy promotions would change the art styles of the units. That would certainly work for things like making Pit Beasts grow larger.

    Edit: I just realized that the dummy promotions are not needed, as art styles can be checked and changed through these python functions:

    pUnit.getUnitArtStyleType()

    pUnit.setUnitArtStyleType(gc.getInfoTypeForString('UNIT_ARTSTYLE_LEVEL2'))

    (I use that in my modmod to make Dragon Fanatics match whatever dragon the owner might control.)


    You would have to edit C:\Program Files (x86)\Firaxis Games\Sid Meier's Civilization 4\Beyond the Sword\Mods\Magister Modmod for FfH2\Assets\XML\Civilizations\CIV4UnitArtStyleTypeInfos.xml like this to add new level based art styles:
    Code:
    		<UnitArtStyleTypeInfo>
    			<Type>UNIT_ARTSTYLE_LEVEL2</Type>
    			<StyleUnits>
    				<StyleUnit>
    					<UnitType>UNIT_PIT_BEAST</UnitType>
    					<UnitMeshGroup>
    						<EarlyArtDefineTag>ART_DEF_UNIT_PIT_BEAST_LEVEL2</EarlyArtDefineTag>
    						<LateArtDefineTag>ART_DEF_UNIT_PIT_BEAST_LEVEL2</LateArtDefineTag>
    						<MiddleArtDefineTag>ART_DEF_UNIT_PIT_BEAST_LEVEL2</MiddleArtDefineTag>
    					</UnitMeshGroup>
    				</StyleUnit>
    			</StyleUnits>
    		</UnitArtStyleTypeInfo>
    
    		<UnitArtStyleTypeInfo>
    			<Type>UNIT_ARTSTYLE_LEVEL3</Type>
    			<StyleUnits>
    				<StyleUnit>
    					<UnitType>UNIT_PIT_BEAST</UnitType>
    					<UnitMeshGroup>
    						<EarlyArtDefineTag>ART_DEF_UNIT_PIT_BEAST_LEVEL3</EarlyArtDefineTag>
    						<LateArtDefineTag>ART_DEF_UNIT_PIT_BEAST_LEVEL3</LateArtDefineTag>
    						<MiddleArtDefineTag>ART_DEF_UNIT_PIT_BEAST_LEVEL3</MiddleArtDefineTag>
    					</UnitMeshGroup>
    				</StyleUnit>
    			</StyleUnits>
    		</UnitArtStyleTypeInfo>
    And edit C:\Program Files (x86)\Firaxis Games\Sid Meier's Civilization 4\Beyond the Sword\Mods\Magister Modmod for FfH2\Assets\XML\Art\CIV4ArtDefines_Unit.xml so that the new unit art points to something.
    Code:
    		<UnitArtInfo>
    			<Type>ART_DEF_UNIT_PIT_BEAST_LEVEL2</Type>
    			<Button>Art/Interface/Buttons/Units/Pit Beast.dds</Button>
    			<fScale>36</fScale>
    			<fInterfaceScale>0.6</fInterfaceScale>
    			<bActAsLand>0</bActAsLand>
    			<bActAsAir>0</bActAsAir>
    			<NIF>Art/Units/Summons/Pit Beast/Devourer.nif</NIF>
    			<KFM>Art/Units/Summons/Pit Beast/Devourer.kfm</KFM>
    			<ShadowDef>
    				<ShadowNIF>Art/Units/01_UnitShadows/LionShadow.nif</ShadowNIF>
    				<ShadowAttachNode>LionBip Spine1</ShadowAttachNode>
    				<fShadowScale>0.04</fShadowScale>
    			</ShadowDef>
    				<fBattleDistance>0.35</fBattleDistance>
    				<fRangedDeathTime>0.28</fRangedDeathTime>
    				<bActAsRanged>0</bActAsRanged>
    				<TrainSound>AS2D_UNIT_BUILD_UNIT</TrainSound>
    			<AudioRunSounds>
    				<AudioRunTypeLoop/>
    				<AudioRunTypeEnd/>
    			</AudioRunSounds>
    		</UnitArtInfo>
    		<UnitArtInfo>
    			<Type>ART_DEF_UNIT_PIT_BEAST_LEVEL3</Type>
    			<Button>Art/Interface/Buttons/Units/Pit Beast.dds</Button>
    			<fScale>40</fScale>
    			<fInterfaceScale>0.4</fInterfaceScale>
    			<bActAsLand>0</bActAsLand>
    			<bActAsAir>0</bActAsAir>
    			<NIF>Art/Units/Summons/Pit Beast/Devourer.nif</NIF>
    			<KFM>Art/Units/Summons/Pit Beast/Devourer.kfm</KFM>
    			<ShadowDef>
    				<ShadowNIF>Art/Units/01_UnitShadows/LionShadow.nif</ShadowNIF>
    				<ShadowAttachNode>LionBip Spine1</ShadowAttachNode>
    				<fShadowScale>0.04</fShadowScale>
    			</ShadowDef>
    				<fBattleDistance>0.35</fBattleDistance>
    				<fRangedDeathTime>0.28</fRangedDeathTime>
    				<bActAsRanged>0</bActAsRanged>
    				<TrainSound>AS2D_UNIT_BUILD_UNIT</TrainSound>
    			<AudioRunSounds>
    				<AudioRunTypeLoop/>
    				<AudioRunTypeEnd/>
    			</AudioRunSounds>
    		</UnitArtInfo>
    
    (When you increase <fScale> to make the unit bigger, I recommend decreasing <fInterfaceScale> so that it does not become way too big in the civilopedia and in the model that shows up in the left side of the screen when the unit is selected. When it is to big, it gets cut off awkwardly.)



    I'm less sure about how to change the group size. I know that the <iGroupSize>1 of the hero promotion makes only the first unit graphic show up for the unit, but I'm not if it can make groups bigger or smaller without reducing them to single unit graphics.

    Note that in those art styles definitions, you have to include multiple <UnitMeshGroup> for each unit if you want all of the units displayed in the graphics to change. If you only have one but the unit in question has a larger group, most of the units in the group won't seem to change.

    I suppose that you could deal with group sizes by making the groups much bigger in the unit's defines, but the making the art styles for the lower levels make a majority of the <UnitMeshGroup> elements point to unit graphics that are too small for anyone to see. It might look odd to have the visible units wait for the invisible ones to attack though.
     
  18. Aurelazza

    Aurelazza Chieftain

    Joined:
    Oct 4, 2012
    Messages:
    58
    I just checked, and settlers have an iGroupSize of 4; for Goblins and Frostlings it's 5. I don't see why iGroupSize couldn't be changed in CIV4ArtDefines_Unit.xml

    I'm embarrassed to admit that I've yet to come across a comprehensive list of Python commands, so I'm at somewhat of a loss as to how I'd set up the trigger for

    pUnit.getUnitArtStyleType()

    pUnit.setUnitArtStyleType(gc.getInfoTypeForString( 'UNIT_ARTSTYLE_LEVEL2'))

    :blush:

    Edit: Looking into this now.

    And suppose that I wanted to get even more ambitious and add in a free promotion and a message along with the unit upgrade. "Your Pit Beast has grown grotesquely massive by feasting upon the fallen. "Strong" promotion gained."

    On another note, in my tinkering around with various files for the sake of learning in a hands-on manner, I decided to try and make everybody's favorite Doviello axeman remain relevant in the mid and late game. I made two Lucian upgrades and the spells to upgrade them when the requirements are met, then tested them to find that they worked exactly as planned.

    The one remaining detail to be addressed is the matter of ensuring that once he's been upgraded, an earlier incarnation of his can't be revived via Life 3. I studied the way the Magister ModMod treats Doviello upgrades and the way it prevents multiple Aurics once The Ascension is complete. I'm unsure which of these two is right, or whether they're both wrong.

    Code:
    		elif iUnit == gc.getInfoTypeForString('UNIT_LUCIAN'):
    			iSluagh = gc.getInfoTypeForString('UNIT_SLUAGH_LUCIAN')
    		elif iUnit == gc.getInfoTypeForString('UNIT_LUCIAN2'):
    			iSluagh = gc.getInfoTypeForString('UNIT_SLUAGH_LUCIAN')
    		elif iUnit == gc.getInfoTypeForString('UNIT_LUCIAN3'):
    			iSluagh = gc.getInfoTypeForString('UNIT_SLUAGH_LUCIAN')
    			#This is to prevent you from being able to ressurect Lucian when he upgrades instead of dies
    			iLucian2 = gc.getInfoTypeForString('UNIT_LUCIAN2')
    			iLucian3 = gc.getInfoTypeForString('UNIT_LUCIAN3')
    			for pUnit in player.getUnitList():
    				if pUnit.getUnitType() == iLucian2 or pUnit.getUnitType() == iLucian3:
    					iSluagh = -1
    					break


    Code:
    		elif iUnit == gc.getInfoTypeForString('UNIT_LUCIAN2') or iUnit == gc.getInfoTypeForString('LUCIAN3'):
    			iSluagh = gc.getInfoTypeForString('UNIT_SLUAGH_LUCIAN')
    			#This is to prevent you from being able to ressurect Lucian when he upgrades instead of dies
    			iLucian2 = gc.getInfoTypeForString('UNIT_LUCIAN2')
    			iLucian3 = gc.getInfoTypeForString('UNIT_LUCIAN3')
    			for pUnit in player.getUnitList():
    				if pUnit.getUnitType() == iLucian2 or pUnit.getUnitType() == iLucian3:
    					iSluagh = -1
    					break
     
  19. MagisterCultuum

    MagisterCultuum Great Sage

    Joined:
    Feb 14, 2007
    Messages:
    15,546
    Location:
    Kael's head
    CIV4ArtDefines_Unit.xml does not contain the iGroupSize element. It only defines the individual unit art models. A unit in the game can be set to display an arbitrary mix of these.

    CIV4PromotionInfos.xml has iGroupSize, but I'm not sure if that can do anything but reduce the group to a single unit.

    CIV4UnitInfos.xml:
    Code:
    			<UnitMeshGroups>
    			<iGroupSize>4</iGroupSize>
    			<fMaxSpeed>1.75</fMaxSpeed>
    			<fPadTime>1</fPadTime>
    			<iMeleeWaveSize>4</iMeleeWaveSize>
    			<iRangedWaveSize>0</iRangedWaveSize>
    				<UnitMeshGroup>
    					<iRequired>1</iRequired>
    					<EarlyArtDefineTag>ART_DEF_UNIT_SETTLER_MALE</EarlyArtDefineTag>
    				</UnitMeshGroup>
    				<UnitMeshGroup>
    					<iRequired>1</iRequired>
    					<EarlyArtDefineTag>ART_DEF_UNIT_SETTLER_FEMALE</EarlyArtDefineTag>
    				</UnitMeshGroup>
    				<UnitMeshGroup>
    					<iRequired>2</iRequired>
    					<EarlyArtDefineTag>ART_DEF_UNIT_SETTLER_CHILD</EarlyArtDefineTag>
    				</UnitMeshGroup>
    			</UnitMeshGroups>
    Here, <iGroupSize> determines the number of units to appear in the group.

    I think that <iMeleeWaveSize> and <iRangedWaveSize> are for determining how many units move to attack.

    Each <UnitMeshGroup> refers to a different kind of unit to display. <EarlyArtDefineTag> tells the game which entry in CIV4ArtDefines_Unit.xml to use to get this art. <iRequired> determines how many units will use that art.


    If I recall correctly and I may not), the game will crash if you set <iGroupSize> to be larger than the sum of the <iRequired> for each <UnitMeshGroup>.

    CIV4UnitArtStyleTypeInfos.xml essentially just overwrites the <UnitMeshGroup> for certain units in certain art styles. It seems to overwrite them in order. If there are more <UnitMeshGroup> for the unit in its unit defines than in the CIV4UnitArtStyleTypeInfos.xml, then the extra will remain unchanged.

    When you use single unit graphics (from the game option or a promotion with <iGroupSize>1) then only one unit with the first <UnitMeshGroup> graphics is displayed.

    A settler does not have a single define in CIV4ArtDefines_Unit.xml, but instead refers to three of them. It uses the male unit graphics once, and then the female once, and then the children twice. With single unit graphics, it only shows the male. If you were to have an art style that gives the unit only one <UnitMeshGroup>, then the male would be changed but the female and children would remain the same.


    ------
    I just discovered that there is a onUnitPromoted function under CvEventManager.py, which runs whenever a unit levels up by using its xp to purchase a promotion. (It does not run if you add levels or promotions through spells, python, worldbuilder, or upgrading a unit.)

    You can use it like this:
    Code:
    	def onUnitPromoted(self, argsList):
    		'Unit Promoted'
    		pUnit, iPromotion = argsList
    		player = PyPlayer(pUnit.getOwner())
    [COLOR="Red"]
    
    		if pUnit.getUnitType() == gc.getInfoTypeForString('UNIT_PIT_BEAST'):
    			if pUnit.getUnitArtStyleType() != gc.getInfoTypeForString('UNIT_ARTSTYLE_LEVEL3'):
    				if pUnit.getLevel() > 2:
    					pUnit.setUnitArtStyleType(gc.getInfoTypeForString('UNIT_ARTSTYLE_LEVEL3'))
    					pUnit.setHasPromotion(gc.getInfoTypeForString('PROMOTION_STRONG'), True)
    					CyInterface().addMessage(pUnit.getOwner(),True,25,CyTranslator().getText("TXT_KEY_MESSAGE_PIT_BEAST_GAINS_STRONG", ()),'',1,'Art/Interface/Buttons/Units/Pit Beast.dds',ColorTypes(7),pUnit.getX(),pUnit.getY(),True,True)
    
    				elif pUnit.getLevel() > 1:
    					pUnit.setUnitArtStyleType(gc.getInfoTypeForString('UNIT_ARTSTYLE_LEVEL2'))[/COLOR]
    
    		if not self.__LOG_UNITPROMOTED:
    			return
    		CvUtil.pyPrint('Unit Promotion Event: %s - %s' %(player.getCivilizationName(), pUnit.getName(),))
    
    (I'm thinking this callback might have been disabled in base FfH2, but work again in Tholal's More Naval AI. Otherwise, it seems like I would have realized I could use it before. I just now edited Magister Modmod so that a unit which purchases either Unholy Taint or Pilgrim will get the same free promotions as if it already had said promotion when it was first initialized.)

    -------------
    Is your modmod based on my modmod or on Base FfH2 (or MNAI)?

    In base FfH2, there are no sluagh units to store data about the departed. The game just checks to see if the unitclass has been maxed out and whether any player owns units of the unitclass. If you make your Lucian upgrades still be UNITCLASS_LUCIAN, then there would be no issues. Note that you could not use the standard method of upgrading a unit and keep it in the same unitclass; you could however easily upgrade the unit through a spell.

    In my modmod things get a bit trickier. Sluagh's aren't the most elegant way of storing the data of dead heroes, but I haven't figured out how to implement it the way lfgr recommended.



    In my modmod, UNIT_HIGH_PRIEST_RIUROS, UNIT_HEIR_RIUROS, and UNIT_EIDOLON_RIUROS are alternate rather than sequential upgrades. Only the death of UNIT_RUIROS could be due to an upgrade, not the death of any of its upgrades.

    I'm assuming that you wish for Lucian 1 to upgrade to Lucian 2, for Lucian 2 to upgrade to Lucian 3, and for Lucian 3 not to upgrade to anything. That means that the "death" of either Lucian 1 or Lucian 2 could actually be the unit upgrading, but that would never be true of the death of Lucian 3.


    I think you'd want it like this:
    Code:
    		elif iUnit == gc.getInfoTypeForString('UNIT_LUCIAN3'):
    			iSluagh = gc.getInfoTypeForString('UNIT_SLUAGH_LUCIAN')
    		elif iUnit == gc.getInfoTypeForString('UNIT_LUCIAN2'):
    			iSluagh = gc.getInfoTypeForString('UNIT_SLUAGH_LUCIAN')
    			#This is to prevent you from being able to resurrect Lucian when he upgrades instead of dies
    			iLucian3 = gc.getInfoTypeForString('UNIT_LUCIAN3')
    			for pUnit in player.getUnitList():
    				if pUnit.getUnitType() == iLucian3:
    					iSluagh = -1
    					break
    		elif iUnit == gc.getInfoTypeForString('UNIT_LUCIAN'):
    			iSluagh = gc.getInfoTypeForString('UNIT_SLUAGH_LUCIAN')
    			#This is to prevent you from being able to ressurect Lucian when he upgrades instead of dies
    			iLucian2 = gc.getInfoTypeForString('UNIT_LUCIAN2')
    			iLucian3 = gc.getInfoTypeForString('UNIT_LUCIAN3')
    			for pUnit in player.getUnitList():
    				if pUnit.getUnitType() == iLucian2 or pUnit.getUnitType() == iLucian3:
    					iSluagh = -1
    					break
    
     
  20. Aurelazza

    Aurelazza Chieftain

    Joined:
    Oct 4, 2012
    Messages:
    58
    Thank you, Magister. I've yet to test the promotion upon leveling script, but the revive prevention seems to work excellently.

    I'm using your modmod as a base, and I don't find your slaugh solution to be inconvenient at all. I'd hardly call what I'm doing a modmod of my own, though - it's really just learning how to mod while making minor tweaks to my FFH modmod of choice. Perhaps I'll make a custom scenario or two, but that would most likely be the extent of it.

    I've been trying to figure out the mechanics behind becoming the leader - and taking control of - a different civilization than your own. I've searched many a python file for anything relating to the Infernal/Mercurian entrance, Gibbon Goetia, or Mulcarn Reborn, all with little success.

    This started with me thinking about how much more enjoyable the Mulcarn Reborn scenario would be if the player simply cycled through every allied civ each turn, leaving no room for the AI to throw a wrench in your strategy and ruin your plans. Depending on the limitations of this mechanic, there's an enormous potential for innovative custom scenarios. How much is known regarding this mechanic?
     

Share This Page