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

Need help for setting up a unit production and maintenance related trait modifier

Discussion in 'Mod Creation Help' started by cool3a2, Dec 10, 2017.

  1. cool3a2

    cool3a2 Chieftain

    Joined:
    Mar 30, 2007
    Messages:
    2,175
    Hope there is someone out there who can help me with this. First of all, I'd like to point out that I am working on my problem since days now, but although being a software developer myself, I am just unable to get it done. So, please beware, that I may sound a bit annoyed when writing this - as I am actually annoyed...

    I believe that I got the basics of modding modifiers and I definitely have no difficulties with the used technologies. At least, I was able to add a working modifier for one of my leaders to raise science output and give culture output of libraries. What I'd like to mod in for my civilization trait modifier are two things:
    • Provide a modifier to lower production costs (or raise production points) for certain units in all cities, preferably only when at war (if possible, only when the player is attacked, a defensive war in other words).
    • Provide another modifier to lower the maintenance cost for the same set of units. Or alternatively, provide a discount for those units.
    As these two things are pretty independent from each other, I'll describe them separately.

    To ease reading the examples a little, I'd like to add that the modifier is called Pro Libertate! and should affect most land units, besides of nukes, aircraft and siege weapons (maybe some more I may not have thought about yet). I will simplify the exercise by limiting this on a single unit per modifier.

    Setting up the production modifier

    I think that this should by the easier part, at least, when ignoring the requirement for firing only when at war, which we will do for now.

    So, I found the modifier called MODIFIER_PLAYER_CITIES_ADJUST_UNIT_TAG_ERA_PRODUCTION. This one is already used, for example for the vikings leader and for multiple policies. All I need to do is change the units and era affected, so let's go. This is my modifier:
    Code:
        <Modifiers>
            <Row>
                <ModifierId>TRAIT_MODIFIER_PROLIBERTATE_PRODUCTION</ModifierId>
                <ModifierType>MODIFIER_PLAYER_CITIES_ADJUST_UNIT_TAG_ERA_PRODUCTION</ModifierType>
            </Row>
        </Modifiers>
    Then, there are three arguments:
    Code:
        <ModifierArguments>
            <Row>
                <ModifierId>TRAIT_MODIFIER_PROLIBERTATE_PRODUCTION</ModifierId>
                <Name>Amount</Name>
                <Value>500</Value>
                <Extra>-1</Extra>
            </Row>
            <Row>
                <ModifierId>TRAIT_MODIFIER_PROLIBERTATE_PRODUCTION</ModifierId>
                <Name>UnitPromotionClass</Name>
                <Value>PROMOTION_CLASS_MELEE</Value>
                <Extra>-1</Extra>
            </Row>
            <Row>
                <ModifierId>TRAIT_MODIFIER_PROLIBERTATE_PRODUCTION</ModifierId>
                <Name>EraType</Name>
                <Value>ERA_ANCIENT</Value>
                <Extra>-1</Extra>
            </Row>
        </ModifierArguments>
    Note that I set the amount to something high to see a clear effect.

    To my understanding, using this modifier, I should be able to start a game with my civilization with the starting era set to ancient, found a city and see that warriors have a reduced built time. But it seems to me like the modifier is not applied at all. I'd expect the game to check the warriors production cost (40, I believe) and divide it by the amount of production points the city generates per turn, then apply the modifiers value (given in percent) and round the result. But the count of turns I actually get is the result of the division and round operations. I hope you could follow me explanations... Did I get something wrong or is the modifier not working?

    Also, there is a similar modifier available without the era word in its name, but it's not used anywhere. This would suit my needs better as I am not planing to limit this modifier to an era. I tried it out, skipping only the era argument, but still no luck. Are there other differences between those two modifiers?

    Setting up the maintenance modifier

    This is somewhat harder as the only available modifier concerning unit maintenance is MODIFIER_PLAYER_ADJUST_UNIT_MAINTENANCE_DISCOUNT which seems to work with counts of gold, not with values given in percent. Also, it seems like I can not set the value to 0.5, for example. All in all, this would require me to set up different modifiers for different eras / units.

    The good news is, that I was able to set it up to affect all units, at least. The bad is, that I am not able to limit it properly on certain units - I'll come back to this in a minute. To simplify things, I limited the modifier to affect only anti-cavalry units. This ways, I should be able to check things by starting a game with my civilization with the starting era set to renaissance (where there is a crossbowman and a pikeman around).

    I started with setting up the requirements and I am somewhat optimistic that I am on the right way in this point. I'll provide my code nevertheless.

    This my requirement:
    Code:
        <Requirements>
            <Row>
                <RequirementId>REQUIRES_UNIT_IS_ANTICAVALRY</RequirementId>
                <RequirementType>REQUIREMENT_UNIT_PROMOTION_CLASS_MATCHES</RequirementType>
            </Row>
        </Requirements>
    Then I set up an argument to that requirement:
    Code:
        <RequirementArguments>
            <Row>
                <RequirementId>REQUIRES_UNIT_IS_ANTICAVALRY</RequirementId>
                <Name>UnitPromotionClass</Name>
                <Value>PROMOTION_CLASS_ANTI_CAVALRY</Value>
            </Row>
        </RequirementArguments>
    Fine. Now I'll set up a requirementset with this. I am not sure, if I'd have to set up the check to ANY at the end, but having only one unit at the moment, this should not make a difference:

    Code:
        <RequirementSets>
            <Row>
                <RequirementSetId>REQUIREMENTS_UNITS_PROLIBERTATE</RequirementSetId>
                <RequirementSetType>REQUIREMENTSET_TEST_ALL</RequirementSetType>
            </Row>
        </RequirementSets>
    Finally, I am wiring the requirement together with the requirementset:
    Code:
        <RequirementSetRequirements>
            <Row>
                <RequirementSetId>REQUIREMENTS_UNITS_PROLIBERTATE</RequirementSetId>
                <RequirementId>REQUIRES_UNIT_IS_ANTICAVALRY</RequirementId>
            </Row>
        </RequirementSetRequirements>
    If I am correct, this should be sufficient to limit my modifiers to certain units.

    Then I set up my modifier. I tried played with it and stopped with something like:
    Code:
        <Modifiers>
            <Row>
                <ModifierId>TRAIT_MODIFIER_PROLIBERTATE_MAINTENANCE</ModifierId>
                <ModifierType>MODIFIER_PLAYER_UNITS_ATTACH_MODIFIER</ModifierType>
                <SubjectRequirementSetId>REQUIREMENTS_UNIT_PROLIBERTATE_MAINTENANCE_DISCOUNT</SubjectRequirementSetId>
                <!--<OwnerRequirementSetId>REQUIREMENTS_UNIT_PROLIBERTATE_MAINTENANCE_DISCOUNT</OwnerRequirementSetId>-->
            </Row>
    
            <Row>
                <ModifierId>TRAIT_MODIFIER_PROLIBERTATE_MAINTENANCE_CORE</ModifierId>
                <ModifierType>MODIFIER_PLAYER_ADJUST_UNIT_MAINTENANCE_DISCOUNT</ModifierType>
                <SubjectRequirementSetId>REQUIREMENTS_UNIT_PROLIBERTATE_MAINTENANCE_DISCOUNT</SubjectRequirementSetId>
        </Modifiers>
    As arguments I used the following:
    Code:
        <ModifierArguments>
            <Row>
                <ModifierId>TRAIT_MODIFIER_PROLIBERTATE_MAINTENANCE</ModifierId>
                <Name>ModifierId</Name>
                <Value>TRAIT_MODIFIER_PROLIBERTATE_MAINTENANCE_CORE</Value>
            </Row>
    
            <Row>
                <ModifierId>TRAIT_MODIFIER_PROLIBERTATE_MAINTENANCE_CORE</ModifierId>
                <Name>Amount</Name>
                <Value>1</Value>
            </Row>
        </ModifierArguments>
    I also played around with OwnerRequirementSetId for limiting the modifiers to the desired units and set up an alternative dynamic modifier to affect only player units (rather than owner), but it just didn't work right. The closest result I was able to achieve was to let the modifier fire when there is an anti-cavalry unit around, but then it affected all units, not only the one in question. At least, the modifier went away when I scraped the pikeman...

    My feeling is that I can not set up the modifier the way I want to as it's just not working the way I need it to. Although I would have thought that a modifier like that should be somewhat easy as the units maintenance cost is actually just another property.

    Future step: limiting the production modifier to war-times

    As mentioned, the production modifier is planned to fire only when the player is at war. It would be even better, if it is a defensive or preventive war. Having taken a look at the sqlite database, I found out that there are requirements like PLAYER_IS_WARMONGER_SUBJECT and PLAYER_IS_AT_PEACE_WITH_ALL_MAJORS and I'd bet that I read that requirements can also be inverted. Question is, how exactly would I have to set up the requirements for this? Also, how exactly does PLAYER_IS_WARMONGER_SUBJECT work?

    Bonus exercise: suggest modifier values and / or alternatives

    I am somewhat open for suggestions at this point. Also, I am not a very experienced player, so I am not sure what would be fair values. And of course, if the modifiers can not be set up the way I wanted, I'd be curious to hear alternative ideas.
     
  2. cool3a2

    cool3a2 Chieftain

    Joined:
    Mar 30, 2007
    Messages:
    2,175
    Seems like I almost got the production modifier working by using the MODIFIER_PLAYER_CITIES_ADJUST_UNIT_PRODUCTION modifier and binding it to the exact unit I want to apply the modifier to. That needed me to set up 21 modifiers as I had to do that for each unit, but anyways. I also set up a requirement to check if the player is at war with any major civilization by inverting the REQUIREMENT_PLAYER_IS_AT_PEACE_WITH_ALL_MAJORS. This let the modifier fire only once the player is at war, but when I killed the other civ, the modifier still remained active. Could be that the other civ still remained in the background as some kind of zombie that I remained to be at war with. Or I was not at peace with that civ as it was dead, setting the relationship with that civ to something else than peace, causing the war-check to return true. Or it's because of the barbs, but I don't think so as they didn't seem to trigger the modifier. Any ideas anyone? Also, does anyone know what the ProgressWeight for the requirement does?

    BTW: I set the modifier to 33%, which doesn't seem to be too strong as the modifier fires only when my civ is at war. Or at least, it should do so.

    EDIT: I believe I got it done by removing the ProgressWeight setting - whatever it does exactly...
     
    Last edited: Dec 17, 2017

Share This Page