How do I check whether a system is closer to one thing than another?

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

Uroshnor

Sergeant
106 Badges
Jun 19, 2012
90
3
  • Stellaris: Synthetic Dawn
  • Hearts of Iron III
  • Heir to the Throne
  • Cities: Skylines - Snowfall
  • Leviathan: Warships
  • Magicka
  • Europa Universalis IV: Cossacks
  • Europa Universalis IV: Res Publica
  • Semper Fi
  • Sengoku
  • Sword of the Stars
  • Hearts of Iron III: Their Finest Hour
  • The Showdown Effect
  • Victoria 2
  • Victoria 2: A House Divided
  • Victoria 2: Heart of Darkness
  • Europa Universalis IV: Third Rome
  • Stellaris - Path to Destruction bundle
  • Cities: Skylines - After Dark
  • Cities: Skylines Deluxe Edition
  • Stellaris
  • Europa Universalis IV: Pre-order
  • Dungeonland
  • Crusader Kings II
  • Crusader Kings II: Charlemagne
  • 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
  • Darkest Hour
  • For the Motherland
  • Europa Universalis III
  • Europa Universalis III Complete
  • Divine Wind
  • Europa Universalis IV: Mare Nostrum
  • Europa Universalis IV: Art of War
  • Europa Universalis IV: Conquest of Paradise
  • Europa Universalis IV: Wealth of Nations
  • Europa Universalis IV: Call to arms event
  • For The Glory
  • Europa Universalis IV: Common Sense
  • Pillars of Eternity
  • Crusader Kings II: Horse Lords
  • Stellaris: Nemesis
  • Crusader Kings II: Conclave
  • 500k Club
  • Europa Universalis III Complete
(alt. title: "How do I scope to every system during galaxy generation?")

So, what I'm trying to do is this: I want to make it so that certain solar system initializers have a higher chance of being used for systems that are closer to a human player's homeworld than to any AI empire's homeworld.

The only way I could think of to do that is to write a scripted effect that sets a flag on all systems that meet that condition, run it from the init_effect block of a solar system initializer that's guaranteed to be used (hoping that it gets run early enough in the process), and then use that flag as a modifier to the usage_odds of the initializers whose position I want to influence.

(tl;dr: It didn't work, and I need help figuring out either an alternative solution, or how to fix it.)

Here's the scripted effect I came up with:
Code:
init_expansion_cluster_flag_effect = {
    every_system = {                                        # Find every system...
        limit = {
            NOR = {                                         # Other than the following:...
                exists = owner                              # Systems that have an owner, or...
                any_neighbor_system = {                     # Systems that are right next to...
                    ignore_hyperlanes = no
                    exists = owner
                    owner = {
                        is_country_type = fallen_empire     # Xenophobic Fallen Empires, or...
                        is_xenophobe = yes
                    }
                }
                has_star_flag = empire_home_system          # Empire homeworlds (probably redundant), or...
                has_star_flag = empire_cluster              # Systems very close to empire homeworlds.
            }
        }                                                   # From that system...
        closest_system = {                                      # Find the closest system...
            limit = {
                exists = owner                                  # That has an owner...
                owner = { is_country_type = default }           # Other than FE, Marauders, etc....
            }
            if = {                                              # If that owner...
                limit = {
                    owner = { is_ai = no }                      # Is a human player...
                }
                PREV = {                                    # Go back a scope...
                    set_star_flag = expansion_cluster       # Set the flag.
                }
            }
        }
    }
    set_star_flag = ran_expansion_cluster_effect    # This is just to confirm that the effect is being executed at all
}
(I called the flag expansion_cluster because it identifies the systems that the player is most likely to be able to expand into. I put my logic in the comments to help me spot flaws in it.)

In order to test it, I made a new solar system initializer to run it in, like so:
Code:
expansion_cluster_test_init = {
    name = "TEST"
    class = "rl_standard_stars"
    
    usage = misc_system_init
    usage_odds = 90000
    max_instances = 1
    
    init_effect = {
        init_expansion_cluster_flag_effect = yes
    }

    # Planet blocks omitted for brevity
}

I started up a new game to test it out, found the TEST system and checked its flags to confirm that the scripted effect executed (it did), but the systems that should have had the expansion_cluster flag didn't have it.

I ran another test with the game set to generate only 1 AI empire (to eliminate as many variables as possible), and I discovered that the TEST system itself had the expansion_cluster flag when in the right area, but it still wasn't getting set on any other systems.

I also tested the effect by running it in an on_game_start event. When I did that, the flag was set properly in all systems that should have it. So I know that the code itself works. The problem can't be a syntax error, or a flaw in the logic of the effect itself, it has to be a problem with when or where I'm running the effect.

So, my hypothesis is that init_effect blocks can't scope outside their own system, and if that's true, I'm stumped. I can't think of a way to set the expansion_cluster flags early enough to affect galaxy gen. I can't use an on_game_start event in practice, because those run after galaxy gen is already finished. And afaik, there's no way to run an effect during galaxy gen other than in init_effect blocks.

If I knew of a way to check whether a system is closer to one thing than another without setting a flag, using only triggers, then I could just use that directly as a modifier to the usage_odds of the initializers I'm trying to influence - sidestepping the flag problem entirely - but I have no idea how to do that.

Do any of you know how to check whether a system is closer to one thing than another without setting a flag? Or alternatively, do you know of a way to scope to every_system during galaxy gen? Either option would help immensely.
 

spacht

Sergeant
124 Badges
Apr 29, 2004
52
35
  • Warlock: Master of the Arcane
  • Magicka
  • Majesty 2
  • Europa Universalis III Complete
  • Europa Universalis IV: Res Publica
  • Semper Fi
  • Sword of the Stars
  • Sword of the Stars II
  • Teleglitch: Die More Edition
  • The Showdown Effect
  • Victoria 2
  • Victoria 2: A House Divided
  • Victoria 2: Heart of Darkness
  • Leviathan: Warships
  • Warlock 2: The Exiled
  • Warlock 2: Wrath of the Nagas
  • War of the Roses
  • 500k Club
  • Cities: Skylines
  • Europa Universalis IV: El Dorado
  • Europa Universalis IV: Pre-order
  • Pride of Nations
  • Mount & Blade: Warband
  • Crusader Kings II: Way of Life
  • Pillars of Eternity
  • Stellaris: Necroids
  • Europa Universalis III
  • Arsenal of Democracy
  • Cities in Motion
  • Crusader Kings II
  • Crusader Kings II: Charlemagne
  • 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: Sword of Islam
  • Darkest Hour
  • Dungeonland
  • A Game of Dwarves
  • Europa Universalis III: Chronicles
  • Europa Universalis III Complete
  • Europa Universalis IV
  • Europa Universalis IV: Art of War
  • Europa Universalis IV: Conquest of Paradise
  • Europa Universalis IV: Wealth of Nations
  • Europa Universalis IV: Call to arms event
  • Hearts of Iron III
  • Hearts of Iron III Collection
  • Heir to the Throne
The easiest way to get a similar result would be to generate the surrounding systems directly in the empire's system initializer, like how it's done with the two guaranteed habitable planets.

But the way you described should work. There are a lot of systems that can't spawn wherever there is an empire_cluster flag. That should work the other way round, having certain systems only spawn in flagged systems. Of course, you should use a unique flag for that specific empire.
 

spacht

Sergeant
124 Badges
Apr 29, 2004
52
35
  • Warlock: Master of the Arcane
  • Magicka
  • Majesty 2
  • Europa Universalis III Complete
  • Europa Universalis IV: Res Publica
  • Semper Fi
  • Sword of the Stars
  • Sword of the Stars II
  • Teleglitch: Die More Edition
  • The Showdown Effect
  • Victoria 2
  • Victoria 2: A House Divided
  • Victoria 2: Heart of Darkness
  • Leviathan: Warships
  • Warlock 2: The Exiled
  • Warlock 2: Wrath of the Nagas
  • War of the Roses
  • 500k Club
  • Cities: Skylines
  • Europa Universalis IV: El Dorado
  • Europa Universalis IV: Pre-order
  • Pride of Nations
  • Mount & Blade: Warband
  • Crusader Kings II: Way of Life
  • Pillars of Eternity
  • Stellaris: Necroids
  • Europa Universalis III
  • Arsenal of Democracy
  • Cities in Motion
  • Crusader Kings II
  • Crusader Kings II: Charlemagne
  • 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: Sword of Islam
  • Darkest Hour
  • Dungeonland
  • A Game of Dwarves
  • Europa Universalis III: Chronicles
  • Europa Universalis III Complete
  • Europa Universalis IV
  • Europa Universalis IV: Art of War
  • Europa Universalis IV: Conquest of Paradise
  • Europa Universalis IV: Wealth of Nations
  • Europa Universalis IV: Call to arms event
  • Hearts of Iron III
  • Hearts of Iron III Collection
  • Heir to the Throne
Ok, i'm just spitballing here, but if you put the following in your human empire initializer, you should get the usual empire_cluster flag 2 jumps out and your special expansion_cluster flag up to 4 jumps out.
Code:
init_effect = {
    every_neighbor_system = {
        set_star_flag = empire_cluster
        every_neighbor_system = {
            set_star_flag = empire_cluster
            every_neighbor_system = {
                limit = { NOT = { has_star_flag = empire_cluster } }
                set_star_flag = expansion_cluster
                every_neighbor_system = {
                    limit = { NOT = { has_star_flag = empire_cluster } }
                    set_star_flag = expansion_cluster
                }
            }
        }
    }
 
    generate_home_system_resources = yes
}
Then you put something like this in the initializers you want in your expansion cluster.
Code:
usage_odds = {
    base = 0
    modifier = {
        has_star_flag = expansion_cluster
        add = 100
    }
}
 

Uroshnor

Sergeant
106 Badges
Jun 19, 2012
90
3
  • Stellaris: Synthetic Dawn
  • Hearts of Iron III
  • Heir to the Throne
  • Cities: Skylines - Snowfall
  • Leviathan: Warships
  • Magicka
  • Europa Universalis IV: Cossacks
  • Europa Universalis IV: Res Publica
  • Semper Fi
  • Sengoku
  • Sword of the Stars
  • Hearts of Iron III: Their Finest Hour
  • The Showdown Effect
  • Victoria 2
  • Victoria 2: A House Divided
  • Victoria 2: Heart of Darkness
  • Europa Universalis IV: Third Rome
  • Stellaris - Path to Destruction bundle
  • Cities: Skylines - After Dark
  • Cities: Skylines Deluxe Edition
  • Stellaris
  • Europa Universalis IV: Pre-order
  • Dungeonland
  • Crusader Kings II
  • Crusader Kings II: Charlemagne
  • 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
  • Darkest Hour
  • For the Motherland
  • Europa Universalis III
  • Europa Universalis III Complete
  • Divine Wind
  • Europa Universalis IV: Mare Nostrum
  • Europa Universalis IV: Art of War
  • Europa Universalis IV: Conquest of Paradise
  • Europa Universalis IV: Wealth of Nations
  • Europa Universalis IV: Call to arms event
  • For The Glory
  • Europa Universalis IV: Common Sense
  • Pillars of Eternity
  • Crusader Kings II: Horse Lords
  • Stellaris: Nemesis
  • Crusader Kings II: Conclave
  • 500k Club
  • Europa Universalis III Complete
The easiest way to get a similar result would be to generate the surrounding systems directly in the empire's system initializer, like how it's done with the two guaranteed habitable planets.

But the way you described should work. There are a lot of systems that can't spawn wherever there is an empire_cluster flag. That should work the other way round, having certain systems only spawn in flagged systems. Of course, you should use a unique flag for that specific empire.
I don't necessarily want these systems to be right next to the player's homeworld - that's why I exclude empire_cluster systems in the scripted effect I posted. I just want them to be closer to the player than to the AI. So I'd really rather not generate them directly from the empire initializer like that.

And the problem isn't making systems spawn in systems that have the expansion_cluster flag. I know for a fact that I can do that, and I know exactly how to do it.

The problem is that I can't set those flags properly in the first place. The empire_cluster flag is set using the every_neighbor_system scope (which works in init_effects just fine), but I'm not just trying to set the flag on every system 4 jumps out from a homeworld, like in your example. I'm trying to set the flag on every system that's closer to the player than to the AI, regardless of how far away it is in absolute terms. And I can't do that with every_neighbor_system scopes, at least not without nesting hundreds of them.

I ran a test by running the following code in an init_effect block:
Code:
every_neighbor_system = {
    set_star_flag = every_neighbor_system_scope_works
}
every_system = {
    set_star_flag = every_system_scope_works
}
Which confirmed to me that, while every_neighbor_system scope definitely works in an init_effect block, every_system scope definitely does not. Which means that, in order to use the flag method, I'd have to find a workaround that will let me scope to almost every system in the galaxy without using every_system scope (and preferably without using hundreds of nested every_neighbor_system scopes either).
 

Uroshnor

Sergeant
106 Badges
Jun 19, 2012
90
3
  • Stellaris: Synthetic Dawn
  • Hearts of Iron III
  • Heir to the Throne
  • Cities: Skylines - Snowfall
  • Leviathan: Warships
  • Magicka
  • Europa Universalis IV: Cossacks
  • Europa Universalis IV: Res Publica
  • Semper Fi
  • Sengoku
  • Sword of the Stars
  • Hearts of Iron III: Their Finest Hour
  • The Showdown Effect
  • Victoria 2
  • Victoria 2: A House Divided
  • Victoria 2: Heart of Darkness
  • Europa Universalis IV: Third Rome
  • Stellaris - Path to Destruction bundle
  • Cities: Skylines - After Dark
  • Cities: Skylines Deluxe Edition
  • Stellaris
  • Europa Universalis IV: Pre-order
  • Dungeonland
  • Crusader Kings II
  • Crusader Kings II: Charlemagne
  • 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
  • Darkest Hour
  • For the Motherland
  • Europa Universalis III
  • Europa Universalis III Complete
  • Divine Wind
  • Europa Universalis IV: Mare Nostrum
  • Europa Universalis IV: Art of War
  • Europa Universalis IV: Conquest of Paradise
  • Europa Universalis IV: Wealth of Nations
  • Europa Universalis IV: Call to arms event
  • For The Glory
  • Europa Universalis IV: Common Sense
  • Pillars of Eternity
  • Crusader Kings II: Horse Lords
  • Stellaris: Nemesis
  • Crusader Kings II: Conclave
  • 500k Club
  • Europa Universalis III Complete
Also, there's an easier way of checking whether a system is within a certain distance of a player, which you can do directly in a usage_odds modifier block:
Code:
any_system = {
    distance = {
        source = PREV
        type = hyperlane
        use_bypasses = no
        min_jumps = 0
        max_jumps = 4   # Or however many you want
    }
    has_owner = yes
    space_owner = {
        is_ai = no
    }
}
But that still doesn't solve my problem. It only checks absolute distance to a single point, not relative distance to two different points.
 

spacht

Sergeant
124 Badges
Apr 29, 2004
52
35
  • Warlock: Master of the Arcane
  • Magicka
  • Majesty 2
  • Europa Universalis III Complete
  • Europa Universalis IV: Res Publica
  • Semper Fi
  • Sword of the Stars
  • Sword of the Stars II
  • Teleglitch: Die More Edition
  • The Showdown Effect
  • Victoria 2
  • Victoria 2: A House Divided
  • Victoria 2: Heart of Darkness
  • Leviathan: Warships
  • Warlock 2: The Exiled
  • Warlock 2: Wrath of the Nagas
  • War of the Roses
  • 500k Club
  • Cities: Skylines
  • Europa Universalis IV: El Dorado
  • Europa Universalis IV: Pre-order
  • Pride of Nations
  • Mount & Blade: Warband
  • Crusader Kings II: Way of Life
  • Pillars of Eternity
  • Stellaris: Necroids
  • Europa Universalis III
  • Arsenal of Democracy
  • Cities in Motion
  • Crusader Kings II
  • Crusader Kings II: Charlemagne
  • 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: Sword of Islam
  • Darkest Hour
  • Dungeonland
  • A Game of Dwarves
  • Europa Universalis III: Chronicles
  • Europa Universalis III Complete
  • Europa Universalis IV
  • Europa Universalis IV: Art of War
  • Europa Universalis IV: Conquest of Paradise
  • Europa Universalis IV: Wealth of Nations
  • Europa Universalis IV: Call to arms event
  • Hearts of Iron III
  • Hearts of Iron III Collection
  • Heir to the Throne
You could use the every_neighbor_system flagging system to put a different flag at each iteration, like empire_cluster_1, empire_cluster_2, etc. Use a different flag for the player empire. That way you've got expanding rings of flags around all empires. Then put a convoluted checking system in the usage_odds block of your intializers, like only spawning in player_empire_cluster_5 when there is no empire_cluster_1 to _5 .

EDIT: With variables instead of flags the checking would be even easier and Solar_system scopes can hold variables.
 
Last edited:

Uroshnor

Sergeant
106 Badges
Jun 19, 2012
90
3
  • Stellaris: Synthetic Dawn
  • Hearts of Iron III
  • Heir to the Throne
  • Cities: Skylines - Snowfall
  • Leviathan: Warships
  • Magicka
  • Europa Universalis IV: Cossacks
  • Europa Universalis IV: Res Publica
  • Semper Fi
  • Sengoku
  • Sword of the Stars
  • Hearts of Iron III: Their Finest Hour
  • The Showdown Effect
  • Victoria 2
  • Victoria 2: A House Divided
  • Victoria 2: Heart of Darkness
  • Europa Universalis IV: Third Rome
  • Stellaris - Path to Destruction bundle
  • Cities: Skylines - After Dark
  • Cities: Skylines Deluxe Edition
  • Stellaris
  • Europa Universalis IV: Pre-order
  • Dungeonland
  • Crusader Kings II
  • Crusader Kings II: Charlemagne
  • 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
  • Darkest Hour
  • For the Motherland
  • Europa Universalis III
  • Europa Universalis III Complete
  • Divine Wind
  • Europa Universalis IV: Mare Nostrum
  • Europa Universalis IV: Art of War
  • Europa Universalis IV: Conquest of Paradise
  • Europa Universalis IV: Wealth of Nations
  • Europa Universalis IV: Call to arms event
  • For The Glory
  • Europa Universalis IV: Common Sense
  • Pillars of Eternity
  • Crusader Kings II: Horse Lords
  • Stellaris: Nemesis
  • Crusader Kings II: Conclave
  • 500k Club
  • Europa Universalis III Complete
You could use the every_neighbor_system flagging system to put a different flag at each iteration, like empire_cluster_1, empire_cluster_2, etc. Use a different flag for the player empire. That way you've got expanding rings of flags around all empires. Then put a convoluted checking system in the usage_odds block of your intializers, like only spawning in player_empire_cluster_5 when there is no empire_cluster_1 to _5 .
I suppose that could work, but if I'm using a bunch of nested every_neighbor_system scopes anyway (which, again, I'd really rather not do), I might as well just do this:
Code:
every_neighbor_system = {
    if = {
        limit = {
            NOR = {
                exists = owner
                any_neighbor_system = {
                    ignore_hyperlanes = no
                    exists = owner
                    owner = {
                        is_country_type = fallen_empire
                        is_xenophobe = yes
                    }
                }
                has_star_flag = empire_home_system
                has_star_flag = empire_cluster
            }
        }
        closest_system = {
            limit = {
                exists = owner
                owner = { is_country_type = default }
            }
            if = {
                limit = {
                    owner = { is_ai = no }
                }
                PREV = {
                    set_star_flag = expansion_cluster
                }
            }
        }
    }
    every_neighbor_system = {
        # Do the same thing we did in the previous scope
        every_neighbor_system = {
            # Do it again
            every_neighbor_system = {
                # Repeat ad nauseum
            }
        }
    }
}
Either way, it would be a ton of nested scopes, but at least this way:
  1. I wouldn't have to override every single vanilla empire system initializer
  2. The usage_odds modifier blocks would be a whole hell of a lot simpler.
But again, I'm ideally looking for a way to do this that does not require endless recursive nested every_neighbor_system scopes.
 
Last edited:

Uroshnor

Sergeant
106 Badges
Jun 19, 2012
90
3
  • Stellaris: Synthetic Dawn
  • Hearts of Iron III
  • Heir to the Throne
  • Cities: Skylines - Snowfall
  • Leviathan: Warships
  • Magicka
  • Europa Universalis IV: Cossacks
  • Europa Universalis IV: Res Publica
  • Semper Fi
  • Sengoku
  • Sword of the Stars
  • Hearts of Iron III: Their Finest Hour
  • The Showdown Effect
  • Victoria 2
  • Victoria 2: A House Divided
  • Victoria 2: Heart of Darkness
  • Europa Universalis IV: Third Rome
  • Stellaris - Path to Destruction bundle
  • Cities: Skylines - After Dark
  • Cities: Skylines Deluxe Edition
  • Stellaris
  • Europa Universalis IV: Pre-order
  • Dungeonland
  • Crusader Kings II
  • Crusader Kings II: Charlemagne
  • 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
  • Darkest Hour
  • For the Motherland
  • Europa Universalis III
  • Europa Universalis III Complete
  • Divine Wind
  • Europa Universalis IV: Mare Nostrum
  • Europa Universalis IV: Art of War
  • Europa Universalis IV: Conquest of Paradise
  • Europa Universalis IV: Wealth of Nations
  • Europa Universalis IV: Call to arms event
  • For The Glory
  • Europa Universalis IV: Common Sense
  • Pillars of Eternity
  • Crusader Kings II: Horse Lords
  • Stellaris: Nemesis
  • Crusader Kings II: Conclave
  • 500k Club
  • Europa Universalis III Complete
Actually, spacht, you gave me an idea. I figured, rather than using endless nested scopes, maybe I can use recursion - that is, call the scripted effect from within itself, while scoped to every_neighbor_system. I've tried a few different iterations of this idea, and here's the best I have so far:
Code:
expansion_cluster_flag_effect = {
    if = {
        limit = {
            is_eligible_for_expansion_cluster = yes
        }
        closest_system = {
            limit = {
                exists = owner
                owner = { is_country_type = default }
            }
            if = {
                limit = {
                    owner = { is_ai = no }
                }
                PREV = {
                    set_star_flag = expansion_cluster
                }
            }
            else = {
                PREV = {
                    set_star_flag = not_expansion_cluster
                }
            }
        }
    }
    else = {
        set_star_flag = not_expansion_cluster
    }
    every_neighbor_system = {
        limit = {
            NOR = {
                has_star_flag = expansion_cluster
                has_star_flag = not_expansion_cluster
            }
        }
        expansion_cluster_flag_effect = yes
    }
}

The scripted trigger I used in that effect is as follows:
Code:
is_eligible_for_expansion_cluster = {
    NOR = {
        exists = owner
        any_neighbor_system = {
            ignore_hyperlanes = no
            exists = owner
            owner = {
                is_country_type = fallen_empire
                is_xenophobe = yes
            }
        }
        has_star_flag = empire_home_system
        has_star_flag = empire_cluster
        has_star_flag = expansion_cluster
        has_star_flag = not_expansion_cluster
    }
}

