Determining if a city state is suzerain-ed by a player

niklas153021

Chieftain
Joined
May 23, 2016
Messages
37
Location
Germany
My overall idea is that a player gets a modifier applied for every city state he is the suzerain of when suzerain of a certain city state. Basically like Pericles' LA, but instead of a simple yield bonus with e.g. a combat modifier.

So, my problem is that I need to identify if a Player is suzeraining a specific city state. I know that you can check whether a player is a city state's suzerain when the city state is the owner of the modifier using the PLAYER_IS_SUZERAIN modifier, but there doesn't seem to be a requirement to do the same thing the other way around.

The next step was that I tried to 'mark' the player using a dummy luxury resource with 0 amenities, but the only way to check whether a player has a resource is the REQUIREMENT_PLAYER_HAS_RESOURCE_OWNED, for which you have to own the resource 'physically' i.e. you have to be accessing the resource by having an apropriate improvement on a plot in your empire with that resource. Also, I stumbled across REQUIREMENT_PLAYER_HAS_DESIRED_LUXURY, but was unsure what exactly it does. It doesn't seem like it can be used with specific arguments and is only used for AI purposes in Montezuma's Agenda/AI.

My next idea was to maybe make the player and city state allies once the player becomes suzerain of the city state and un-ally them once the suzerainity expires. Thus, I'd be able to check for an allied city state from the perspective of the player, using something like REQUIREMENT_ALLY. So this is my first question: Is there a way to make two civs allies using modifiers or lua and if yes, how?

I know that making them both allies would have the downside of having the player automatically declare war on everyone attacking the city state. So my second question is: Is there any way to determine if a player has some modifier applied to himself? Is there any way to 'mark' the player as the suzerain? I also had the idea of using PseudoYields by giving he player a certain amount of the yield when being the suzerain of the city state and resetting it to 0 otherwise, but I'm unsure whether things like REQUIREMENT_YIELD_LEAD (or what it was called) work with PseudoYields as opposed to regular yields.

I hope that this is understandable enough, if you have questions, I'll try to explain my issue further.
 
...but the only way to check whether a player has a resource is the REQUIREMENT_PLAYER_HAS_RESOURCE_OWNED, for which you have to own the resource 'physically' i.e. you have to be accessing the resource by having an apropriate improvement on a plot in your empire with that resource.

This is certainly not the case, in a mod I'm working on, I am using REQUIREMENT_PLAYER_HAS_RESOURCE_OWNED for my Manufacturing Plant to work with "merchant goods", which is a luxury resource produced via MODIFIER_SINGLE_CITY_GRANT_RESOURCE_IN_CITY, and it works, despite not placing anything on the map.

As for your overall question, can't you just use MODIFIER_ALL_PLAYERS_ATTACH_MODIFIER with the PLAYER_IS_SUZERAIN requirement, like every other City-State Suzerain bonus? That should let you change the modifier's owner to the Player and do what you want. For your combat modifier, you could attach a modifier that applied an ability via MODIFIER_PLAYER_UNITS_GRANT_ABILITY.

Now, the downside is you'd have to attach it to every single City-State via the Traits table, but it would just be some copy-paste work.
 
This is certainly not the case, in a mod I'm working on, I am using REQUIREMENT_PLAYER_HAS_RESOURCE_OWNED for my Manufacturing Plant to work with "merchant goods", which is a luxury resource produced via MODIFIER_SINGLE_CITY_GRANT_RESOURCE_IN_CITY, and it works, despite not placing anything on the map.

Would it be possible to have a look at the code? Because I'm a bit clueless right now...
 
Well, it's scattered all over the place throughout the various files in my mod, but the most relevant bits are:

Spoiler :
Code:
<RequirementSets> Table:
       <Row>
           <RequirementSetId>MAGIL_PLAYER_HAS_FINECLOTHES_REQUIREMENTS</RequirementSetId>
           <RequirementSetType>REQUIREMENTSET_TEST_ALL</RequirementSetType>
       </Row>
<RequirementSetRequirements> Table:
       <Row>
           <RequirementSetId>MAGIL_PLAYER_HAS_FINECLOTHES_REQUIREMENTS</RequirementSetId>
           <RequirementId>MAGIL_REQUIRES_FINECLOTHES</RequirementId>
       </Row>
<Requirements> Table:
       <Row>
           <RequirementId>MAGIL_REQUIRES_FINECLOTHES</RequirementId>
           <RequirementType>REQUIREMENT_PLAYER_HAS_RESOURCE_OWNED</RequirementType>
       </Row>
<RequirementArguments> Table:
       <Row>
           <RequirementId>MAGIL_REQUIRES_FINECLOTHES</RequirementId>
           <Name>ResourceType</Name>
           <Value>RESOURCE_TAILORS_GOODS</Value>
       </Row>
Finally, the <Modifiers> table for the modifier itself:
       <Row>
           <ModifierId>MAGIL_MANUFACTORY_FINEDRINKS_PRODUCTION</ModifierId>
           <ModifierType>MODIFIER_BUILDING_YIELD_CHANGE</ModifierType>
           <SubjectRequirementSetId>MAGIL_PLAYER_HAS_FINEDRINKS_REQUIREMENTS</SubjectRequirementSetId>
       </Row>
