• We have updated our Community Code of Conduct. Please read through the new rules for the forum that are an integral part of Paradox Interactive’s User Agreement.
So there's been a lot of confusion around any_war. The last discussion was that any_war assumes its parent's scope, which in this case would be the root scope (I think char?). So that "attacker" is allowed in char? Or that it actually counts as war scope which does have attacker?



Does anywhere else use ROOT to be different from the actual root scope? This seems rather strange.


So "any_liege = ROOT_FROMFROM" is valid? As opposed to "any_liege = { some char stuff }". This seems rather different from all other scopes.

====================

Regarding trigger_switch: For now I am still adding them as people report them. One possible interpretation of how trigger_switch works is the following:

When it appears in some scope (char/prov/etc), let pairs of (X, Y) be all pairs such that "X=Y" is valid in that scope, and Y is a string/int/etc (not something in brackets). Then this is valid:
Code:
trigger_switch = { on_trigger = X switch = { Y = { } } }

Hence some things are valid (in char scope) are
Code:
trigger_switch = { on_trigger = "ai" switch = { "yes" = {} "no" = {} } }

Code:
trigger_switch = { on_trigger = "holds_favor_on" switch = { "ROOT" = {} FROM = {} } }

Code:
trigger_switch = { on_trigger = "ai_honor" switch = { 0 = {} 1 = {} } }

Code:
trigger_switch = { on_trigger = "is_targetted_decision_allowed" switch = { decision1 = {} decision2 = {} } }

Is this somewhat right or what?

Or can someone just ask in one of the dev threads what exactly is allowed in trigger_switch and bring it back here.

I though the syntax wasn't

Code:
trigger_switch = { on_trigger = X switch = { value1 = {} ... valueN = {} } }

but just

Code:
trigger_switch = { on_trigger = X  value1 = {} ... valueN = {}  }
 
