1. We have added a Gift Upgrades feature that allows you to gift an account upgrade to another member, just in time for the holiday season. You can see the gift option when going to the Account Upgrades screen, or on any user profile screen.
    Dismiss Notice

RFC Modding Central

Discussion in 'Rhye's and Fall Modmods' started by Linkman226, Aug 29, 2011.

  1. embryodead

    embryodead Caliph

    Joined:
    Jan 1, 2003
    Messages:
    5,179
    Location:
    basement
    You can extend the event to provide more data, not sure if there won't be any compatibility issues, but there shouldn't be. This may look bad but it's also a set of simple copy & paste one-liners ;)

    In CvEventReporter.cpp/.h and CvDllPythonEvents.cpp/.h find combatResult method and add another argument there (int iAttacker). In CvDllPytonEvents.cpp you'll need to add line like this: eventData.add(iAttacker);

    Same with CvDLLEventReporterIFaceBase.h (that's where the compat issues may come up).

    In CvUnit find all lines with CvEventReporter::getInstance().combatResult ... and add another the attacker's ID ( basically getID() ).

    You'll also need to override the onCombatResults of the default CvEventManager.py so that it reads the third argument.

    ---

    Depends on what you are doing, but you may also consider just doing it in C++ instead.
     
  2. srpt

    srpt Deist

    Joined:
    May 10, 2010
    Messages:
    2,025
    Location:
    Toronto
    I want the chance to enslave a unit to vary depending on whether you are attacking or defending. all the code for enslaving is in python.

    would I override the regular CvEventManager by including my own modded version of the file in the mod folder or some other way?
     
  3. embryodead

    embryodead Caliph

    Joined:
    Jan 1, 2003
    Messages:
    5,179
    Location:
    basement
    Yeah.
     
  4. srpt

    srpt Deist

    Joined:
    May 10, 2010
    Messages:
    2,025
    Location:
    Toronto
    I asked this question in the main modding questions thread, but no one had an answer:

    can anyone help me?
     
  5. srpt

    srpt Deist

    Joined:
    May 10, 2010
    Messages:
    2,025
    Location:
    Toronto
    trying to understand stability better.

    is it true that the various stability parameters are used only to display information to the player and aren't involved in the calculation of actual stability?
     
  6. Leoreth

    Leoreth 古典部の会員 Moderator

    Joined:
    Aug 23, 2009
    Messages:
    32,449
    Gender:
    Male
    Location:
    Kamiyama
    Yes, they're only used for the numbers in the Financial Advisor.
     
  7. SeekTruthFromFacts

    SeekTruthFromFacts Chieftain

    Joined:
    Nov 2, 2009
    Messages:
    656
    The link to enable Python exceptions and logging is dead.
     
  8. srpt

    srpt Deist

    Joined:
    May 10, 2010
    Messages:
    2,025
    Location:
    Toronto
    in your CivilizationIV.ini file set HidePythonExceptions = 0 and LoggingEnabled = 1
     
  9. Leoreth

    Leoreth 古典部の会員 Moderator

    Joined:
    Aug 23, 2009
    Messages:
    32,449
    Gender:
    Male
    Location:
    Kamiyama
    The link still works for me by the way ...
     
  10. srpt

    srpt Deist

    Joined:
    May 10, 2010
    Messages:
    2,025
    Location:
    Toronto
    I'm working on making barbarians hireable as mercenaries.

    I'm doing this by creating alternative versions of the "getEraAppropriateRandomMercenary" definition and the "hire" definition called "getSpecificMercenary" and "spothire", passing a name and grid coordinates.

    everything works for the 1st unit: the unit appears on the map, it also appears as hired in the mercenary screen, the hire cost and the maintenance costs are properly calculated and deducted. for the next and subsequent units the unit appears on the map but the rest doesn't happen.

    Spoiler :
    Code:
    	def getSpecificMercenary(self, iPlayer, iUnitType, strName, iX, iY):
    		' Mercenary - the mercenary'
    		# returns a specific mercenary with a name but no promotions
    		# Setup the mercenary data structure if it hasn't been setup yet.		
    		# if(sdEntityExists("Mercenaries Mod","MercenaryData") == False): # edead
    			# self.setupMercenaryData() # edead
    
    		# return immediately if the iEra doesn't contain a valid value for an era
    		#if(gc.getEraInfo(iEra) == None):
    			#return
    
    		# Initialize the prereqTechEra so it doesn't equal the iEra
    		#prereqTechEra = iEra * -1
    
    		# If iEra is set to 0 then the game just began and set the prereqTechEra 
    		# to -1
    		#if(prereqTechEra == iEra):
    			#prereqTechEra = -1
    
    		# Get the current active player, this use to get the barbarian player but
    		# it had to be changed since barbarians will not always exist in games.
    		# Yes, I know I should change the variable name, but alas I am lazy ...
    		# well maybe not so lazy since I at least took the time to document this
    		# and I could have used the time instead to change the variable name but
    		# I did not ... so live with it.
    		barbarianPlayer = gc.getPlayer(gc.getGame().getActivePlayer())
    
    		mercenary = None
    
    		promotionList = []
    		
    		# Loop until we get a unit with at least some promotions
    		#while(len(promotionList) < g_iMinimumStartingMercenaryPromotionCount):
    
    			#bLoop = True #Rhye
    			#iLoopCounter = 0 #Rhye
    			# Loop until we get a unit that matches the required era
    			#while(prereqTechEra != iEra): #Rhye
    			#while(bLoop): #Rhye
    				#promotionList = []
    
    				#Rhye - start loopfix (infinite loop happens if renaissance+ techs that offer no units are enabled by WB while in the ancient age)
    				#iLoopCounter += 1
    				#if (iLoopCounter > 5000):
    					#return None
    				#Rhye - end
    
    				# The random type of unit that will be created
    				#iUnitType = gc.getGame().getMapRand().get(gc.getNumUnitInfos(), "Random Unit Info")
    				#iUnitType = con.lMercenaries[gc.getGame().getSorenRandNum(len(con.lMercenaries), "Random Unit Info")] # edead: merc whitelist
    				
    				# Get the PyUnitInfo for the iUnitType
    		pUnitInfo = PyInfo.UnitInfo(iUnitType)
    		
    
    		# Create the mercenary unit if we have a valid iUnitType value
    		if(iUnitType != -1):
    				
    			#Rhye - start bugfix
    			# Create the mercenary unit
    			#tmpUnit = barbarianPlayer.initUnit(iUnitType, 0, 0, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)
    			tmpUnit = barbarianPlayer.initUnit(iUnitType, con.iMercX, con.iMercY, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH) # edead
    								
    			# Create the actual mercenary object, we do not pass in the tmpUnit object itself 
    			# because we do not want to accidentally set it as the CyUnit in the Mercenary class
    			#Rhye - start
    			#mercenary = Mercenary(MercenaryNameUtils.getRandomMercenaryName(), gc.getUnitInfo(iUnitType), promotionList, tmpUnit.getExperience(), tmpUnit.experienceNeeded())
    			mercenary = Mercenary(strName, gc.getUnitInfo(iUnitType), promotionList, tmpUnit.getExperience(), tmpUnit.experienceNeeded())
    			#Rhye - end
    
    			# Kill off the tmpUnit since it does not need to exist in the game until someone hires the 
    			# mercenary
    			tmpUnit.kill(false,PlayerTypes.NO_PLAYER)
    
    		#edead - start
    		for x in range(con.iMercX-1, con.iMercX+2):
    			for y in range(con.iMercY-1, con.iMercY+2):
    				gc.getMap().plot(x, y).setRevealed(gc.getGame().getActivePlayer(), False, True, -1);
    		#edead - end
    				
    		# Debug code - start		
    		if(g_bDebug):
    			self.printMercenaryDataToLog(mercenary)
    		# Debug code - end
    		
    		
    		
    		# Get the starting location for the mercenary if we are not delaying their
    		# placement	
    		#city = None
    		#if(not g_bDelayMercenaryPlacement):
    			# edead: start naval mercenaries
    		#if mercenary.getUnitInfo().getDomainType() == gc.getInfoTypeForString("DOMAIN_LAND"):
    			#city = self.getMercenaryStartingLocation(iPlayer)
    		#else:
    			#city = self.getCoastalStartingLocation(iPlayer) 
    				
    		mercenary.spothire(iPlayer, iX, iY)
    		
    		# Saves the mercenary in the global mercenary pool
    		self.saveMercenary(mercenary)
    
    		# Finally return the mercenary
    		#return mercenary



    Spoiler :
    Code:
    	def spothire(self, iPlayer, iX, iY):
    		' CyUnit - the instance of the mercenary in the game '
    
    		# get the player instance
    		player = gc.getPlayer(iPlayer)
    		
    		# return nothing if the iPlayer is an invalid value
    		if(player == None):
    			return
    			
    		# return nothing if the player is dead
    		if(player.isAlive() == false):
    			return
    
    		# Set the player as the owner of the mercenary.	
    		self.iOwner = iPlayer
    		
    		# Set the mercenary as hired
    		self.bHired = true
    		
    		unitType = gc.getInfoTypeForString(self.objUnitInfo.getType())
    
    		
    		# Create the unit and place it in the game		
    		self.objUnit = player.initUnit(unitType, iX, iY, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)
    
    		# If g_bConsumeMercenaryMovesOnHire is set to true then use up all of the 
    		# mercenaries moves, otherwise just select the mercenary.
    		if(g_bConsumeMercenaryMovesOnHire):
    			self.objUnit.finishMoves()
    		elif(CyGame().isNetworkMultiPlayer()):
    			self.objUnit.finishMoves()
    		else:
    			CyInterface().selectUnit(self.objUnit, true, false, false)
    
    		if(g_bDisplayMercenaryMessages):
    			strMessage = rstrip(self.getName()) + " has been retained as a mercenary"
    			# Inform the player that the mercenary has arrived.
    			CyInterface().addMessage(self.iOwner, False, 20, strMessage, "", 0, self.objUnitInfo.getButton(), ColorTypes(0), iX, iY, True, True) 
    				
    		# Apply of the promotions to the mercenary in the game
    		self.applyPromotions()
    
    		# Set the mercenaries experience
    		self.setExperience()		
    
    		# Set the mercenaries unique name
    		self.objUnit.setName(self.strMercenaryName)
    
    		self.iPlacementTurn = -1
    
    		if(g_bDisplayMercenaryMessages and self.iBuilder != -1):
    			strMessage = rstrip(self.getName()) + " has been hired by " + gc.getPlayer(self.iOwner).getName()
    			# Inform the player that the mercenary has been hired.
    			CyInterface().addMessage(self.iBuilder, True, 20, strMessage, "", 0, "", ColorTypes(0), -1, -1, True, True) 
    	
    		# Subtract cost to hire from player current cash
    		#if(self.iOwner != self.iBuilder):
    			#Rhye - start Carthaginian UP
    			#player.setGold(player.getGold()-self.getHireCost())
    		player.setGold(player.getGold()-self.getHireCostXPlayer(iPlayer))
    			#Rhye - end Carthaginian UP
    		
    		# if(self.iBuilder != -1 and self.iOwner != self.iBuilder):
    			#Rhye - start Carthaginian UP
    			#gc.getPlayer(self.iBuilder).setGold(gc.getPlayer(self.iBuilder).getGold() + self.getHireCost())
    			# gc.getPlayer(self.iBuilder).setGold(gc.getPlayer(self.iBuilder).getGold() + self.getHireCostXPlayer(iPlayer))
    			#Rhye - end Carthaginian UP
     
  11. srpt

    srpt Deist

    Joined:
    May 10, 2010
    Messages:
    2,025
    Location:
    Toronto
    I have this completely working now except for the fact that every mercenary must have a unique name to properly become part of the mercenary pool. for now I just have it naming them Seleucid Scythian Horseman 1, Seleucid Scythian Horseman 2 etc and it works but it looks awkward.
     
  12. srpt

    srpt Deist

    Joined:
    May 10, 2010
    Messages:
    2,025
    Location:
    Toronto
    is it possible to not have the StoredData reset when reloading python modules?
     
  13. embryodead

    embryodead Caliph

    Joined:
    Jan 1, 2003
    Messages:
    5,179
    Location:
    basement
    Yes. This is the line that does it in SoI, in CvRFCEventHandler.py:
    Code:
    if gc.getMap().getMapScriptName(): # Baldyr: loads stored data on module reload
    	sd.load()
    But you already have it. Is it not working?
     
  14. only sky

    only sky Chieftain

    Joined:
    Jan 18, 2013
    Messages:
    65
    Location:
    China
    how to apply better graphics to RFC :dawn of mankind?
    Resently I am playing RFC&#65306;dawn of mankind with Varietas Delectat.
    I want to play it with the graphics of Realism Invictus.
    I copied the graphics file to the assets of RFC&#65306;dawn of mankind, but it didn't seem compatible. I really don't know how to solve it.
    thank you!
     
  15. baseballpie

    baseballpie Chieftain

    Joined:
    Nov 13, 2012
    Messages:
    2,090
    Could you tell me how to enable more instances of dynamic names for different circumstances? I have just about zero experience in modding, so any help would be appreciated.
     
  16. srpt

    srpt Deist

    Joined:
    May 10, 2010
    Messages:
    2,025
    Location:
    Toronto
    everything is in DynamicCivs.py. the file basically consists of 2 things: 1.lists of names and the civs and circumstances they apply to and 2. methods to check for a name change under certain circumstances. have a look at it. you should be able to figure out how to make changes. you also need to enable python exceptions (error reporting) in your civ.ini file so you will know if you've made a mistake.
     
  17. embryodead

    embryodead Caliph

    Joined:
    Jan 1, 2003
    Messages:
    5,179
    Location:
    basement
    I should mention that DynamicCivs.py is only part of Sword of Islam and any RFC mod based on it. You won't find that file in the original RFC, which unfortunately handles dynamic civ names in the DLL, and for that you'd need to set up the SDK and learn the basics of C++ first. Specifically, Rhye put them in CvPlayer:: processCivNames() function, and that's where you'd add anything.
     
  18. baseballpie

    baseballpie Chieftain

    Joined:
    Nov 13, 2012
    Messages:
    2,090
    Oh, OK.
     
  19. baseballpie

    baseballpie Chieftain

    Joined:
    Nov 13, 2012
    Messages:
    2,090
    Are there any resources where I could learn how to create a new civ?
     
  20. merijn_v1

    merijn_v1 Black Belt

    Joined:
    Dec 29, 2008
    Messages:
    5,428
    Location:
    The city of the original vlaai

Share This Page