XRWS           X«     Vext_01.cat ext_01.dat libraries/god.xml 555 1756532798 2799be4a5ebf0655d7b5673fde908488
md/factiongoal_hold_space.xml 3618 1756467815 6f77d4255eaa809e0b916e0674bb014e
md/factiongoal_invade_space.xml 2808 1756538261 74632bb804e725c11957d745164e5e04
md/factionlogic_economy.xml 2556 1756445106 74f701ed476eb1b5cab563a57485781a
md/factionlogic_stations.xml 1395 1756445106 1a95aa1b6c024af73516cbda0ac20696
md/khaak_activity.xml 3301 1756467815 b75cb7bbc631989ff9bf196d0cbf990a
md/lib.rngsphere.xml 3121 1756541592 a6dd8aab96dac4e2b64410ef948f36b1
md/lib_generic.xml 1241 1756445106 78103fb40ab2b3779b87f6b760425cea
md/sphericalize_god_stations.xml 3432 1756541587 8a981fa25f4a64245e5db513f3632770
<?xml version="1.0" encoding="utf-8"?>
<diff>
    <replace sel="/god/stations/defaults/location/@coreboundaryzoneheight">360000</replace>
    <add sel="/god/products" pos="prepend">
        <defaults>
            <location newzonechance="0.5" coreboundaryzoneheight="360000">
                <corerange max="1.3"/>
                <region allowhazardous="false" allowgravidar="true"/>
            </location>
            <modules production="5" storage="10" />
            <quota zone="3" sector="30" />
        </defaults>
    </add>
</diff><?xml version="1.0" encoding="utf-8"?>
<diff>

  <!-- 1) High-tech factory: insert sphere pick before the old polar RNG, then remove the three RNG lines -->
  <replace sel="//create_factory[.//select[@ware='$HightechWare']]/preceding-sibling::set_value[@name='$Yaw' and @min='0deg' and @max='360deg'][1]">
    <run_actions ref="md.hds_rng_sphere_lib.HDS_RNG_Sphere_RandPoint" result="$Position">
      <param name="center" value="$SectorCentre"/>
      <param name="R"      value="$SectorCoreSize"/>
      <param name="squash" value="0.60f"/>
    </run_actions>
  </replace>
  <remove sel="//create_factory[.//select[@ware='$HightechWare']]/preceding-sibling::set_value[@name='$Y' and contains(@min,'$SectorCentre.y') and contains(@max,'$SectorCentre.y')][1]"/>
  <remove sel="//create_factory[.//select[@ware='$HightechWare']]/preceding-sibling::set_value[@name='$PlacementDist' and @min='0km' and @max='$SectorCoreSize' and @profile='bell' and @scale='2'][1]"/>

  <!-- Replace the safepos XYZ with value="$Position" for the same High-tech create_factory -->
  <replace sel="//create_factory[.//select[@ware='$HightechWare']]/safepos[@x and @y and @z and contains(@x,'$SectorCentre.x') and @y='$Y' and contains(@z,'$SectorCentre.z')]">
    <safepos value="$Position" includeplotbox="true"/>
  </replace>

  <!-- 2) Low-tech factory: same pattern (insert pick, remove three RNG lines, switch safepos) -->
  <replace sel="//create_factory[.//select[@ware='$LowtechWare']]/preceding-sibling::set_value[@name='$Yaw' and @min='0deg' and @max='360deg'][1]">
    <run_actions ref="md.hds_rng_sphere_lib.HDS_RNG_Sphere_RandPoint" result="$Position">
      <param name="center" value="$SectorCentre"/>
      <param name="R"      value="$SectorCoreSize"/>
      <param name="squash" value="0.60f"/>
    </run_actions>
  </replace>
  <remove sel="//create_factory[.//select[@ware='$LowtechWare']]/preceding-sibling::set_value[@name='$Y' and contains(@min,'$SectorCentre.y') and contains(@max,'$SectorCentre.y')][1]"/>
  <remove sel="//create_factory[.//select[@ware='$LowtechWare']]/preceding-sibling::set_value[@name='$PlacementDist' and @min='0km' and @max='$SectorCoreSize' and @profile='bell' and @scale='2'][1]"/>

  <replace sel="//create_factory[.//select[@ware='$LowtechWare']]/safepos[@x and @y and @z and contains(@x,'$SectorCentre.x') and @y='$Y' and contains(@z,'$SectorCentre.z')]">
    <safepos value="$Position" includeplotbox="true"/>
  </replace>

  <!-- 3) Build-station subgoal: replace wide get_safe_pos with (sphere pick â†’ local nudge that preserves intent) -->
  <add sel="//get_safe_pos[@result='$NewSubgoalTable.$Position' and @sector='$NewSubgoalTable.$Target' and (@radius='5km' or @radius='10km') and @object='$NewSubgoalTable.$Target' and @max='100km'][1]" pos="before">
    <run_actions ref="md.hds_rng_sphere_lib.HDS_RNG_Sphere_RandPoint" result="$NewSubgoalTable.$Position">
      <param name="center" value="$NewSubgoalTable.$Target.coreposition"/>
      <param name="R"      value="[$NewSubgoalTable.$Target.coresize / 2.0f, 600km].min"/>
      <param name="squash" value="0.60f"/>
    </run_actions>
  </add>
  <replace sel="//get_safe_pos[@result='$NewSubgoalTable.$Position' and @sector='$NewSubgoalTable.$Target' and (@radius='5km' or @radius='10km') and @object='$NewSubgoalTable.$Target' and @max='100km'][1]">
    <get_safe_pos result="$NewSubgoalTable.$Position"
                  sector="$NewSubgoalTable.$Target"
                  value="$NewSubgoalTable.$Position"
                  radius="5km"
                  comment="position of new to build station"/>
  </replace>