Maybe this conversation with Divine will clear things up.
Code:
      custom_tooltip = {
         text = pattern_selfish_save_ally_custom_tooltip
         hidden_tooltip = {
           any_allied_character = {
             any_war = {
               defender = {
                 is_allied_with = ROOT
               }
               attacker = {
                 is_liege_or_above = FROM
               }
               OR = {
                 war_score = -5
                 defender = {
                   attacker = {
                     relative_power_including_allies_attacker = {
                       who = PREV # Defender
                       power = 1.0
Is the last part syntactically correct? defender = { attacker = { seems odd, as defender is a character scope, and attacker is otherwise only used in a war scope. This is in 05_selfish_pattern.txt.

This one is a little worse. It is not how we actually want things to work and it breaks rules about scopes. BUT it actually works because scope changes doesn't clear war scopes. A rewrite of the current script also seems a bit tricky if we didn't use this faulty part of the code. To sum it up: It looks terrible, it shouldn't work, it works, but I can't guarantee that we won't fix it.
It would actually be easy to fix the second with event targets:
Code:
defender = {
   save_event_target_as = current_defender
}
attacker = {
    relative_power_including_allies_attacker = {
       who = event_target:current_defender
        power = 1.0
   }
}

Unfortunately save_event_target_as is only usable as an effect and won't work in voting patterns that only consist of triggers. I know that the usage of them in war effects also confuse me from time to time.
How about this then, not using event targets?
Code:
  custom_tooltip = {
     text = pattern_selfish_save_ally_custom_tooltip
     hidden_tooltip = {
       any_allied_character = {
         any_war = {
           defender = {
             is_allied_with = ROOT
           }
           attacker = {
             is_liege_or_above = FROM
           }
           OR = {
             war_score = -5
             defender = {
               PREV = { #war scope
                 attacker = {
                   relative_power_including_allies_attacker = {
                     who = PREVPREV # Defender
                     power = 1.0
                   }
                 }
               }
             }
           }
         }
       }
     }
   }
Looks like it should work, following the rules and not taking advantage of the odd behavior of war scopes.
I'm intrigued to delve deeper into it but I don't really have time to do it right now. It might work, but I fear that nesting PREV-scopes inside of PREV-scopes will have unforeseen relativity consequences. =) My guess is that you'll need to go back to ROOT and then try to pick out the same war-scope again and then scope to attacker and pray that you reach back to the initial defender-scope with just a quad PREV-scope (ie PREVPREVPREVPREV).
Code:
  custom_tooltip = {
     text = pattern_selfish_save_ally_custom_tooltip
     hidden_tooltip = {
       any_allied_character = {
         any_war = {
           defender = {
             is_allied_with = ROOT
           }
           attacker = {
             is_liege_or_above = FROM
           }
           OR = {
             war_score = -5
             defender = {
               ROOT = {
                 any_allied_character = {
                   any_war = {
                     defender = {
                       character = PREVPREVPREVPREV
                     }
                     attacker = {
                       is_liege_or_above = FROM
                       relative_power_including_allies_attacker = {
                         who = PREVPREVPREVPREV # Defender
                         power = 1.0
                       }
                     }
                   }
                 }
               }
             }
           }
         }
       }
     }
   }
ought to do it, if the previous snippet won't work.

Yeah, that looks like it would work.

As for
Does anywhere else use ROOT to be different from the actual root scope? This seems rather strange.

Yes, in CBs:
## normal scopes(including posttitle scopes) ##
# ROOT = receiver
# FROM = giver
# <no scope change> = attacker or receiver
## title scopes ##
# ROOT = receiver
# FROM = giver
# <no scope change> = thirdparty landed title
 
This version has several false positives on the following valid code:
Code:
namespace = testz

character_event = {
    id = testz.1
    hide_window = yes
  
    is_triggered_only = yes
  
    immediate = {
        any_playable_ruler = {
            any_demesne_title = {
                trigger_switch = {
                    on_trigger = title
                    e_hre = { holder_scope = { log = "T001: [This.GetTitledName]" } }
                    e_byzantium = { holder_scope = { log = "T001: [This.GetTitledName]" } }
                    k_france = { holder_scope = { log = "T001: [This.GetTitledName]" } }
                    k_jerusalem = { holder_scope = { log = "T001: [This.GetTitledName]" } }
                    k_england = { holder_scope = { log = "T001: [This.GetTitledName]" } }
                    k_rum = { holder_scope = { log = "T001: [This.GetTitledName]" } }
                    k_bulgaria = { holder_scope = { log = "T001: [This.GetTitledName]" } }
                    k_scotland = { holder_scope = { log = "T001: [This.GetTitledName]" } }
                }
            }
        }
    }
}

character_event = {
    id = testz.2
    hide_window = yes
  
    is_triggered_only = yes
  
    immediate = {
        any_independent_ruler = {
            any_realm_province = {
                trigger_switch = {
                    on_trigger = province_id
                    31 = { owner = { log = "T002: Province 31 owned by [This.GetTitledName]" } }
                    32 = { owner = { log = "T002: Province 32 owned by [This.GetTitledName]" } }
                    841 = { owner = { log = "T002: Province 841 owned by [This.GetTitledName]" } }
                    842 = { owner = { log = "T002: Province 842 owned by [This.GetTitledName]" } }
                }
            }
        }
    }
}
The code works as would be expected: the engine supports title and province_id for the trigger switches (presumably in scopes in which they would make sense), so the game correctly belches out the owners of the relevant titles or provinces, respectively, into the logs.
 
  • 1
Reactions:
I keep getting errors like this

Code:
--- Error 1 of 1 ---
At <mod>\events\ACR_promethean_events.txt [character_event\option\capital_scope\add_province_modifier\name] (Line 3471, column 30):
"peasant_unrest" is not a valid NormalModifier.

But peasant_unrest is a modifier from vanilla and seems to work perfectly fine in game.
 
Did you add any event modifiers to your copy of the vanilla file? Do you get a parse error in that file?
 
I should have said "any character trigger that has a simple RHS", since ones with complex RHS like had_character_modifier don't fit the syntax. @Divine, can you confirm that that is how trigger_switch works? And that character triggers that are also valid in province scope can be used as trigger_switch on_triggers?

Yes, the trigger_switch works with all triggers that have a non-complex right-hand-side argument. It will just try to do a normal evaluation during the on_triggers from the scope that the trigger_switch clause is residing in. So you can actually be in a province scope and do a trigger_switch on a province trigger as long as it has a non-complex right-hand-side. A thing to remember though is that if more than one value in on_triggers evaluate as true it will still only execute the first in the list that evaluates to true.
 
  • 2
Reactions:
Yes, the trigger_switch works with all triggers that have a non-complex right-hand-side argument. It will just try to do a normal evaluation during the on_triggers from the scope that the trigger_switch clause is residing in. So you can actually be in a province scope and do a trigger_switch on a province trigger as long as it has a non-complex right-hand-side. A thing to remember though is that if more than one value in on_triggers evaluate as true it will still only execute the first in the list that evaluates to true.
But it has been reported that region does not work in a province scope as an on_trigger, and it should according to that.
 
@richvh: There was an issue with the functionality coupled with that trigger and maybe some others. I rewrote part of the code for it so it "should" work with all non-complex right-hand-side triggers. The code change however implicated a syntax change which I've added some error logging for. The trigger_switch effect now REQUIRES the on_trigger line to be defined before all other switch-cases. (My guess is that anyone using the trigger_switch will already be using this syntax)
 
  • 3
Reactions:
@richvh: There was an issue with the functionality coupled with that trigger and maybe some others. I rewrote part of the code for it so it "should" work with all non-complex right-hand-side triggers. The code change however implicated a syntax change which I've added some error logging for. The trigger_switch effect now REQUIRES the on_trigger line to be defined before all other switch-cases. (My guess is that anyone using the trigger_switch will already be using this syntax)
I certainly have been using that syntax, and assumed it was already required.
 
@richvh: There was an issue with the functionality coupled with that trigger and maybe some others. I rewrote part of the code for it so it "should" work with all non-complex right-hand-side triggers. The code change however implicated a syntax change which I've added some error logging for. The trigger_switch effect now REQUIRES the on_trigger line to be defined before all other switch-cases. (My guess is that anyone using the trigger_switch will already be using this syntax)
Related question: do event_target s count as non-complex scopes?
for example:

trigger_switch = {
on_switch = character
1 = { <do some stuff>} #applies some effect to character with ID 1
event_target:my_target = { <do some stuff>} ##Does this work?
}

And what about flags constructed with @-syntax.


trigger_switch = {
on_switch = has_character_flag
my_flag = { <do some stuff>} #applies some effect to object with flag my_flag
my_flag@ROOT = { <do some stuff>} ##Does this work? Should apply some effect to object with flag my_flag_<id of ROOT>.
}
 
Code:
--- Error 1 of 1 ---
At <mod>\history\characters\mongol.txt [166937\1240.1.1\birth] (Line 7848, column 3):
This character, 166937, is a bastard/legit_bastard, but does not have the trait.
The mother is scripted to be a concubine prior to the birth of this character:
Code:
  1238.1.1={
     effect = { add_consort = 166938 }
   }
Code:
166937 ={
   name="Asutai" # son of Möngke
   dynasty=11100
   religion="tengri_pagan"
   culture="mongol"
   father=217265
   mother=166938
   add_trait="child_of_consort"
   1240.1.1 = {
     birth = yes
   }
   1266.1.1 = {
     death = yes
   }
}
Side note: the code I am in the process of integrating originally had the add_consort coded differently, i.e.,
Code:
  1238.1.1={
     effect={c_166938={add_consort=ROOT}}
   }
Which method of adding consorts actually works? Does anyone have experience with this?
 
Code:
--- Error 1 of 1 ---
At <mod>\history\characters\mongol.txt [166858\1195.1.1\effect\set_mother] (Line 6525, column 4):
"172003" is not a valid MaybeEventTargetChar or 0.
A valid character ID should be a valid RHS for set_mother/set_father
 
Can confirm: simple booleans like is_female, is_playable, etc. seem to work for the on_trigger (with yes/no = { ... } branches). Very convenient. Scripted triggers, however, do not, and rather crash the game.

It'd be quite neat if they did work, though, because that's just the place they'd be most useful: scripted triggers can be complicated and costly to evaluate, so having separate if = { ... } statements for the yes and no branches is very suboptimal, and the game engine evaluating it only once (and caching the result) with a trigger_switch would be useful.
 
Can confirm: simple booleans like is_female, is_playable, etc. seem to work for the on_trigger (with yes/no = { ... } branches). Very convenient. Scripted triggers, however, do not, and rather crash the game.

It'd be quite neat if they did work, though, because that's just the place they'd be most useful: scripted triggers can be complicated and costly to evaluate, so having separate if = { ... } statements for the yes and no branches is very suboptimal, and the game engine evaluating it only once (and caching the result) with a trigger_switch would be useful.
According to one of the devs, any simple trigger should work. 'Simple' means 'xxx = yyy', and it doesn't involve any '{}'.

To prevent double evaluation of a complex trigger, do 'set_variable <xxx> = 0 if = { limit = <complex trigger> set_variable <xxx> = 1 }'. Then test xxx when you want to decide what to do.
 
  • 2
Reactions: