How do I set a timed_planet_flag based on size of planet?

  • 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.

Valrith

Recruit
12 Badges
Jul 7, 2016
6
0
  • Crusader Kings II
  • Crusader Kings II: Legacy of Rome
  • Crusader Kings II: The Old Gods
  • Crusader Kings II: Rajas of India
  • Crusader Kings II: The Republic
  • Crusader Kings II: Sons of Abraham
  • Crusader Kings II: Sunset Invasion
  • Crusader Kings II: Sword of Islam
  • Stellaris
  • Stellaris: Galaxy Edition
  • Stellaris: Galaxy Edition
  • Stellaris: Leviathans Story Pack
I'm working on a small mod that increases the size of the planet over time, with the time delay until the next planet size increase hard coded in a tedious switch statement:


Code:
    every_owned_planet = {
        limit = {
            planet_size < 26
            num_pops > 0
            OR = {
              has_planet_flag = ai_terraforming_size
              has_building = building_tile_terraformer
            } 
            NOT = {
                has_planet_flag = recently_terraformed
            }
      }

      switch = {
        trigger = planet_size
        1 = { set_timed_planet_flag = { flag = recently_terraformed days = 27 } change_planet_size = 1 }
        2 = { set_timed_planet_flag = { flag = recently_terraformed days = 54 } change_planet_size = 1 }
        3 = { set_timed_planet_flag = { flag = recently_terraformed days = 81 } change_planet_size = 1 }
        4 = { set_timed_planet_flag = { flag = recently_terraformed days = 108 } change_planet_size = 1 }
        5 = { set_timed_planet_flag = { flag = recently_terraformed days = 135 } change_planet_size = 1 }
        .
        .
        .
        24 = {
                   change_planet_size = 1
                   remove_planet_flag = ai_terraforming_size
                   remove_modifier = "terraforming_ecosystem"
                   every_tile = { limit = {has_building = building_tile_terraformer} remove_building = yes }
             }

I would really like to remove those hard coded values (and the switch statement entirely) by setting the days = planet_size * tile_delay, where tile_delay is based on a constant adjusted by the country having either of the two terraforming resources available.

Unfortunately, I've tried dozens of iterations of set_variable, while iterations, every_tile iterations and other techniques, but can't get the script interpreter happy.

Some examples of what I've tried:

Code:
while = {
  count = planet_size
  change_variable = {
    which = terraform_delay
    amount = 27
  }
}
This throws a malformed token error for planet_size, even though it works similarly with the switch trigger =

Code:
every_tile = {
  change_variable = {
    which = terraform_delay
    amount = 27
  }
}
Several iterations of the above, all resulting in Invalid Scope for either the change_variable statement, or when I try to use the variable later in the code.

Am I beating my head against an impossible task, or is there a way to set, and then use a variable later in this way?

Thanks in advance!
 
You can't apply variables for tiles. They could be used only with country, fleet, leader, planet and star scopes. So, you can try smth like this:
Code:
random_owned_planet = {
    limit = { ... }
        set_variable = { which = "planet_size" value = 0 }
        every_tile = {
            prev = { change_variable = { which = "planet_size" value = 1 } }
        }
}
 
Using your technique with a few adjustments, I've gotten it to where I think the value is set to what I want (can't seem to view it with a Log = command however, it throws an error).

Unfortunately, when I try to use the value in the set_timed_planet_flag it gives me a malformed token.

Here's the code that throws the Malformed Token error "this.terraform_delay"

Code:
             set_timed_planet_flag = { flag = recently_terraformed days = this.terraform_delay }

The Log command outputs a planet name, so I'm confident that terraform_delay is on the current scope (change_planet_size works as well), but it seems to not be accessable.

I've tried several forms of terraform_delay, prev.terraform_delay, but can't seem to access it's value correctly.

Any further thoughts?

Here's the entire event code as it stands right now:
Code:
country_event = {
    id = tform.2
    hide_window = yes
  trigger = {
    is_country_type = default
     has_technology = tech_terrestrial_sculpting
  }
    mean_time_to_happen = {
        days = 30
    }
      
  immediate = {
    set_variable { which = terraform_interval value = 27 }
    if = {
      limit = {
        has_country_strategic_resource = {
               type = sr_terraform_gases
                 amount > 0
             }
            }
            change_variable = { which = terraform_interval value = -4 }
        }
    if = {
      limit = {
        has_country_strategic_resource = {
               type = sr_terraform_liquids
                 amount > 0
             }
            }
            change_variable = { which = terraform_interval value = -4 }
        }
          
  
    every_owned_planet = {
      #set_variable = { which = num_tiles value = planet_size }
       limit = {
           planet_size < 26
           num_pops > 0
           OR = {
             has_planet_flag = ai_terraforming_size
             has_building = building_tile_terraformer
           } 
           NOT = {
               has_planet_flag = recently_terraformed
           }
      }
      set_variable = { which = num_tiles value = 0 }
      set_variable = { which = terraform_delay value = 0 }
      every_tile = {
        prev = {
          change_variable = { which = prev.terraform_delay value = owner.terraform_interval }
        } 
      }
#      Log = "Next terraform interval for [This.GetName] is <[This.terraform_delay]>."
      
      
            IF = {
                limit = {
                    has_modifier = "terraforming_ecosystem"
                }
                remove_modifier = "terraforming_ecosystem"
            }          
            add_modifier = {
                modifier = "terraforming_ecosystem"
            }
          
            if {
             limit = {
               planet_size < 24
             }
             Log = "This scope is [This.GetName]"
             set_timed_planet_flag = { flag = recently_terraformed days = this.terraform_delay }
             change_planet_size = 1
             else = {
                 change_planet_size = 1
                 remove_planet_flag = ai_terraforming_size
                 remove_modifier = "terraforming_ecosystem"
                 every_tile = { limit = {has_building = building_tile_terraformer} remove_building = yes }
                }
            }
        } 
    }
}
 
Code:
days = this.terraform_delay

Don't think the right side of the qualifier allows that. Try assigning to a parameter and then use that.
 
I've not dealt with parameters before, but initial search seems to indicate that parameters are commonly used to pass objects somewhere?

Are there any decent modding guide writeups that describe proper use? I'll play with it, but really not sure how to use them as you suggest here...for example, what type would the parameter be--number? integer?
 
Admittedly I've never tried assigning an int to a parameter, but parameters tend to be accepted on the right side of qualifiers more regularly. It varies from function to function, but it's worth a try.

edit

Code:
change_variable = { which = prev.terraform_delay value = owner.terraform_interval }

Again here you're assuming that Clausewitz can handle that kind of qualification. Pretty sure it's not that advanced. Is this throwing a wobbly too?
 
Various random attempts:

Code:
             set_timed_planet_flag = { flag = recently_terraformed days = parameter:terraform_delay }
Throws [effect.cpp:264]: Error: "Malformed token: parameter:terraform_delay, near line: 101

Code:
             set_timed_planet_flag = { flag = recently_terraformed parameter:days = terraform_delay }

Throws [effect.cpp:264]: Error: "Unhandled Entry: parameter:days, near line: 101

Trying to set up the parameter beforehand using various code examples from other events:
Code:
            if {
        parameters = {
           tDelay = { type = integer }
         }
             limit = {
               planet_size < 24
             }
             Log = "This scope is [This.GetName]"
             set_timed_planet_flag = { flag = recently_terraformed days = terraform_delay }

Throws various completely uninformative errors as well.
 
set_timed_planet_flag = { flag = recently_terraformed parameter:days = terraform_delay }

Based on additional testing as well as general understanding of the concept of parameters within various programming languages and examples from vanilla 1.3, this *should* be the syntax---but only if they implemented days as a parameter to the set_timed_planet_flag c++ implementation.

Which it's at least somewhat apparent they didn't, so no luck.
 
I'm interested in your code as its an interesting approach to using tech. I didn't realize that the multiply and divide variable effects existed or even that variables could be called easily. As to your problem I decided to conduct a find-in-files search using notepad++ regarding usage of timed flags. A malformed token would imply some value was passed somewhere into a location where it couldn't be processed (at least thats how I understand it). All examples of timed flags in stellaris use flat numeric values, and there seems to be a direct avoidance of using anything but a direct whole number as its timing component. In several instances I noticed that it would be far easier to simply use a dynamic value, but paradox seems to insist on using multiple value to value checks. A tedious process not unlike what you were trying to avoid in the first place. Go figure.

I assume that the capacity for timed numbers in general are limited in what values can be passed to it. The reason being that I conducted a search in /common and /events looking for all instances of days = value. In all cases only a numeric whole number was used and no other values were called. I observed the same usage with a similar search for months and I assume years is no different. There might be some other way where you can 'strip' the excess data while still calling a dynamic value, but in my experience with modding this is probably something just hardcoded with no recourse. I'm not sure where to file this on the wiki but it would be fairly useful to know.

In short my hypothesis is: All timed countdowns require explicit whole number values and do not accept anything else. Where timed countdowns refer to days, months and years in all possible uses. If you can prove or disprove it, or find a way around it, do let me know. I'd perfer to be simply really tired and glacing over something obvious that answers your problem succintly :p
 
  • 1
Reactions:
Short answer then is days = only takes an int value on the right. Blargh.

All timed countdowns require explicit whole number values and do not accept anything else.

Kingtrin is ninja. You never see them coming.
 
Short answer then is days = only takes an int value on the right. Blargh.



Kingtrin is ninja. You never see them coming.

I did a thing! me smart :D

Its fairly odd though because the first part of the variable statement does provide the functionality needed. As seen here.

which = prev.terraform_delay

Days is just being stubborn about only receiving integers. I'm suprised its so limited but understanding the eccentricites of engine work is beyond my feeble brain. Poke paradox and we might see a half-assed workaround?