</diff>
<?xml version="1.0" encoding="utf-8"?>
<diff>

  <!-- A) Prepare phase â†’ BuildStation (no fixed Z) -->
  <add sel="//get_safe_pos[@result='$NewSubgoalTable.$Position' and @sector='$NewSubgoalTable.$Target' and @radius='5km' and @object='$NewSubgoalTable.$EntryPoint.destination' and @max='10km' and not(@z)][1]" pos="before">
    <run_actions ref="md.hds_rng_sphere_lib.HDS_RNG_Sphere_RandPoint" result="$SpherePos">
      <param name="center" value="$NewSubgoalTable.$EntryPoint.destination.position"/>
      <param name="R"      value="10km"/>
      <param name="squash" value="1.0f"/>
    </run_actions>
  </add>

  <replace sel="//get_safe_pos[@result='$NewSubgoalTable.$Position' and @sector='$NewSubgoalTable.$Target' and @radius='5km' and @object='$NewSubgoalTable.$EntryPoint.destination' and @max='10km' and not(@z)][1]">
    <get_safe_pos result="$NewSubgoalTable.$Position"
                  sector="$NewSubgoalTable.$Target"
                  value="$SpherePos"
                  radius="5km"
                  includeplotbox="true"/>
  </replace>

  <!-- B) Beachhead phase â†’ BuildStation (preserve z='5km') -->
  <!--Try patching vanilla and Faction Fix modded-->
  <add sel="(//get_safe_pos[@result='$NewSubgoalTable.$Position' and @sector='$NewSubgoalTable.$Target' and @radius='5km' and @object='$NewSubgoalTable.$EntryPoint.destination' and @max='10km' and @z='5km']|//get_safe_pos[@result='$NewSubgoalTable.$Position' and @sector='$NewSubgoalTable.$Target' and @radius='5km' and @x='this.$GatePos.x + sin(this.$RandYaw) * this.$PlacementDist' and @y='this.$GatePos.y + this.$YOffset' and @z='this.$GatePos.z + cos(this.$RandYaw) * this.$PlacementDist' and @includeplotbox='true'])[1]" pos="before">
    <run_actions ref="md.hds_rng_sphere_lib.HDS_RNG_Sphere_RandPoint" result="$SpherePos">
      <param name="center" value="$NewSubgoalTable.$EntryPoint.destination.position"/>
      <param name="R"      value="10km"/>
      <param name="squash" value="1.0f"/>
    </run_actions>
  </add>

  <replace sel="(//get_safe_pos[@result='$NewSubgoalTable.$Position' and @sector='$NewSubgoalTable.$Target' and @radius='5km' and @object='$NewSubgoalTable.$EntryPoint.destination' and @max='10km' and @z='5km']|//get_safe_pos[@result='$NewSubgoalTable.$Position' and @sector='$NewSubgoalTable.$Target' and @radius='5km' and @x='this.$GatePos.x + sin(this.$RandYaw) * this.$PlacementDist' and @y='this.$GatePos.y + this.$YOffset' and @z='this.$GatePos.z + cos(this.$RandYaw) * this.$PlacementDist' and @includeplotbox='true'])[1]">
    <get_safe_pos result="$NewSubgoalTable.$Position"
                  sector="$NewSubgoalTable.$Target"
                  value="$SpherePos"
                  radius="5km"
                  z="5km"
                  includeplotbox="true"/>
  </replace>

