(SOLVED) Question about possibility of adding two instances of the same type

Dtony

Chieftain
Joined
Aug 23, 2021
Messages
43
Is it possible to have a UA that gives two free units or buildings? what about different UU of the same type?

for example I if I wanted to add two free buildings to my a leaders UA

Code:
<GameData>
       <Traits>
            <Update>
                <Where Type="TRAIT_SLAYER_OF_TIAMAT" />
                <Set>                
                  <FreeBuilding>BUILDING_HARBOR</FreeBuilding>
                   <FreeBuilding>BUILDING_BAZAAR</FreeBuilding>
                   </Set>
           </Update>
        </Traits>
</GameData>

is there a way I can code this for the game to take it?

what about tow UU's of the same type?

Say I want to replace the chariot archer, but I want the option to be able to build a Hunnic horse archer and/or an Egyptian war chariot. is there a way I can write the code for the game to take it?

Code:
<GameData>
<Civilization_UnitClassOverrides>
        <Row>
            <CivilizationType>CIVILIZATION_ASSYRIA</CivilizationType>
            <UnitClassType>UNITCLASS_CHARIOT_ARCHER</UnitClassType>
            <UnitType>UNIT_HUN_HORSE_ARCHER</UnitType>
        </Row>
        <Row>
            <CivilizationType>CIVILIZATION_ASSYRIA</CivilizationType>
            <UnitClassType>UNITCLASS_CHARIOT_ARCHER</UnitClassType>
            <UnitType>UNIT_EGYPTIAN_WAR_CHARIOT</UnitType>
        </Row>
</Civilization_UnitClassOverrides>
</GameData>
 
This:
Code:
<GameData>
      <Traits>
            <Update>
                <Where Type="TRAIT_SLAYER_OF_TIAMAT" />
                <Set>               
                  <FreeBuilding>BUILDING_HARBOR</FreeBuilding>
                   <FreeBuilding>BUILDING_BAZAAR</FreeBuilding>
                   </Set>
           </Update>
        </Traits>
</GameData>
Is not possible. I mean, you can try it, but the XML → SQL parser is going to throw an error in database.log, and then throw the file out entirely that it's in, resulting in nothing being updated at all.

If you try to pull this off with SQL directly with the equivalent statement:
Code:
UPDATE Traits SET FreeBuilding = "BUILDING_HARBOR", FreeBuilding = "BUILDING_BAZAAR" WHERE Type = "TRAIT_SLAYER_OF_TIAMAT";
What you'll find happens is the second SET just overwrites the first, leading to just a free bazaar, but not a free harbor.

You can't have duplicate columns within the same table. For once, that's not a bad design choice by Firaxis, that's fundamentally just how SQL (and offshoots like SQLite, which is what Civ5 actually uses) databases work. Sorry.

You just split the <FreeBuilding>s across multiple UAs, although I don't actually remember if it breaks anything if multiple UAs are assigned to a single leader. That said, it's fairly trivial to write a Lua script that re-implements the logic of <FreeBuilding>, but able to handle more than one building type, and using both GameEvents.PlayerCityFounded and GameEvents.CityCaptureComplete as the event hook(s).

As for this:
Code:
<GameData>
<Civilization_UnitClassOverrides>
       <Row>
            <CivilizationType>CIVILIZATION_ASSYRIA</CivilizationType>
            <UnitClassType>UNITCLASS_CHARIOT_ARCHER</UnitClassType>
            <UnitType>UNIT_HUN_HORSE_ARCHER</UnitType>
        </Row>
        <Row>
            <CivilizationType>CIVILIZATION_ASSYRIA</CivilizationType>
            <UnitClassType>UNITCLASS_CHARIOT_ARCHER</UnitClassType>
            <UnitType>UNIT_EGYPTIAN_WAR_CHARIOT</UnitType>
        </Row>
</Civilization_UnitClassOverrides>
</GameData>
Just at first glance, I'm 99% sure this won't work, but I'm not sure how to articulate why it won't as I've never seen anyone try it before. It's most likely going to just make the Egyptian war chariot overwrite the Hunnic horse archer as the chariot archer replacement - if not make the game crash entirely, probably upon opening the civ selection screen, when the game is trying to work out what UUs exactly need to be displayed.

What you would want to do instead is make an exact copy of one of these units (named differently of course, since <Type> in <Units> must be unique), but with its unitclass switched for a new unitclass that has no <DefaultUnit>.
 
You just split the <FreeBuilding>s across multiple UAs, although I don't actually remember if it breaks anything if multiple UAs are assigned to a single leader.

What you would want to do instead is make an exact copy of one of these units (named differently of course, since <Type> in <Units> must be unique), but with its unitclass switched for a new unitclass that has no <DefaultUnit>.

Can you give me an example xml code of how I Can have one leader with two UA's?

I didn't know there were unit classes that didn't have default units. I'll try to look for it

edit:

I think it would work like this?

Code:
<GameData>
    <Leader_Traits>
        <Row>
            <LeaderType>LEADER_ASHURBANIPAL</LeaderType>
            <TraitType>TRAIT_SLAYER_OF_TIAMAT</TraitType>
            <TraitType>TRAIT_CREATIVE</TraitType>
        </Row>
    </Leader_Traits>
</GameData>
 
I didn't know there were unit classes that didn't have default units. I'll try to look for it
There are no such unitclasses in the base game - you won't find any. But check the schema for the <Units> table, and note how the <DefaultUnit> column doesn't stipulate "not null" like the <Type> column does - meaning a unitclass doesn't actually have to have a default unit assigned to it.
Code:
<Table name="UnitClasses">
        <Column name="ID" type="integer" primarykey="true" autoincrement="true"/>
        <Column name="Type" type="text" notnull="true" unique="true"/>
        <Column name="Description" type="text"/>
        <Column name="MaxGlobalInstances" type="integer" default="-1"/>
        <Column name="MaxTeamInstances" type="integer" default="-1"/>
        <Column name="MaxPlayerInstances" type="integer" default="-1"/>
        <Column name="InstanceCostModifier" type="integer" default="0"/>
        <Column name="DefaultUnit" type="text"/>
    </Table>