The modifier argument is +1 Production, so it adds +1 production if the RequirementSet is met, i.e. player has Fine Clothes resource. It doesn't care whether or not it's actually a tile, as long as the player has the resource it turns on, otherwise it doesn't. I use 7 other modifiers set up the same way, and I've tested them to confirm that it's working using Firetuner.

The modifier that grants the luxury is:
       <Row>
           <ModifierId>MAGIL_GRANT_TAILORS_GOODS</ModifierId>
           <ModifierType>MODIFIER_SINGLE_CITY_GRANT_RESOURCE_IN_CITY</ModifierType>
           <SubjectRequirementSetId>MAGIL_TAILORS_GOODS_REQUIREMENTS</SubjectRequirementSetId>
       </Row>
The RequirementSet is not really relevant to your question, but the Argument is simply:
       <Row>
           <ModifierId>MAGIL_GRANT_TAILORS_GOODS</ModifierId>
           <Name>ResourceType</Name>
           <Value>RESOURCE_TAILORS_GOODS</Value>
       </Row>
       <Row>
           <ModifierId>MAGIL_GRANT_TAILORS_GOODS</ModifierId>
           <Name>Amount</Name>
           <Value>1</Value>
       </Row>
They work fine together, as far as I can tell. As long as the Resource appears on your Reports screen the building gets the bonus.
Building Modifiers table:
       <Row>
           <BuildingType>BUILDING_MZ_TAILORS_ROW</BuildingType>
           <ModifierId>MAGIL_GRANT_TAILORS_GOODS</ModifierId>
       </Row>
       <Row>
           <BuildingType>BUILDING_MZ_MANUFACTORY</BuildingType>
           <ModifierId>MAGIL_MANUFACTORY_FINEDRINKS_PRODUCTION</ModifierId>
       </Row>

Does any of that help?
 
First of all, thank you for sharing your code.

Unfortunately, while using the same modifiers and requirements, my bonus won't apply. My problem now is, that according to my GameEffects.log the REQUIREMENT_PLAYER_HAS_RESOURCE_OWNED is never met. I tried to give the resource to the capital, then switched it to giving it straight to the player. I switched the resource from strategid to luxury and back and forth. Nothing. This is so frustrating.
 
Can you confirm on the Reports screen that the resource is actually being granted? It'd be helpful to determine which part of the code isn't working.
 
I do get the resource according to the reports screen and it even shows up in the top bar when setting it as a strategic resource. I checked my GameEffects.log, but there were no warnings; the requirementsets are created, but always with the result of 0 matches.
 
There is a Lua code you can use to listen for the Modifier/RequirementSet/Requirement functioning and provide output for a variety of values (output can be checked through FireTuner or in the Lua.log file):

(1) get the object number and name of the modifier owner;
(2) get the subjects (valid modifier subjects) and tracked objects (partially valid modifier subjects) of the modifier;
(3) check whether the modifier is Active;
(4) check for many of the values of requirements - name, subject, etc.

I haven't gotten all of them completely to work, but it's quite useful for checking how the specific modifier types and requirement/set types operate during the game.
 
Could you explain a little further? I have completely no idea of lua modding and how to implement said concepts, so I'd be happy if yoou could elaborate a bit further :)
 
It's possible that you're implementing your resource check in a way that's making it check whether the City-State has access to the resource rather than the player. Without seeing the full way you're doing this it's difficult to speculate further, but that's my best guess at what is happening.
 
Here is my code:

(Beware of much commentary and little SQL)

Spoiler Code :

Code:
-- Just adding this for convenience when attaching modifiers to all city-states
-- The ModifierType is working, checked that via my logs; the given modifier is attachd to each CS

INSERT INTO Types (Type, Kind)
VALUES     ('MODIFIER_MINOR_PLAYERS_ATTACH_MODIFIER', 'KIND_MODIFIER');

INSERT INTO DynamicModifiers (ModifierType, EffectType, CollectionType)
VALUES     ('MODIFIER_MINOR_PLAYERS_ATTACH_MODIFIER', 'EFFECT_ATTACH_MODIFIER', 'COLLECTION_MINOR_PLAYERS');