So theoretically, this effect should iterate through every system in the galaxy (other than those few that aren't connected by hyperlane - namely, the Corrupted Avatar system and the L-Cluster) until all of them are flagged.

When I run it from an init_effect, though, it flags the origin system and neighbor systems within ~3-5 jumps, but it stops there, and the rest of the galaxy doesn't get flagged. I'm not sure why. I figure there might be a flaw in my logic somewhere, or possibly there might be some sort of hardcoded limit on recursion. Maybe both, idk. I'm stumped again.
 

Uroshnor

Sergeant
106 Badges
Jun 19, 2012
90
3
  • Stellaris: Synthetic Dawn
  • Hearts of Iron III
  • Heir to the Throne
  • Cities: Skylines - Snowfall
  • Leviathan: Warships
  • Magicka
  • Europa Universalis IV: Cossacks
  • Europa Universalis IV: Res Publica
  • Semper Fi
  • Sengoku
  • Sword of the Stars
  • Hearts of Iron III: Their Finest Hour
  • The Showdown Effect
  • Victoria 2
  • Victoria 2: A House Divided
  • Victoria 2: Heart of Darkness
  • Europa Universalis IV: Third Rome
  • Stellaris - Path to Destruction bundle
  • Cities: Skylines - After Dark
  • Cities: Skylines Deluxe Edition
  • Stellaris
  • Europa Universalis IV: Pre-order
  • Dungeonland
  • Crusader Kings II
  • Crusader Kings II: Charlemagne
  • 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
  • Darkest Hour
  • For the Motherland
  • Europa Universalis III
  • Europa Universalis III Complete
  • Divine Wind
  • Europa Universalis IV: Mare Nostrum
  • Europa Universalis IV: Art of War
  • Europa Universalis IV: Conquest of Paradise
  • Europa Universalis IV: Wealth of Nations
  • Europa Universalis IV: Call to arms event
  • For The Glory
  • Europa Universalis IV: Common Sense
  • Pillars of Eternity
  • Crusader Kings II: Horse Lords
  • Stellaris: Nemesis
  • Crusader Kings II: Conclave
  • 500k Club
  • Europa Universalis III Complete
I just ran another test of the same code, but this time with hyperlane density turned up to max. This time, the effect rippled out significantly farther than before - I'd estimate that roughly 1/4 of the galaxy was flagged with either expansion_cluster or not_expansion_cluster - but it still stopped before flagging the whole galaxy. I'm not sure what that means.
 

Uroshnor

Sergeant
106 Badges
Jun 19, 2012
90
3
  • Stellaris: Synthetic Dawn
  • Hearts of Iron III
  • Heir to the Throne
  • Cities: Skylines - Snowfall
  • Leviathan: Warships
  • Magicka
  • Europa Universalis IV: Cossacks
  • Europa Universalis IV: Res Publica
  • Semper Fi
  • Sengoku
  • Sword of the Stars
  • Hearts of Iron III: Their Finest Hour
  • The Showdown Effect
  • Victoria 2
  • Victoria 2: A House Divided
  • Victoria 2: Heart of Darkness
  • Europa Universalis IV: Third Rome
  • Stellaris - Path to Destruction bundle
  • Cities: Skylines - After Dark
  • Cities: Skylines Deluxe Edition
  • Stellaris
  • Europa Universalis IV: Pre-order
  • Dungeonland
  • Crusader Kings II
  • Crusader Kings II: Charlemagne
  • 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
  • Darkest Hour
  • For the Motherland
  • Europa Universalis III
  • Europa Universalis III Complete
  • Divine Wind
  • Europa Universalis IV: Mare Nostrum
  • Europa Universalis IV: Art of War
  • Europa Universalis IV: Conquest of Paradise
  • Europa Universalis IV: Wealth of Nations
  • Europa Universalis IV: Call to arms event
  • For The Glory
  • Europa Universalis IV: Common Sense
  • Pillars of Eternity
  • Crusader Kings II: Horse Lords
  • Stellaris: Nemesis
  • Crusader Kings II: Conclave
  • 500k Club
  • Europa Universalis III Complete
I still don't know why the effect isn't flagging every system, but I found a way to make it work anyway!

Basically, I realized that since the effect only works on systems 3-5 jumps out, it needs to be run in many different systems, all across the galaxy, not just in one.

So here's what I did: I copied the first two initializers (basic_init_01 and basic_init_02) from misc_system_initializers.txt into a new file, and changed their names so as not to override the vanilla ones. Those are the two most commonly-used initializers in vanilla galaxy gen, so it won't be conspicuous if we spawn a bunch more of them to run init_effects from.

Next, I replaced the usage_odds blocks in each of my new initializers with the following:
Code:
usage = misc_system_init
usage_odds = {
    base = 999999999    # This can be any arbitrarily huge number
    modifier = {
        factor = 0
        OR = {
            has_star_flag = expansion_cluster
            has_star_flag = not_expansion_cluster
        }
    }
    modifier = {
        factor = 0
        any_system = {
            distance = {
                source = PREV
                type = hyperlane
                use_bypasses = no
                min_jumps = 0
                max_jumps = 2
            }
            has_star_flag = expansion_cluster_flagger
        }
    }
}

flags = { expansion_cluster_flagger }

init_effect = {
    expansion_cluster_flag_effect = yes
}
This will ensure that the initializers keep spawning new systems (at least 3 jumps apart from each other), and running my scripted effect from them, until the entire galaxy is flagged. I'd estimate that in a medium (600 star) galaxy, no more than 50 or so of these get spawned. And again, these are copied from the two most commonly-used vanilla initializers, so their presence isn't noticeable at all if you don't have debugtooltip on. I've tested using the expansion_cluster flags set from these initializers to modify the usage_odds of other initializers, and it works perfectly.

This solution is kludgy as hell, and I kinda hate that I had to do it this way, but it does work for what I need it to do.

It still doesn't answer the question I asked in the post title, though - only the one I asked in the alt. title - so I'd still be interested in hearing whether there's a way to check whether a system is closer to one thing than another without resorting to a massive kludge like this.

Btw, I've refined the scripted effect and scripted trigger a bit since the last time I posted them here, so I'll post the new versions in case anyone is interested.

Scripted effect:
Code:
expansion_cluster_flag_effect = {
    if = {
        limit = {
            is_eligible_for_expansion_cluster = yes
        }
        closest_system = {
            limit = {
                exists = owner
                owner = { is_country_type = default }
            }
            if = {
                limit = {
                    owner = { is_ai = no }
                }
                PREV = {
                    set_star_flag = expansion_cluster
                }
            }
            else = {
                PREV = {
                    set_star_flag = not_expansion_cluster
                }
            }
        }
    }
    else_if = {
        limit = {
            NOT = {
                has_star_flag = expansion_cluster
            }
        }
        set_star_flag = not_expansion_cluster
    }
    every_neighbor_system = {
        limit = {
            NOR = {
                has_star_flag = expansion_cluster
                has_star_flag = not_expansion_cluster
            }
        }
        expansion_cluster_flag_effect = yes
    }
}

Scripted trigger:
Code:
is_eligible_for_expansion_cluster = {
    NOR = {
        exists = owner
        any_neighbor_system = {
            ignore_hyperlanes = no
            exists = owner
            owner = {
                is_country_type = fallen_empire
                is_xenophobe = yes
            }
        }
        has_star_flag = expansion_cluster
        has_star_flag = not_expansion_cluster
    }
}

And finally, thank you again, spacht. Even though the solutions you suggested weren't what I was looking for, they did inspire me to try a recursive approach, which is what ultimately worked. I really do appreciate it.