Look at any mod that adds a new civilization that has a UU that "replaces nothing", and there's like a 90% chance that this is the technique the modder is using to pull it off. (The other, rarer method involves a Lua script that hooks to GameEvents.PlayerCanTrain.)
I think it would work like this?
Code:
<GameData>
   <Leader_Traits>
        <Row>
            <LeaderType>LEADER_ASHURBANIPAL</LeaderType>
            <TraitType>TRAIT_SLAYER_OF_TIAMAT</TraitType>
            <TraitType>TRAIT_CREATIVE</TraitType>
        </Row>
    </Leader_Traits>
</GameData>
No... dude, you're doing the exact same thing that would have made the original code not work.
You can't use the same column twice in a single row. It DOES. NOT. WORK. Not in Civ5's database - not in any SQL database. It just fundamentally breaks the database structure: one entry per row/column intersection.
If you need to use a column twice for different values, you need to split it up among multiple rows:
Code:
<GameData>
   <Leader_Traits>
        <Row>
            <LeaderType>LEADER_ASHURBANIPAL</LeaderType>
            <TraitType>TRAIT_SLAYER_OF_TIAMAT</TraitType>
        </Row>
        <Row>
            <LeaderType>LEADER_ASHURBANIPAL</LeaderType>
            <TraitType>TRAIT_CREATIVE</TraitType>
        </Row>
    </Leader_Traits>
</GameData>
Again, I don't actually remember if assigning multiple UAs to a single leader actually works, per se, but this is at least syntactically valid.
 
What you would want to do instead is make an exact copy of one of these units (named differently of course, since <Type> in <Units> must be unique), but with its unitclass switched for a new unitclass that has no <DefaultUnit>.

There are no such unitclasses in the base game - you won't find any. But check the schema for the <Units> table, and note how the <DefaultUnit> column doesn't stipulate "not null" like the <Type> column does - meaning a unitclass doesn't actually have to have a default unit assigned to it.

I'm still having a bit of trouble. I copied the UU Byzantine Cataphract and renamed it Byzantine Cataphracts, note the plural. I'm not sure what to do on the unit class code though. I was thinking something like modifying this
Code:
        <Row>
            <Type>UNITCLASS_HORSEMAN</Type>
            <Description>Horsemen</Description>
            <DefaultUnit>UNIT_HORSEMAN</DefaultUnit>
        </Row>

to this

Code:
        <Row>
            <Type>UNITCLASS_HORSEMAN</Type>
            <Description>Horsemen</Description>
        </Row>

so now unit class horseman has no default unit class. is this correct?

If i have to have the colum default unit then maybe this
Code:
        <Row>
            <Type>UNITCLASS_HORSEMAN</Type>
            <Description>Horsemen</Description>
            <DefaultUnit></DefaultUnit>
        </Row>
 
I was thinking something like modifying this
Code:
        <Row>
            <Type>UNITCLASS_HORSEMAN</Type>
            <Description>Horsemen</Description>
            <DefaultUnit>UNIT_HORSEMAN</DefaultUnit>
        </Row>

to this

Code:
        <Row>
            <Type>UNITCLASS_HORSEMAN</Type>
            <Description>Horsemen</Description>
        </Row>

so now unit class horseman has no default unit class. is this correct?
You're correct that that's what that change does - removing the default unit from the horseman unitclass - but that's not what you need to do, since that will just make horsemen untrainable for every single civ that doesn't have a horseman UU.

I'm also not sure why we're suddenly talking about the unitclass of Byzantine cataphracts at all - the suggestion to create a new unitclass came up in the context of you wanting to assign a civilization two different UUs that both replace the chariot archer - the Egyptian war chariot and the Hunnic horse archer. Since I don't think you can overwrite the same unitclass twice for a single civ, what I was saying was to create a duplicate of one of those units (horse archer and war chariot) but with a completely new unitclass, i.e.:
Code:
<Units>
    <Row>
        <Class>UNITCLASS_HORSE_ARCHER_DTONY</Class>
        <Type>UNIT_HUN_HORSE_ARCHER_DTONY</Type>
        <PrereqTech>TECH_THE_WHEEL</PrereqTech>
        <Combat>7</Combat>
        <RangedCombat>10</RangedCombat>
        <Cost>56</Cost>
        <FaithCost>112</FaithCost>
        <RequiresFaithPurchaseEnabled>true</RequiresFaithPurchaseEnabled>
        <Moves>4</Moves>
        <Range>2</Range>
        ...
And then define that unitclass to have no default unit:
Code:
<UnitClasses>
    <Row>
        <Type>UNITCLASS_HORSE_ARCHER_DTONY</Type>
        <Description>TXT_KEY_UNIT_HUN_HORSE_ARCHER</Description>
        <DefaultUnit/> <!-- This line isn't strictly necessary, but it's good to add for clarity -->
    </Row>
    ...
And then overwrite the (non-existent) default to set it as the UU:
Code:
<Civilization_UnitClassOverrides>
    <Row>
        <CivilizationType>CIVILIZATION_ASSYRIA</CivilizationType>
        <UnitClassType>UNITCLASS_HORSE_ARCHER_DTONY</UnitClassType>
        <UnitType>UNIT_HUN_HORSE_ARCHER_DTONY</UnitType>
    </Row>
    ...
 
Top Bottom