</diff>
<?xml version="1.0" encoding="utf-8"?>
<diff>

  <!-- A) $BuildInSector branch: insert sphere pick; remove old polar RNG; drive safepos from value -->
  <!-- Replace first polar selection line with RNG Sphere -->
  <replace
    sel="//do_if[@value='@$BuildInSector']//create_factory[.//select[@ware='$Ware']]/preceding-sibling::set_value[@name='$Yaw' and @min='0deg' and @max='360deg'][1]">
    <run_actions ref="md.hds_rng_sphere_lib.HDS_RNG_Sphere_RandPoint" result="$Position">
      <param name="center" value="$RequestSector.coreposition"/>
      <param name="R"      value="$SectorCoreSize"/>
      <param name="squash" value="0.60f"/>
    </run_actions>
  </replace>

  <!-- Remove the remaining polar RNG lines -->
  <remove sel="//do_if[@value='@$BuildInSector']//create_factory[.//select[@ware='$Ware']]/preceding-sibling::set_value[@name='$Y' and contains(@min,'$SectorCentre.y') and contains(@max,'$SectorCentre.y')][1]"/>
  <remove sel="//do_if[@value='@$BuildInSector']//create_factory[.//select[@ware='$Ware']]/preceding-sibling::set_value[@name='$PlacementDist' and @min='0km' and @max='$SectorCoreSize' and @profile='bell' and @scale='2'][1]"/>

  <!-- Replace safepos XYZ with value="$Position" (keep includeplotbox/radius) -->
  <replace sel="//do_if[@value='@$BuildInSector']//create_factory[.//select[@ware='$Ware']]/safepos[@x and @y and @z and contains(@x,'$SectorCentre.x') and @y='$Y' and contains(@z,'$SectorCentre.z') and @radius='3km']">
    <safepos value="$Position" includeplotbox="true" radius="3km"/>
  </replace>

  <!-- B) Else branch: add sphere pick before the 40km scatter; switch safepos to value="$Position" -->
  <!-- Insert RNG right before the existing safepos with max="40km" -->
  <add
    sel="//do_else[preceding-sibling::do_if[@value='@$BuildInSector']]//create_factory[.//select[@ware='$Ware']]/safepos[@max='40km' and @includeplotbox='true' and @radius='3km'][1]"
    pos="before">
    <run_actions ref="md.hds_rng_sphere_lib.HDS_RNG_Sphere_RandPoint" result="$Position">
      <param name="center" value="$RequestSector.coreposition"/>
      <param name="R"      value="40km"/>
      <param name="squash" value="1.0f"/>
    </run_actions>
  </add>

  <!-- Replace the wide safepos with one that uses our picked position -->
  <replace sel="//do_else[preceding-sibling::do_if[@value='@$BuildInSector']]//create_factory[.//select[@ware='$Ware']]/safepos[@max='40km' and @includeplotbox='true' and @radius='3km'][1]">
    <safepos value="$Position" includeplotbox="true" radius="3km"/>
  </replace>

