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

Adding a custom trait to a civilization

Discussion in 'Civ5 - Modding Tutorials & Reference' started by Hambil, Apr 20, 2013.

  1. Hambil

    Hambil Emperor

    Joined:
    Oct 16, 2006
    Messages:
    1,100
    Assumptions:
    1) You already have ModBuddy and know how to use it. Otherwise see The Newbie Modder'd Guide to Civilization V.

    For this tutorial I will take Ghandi out of CivUp and make him playable standalone. Appropriate credit to Thal for his amazing CivUp.

    Each post will be a step in the tutorial. Let's begin!
     
  2. Hambil

    Hambil Emperor

    Joined:
    Oct 16, 2006
    Messages:
    1,100
    The project and database:
    Create a new project in Mod Buddy called "Custom Leader Trait Tutorial" and create two subdirectories, 'xml' and 'lua'.

    In the xml directory create a new sql file called traits.sql. In the file put the following code:

    Code:
    DELETE FROM Language_EN_US WHERE Tag = 'TXT_KEY_TRAIT_POPULATION_GROWTH';
    INSERT INTO Language_EN_US (Tag, Text, Gender, Plurality) VALUES ('TXT_KEY_TRAIT_POPULATION_GROWTH', 'Food buildings add 1 [ICON_CITIZEN] Population when constructed.[NEWLINE]Starts with a Worker instead of a Warrior.', '', '');
    
    ALTER TABLE Traits ADD NoWarrior boolean;
    
    INSERT INTO Trait_YieldFromConstruction (TraitType, BuildingType, YieldType, Yield)
    SELECT 'TRAIT_POPULATION_GROWTH', Type, 'YIELD_POPULATION', 1
    FROM Buildings WHERE Type IN (
    	'BUILDING_HARBOR',
    	'BUILDING_GARDEN',
    	'BUILDING_GRANARY',
    	'BUILDING_INDUS_SANITATION',
    	'BUILDING_HOSPITAL',
    	'BUILDING_MEDICAL_LAB'
    );
    
    This code first deletes the description of Ghandi's trait in the database, then adds our own new one.

    Next it alters food builds to add an additional population when built. This is an xml trait that will require no lua but is included here for completeness.
     
  3. Hambil

    Hambil Emperor

    Joined:
    Oct 16, 2006
    Messages:
    1,100
    The xml:
    Add a new file to the xml directory called traits.xml. In it, put the following xml:

    Code:
    	<Traits>
    		<Update>
    			<Where Type="TRAIT_POPULATION_GROWTH" />
    			<Set CityUnhappinessModifier="0"
    				 PopulationUnhappinessModifier="-20"
    				 NoWarrior="true"
    				 FreeUnit="UNITCLASS_WORKER"
    				 />
    		</Update>
    	</Traits>
    
    Make sure you use the Mod Buddy template because it automatically adds in the basic framework. You insert your code inbetween the <GameData> tags.

    Code:
    <?xml version="1.0" encoding="utf-8"?>
    <!-- Created by ModBuddy on 4/4/2013 7:25:05 AM -->
    <GameData>
    
    </GameData>
    
    This xml alters the trait TRAIT_POPULATION_GROWTH (Ghandi's trait) to add our new NoWarrior attribute, and to give Ghandi a free worker on startup.
     
  4. Hambil

    Hambil Emperor

    Joined:
    Oct 16, 2006
    Messages:
    1,100
    The lua code:

    Create a new file called traits.lua in the lua subdirectory. In it place:

    Code:
    print("***[ This is the Custom Leader Trait Tutorial ]***")
    
    function PlayerStartBonuses(player)
    	local trait
    	local leaderType
    	local traitType
    	local UNITAI_WORKER = 2
    
    	print("PlayerStartBonuses")
    
    	-- Loop through the players
    	for playerID, player in pairs(Players) do
    
    		-- Make sure player is alive and not a barbarian or minor civ
    		if player and player:IsEverAlive() and not player:IsBarbarian() and not player:IsMinorCiv() then
    			
    			-- Get the trait info for this player
    			leaderType = GameInfo.Leaders[player:GetLeaderType()].Type
    			traitType = GameInfo.Leader_Traits("LeaderType ='" .. leaderType .. "'")().TraitType
    			trait = GameInfo.Traits[traitType]
    				
    			-- If the player has the NoWarrior trait (custom trait) kill the warrior
    			if trait and trait.NoWarrior then
    
    				-- If this is a reload/reseed whatever, create the worker again
    				if UI:IsLoadedGame() then
    					player:AddFreeUnit(GameInfo.Units.UNIT_WORKER.ID, UNITAI_WORKER) 
    				end
    					
    				-- Another mod may have changed starting units so if this is ERA ancient, just kill them all. 
    				-- The game already supplies you with a worker if you start above ancient ERA
    				print(player:GetName() .. 'Starting Unit(s) Killed!')
    				for unit in player:Units() do
    					for unit in player:Units() do
    						if player:GetCurrentEra() == GameInfoTypes.ERA_ANCIENT and unit:GetUnitType() ~= GameInfoTypes.UNIT_WORKER and unit:GetUnitType() ~= GameInfoTypes.UNIT_SETTLER then
    							unit:Kill()
    						end
    					end
    				end
    			end
    
    		end
    	end 
    
    	print("PlayerStartBonuses Done")
    
    end
    Events.SequenceGameInitComplete.Add(PlayerStartBonuses)
    
    You will see we add an event handler at the bottom, that causes our code to be called when the game is initialized. There are comments in the code to explain what it is doing, as well as some prints to help with Fire Tuner debugging.
     
  5. Hambil

    Hambil Emperor

    Joined:
    Oct 16, 2006
    Messages:
    1,100
    The project again:

    Make sure under properties in the project you have the sql and xml files set to load and update the database. Make sure you define the lua/traits.lua file as an InGameUIAddin.

    See attached completed working project.
     

    Attached Files:

  6. Genghis.Khan

    Genghis.Khan Person

    Joined:
    Jun 9, 2012
    Messages:
    934
    Location:
    Somewhere
    Hambil, instead of removing the Warrior and adding the Worker in Lua, can't you do that in XML

    Code:
    <GameData>
    <Civilization_FreeUnits>
    		<Row>
    			<CivilizationType>CIVILIZATION_INDIA</CivilizationType>
    			<UnitClassType>UNITCLASS_WORKER</UnitClassType>
    			<Count>1</Count>
    			<UnitAIType>UNITAI_WORKER</UnitAIType>
    		</Row>
    </Civilization_FreeUnits>
    </GameData>
    
    <Civilization_FreeUnits>
    <Update>
    <Where Type="CIVILIZATION_INDIA" />
    <Set Count="0" />
    </Update> 
    </Civilization_FreeUnits>
    P.S: Hambil, my #1 Tutorial Request would be a Guide to Lua in Civilization V Modding.... Is that possible?
     
  7. Hambil

    Hambil Emperor

    Joined:
    Oct 16, 2006
    Messages:
    1,100
    I don't know the XML side well enough to say, yet. But even if it could there would be plenty of other traits players might add that would require lua, so I think the tutorial is okay.

    "Guide to Lua in Civilization V Modding" is a very broad topic. Can you be more specific about your needs?
     
  8. bouncymischa

    bouncymischa Synthetic Genie

    Joined:
    Nov 28, 2012
    Messages:
    1,537
    Location:
    In a bottle
    I have a question that's nagging at me...

    The example is good at showing how I can integrate Lua and XML, and I'm interested in experimenting with it a bit... however, I'm a bit baffled at the code for Trait_YieldFromConstruction doesn't actually exist in the files for Civ V. I'm guessing that there's some code in CivUP or GEM that enables this, but I can't find it.

    So I was wondering if you could tell me where the code for Trait_YieldFromConstruction is found?

    EDIT: Bah, just found it in CivUP_Events.lua ... now to just figure out how it works...
     
  9. Hambil

    Hambil Emperor

    Joined:
    Oct 16, 2006
    Messages:
    1,100
    Sorry about that - was my first tutorial. I didn't realize it was incomplete. I will look up that trait code also and add it to the tutorial.
     
  10. bouncymischa

    bouncymischa Synthetic Genie

    Joined:
    Nov 28, 2012
    Messages:
    1,537
    Location:
    In a bottle
    Eh, it's fine -- the "No Warriors" tag is the more important part of it the lesson.

    Trait_YieldFromConstruction is actually kind of a pain, because it calls City_ChangeYieldStored, which is buried in the YieldLibrary.lua. Another interesting function, but having to include both functions for your example might be a bit much. X3
     
  11. XboxAddict77

    XboxAddict77 Wonder Spammer

    Joined:
    Mar 14, 2013
    Messages:
    261
    I have been trying but I can't think on how to do this: A trait that gives production on land military units
     
  12. bouncymischa

    bouncymischa Synthetic Genie

    Joined:
    Nov 28, 2012
    Messages:
    1,537
    Location:
    In a bottle
    Production in what way? Making it easier to build them? You can do that by having the trait give every city a free building that gives a bonus to the production of land units...
     
  13. XboxAddict77

    XboxAddict77 Wonder Spammer

    Joined:
    Mar 14, 2013
    Messages:
    261
    That's exactly what I would need which one is that one? I tried this but I couldn't get it to worlk I'm very new to modding.
    HTML:
    <Traits>
    		<Row>
    			<Type>PATRIA_O_MUERTE</Type>
    			<Description>TXT_KEY_TRAIT_PATRIA_O_MUERTE</Description>
    			<ShortDescription>TXT_KEY_TRAIT_PATRIA_O_MUERTE_SHORT</ShortDescription>
    			<CityUnhappinessModifier>25</CityUnhappinessModifier>
    			<update>
    				<Set>Cost="30"</Set>
    				<Where>Type="UNIT_WARIOR"</Where> 
    			</update>
    		</Row>
    	</Traits>
    I basically used an update to make warriors only use 30 Hammers instead of 40 which is a 25% off, then I'd do this with all other units are you saying there's an easier way?
    BTW this is for a Cuba mod and Patria O Muerte means "Homeland or death."
     
  14. XboxAddict77

    XboxAddict77 Wonder Spammer

    Joined:
    Mar 14, 2013
    Messages:
    261
    So I found out I could just use the <freebuilding> tag to give a free building but how do I make that building <yield>PRODUCTION<yield/> to only military units? NOT other buildings or civilian units. If anyone helps it means alot! Thanks in advance!
     
  15. bouncymischa

    bouncymischa Synthetic Genie

    Joined:
    Nov 28, 2012
    Messages:
    1,537
    Location:
    In a bottle
    You can't add production to a unit directly, but under buildings you have Buildings_UnitCombatProductionModifiers which allows you to increase the rate of unit production by a certain percentage. The Forge in the standard unit files has an example of this, set to 15% for melee units, I think.
     
  16. XboxAddict77

    XboxAddict77 Wonder Spammer

    Joined:
    Mar 14, 2013
    Messages:
    261
    Thank you thats perfect. I'll just make a DummyBuilding that appears in all the cities and gives production to military units that way. Thanks!
     
  17. j51

    j51 Blue Star Cadet

    Joined:
    Oct 22, 2006
    Messages:
    1,178
    Location:
    Ping Island
    Is there a way to tie all great people to golden ages? Something like, "double great person generation during golden ages."

    What about tying growth to golden ages: "+50% growth during golden ages"?

    Can additional yields output be tied to building types? Say, "+1 production per science building"?

    Finally, can yields be tied to river adjacent tiles?
     
  18. j51

    j51 Blue Star Cadet

    Joined:
    Oct 22, 2006
    Messages:
    1,178
    Location:
    Ping Island
    Anyone?
     
  19. DoktorApplejuce

    DoktorApplejuce Champion of Kirkwall

    Joined:
    Apr 9, 2015
    Messages:
    582
    Location:
    Canada
    Sorry to bother you with this, but you seem to know what you're talking about, and I haven't gotten a reply anywhere else.

    I'm looking to make a custom civ with a special trait that causes any offensive spies to produce faith, while defensive spies and diplomats produce culture. Any ideas how I could make this work. Thank you so much.
     
  20. Jarula

    Jarula King

    Joined:
    Oct 22, 2016
    Messages:
    680
    Gender:
    Male
    How Do I make using XML a trait that reduces hurry cost basically -25% purchase cost modifier?
     

Share This Page