-- The first three modifiers are deirectly attached to the CS's trait, the latter two are attached to the player using the first three.
-- Modifier No. 1 attaches Modifier No. 3 to all city states
-- (Owner: Kiev's trait; Subject: All CSs)

-- Modifier No. 2 attaches the modifier for giving the unique resource to the player to Kiev's suzerain
-- (Owner: Kiev's trait; Subject: Kiev's suzerain)

-- Modifier No. 3 attaches Modifier No. 5 to every player that is suzerain of this CS itself AND owns the resource you only get from Kiev     
-- (Owner: Each CS; Subject: It's suzerain if that player owns the Kiev resource)

-- Modifier No. 4 gives the player a trade route - or basicly anything else, as this is the bonus that is supposed to be given to you by each of your suzed CSs.
-- (Owner: Player; Subject: [Depends on the Modifier])

-- Modifier No. 5 grants the player the resource in question.
-- (Owner: Player; Subject: Player)

INSERT INTO Modifiers (ModifierId, ModifierType, SubjectRequirementSetId)
VALUES    ('MINOR_CIV_NCS_KIEV_UNIQUE_INFLUENCE_BONUS_CS', 'MODIFIER_MINOR_PLAYERS_ATTACH_MODIFIER', NULL),
        ('MINOR_CIV_NCS_KIEV_UNIQUE_INFLUENCE_BONUS_RES', 'MODIFIER_ALL_PLAYERS_ATTACH_MODIFIER', 'PLAYER_IS_SUZERAIN'),
        ('MINOR_CIV_NCS_KIEV_UNIQUE_INFLUENCE_BONUS_PLAYER', 'MODIFIER_ALL_PLAYERS_ATTACH_MODIFIER', 'PLAYER_IS_SUZERAIN_AND_SUZERAIN_OF_KIEV'),
        
        ('MINOR_CIV_KIEV_DUMMY_BONUS', 'MODIFIER_PLAYER_ADJUST_TRADE_ROUTE_CAPACITY', NULL),
        ('MINOR_CIV_KIEV_DUMMY_RESOURCE', 'MODIFIER_PLAYER_ADJUST_FREE_RESOURCE_IMPORT', NULL);
        
INSERT INTO ModifierArguments(ModifierId, Name, Value)
VALUES
        ('MINOR_CIV_NCS_KIEV_UNIQUE_INFLUENCE_BONUS_CS', 'ModifierId', 'MINOR_CIV_NCS_KIEV_UNIQUE_INFLUENCE_BONUS_PLAYER'),
        ('MINOR_CIV_NCS_KIEV_UNIQUE_INFLUENCE_BONUS_PLAYER', 'ModifierId', 'MINOR_CIV_KIEV_DUMMY_BONUS'),
        ('MINOR_CIV_NCS_KIEV_UNIQUE_INFLUENCE_BONUS_RES', 'ModifierId', 'MINOR_CIV_KIEV_DUMMY_RESOURCE'),
        
        ('MINOR_CIV_KIEV_DUMMY_BONUS', 'Amount', 1),
        ('MINOR_CIV_KIEV_DUMMY_RESOURCE', 'ResourceType', 'RESOURCE_DUMMY_NCS_KIEV'),
        ('MINOR_CIV_KIEV_DUMMY_RESOURCE', 'Amount', 1);


-- Now to the requirements...
-- This requirement is supposed to check whether the player owns the Kiev resource
-- And just to underline it: SUPPOSED to... But more on that later

INSERT INTO Requirements(RequirementId, RequirementType)
VALUES    ('REQUIRES_NCS_IS_KIEV_SUZERAIN', 'REQUIREMENT_PLAYER_HAS_RESOURCE_OWNED');


-- You might ask if this is the correct name of the resource; Yes, it is
-- I double, triple and quadruple checked the names of my ResourceTypes, Modifiers, Requirements etc. and always had a look into my Database.log

INSERT INTO RequirementArguments(RequirementId, Name, Value)
VALUES    ('REQUIRES_NCS_IS_KIEV_SUZERAIN', 'ResourceType', 'RESOURCE_DUMMY_NCS_KIEV');


-- Nothing too special here, just the RequirementSet.
-- Should be testing all the requirements, as we want to know whether the player is both suzerain of that CS and suzerain of Kiev, right?

INSERT INTO RequirementSets(RequirementSetId, RequirementSetType)
VALUES    ('PLAYER_IS_SUZERAIN_AND_SUZERAIN_OF_KIEV', 'REQUIREMENTSET_TEST_ALL');


-- So, to my knowledge everything you just read above this line is working.
-- The modifiers 1, 2, 3 and 5 are applied to the respective players/CSs, the resource is present in my reports screen etc.
-- This is the furthest point I can track the error back to:
-- When I removed the second requirement from the table below, every CS was giving their suzerain the extra trade route.
-- However, when boh are in, no player gets the bonus. The log tells me that the requirements were met in 0 of e.g. 21 cases - so no player can fullfill these requirements
-- Same goes for removing the first one. I expected the suzerain of Kiev getting the bonus from all CSs on the map, but this, agian, was not the case.
-- The same thing happened as with both requirements: No bonus for anyone :C
-- And this is what made me suspect the requirement checking for resources of keeping my mod from working as intended, but apparently there has to be some error on my side and somwhere in the code above...

INSERT INTO RequirementSetRequirements(RequirementSetId, RequirementId)
VALUES    ('PLAYER_IS_SUZERAIN_AND_SUZERAIN_OF_KIEV', 'REQUIRES_PLAYER_IS_SUZERAIN'),
        ('PLAYER_IS_SUZERAIN_AND_SUZERAIN_OF_KIEV', 'REQUIRES_NCS_IS_KIEV_SUZERAIN');
 
Top Bottom