</diff>
<?xml version="1.0" encoding="utf-8"?>
<diff>
    <!-- 1) ZONE-BASED: replace local random offset with our sphere RNG (no center; acts as offset) -->
    <replace
        sel="//library[@name='Find_Location_And_Build_Station']//do_if[@value='$SpawnZone']/create_position[@name='$Position']">
        <run_actions ref="md.hds_rng_sphere_lib.HDS_RNG_Sphere_RandPoint" result="$Position">
            <param name="R" value="40km" />
            <param name="squash" value="1.0f" />
        </run_actions>
    </replace>
    <remove
        sel="//library[@name='Find_Location_And_Build_Station']//do_if[@value='$SpawnZone']/set_value[@name='$Y_Position']" />
    <remove
        sel="//library[@name='Find_Location_And_Build_Station']//do_if[@value='$SpawnZone']/set_value[@name='$Position' and contains(@exact,'$Y_Position')]" />

    <!-- 2) CORE FALLBACK: replace GetRandomCorePosition_1 with sphere RNG about sector core -->
    <replace
        sel="//library[@name='Find_Location_And_Build_Station']//include_actions[@ref='GetRandomCorePosition_1']">
        <run_actions ref="md.hds_rng_sphere_lib.HDS_RNG_Sphere_RandPoint" result="$Position">
            <param name="center" value="$ChosenSector.coreposition" />
            <param name="R" value="[$ChosenSector.coresize / 2.0f, 600km].min" />
            <param name="squash" value="0.60" />
        </run_actions>
    </replace>
</diff><?xml version="1.0" encoding="utf-8"?>
<diff>

    <!-- 1) Hive station: replace polar RNG with sphere RNG; feed safepos from $Position (keep
    includeplotbox only) -->
    <replace sel="//create_station[@macro='macro.landmarks_kha_hive_01_macro']/preceding-sibling::set_value[@name='$Yaw'][1]">
        <run_actions ref="md.hds_rng_sphere_lib.HDS_RNG_Sphere_RandPoint" result="$Position">
            <param name="center" value="$SectorCentre" />
            <param name="Rmin" value="this.$NewSector.coresize / 2.0f + 170km" />
            <param name="R" value="this.$NewSector.coresize / 2.0f + 190km" />
            <param name="squash" value="0.60f" />
        </run_actions>
    </replace>
    <remove sel="//create_station[@macro='macro.landmarks_kha_hive_01_macro']/preceding-sibling::set_value[@name='$Y' and contains(@min,'$SectorCentre.y')][1]" />
    <remove sel="//create_station[@macro='macro.landmarks_kha_hive_01_macro']/preceding-sibling::set_value[@name='$PlacementDist'][1]" />
    <replace sel="//create_station[@macro='macro.landmarks_kha_hive_01_macro']/safepos">
        <safepos value="$Position" includeplotbox="true" />
    </replace>

    <!-- 2) Defence platforms ring: seed from RNG (center=hive pos; annulus via Rmin/R); keep
    space/ignored/includefiringrange/includeplotbox, drop min/max -->
    <add sel="//safepos[@value='this.$StationSectorPos' and @space='this.$NewSector' and @min='9050m' and @max='9200m']/parent::create_station" pos="before">
        <run_actions ref="md.hds_rng_sphere_lib.HDS_RNG_Sphere_RandPoint" result="$Position">
            <param name="center" value="this.$StationSectorPos" />
            <param name="Rmin" value="9050m" />
            <param name="R" value="9200m" />
            <param name="squash" value="1.0f" />
        </run_actions>
    </add>
    <replace sel="//safepos[@value='this.$StationSectorPos' and @space='this.$NewSector' and @min='9050m' and @max='9200m']">
        <safepos value="$Position" space="this.$NewSector" ignored="this.$NewStation"
            includefiringrange="false" includeplotbox="false" />
    </replace>

    <!-- 3) Outpost station: replace polar RNG with sphere RNG; feed safepos from $Position (keep
    includeplotbox only) -->
    <replace sel="//create_station[@macro='macro.landmarks_kha_nest_01_macro']/preceding-sibling::set_value[@name='$Yaw'][1]">
        <run_actions ref="md.hds_rng_sphere_lib.HDS_RNG_Sphere_RandPoint" result="$Position">
            <param name="center" value="$SectorCentre" />
            <param name="Rmin" value="this.$SelectedSector.coresize / 2.0f + 140km" />
            <param name="R" value="this.$SelectedSector.coresize / 2.0f + 180km" />
            <param name="squash" value="0.60f" />
        </run_actions>
    </replace>
    <remove sel="//create_station[@macro='macro.landmarks_kha_nest_01_macro']/preceding-sibling::set_value[@name='$Y' and contains(@min,'$SectorCentre.y')][1]" />
    <remove sel="//create_station[@macro='macro_landmarks_kha_nest_01_macro' or @macro='macro.landmarks_kha_nest_01_macro']/preceding-sibling::set_value[@name='$PlacementDist'][1]" />
    <replace sel="//create_station[@macro='macro.landmarks_kha_nest_01_macro']/safepos">
        <safepos value="$Position" includeplotbox="true" />
    </replace>

