1. We have added the ability to collapse/expand forum categories and widgets on forum home.
    Dismiss Notice
  2. Photobucket has changed its policy concerning hotlinking images and now requires an account with a $399.00 annual fee to allow hotlink. More information is available at: this link.
    Dismiss Notice
  3. All Civ avatars are brought back and available for selection in the Avatar Gallery! There are 945 avatars total.
    Dismiss Notice
  4. To make the site more secure, we have installed SSL certificates and enabled HTTPS for both the main site and forums.
    Dismiss Notice
  5. Civ6 is released! Order now! (Amazon US | Amazon UK | Amazon CA | Amazon DE | Amazon FR)
    Dismiss Notice
  6. Dismiss Notice
  7. 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. Aurelazza

    Aurelazza Chieftain

    Joined:
    Oct 4, 2012
    Messages:
    58
    Forgive me for committing the cardinal sin of double-posting, but I ran across an interesting problem here.
     
  2. Duc Beauregard

    Duc Beauregard Chieftain

    Joined:
    Apr 1, 2012
    Messages:
    13
    Hey, everyone
    I had an idea about a unit that could rebel, and then recruit units. After I started to work on it, I saw that the summon feature might use Python? I was copying the promotions and effects to raise a skeleton when I saw it, and was wondering if a change in python is needed, or not.
    Basically, what I want is to have unit randomly rebel and become barbarian, then also spawn underlings until the unit is killed. After accumulating a nice sized army, the horde should attack (though the barbarians attack if they get a nice enough army anyways, right?). It seems like it should be an easy trick, though I just don't know how to do it yet.
    Cheers
     
  3. Zlatko

    Zlatko CIW

    Joined:
    Apr 1, 2010
    Messages:
    713
    Location:
    Solar System
    Which files and how i can use your improvements (bandit camps i really don't know their name and etc) which spawn barbarian units, i just want this. Which XML files, PY files and SDK files is need for that?
     
  4. MagisterCultuum

    MagisterCultuum Great Sage

    Joined:
    Feb 14, 2007
    Messages:
    15,599
    Location:
    Kael's head
    You would use the <SpawnUnitType> tag in C:\Program Files (x86)\Firaxis Games\Sid Meier's Civilization 4\Beyond the Sword\Mods\Fall from Heaven 2\Assets\XML\Terrain\CIV4ImprovementInfos.xml. You put the type of unit between those tabs at the end of the improvement's defines, like <SpawnUnitType>UNIT_GOBLIN_SCORPION_CLAN</SpawnUnitType>

    Since this tag is not used in base BtS, using them in an unrelated mod would require editing Assets\XML\Terrain\CIV4TerrainSchema.xml and compile a new DLL making changes to CvGameTextMgr.cpp, CvInfos.cpp, CvInfos.h, CvPlot.cpp, CvUnit.cpp, and CyInfoInterface2.cpp.
     
  5. Zlatko

    Zlatko CIW

    Joined:
    Apr 1, 2010
    Messages:
    713
    Location:
    Solar System
  6. MagisterCultuum

    MagisterCultuum Great Sage

    Joined:
    Feb 14, 2007
    Messages:
    15,599
    Location:
    Kael's head
    The first post of this thread contains a link to a zip archive of the DLL's source code.
     
  7. Zlatko

    Zlatko CIW

    Joined:
    Apr 1, 2010
    Messages:
    713
    Location:
    Solar System
    I try to merge yesterday but i was confused, don't know which part of code to use, i am found SpawnUnitType tag in source codes. And do you know where i can found source files for RifE (Rise from Erebus) in rife spawn works more better than in FFH2 ?
     
  8. Zlatko

    Zlatko CIW

    Joined:
    Apr 1, 2010
    Messages:
    713
    Location:
    Solar System
    I want to use all tags from PromotionInfos (FfH2), can someone tell me which .py, .cpp and .h files i must use? Merge BTS + PromotionInfos tags (FfH2).
     
  9. Tholal

    Tholal Chieftain

    Joined:
    May 19, 2009
    Messages:
    1,671
    Rife Source code is here - https://sourceforge.net/p/rife/code/HEAD/tree/

    You can also find the source code for my mod on Sourceforge - https://sourceforge.net/projects/tholalsffhaimod/

    I dont think you need any python files for the new Promotion tags. You'll have to search for each tag in the .ccp files and .h files to figure out what lines of code need to be merged.
     
  10. Tholal

    Tholal Chieftain

    Joined:
    May 19, 2009
    Messages:
    1,671
    You would probably want to put your code in CvEventManager - onBeginPlayerTurn

    Loop through the units to randomly choose ones to give the barbarian promotion to, and then also check for units with that promotion. If they have it, then try and spawn some underlings.
     
  11. Zlatko

    Zlatko CIW

    Joined:
    Apr 1, 2010
    Messages:
    713
    Location:
    Solar System
    @Tholal
    Thanks, i must found tags name from XML in .cpp and .h and merge all with BTS (FfH2 or RifE i will choose better or easier). Did Promotion and Spells or Unit infos had some relationship? I only want to use promotion tags and later merge this tags with some another tags and some another SDK mod components.

    And of course i will see you mods and interesting stuff.
     
  12. schargiel

    schargiel Chieftain

    Joined:
    Feb 15, 2013
    Messages:
    32
    Hi.
    I am working on a szenario on Games of Throne based on Magistermodmod.
    I would like to integrate the gameoption that the first civic wins that has built its palace in Kings Landing.

    I am new with modding, so I need help. I know it has to be done in the ScenarioFunctions.py but I have no idea how to write it.

    If anyone can help me, I would be so glad.
     
  13. MagisterCultuum

    MagisterCultuum Great Sage

    Joined:
    Feb 14, 2007
    Messages:
    15,599
    Location:
    Kael's head
    I recently tried giving a building a negative number for <iNumFreeBonuses>, and noticed something odd.


    If I try to make a building provide -1 sources of Death Mana then it instead grants +3 sources, but when I try t make it grant -2 then it does indeed reduce the number of Death mana the player controls by 2.

    Any idea why this might be happening?


    (Note that this is of course in my modmod, which uses the MNAI DLL. I was thinking that I might prefer to have the Sidar's Shrine of Arawn UB reduce the amount of Death mana controlled by 1 per building, rather than making the mana completely unavailable or granting such a large unhappiness penalty for possessing the resource. Having he building provide 3 Death mana is very wrong, but ending up with -20 death mana like in my last game seems odd too.)
     
  14. Tholal

    Tholal Chieftain

    Joined:
    May 19, 2009
    Messages:
    1,671
    -1 is often used as a special designation. In this case, there's some weird code in getNumFreeBonuses. Not sure why it's doing this but there must be some reasoning behind it.

    Code:
    int CvGame::getNumFreeBonuses(BuildingTypes eBuilding)
    {
    	if (GC.getBuildingInfo(eBuilding).getNumFreeBonuses() == -1)
    	{
    		return GC.getWorldInfo(GC.getMapINLINE().getWorldSize()).getNumFreeBuildingBonuses();
    	}
    	else
    	{
    		return GC.getBuildingInfo(eBuilding).getNumFreeBonuses();
    	}
    }
     
  15. talonschild

    talonschild Drive-By NESer

    Joined:
    Nov 29, 2011
    Messages:
    1,945
    Location:
    Vancouver, BC, Canada
    In which file would I find the unique names given to units (e.g. a barbarian djinn spawned, called Danir Quian, etc.)?
     
  16. omegaflames

    omegaflames Chieftain

    Joined:
    Sep 21, 2012
    Messages:
    91
    Most of the time those unique names are given via the python because they were created via an event (the priest of winter's get their names like this under def onProjectBuilt in CvEventManager.py) however you can also give them from a list of names like UNIT_ADVENTURER is done in CIV4UnitInfos.xml (this will require editing CIV4GameText_FFH2.xml with the names you want in the list)
     
  17. MagisterCultuum

    MagisterCultuum Great Sage

    Joined:
    Feb 14, 2007
    Messages:
    15,599
    Location:
    Kael's head
    Technically you can add a custom name to a unit's CIVUnitInfos.xml defied directly, without necessarily adding a TXT_KEY_ for it, and within Assets\XML\Text the file where you place a new TXT_KEY_ does not matter much.


    Most of the units in the game which get a custom name have their named generated (pseudo-)randomly in CustomFunctions.py under def MarnokNameGenerator(self, unit):
    Spoiler :
    Code:
    
    	def MarnokNameGenerator(self, unit):
    		pPlayer = gc.getPlayer(unit.getOwner())	
    		pCiv = pPlayer.getCivilizationType() 
    		pReligion = pPlayer.getStateReligion()
    		pAlign = pPlayer.getAlignment() 
    
    		lPre=["ta","go","da","bar","arc","ken","an","ad","mi","kon","kar","mar","wal","he", "ha", "re", "ar", "bal", "bel", "bo", "bri", "car","dag","dan","ma","ja","co","be","ga","qui","sa"]
    		lMid=["ad","z","the","and","tha","ent","ion","tio","for","tis","oft","che","gan","an","en","wen","on","d","n","g","t","ow","dal"]
    		lEnd=["ar","sta","na","is","el","es","ie","us","un","th", "er","on","an","re","in","ed","nd","at","en","le","man","ck","ton","nok","git","us","or","a","da","u","cha","ir"]
    	
    		lEpithet=["red","blue","black","grey","white","strong","brave","old","young","great","slayer","hunter","seeker"]
    		lNoun=["spirit","soul","boon","born","staff","rod","shield","autumn","winter","spring","summer","wit","horn","tusk","glory","claw","tooth","head","heart", "blood","breath", "blade", "hand", "lover","bringer","maker","taker","river","stream","moon","star","face","foot","half","one","hundred","thousand"]
    		lSchema=["CPME","CPMESCPME","CPESCPE","CPE","CPMME","CPMDCME","CPMAME","KCPMESCUM","CPMME[ the ]CX", "CPMESCXN", "CPMME[ of ]CPMME", "CNNSCXN"]
    
    		if pAlign == gc.getInfoTypeForString('ALIGNMENT_EVIL'):
    			lNoun = lNoun + ["fear","terror","reign","brood","snare","war","strife","pain","hate","evil","hell","misery","murder","anger","fury","rage","spawn","sly","blood","bone","scythe","slave","bound","ooze","scum"]
    			lEpithet=["dark","black","white","cruel","foul"]		
    	
    		if pReligion == gc.getInfoTypeForString('RELIGION_THE_ASHEN_VEIL'):
    			lEpithet = lEpithet + ["fallen","diseased","infernal","profane","corrupt"]
    			lSchema = lSchema + ["CPME[ the ]CX"]
    		if pReligion == gc.getInfoTypeForString('RELIGION_OCTOPUS_OVERLORDS'):
    			lPre = lPre + ["cth","cht","shu","az","ts","dag","hy","gla","gh","rh","x","ll"]		
    			lMid = lMid + ["ul","tha","on","ug","st","oi"]	
    			lEnd = lEnd + ["hu","on", "ha","ua","oa","uth","oth","ath","thua", "thoa","ur","ll","og","hua"]
    			lEpithet = lEpithet + ["nameless","webbed","deep","watery"]
    			lNoun = lNoun + ["tentacle","wind","wave","sea","ocean","dark","crab","abyss","island"]
    			lSchema = lSchema + ["CPMME","CPDMME","CPAMAME","CPMAME","CPAMAMEDCPAMAE"]
    		if pReligion == gc.getInfoTypeForString('RELIGION_THE_ORDER'):
    			lPre = lPre + ["ph","v","j"]		
    			lMid = lMid + ["an","al","un"]	
    			lEnd = lEnd + ["uel","in","il"]
    			lEpithet = lEpithet + ["confessor","crusader", "faithful","obedient","good"]
    			lNoun = lNoun + ["order", "faith", "heaven","law"]
    			lSchema = lSchema + ["CPESCPME","CPMESCPE","CPMESCPME", "CPESCPE"]
    		if pReligion == gc.getInfoTypeForString('RELIGION_FELLOWSHIP_OF_LEAVES'):
    			lPre = lPre + ["ki","ky","yv"]		
    			lMid = lMid + ["th","ri"]	
    			lEnd = lEnd + ["ra","el","ain"]
    			lEpithet = lEpithet + ["green"]
    			lNoun = lNoun + ["tree","bush","wood","berry","elm","willow","oak","leaf","flower","blossom"]
    			lSchema = lSchema + ["CPESCN","CPMESCNN","CPMESCXN"]		
    		if pReligion == gc.getInfoTypeForString('RELIGION_RUNES_OF_KILMORPH'):
    			lPre = lPre + ["bam","ar","khel","ki"]		
    			lMid = lMid + ["th","b","en"]	
    			lEnd = lEnd + ["ur","dain","ain","don"]
    			lEpithet = lEpithet + ["deep","guard","miner"]
    			lNoun = lNoun + ["rune","flint","slate","stone","rock","iron","copper","mithril","thane","umber"]
    			lSchema = lSchema + ["CPME","CPMME"]	
    		if pReligion == gc.getInfoTypeForString('RELIGION_THE_EMPYREAN'):
    			lEpithet = lEpithet + ["radiant","holy"]
    			lNoun = lNoun + ["honor"]
    		if pReligion == gc.getInfoTypeForString('RELIGION_COUNCIL_OF_ESUS'):
    			lEpithet = lEpithet + ["hidden","dark"]
    			lNoun = lNoun + ["cloak","shadow","mask"]
    			lSchema = lSchema + ["CPME","CPMME"]	
    
    		if unit.isHasPromotion(gc.getInfoTypeForString('PROMOTION_ENRAGED')) == True:
    			# I have left this as a copy of the Barbarian, see how it goes, this might do the trick. I plan to use it when there is a chance a unit will go Barbarian anyway.
    			lPre = lPre + ["gru","bra","no","os","dir","ka","z"]
    			lMid = lMid + ["g","ck","gg","sh","b","bh","aa"]
    			lEnd = lEnd + ["al","e","ek","esh","ol","olg","alg"]
    			lNoun = lNoun + ["death", "hate", "rage", "mad","insane","berserk"]		
    			lEpithet = lEpithet + ["smasher", "breaker", "mangle","monger"]
    
    		if unit.isHasPromotion(gc.getInfoTypeForString('PROMOTION_CRAZED')) == True:
    			# might want to tone this down, because I plan to use it as possession/driven to madness, less than madcap zaniness.
    			lPre = lPre + ["mad","pim","zi","zo","fli","mum","dum","odd","slur"]
    			lMid = lMid + ["bl","pl","gg","ug","bl","b","zz","abb","odd"]
    			lEnd = lEnd + ["ad","ap","izzle","onk","ing","er","po","eep","oggle","y"]	
    		
    		if unit.isHasPromotion(gc.getInfoTypeForString('PROMOTION_VAMPIRE')) == True:
    			lPre = lPre + ["dra","al","nos","vam","vla","tep","bat","bar","cor","lil","ray","zar","stra","le"]
    			lMid = lMid + ["cul","u","car","fer","pir","or","na","ov","sta"]
    			lEnd = lEnd + ["a","d","u","e","es","y","bas","vin","ith","ne","ak","ich","hd","t"]	
    
    		if unit.isHasPromotion(gc.getInfoTypeForString('PROMOTION_DEMON')) == True:
    			lPre = lPre + ["aa","ab","adr","ah","al","de","ba","cro","da","be","eu","el","ha","ib","me","she","sth","z"]
    			lMid = lMid + ["rax","lia","ri","al","as","b","bh","aa","al","ze","phi","sto","phe","cc","ee"]
    			lEnd = lEnd + ["tor","tan","ept","lu","res","ah","mon","gon","bul","gul","lis","les","uz"]
    			lSchema = ["CPMMME","CPMACME", "CPKMAUAPUE", "CPMMME[ the ]CNX"]				
    		
    		if unit.getUnitType() == gc.getInfoTypeForString('UNIT_HILL_GIANT'):
    			lPre = lPre + ["gor","gra","gar","gi","gol"]
    			lMid = lMid + ["gan","li","ri","go"]
    			lEnd = lEnd + ["tus","tan","ath","tha"]
    			lSchema = lSchema +["CXNSCNN","CPESCNE", "CPMME[ the ]CX"]		
    			lEpithet = lEpithet + ["large","huge","collossal","brutal","basher","smasher","crasher","crusher"]		
    			lNoun = lNoun + ["fist","tor","hill","brute","stomp"]
    
    		if unit.getUnitType() == gc.getInfoTypeForString('UNIT_LIZARDMAN'):
    			lPre = lPre + ["ss","s","th","sth","hss"]
    			lEnd = lEnd + ["ess","iss","ath","tha"]
    			lEpithet = lEpithet + ["cold"]			
    			lNoun = lNoun + ["hiss","tongue","slither","scale","tail","ruin"]
    			lSchema = lSchema + ["CPAECPAE","CPAKECPAU","CPAMMAE"]		
    		if unit.getUnitType() == gc.getInfoTypeForString('UNIT_FIRE_ELEMENTAL') or unit.getUnitType() == gc.getInfoTypeForString('UNIT_AZER'):
    			lPre = lPre + ["ss","cra","th","sth","hss","roa"]
    			lMid = lMid + ["ss","ck","rr","oa","iss","tt"]		
    			lEnd = lEnd + ["le","iss","st","r","er"]
    			lNoun = lNoun + ["hot", "burn","scald","roast","flame","scorch","char","sear","singe","fire","spit"]			
    			lSchema = ["CNN","CNX","CPME","CPME[ the ]CNX","CPMME","CNNSCPME"]
    		if unit.getUnitType() == gc.getInfoTypeForString('UNIT_WATER_ELEMENTAL'):
    			lPre = lPre + ["who","spl","dr","sl","spr","sw","b"]
    			lMid = lMid + ["o","a","i","ub","ib"]		
    			lEnd = lEnd + ["sh","p","ter","ble"]
    			lNoun = lNoun + ["wave","lap","sea","lake","water","tide","surf","spray","wet","damp","soak","gurgle","bubble"]			
    			lSchema = ["CNN","CNX","CPME","CPME[ the ]CNX","CPMME","CNNSCPME"]	
    		if unit.getUnitType() == gc.getInfoTypeForString('UNIT_AIR_ELEMENTAL'):
    			lPre = lPre + ["ff","ph","th","ff","ph","th"]
    			lMid = lMid + ["oo","aa","ee","ah","oh"]		
    			lEnd = lEnd + ["ff","ph","th","ff","ph","th"]
    			lNoun = lNoun + ["wind","air","zephyr","breeze","gust","blast","blow"]			
    			lSchema = ["CNN","CNX","CPME","CPME[ the ]CNX","CPMME","CNNSCPME"]	
    		if unit.getUnitType() == gc.getInfoTypeForString('UNIT_EARTH_ELEMENTAL'):
    			lPre = lPre + ["gra","gro","kro","ff","ph","th"]
    			lMid = lMid + ["o","a","u"]		
    			lEnd = lEnd + ["ck","g","k"]
    			lNoun = lNoun + ["rock","stone","boulder","slate","granite","rumble","quake"]			
    			lSchema = ["CNN","CNX","CPME","CPME[ the ]CNX","CPMME","CNNSCPME"]	
    	
    		# SEA BASED
    		# Check for ships - special schemas
    		if unit.getUnitCombatType() == gc.getInfoTypeForString('UNITCOMBAT_NAVAL'):
    			lEnd = lEnd + ["ton","town","port"]
    			lNoun = lNoun + ["lady","jolly","keel","bow","stern", "mast","sail","deck","hull","reef","wave"]
    			lEpithet = lEpithet + ["sea", "red", "blue","grand","barnacle","gull"]
    			lSchema = ["[The ]CNN", "[The ]CXN", "[The ]CNX","[The ]CNSCN", "[The ]CNSCX","CPME['s ]CN","[The ]CPME", "[The ]CNX","CNX","CN['s ]CN"]
    	
    		# # #
    		# Pick a Schema
    		sSchema = lSchema[CyGame().getSorenRandNum(len(lSchema), "Name Gen")-1]
    		sFull = ""
    		sKeep = ""
    		iUpper = 0
    		iKeep = 0
    		iSkip = 0
    	
    		# Run through each character in schema to generate name
    		for iCount in range (0,len(sSchema)):
    			sAdd=""
    			iDone = 0
    			sAction = sSchema[iCount]
    			if iSkip == 1:
    				if sAction == "]":
    					iSkip = 0
    				else:
    					sAdd = sAction
    					iDone = 1		
    			else:					# MAIN SECTION
    				if sAction == "P": 	# Pre 	: beginnings of names
    					sAdd = lPre[CyGame().getSorenRandNum(len(lPre), "Name Gen")-1]
    					iDone = 1
    				if sAction == "M":	# Mid 	: middle syllables
    					sAdd = lMid[CyGame().getSorenRandNum(len(lMid), "Name Gen")-1]	
    					iDone = 1	
    				if sAction == "E":	# End	: end of names
    					sAdd = lEnd[CyGame().getSorenRandNum(len(lEnd), "Name Gen")-1]
    					iDone = 1
    				if sAction == "X":	# Epithet	: epithet word part
    					#epithets ("e" was taken!)
    					sAdd = lEpithet[CyGame().getSorenRandNum(len(lEpithet), "Name Gen")-1]
    					iDone = 1
    				if sAction == "N":	# Noun	: noun word part
    					#noun
    					sAdd = lNoun[CyGame().getSorenRandNum(len(lNoun), "Name Gen")-1]	
    					iDone = 1
    				if sAction == "S":	# Space	: a space character. (Introduced before [ ] was possible )
    					sAdd =  " "
    					iDone = 1
    				if sAction == "D":	# Dash	: a - character. Thought to be common and useful enough to warrant inclusion : Introduced before [-] was possible 
    					sAdd =  "-"
    					iDone = 1
    				if sAction == "A":	# '		: a ' character - as for -, introduced early
    					sAdd = "'" 
    					iDone = 1
    				if sAction == "C":	# Caps	: capitalizes first letter of next phrase generated. No effect on non-letters.
    					iUpper = 1
    				if sAction == "K":	# Keep	: stores the next phrase generated for re-use with U
    					iKeep = 1
    				if sAction == "U":	# Use	: re-uses a stored phrase.
    					sAdd = sKeep
    					iDone = 1
    				if sAction == "[":	# Print	: anything between [] is added to the final phrase "as is". Useful for [ the ] and [ of ] among others.
    					iSkip = 1
    			# capitalizes phrase once.	
    			if iUpper == 1 and iDone == 1:
    				sAdd = sAdd.capitalize()
    				iUpper = 0
    			# stores the next phrase generated.	
    			if iKeep == 1 and iDone == 1:
    				sKeep = sAdd
    				iKeep = 0
    			# only adds the phrase if a new bit was actally created.
    			if iDone == 1:
    				sFull = sFull + sAdd
    
    		# trim name length			
    		if len(sFull) > 25:
    			sFull = sFull[:25]		
    		#CyInterface().addMessage(caster.getOwner(),True,25,"NAME : "+sFull,'AS2D_POSITIVE_DINK',1,'Art/Interface/Buttons/Spells/Rob Grave.dds',ColorTypes(8),pPlot.getX(),pPlot.getY(),True,True)
    
    		return sFull
    
     
  18. talonschild

    talonschild Drive-By NESer

    Joined:
    Nov 29, 2011
    Messages:
    1,945
    Location:
    Vancouver, BC, Canada
    Thank you both very much.
     
  19. WilliamOfOrange

    WilliamOfOrange Chieftain

    Joined:
    Jul 17, 2003
    Messages:
    998
    Location:
    Lincolnshire, UK
    I have a question regarding the flying promotion. I could have sworn on my old computer, when I had a mod going that the flying promotion actually raised the unit up in the air a bit. I am not seeing that on my Orbis modmod. I don't know if I forgot what I did to get that effect or I am making that up. Does anyone know what I mean? If not, any thoughts on graphically showing the unit up "while flying"? I seem to recall the waterwalking did something similar, lowering the unit, but I could be mistaken.
     
  20. A_Hamster

    A_Hamster Small Furry Animal

    Joined:
    Dec 20, 2007
    Messages:
    627
    It's not in vanilla FfH II, that's for sure. It's been a while since I've played Orbis, but I don't remember the Flying promotion havign a graphical effect associated with it.

    Don't know how you'd get the effect you'd want either.

     

Share This Page