Skip to content

Commit

Permalink
Witness: apworld support (ArchipelagoMW#1885)
Browse files Browse the repository at this point in the history
  • Loading branch information
NewSoupVi authored Jun 25, 2023
1 parent 7a4e903 commit 46b13e0
Show file tree
Hide file tree
Showing 2 changed files with 160 additions and 139 deletions.
259 changes: 126 additions & 133 deletions worlds/witness/static_logic.py
Original file line number Diff line number Diff line change
@@ -1,123 +1,119 @@
import os

from .utils import define_new_region, parse_lambda, lazy
from .utils import define_new_region, parse_lambda, lazy, get_logic_file, get_items


class StaticWitnessLogicObj:
def read_logic_file(self, file_path="WitnessLogic.txt"):
"""
Reads the logic file and does the initial population of data structures
"""
path = os.path.join(os.path.dirname(__file__), file_path)
lines = get_logic_file(file_path)

with open(path, "r", encoding="utf-8") as file:
current_region = dict()
current_region = dict()
counter = 0

counter = 0
for line in lines:
if line == "":
continue

for line in file.readlines():
line = line.strip()
if line[-1] == ":":
new_region_and_connections = define_new_region(line)
current_region = new_region_and_connections[0]
region_name = current_region["name"]
self.ALL_REGIONS_BY_NAME[region_name] = current_region
self.STATIC_CONNECTIONS_BY_REGION_NAME[region_name] = new_region_and_connections[1]
continue

if line == "":
continue

if line[-1] == ":":
new_region_and_connections = define_new_region(line)
current_region = new_region_and_connections[0]
region_name = current_region["name"]
self.ALL_REGIONS_BY_NAME[region_name] = current_region
self.STATIC_CONNECTIONS_BY_REGION_NAME[region_name] = new_region_and_connections[1]
continue

line_split = line.split(" - ")

location_id = line_split.pop(0)

check_name_full = line_split.pop(0)

check_hex = check_name_full[0:7]
check_name = check_name_full[9:-1]

required_panel_lambda = line_split.pop(0)
line_split = line.split(" - ")

full_check_name = current_region["shortName"] + " " + check_name
location_id = line_split.pop(0)

if location_id == "Door" or location_id == "Laser":
self.CHECKS_BY_HEX[check_hex] = {
"checkName": full_check_name,
"checkHex": check_hex,
"region": current_region,
"id": None,
"panelType": location_id
}
check_name_full = line_split.pop(0)

self.CHECKS_BY_NAME[self.CHECKS_BY_HEX[check_hex]["checkName"]] = self.CHECKS_BY_HEX[check_hex]

self.STATIC_DEPENDENT_REQUIREMENTS_BY_HEX[check_hex] = {
"panels": parse_lambda(required_panel_lambda)
}

current_region["panels"].append(check_hex)
continue

required_item_lambda = line_split.pop(0)

laser_names = {
"Laser",
"Laser Hedges",
"Laser Pressure Plates",
"Desert Laser Redirect"
}
is_vault_or_video = "Vault" in check_name or "Video" in check_name

if "Discard" in check_name:
location_type = "Discard"
elif is_vault_or_video or check_name == "Tutorial Gate Close":
location_type = "Vault"
elif check_name in laser_names:
location_type = "Laser"
elif "Obelisk Side" in check_name:
location_type = "Obelisk Side"
full_check_name = check_name
elif "EP" in check_name:
location_type = "EP"
else:
location_type = "General"

required_items = parse_lambda(required_item_lambda)
required_panels = parse_lambda(required_panel_lambda)

required_items = frozenset(required_items)

requirement = {
"panels": required_panels,
"items": required_items
}
check_hex = check_name_full[0:7]
check_name = check_name_full[9:-1]

if location_type == "Obelisk Side":
eps = set(list(required_panels)[0])
eps -= {"Theater to Tunnels"}
required_panel_lambda = line_split.pop(0)

eps_ints = {int(h, 16) for h in eps}

self.OBELISK_SIDE_ID_TO_EP_HEXES[int(check_hex, 16)] = eps_ints
for ep_hex in eps:
self.EP_TO_OBELISK_SIDE[ep_hex] = check_hex
full_check_name = current_region["shortName"] + " " + check_name

if location_id == "Door" or location_id == "Laser":
self.CHECKS_BY_HEX[check_hex] = {
"checkName": full_check_name,
"checkHex": check_hex,
"region": current_region,
"id": int(location_id),
"panelType": location_type
"id": None,
"panelType": location_id
}

self.ENTITY_ID_TO_NAME[check_hex] = full_check_name

self.CHECKS_BY_NAME[self.CHECKS_BY_HEX[check_hex]["checkName"]] = self.CHECKS_BY_HEX[check_hex]
self.STATIC_DEPENDENT_REQUIREMENTS_BY_HEX[check_hex] = requirement

self.STATIC_DEPENDENT_REQUIREMENTS_BY_HEX[check_hex] = {
"panels": parse_lambda(required_panel_lambda)
}

current_region["panels"].append(check_hex)
continue

required_item_lambda = line_split.pop(0)

laser_names = {
"Laser",
"Laser Hedges",
"Laser Pressure Plates",
"Desert Laser Redirect"
}
is_vault_or_video = "Vault" in check_name or "Video" in check_name

if "Discard" in check_name:
location_type = "Discard"
elif is_vault_or_video or check_name == "Tutorial Gate Close":
location_type = "Vault"
elif check_name in laser_names:
location_type = "Laser"
elif "Obelisk Side" in check_name:
location_type = "Obelisk Side"
full_check_name = check_name
elif "EP" in check_name:
location_type = "EP"
else:
location_type = "General"

required_items = parse_lambda(required_item_lambda)
required_panels = parse_lambda(required_panel_lambda)

required_items = frozenset(required_items)

requirement = {
"panels": required_panels,
"items": required_items
}

if location_type == "Obelisk Side":
eps = set(list(required_panels)[0])
eps -= {"Theater to Tunnels"}

eps_ints = {int(h, 16) for h in eps}

self.OBELISK_SIDE_ID_TO_EP_HEXES[int(check_hex, 16)] = eps_ints
for ep_hex in eps:
self.EP_TO_OBELISK_SIDE[ep_hex] = check_hex

self.CHECKS_BY_HEX[check_hex] = {
"checkName": full_check_name,
"checkHex": check_hex,
"region": current_region,
"id": int(location_id),
"panelType": location_type
}

self.ENTITY_ID_TO_NAME[check_hex] = full_check_name

self.CHECKS_BY_NAME[self.CHECKS_BY_HEX[check_hex]["checkName"]] = self.CHECKS_BY_HEX[check_hex]
self.STATIC_DEPENDENT_REQUIREMENTS_BY_HEX[check_hex] = requirement

current_region["panels"].append(check_hex)

def __init__(self, file_path="WitnessLogic.txt"):
# All regions with a list of panels in them and the connections to other regions, before logic adjustments
Expand Down Expand Up @@ -166,48 +162,45 @@ def parse_items(self):
Parses currently defined items from WitnessItems.txt
"""

path = os.path.join(os.path.dirname(__file__), "WitnessItems.txt")
with open(path, "r", encoding="utf-8") as file:
current_set = self.ALL_SYMBOL_ITEMS

for line in file.readlines():
line = line.strip()

if line == "Progression:":
current_set = self.ALL_SYMBOL_ITEMS
continue
if line == "Boosts:":
current_set = self.ALL_BOOSTS
continue
if line == "Traps:":
current_set = self.ALL_TRAPS
continue
if line == "Usefuls:":
current_set = self.ALL_USEFULS
continue
if line == "Doors:":
current_set = self.ALL_DOOR_ITEMS
continue
if line == "":
continue

line_split = line.split(" - ")

if current_set is self.ALL_USEFULS:
current_set.add((line_split[1], int(line_split[0]), line_split[2] == "True"))
elif current_set is self.ALL_DOOR_ITEMS:
new_door = (line_split[1], int(line_split[0]), frozenset(line_split[2].split(",")))
current_set.add(new_door)
self.ALL_DOOR_ITEMS_AS_DICT[line_split[1]] = new_door
else:
if len(line_split) > 2:
progressive_items = line_split[2].split(",")
for i, value in enumerate(progressive_items):
self.ITEMS_TO_PROGRESSIVE[value] = line_split[1]
self.PROGRESSIVE_TO_ITEMS[line_split[1]] = progressive_items
current_set.add((line_split[1], int(line_split[0])))
continue
lines = get_items()
current_set = self.ALL_SYMBOL_ITEMS

for line in lines:
if line == "Progression:":
current_set = self.ALL_SYMBOL_ITEMS
continue
if line == "Boosts:":
current_set = self.ALL_BOOSTS
continue
if line == "Traps:":
current_set = self.ALL_TRAPS
continue
if line == "Usefuls:":
current_set = self.ALL_USEFULS
continue
if line == "Doors:":
current_set = self.ALL_DOOR_ITEMS
continue
if line == "":
continue

line_split = line.split(" - ")

if current_set is self.ALL_USEFULS:
current_set.add((line_split[1], int(line_split[0]), line_split[2] == "True"))
elif current_set is self.ALL_DOOR_ITEMS:
new_door = (line_split[1], int(line_split[0]), frozenset(line_split[2].split(",")))
current_set.add(new_door)
self.ALL_DOOR_ITEMS_AS_DICT[line_split[1]] = new_door
else:
if len(line_split) > 2:
progressive_items = line_split[2].split(",")
for i, value in enumerate(progressive_items):
self.ITEMS_TO_PROGRESSIVE[value] = line_split[1]
self.PROGRESSIVE_TO_ITEMS[line_split[1]] = progressive_items
current_set.add((line_split[1], int(line_split[0])))
continue
current_set.add((line_split[1], int(line_split[0])))

@lazy
def sigma_expert(self) -> StaticWitnessLogicObj:
Expand Down
40 changes: 34 additions & 6 deletions worlds/witness/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from itertools import accumulate
from typing import *
from fractions import Fraction
from collections import Counter
from pkgutil import get_data


def make_warning_string(any_j: bool, any_u: bool, any_d: bool, all_j: bool, all_u: bool, all_d: bool) -> str:
Expand Down Expand Up @@ -142,10 +142,8 @@ def __get__(self, instance, class_):


def get_adjustment_file(adjustment_file):
path = os.path.join(os.path.dirname(__file__), adjustment_file)

with open(path) as f:
return [line.strip() for line in f.readlines()]
data = get_data(__name__, adjustment_file).decode('utf-8')
return [line.strip() for line in data.split("\n")]


@cache_argsless
Expand Down Expand Up @@ -225,4 +223,34 @@ def get_ep_no_mountain():

@cache_argsless
def get_ep_no_videos():
return get_adjustment_file("settings/EP_Shuffle/EP_Videos.txt")
return get_adjustment_file("settings/EP_Shuffle/EP_Videos.txt")


@cache_argsless
def get_sigma_normal_logic():
return get_adjustment_file("WitnessLogic.txt")


@cache_argsless
def get_sigma_expert_logic():
return get_adjustment_file("WitnessLogicExpert.txt")


@cache_argsless
def get_vanilla_logic():
return get_adjustment_file("WitnessLogicVanilla.txt")


@cache_argsless
def get_items():
return get_adjustment_file("WitnessItems.txt")


def get_logic_file(filepath: str):
if filepath == "WitnessLogic.txt":
return get_sigma_normal_logic()
if filepath == "WitnessLogicExpert.txt":
return get_sigma_expert_logic()
if filepath == "WitnessLogicVanilla.txt":
return get_vanilla_logic
return get_adjustment_file(filepath)

0 comments on commit 46b13e0

Please sign in to comment.