</diff><?xml version="1.0" encoding="utf-8"?>
<mdscript name="hds_rng_sphere_lib">
    <cues>

        <!-- Random point in a sphere centered at (cx,cy,cz) with biased radius and Y "squash".
         Call with <run_actions ref="md.hds_rng_sphere_lib.HDS_RNG_Sphere_RandPoint">â€¦</run_actions>
         Params:
            - center (position) OR (cx,cy,cz) lengths (center wins if given)
            - Rmin (length) : minimum distance to offset  from center position
            - R (length) : sphere radius
            - squash (float, default 1.0f): 1.0f = no squash; 0.0f = fully flattened
         Outputs (in caller scope): $out_x, $out_y, $out_z, $out_pos
        -->
        <library name="HDS_RNG_Sphere_RandPoint" purpose="run_actions">
            <params>
                <param name="center" default="null" />
                <param name="cx" default="0" />
                <param name="cy" default="0" />
                <param name="cz" default="0" />
                <param name="Rmin" default="0" />
                <param name="R" />
                <param name="squash" default="1.0f" />
            </params>

            <actions>
                <!-- Resolve center -->
                <do_if value="typeof $center != datatype.null">
                    <set_value name="$cx" exact="$center.x" />
                    <set_value name="$cy" exact="$center.y" />
                    <set_value name="$cz" exact="$center.z" />
                </do_if>

                <!-- radius fraction s in [0,1], mixed uniform/averaged bias -->
                <do_if value="true" chance="50">
                    <set_value name="$sum" exact="[0.0,1.0].randominrange" />
                </do_if>
                <do_else>
                    <set_value name="$sum" exact="0.0" />
                    <do_all exact="5" counter="$idx">
                        <set_value name="$sum" operation="add" exact="[0.0,0.2].randominrange" />
                    </do_all>
                </do_else>
                <set_value name="$r" exact="(($R - $Rmin) * $sum) + $Rmin" />

                <!-- random direction, uniform on sphere -->
                <set_value name="$pi" exact="3.141592653589793" />
                <set_value name="$u" exact="2.0 * [0.0,1.0].randominrange - 1.0" />        <!-- cos(theta) ~U(-1,1) -->
                <set_value name="$phi" exact="2.0 * $pi * [0.0,1.0].randominrange" />
                <set_value name="$t" exact="sqrt(1.0 - $u*$u)" />
                <set_value name="$dirx" exact="$t * cos($phi)" />
                <set_value name="$diry" exact="$u" />
                <set_value name="$dirz" exact="$t * sin($phi)" />

                <set_value name="$x" exact="$cx + ($r * $dirx)" />
                <set_value name="$y" exact="$cy + ($r * $diry * $squash)" />
                <set_value name="$z" exact="$cz + ($r * $dirz)" />

                <!-- output -->
                 <debug_text text="'[HDS] Generated RNG Sphere point ' + position.[$x, $y, $z]" />
                <return value="position.[$x, $y, $z]" />
            </actions>
        </library>

    </cues>
</mdscript><?xml version="1.0" encoding="utf-8"?>
<diff>
  <!-- HDS_YVARY: inject sphere offset around the nearest gravidar-obscuring position -->
  <add
    sel="//library[@name='GetGravidarObscuringSectorPosition']//get_safe_pos[@result='$SafePos' and @radius='$SafeposRadius' and @value='$NearestPos' and @min='1km' and @max='10km' and @allowyaxis='false' and @includeplotbox='true' and @sector='$Sector']"
    pos="before">
    <run_actions ref="md.hds_rng_sphere_lib.HDS_RNG_Sphere_RandPoint" result="$SpherePos">
      <param name="center" value="$NearestPos"/>
      <param name="R"      value="10km"/>
      <param name="squash" value="1.0f"/>
    </run_actions>
  </add>

  <!-- Replace the original safety call to use our offset and drop min/max/allowyaxis -->
  <replace
    sel="//library[@name='GetGravidarObscuringSectorPosition']//get_safe_pos[@result='$SafePos' and @radius='$SafeposRadius' and @value='$NearestPos' and @min='1km' and @max='10km' and @allowyaxis='false' and @includeplotbox='true' and @sector='$Sector']">
    <get_safe_pos result="$SafePos"
                  radius="$SafeposRadius"
                  value="$SpherePos"
                  includeplotbox="true"
                  sector="$Sector"/>
  </replace>
</diff>
<?xml version="1.0" encoding="utf-8"?>
<mdscript name="hds_sphericalize_god_stations">
    <cues>
        <!-- Listen for both GOD station + factory spawns, but only at game start -->
        <cue name="GodSpawn_Listener_Debug" instantiate="true">
            <conditions>
                <check_any>
                    <event_god_created_factory space="player.galaxy" />
                    <check_all>
                        <event_god_created_station space="player.galaxy" />
                        <check_value value="@event.param.ispiratebase" /> <!-- All non-zone-anchored, non-static stations in GOD are pirate bases. -->
                    </check_all>
                </check_any>
                <check_value value="@event.param.godentry != 'pir_spaceweed'" /> <!-- the only static factory -->
                <check_value value="event.param.isgamestartgodentry" />
                <check_value value="@event.param.state == componentstate.operational" /> <!-- Only modify initial pre-built placements -->
                <check_value value="@event.param.position != position.[0.0,0.0,0.0]" /> <!-- 0,0,0 positions seem to be placeholder? -->
            </conditions>

            <actions>
                <set_value name="$Station" exact="event.param" />
                <set_value name="$StationPos" exact="event.param.position" />
                <set_value name="$Sector" exact="event.param.sector" />
                <set_value name="$SecCenter" exact="$Sector.coreposition"/>
                <set_value name="$SecRadius" exact="$Sector.coresize / 2.0f"/>
                <set_value name="$FlatOffset" exact="position.[$StationPos.x - $SecCenter.x, 0.0, $StationPos.z - $SecCenter.z]" />
                <set_value name="$SphereHeightSq" exact="((1.3f* $SecRadius) ^ 2) - ($FlatOffset.x ^ 2) - ($FlatOffset.z ^ 2)" /> <!-- GOD default is 1.3x radius -->
                <set_value name="$SphereHeight" exact="[sqrt([$SphereHeightSq, 0.0f].max), 10000.0f].max" /> <!-- Avoid neg sqrt from stations outside default core radius, min 10km-->

                <!-- radius fraction s in [0,1], mixed uniform/averaged bias -->
                <do_if value="true" chance="50">
                    <set_value name="$sum" exact="[0.0,1.0].randominrange" />
                </do_if>
                <do_else>
                    <set_value name="$sum" exact="0.0" />
                    <do_all exact="5" counter="$idx">
                        <set_value name="$sum" operation="add" exact="[0.0,0.2].randominrange" />
                    </do_all>
                </do_else>
                <set_value name="$sum" exact="$sum * 0.4615f" /> <!-- 130% expanded -> ~60% squashed -->
                <set_value name="$sum" exact="$sum * -1.0f" chance="50" /> <!-- 50% negative -->

                <set_value name="$StationDest" exact="position.[$StationPos.x, $SecCenter.y + ($sum * $SphereHeight), $StationPos.z]" />
                <warp object="$Station" sector="$Sector">
                    <safepos value="$StationDest" allowyaxis="true" includeplotbox="true" ignored="$Station" />
                </warp>
                <debug_text text="'[HDS] Warped ' + $Station.debugname + ' from ' + $StationPos + ' to ' + $StationDest + ' in ' + $Sector.debugname + ' (' + $StationDest.y + ':' + $SecRadius + ')'" />
            </actions>
        </cue>
    </cues>
</mdscript><?xml version="1.0" encoding="utf-8"?>
<content id="" name="" version="010" author="Reithan" date="2025-08-30" save="false" description="" lastupdate="">
</content>
