Skip to content

Instantly share code, notes, and snippets.

@Facenapalm
Last active August 1, 2022 03:14
Show Gist options
  • Save Facenapalm/e3949a77a1190e64210ac979440e0bd0 to your computer and use it in GitHub Desktop.
Save Facenapalm/e3949a77a1190e64210ac979440e0bd0 to your computer and use it in GitHub Desktop.
Stellaris save scanner that seeks for conditions for "Outside Context" achievement. Written for Cepheus v3.4.5
# Copyright (c) 2022 Facenapalm
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
import zipfile
import os
import os.path
import re
import math
def extract_block(data, position, nesting_level=2):
def helper(position, nesting_level, edge, delta):
while position != edge:
if data[position] == "}":
nesting_level -= 1
if data[position] == "{":
nesting_level += 1
if nesting_level == 0:
break
position += delta
return position
return data[helper(position, -nesting_level, 0, -1):helper(position, nesting_level, len(data)-1, 1)+1]
for file in os.listdir("."):
filename = os.fsdecode(file)
if not os.path.isdir(filename):
continue
try:
archive = zipfile.ZipFile(filename + "/ironman.sav", "r")
save = archive.open("gamestate")
data = save.read().decode("utf-8")
earth_info_pos = data.find("NAME_Sol_III")
if earth_info_pos == -1:
print("{}: Earth not found".format(filename))
continue
earth_info = extract_block(data, earth_info_pos)
planet_class = re.search(r"planet_class=\"([a-z_]+)\"", earth_info).group(1)
if planet_class != "pc_continental":
print("{}: Earth type is {} (pc_continental is required for habitable planet)".format(filename, planet_class))
continue
pop_count = re.search(r"num_sapient_pops=(\d+)", earth_info).group(1)
if pop_count != "24":
print("{}: Earth pop count is {} (24 is required for machine age)".format(filename, pop_count))
continue
sol_info_pos = data.index("NAME_Sol")
sol_info = extract_block(data, sol_info_pos)
coordinate_match = re.search(r"coordinate=\{\s*x=(?P<x>-?\d+(?:\.\d+)?)\s*y=(?P<y>-?\d+(?:\.\d+)?)", sol_info)
x = float(coordinate_match.group("x"))
y = float(coordinate_match.group("y"))
direction = ("top" if y < 0 else "bottom") + " " + ("right" if x < 0 else "left")
angle = round(math.degrees(math.atan2(-y, -x)))
radius = round(math.hypot(x, y))
print("{}: potentially okay. Sol at {} ({}, {}), angle={}, radius={}".format(filename, direction, x, y, angle, radius))
except Exception as error:
print("{}: {}".format(filename, error))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment