* Blasphemous: WIP overhaul * Entrance rule mistake * stuff * Getting closer * Real?? Maybe?? * Don't fail me now 🙏 * Add starting location tests * More tests (it still doesn't work actually 😔) * REAL * Add unreachable regions to test_reachability.py * PR ready - Remove unused functions from init - Use group exclusive functions in rules - Style changes * Bump required client version * Clean up unused imports * Change slot data * Review fixes - Prevent strength calculations from including excess items - Add new lines to ends of files - Fix missed deprecated option and random usage in init * Update option docstrings, add groups * Add preprocessor files * Update option docstrings again actually * Update player strength calculation * Rename group methods * Fix missing logic for RESCUED_CHERUB_06 * Register indirect conditions * Register indirect conditions (part 2) * Update extracted logic, change slot data key * Add region to excluded list * A capital letter * Use camelCase keys in preprocessor * Write some of new setup guide * Remove indents before list points * Change locationinfo to list of dictonaries * Finish docs, update extractor config and data * Mark region_data.py as generated * Suggested changes * More suggested changes * Suggested changes again - Use OptionError - Create list of disabled locations before looping - Check if options are equal to str instead of int - Clean up start location override - Reword some of setup guide - Organize location list - Remove unnecessary escaped quotes from option docstrings - Add world type to test base * C# moment * Requested changes * Update .gitattributes --------- Co-authored-by: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com>
		
			
				
	
	
		
			583 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			583 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
# Preprocessor to convert Blasphemous Randomizer logic into a StringWorldDefinition for use with APHKLogicExtractor
 | 
						|
# https://github.com/BrandenEK/Blasphemous.Randomizer
 | 
						|
# https://github.com/ArchipelagoMW-HollowKnight/APHKLogicExtractor
 | 
						|
 | 
						|
 | 
						|
import json, requests, argparse
 | 
						|
from typing import List, Dict, Any
 | 
						|
 | 
						|
 | 
						|
def load_resource_local(file: str) -> List[Dict[str, Any]]:
 | 
						|
    print(f"Reading from {file}")
 | 
						|
    loaded = []
 | 
						|
    with open(file, encoding="utf-8") as f:
 | 
						|
        loaded = read_json(f.readlines())
 | 
						|
        f.close()
 | 
						|
 | 
						|
    return loaded
 | 
						|
 | 
						|
 | 
						|
def load_resource_from_web(url: str) -> List[Dict[str, Any]]:
 | 
						|
    req = requests.get(url, timeout=1)
 | 
						|
    print(f"Reading from {url}")
 | 
						|
    req.encoding = "utf-8"
 | 
						|
    lines: List[str] = []
 | 
						|
    for line in req.text.splitlines():
 | 
						|
        while "\t" in line:
 | 
						|
            line = line[1::]
 | 
						|
        if line != "":
 | 
						|
            lines.append(line)
 | 
						|
    return read_json(lines)
 | 
						|
 | 
						|
 | 
						|
def read_json(lines: List[str]) -> List[Dict[str, Any]]:
 | 
						|
    loaded = []
 | 
						|
    creating_object: bool = False
 | 
						|
    obj: str = ""
 | 
						|
    for line in lines:
 | 
						|
        stripped = line.strip()
 | 
						|
        if "{" in stripped:
 | 
						|
            creating_object = True
 | 
						|
            obj += stripped
 | 
						|
            continue
 | 
						|
        elif "}," in stripped or "}" in stripped and "]" in lines[lines.index(line)+1]:
 | 
						|
            creating_object = False
 | 
						|
            obj += "}"
 | 
						|
            #print(f"obj = {obj}")
 | 
						|
            loaded.append(json.loads(obj))
 | 
						|
            obj = ""
 | 
						|
            continue
 | 
						|
 | 
						|
        if not creating_object:
 | 
						|
            continue
 | 
						|
        else:
 | 
						|
            try:
 | 
						|
                if "}," in lines[lines.index(line)+1] and stripped[-1] == ",":
 | 
						|
                    obj += stripped[:-1]
 | 
						|
                else:
 | 
						|
                    obj += stripped
 | 
						|
            except IndexError:
 | 
						|
                obj += stripped
 | 
						|
 | 
						|
    return loaded
 | 
						|
 | 
						|
 | 
						|
def get_room_from_door(door: str) -> str:
 | 
						|
    return door[:door.find("[")]
 | 
						|
 | 
						|
 | 
						|
def preprocess_logic(is_door: bool, id: str, logic: str) -> str:
 | 
						|
    if id in logic and not is_door:
 | 
						|
        index: int = logic.find(id)
 | 
						|
        logic = logic[:index] + logic[index+len(id)+4:]
 | 
						|
 | 
						|
    while ">=" in logic:
 | 
						|
        index: int = logic.find(">=")
 | 
						|
        logic = logic[:index-1] + logic[index+3:]
 | 
						|
 | 
						|
    while ">" in logic:
 | 
						|
        index: int = logic.find(">")
 | 
						|
        count = int(logic[index+2])
 | 
						|
        count += 1
 | 
						|
        logic = logic[:index-1] + str(count) + logic[index+3:]
 | 
						|
 | 
						|
    while "<=" in logic:
 | 
						|
        index: int = logic.find("<=")
 | 
						|
        logic = logic[:index-1] + logic[index+3:]
 | 
						|
    
 | 
						|
    while "<" in logic:
 | 
						|
        index: int = logic.find("<")
 | 
						|
        count = int(logic[index+2])
 | 
						|
        count += 1
 | 
						|
        logic = logic[:index-1] + str(count) + logic[index+3:]
 | 
						|
 | 
						|
    #print(logic)
 | 
						|
    return logic
 | 
						|
 | 
						|
 | 
						|
def build_logic_conditions(logic: str) -> List[List[str]]:
 | 
						|
    all_conditions: List[List[str]] = []
 | 
						|
 | 
						|
    parts = logic.split()
 | 
						|
    sub_part: str = ""
 | 
						|
    current_index: int = 0
 | 
						|
    parens: int = -1
 | 
						|
    current_condition: List[str] = []
 | 
						|
    parens_conditions: List[List[List[str]]] = []
 | 
						|
 | 
						|
    for index, part in enumerate(parts):
 | 
						|
        #print(current_index, index, parens, part)
 | 
						|
 | 
						|
        # skip parts that have already been handled
 | 
						|
        if index < current_index:
 | 
						|
            continue
 | 
						|
 | 
						|
        # break loop if reached final part
 | 
						|
        try:
 | 
						|
            parts[index+1]
 | 
						|
        except IndexError:
 | 
						|
            #print("INDEXERROR", part)
 | 
						|
            if parens < 0:
 | 
						|
                current_condition.append(part)
 | 
						|
                if len(parens_conditions) > 0:
 | 
						|
                    for i in parens_conditions:
 | 
						|
                        for j in i:
 | 
						|
                            all_conditions.append(j + current_condition)
 | 
						|
                else:
 | 
						|
                    all_conditions.append(current_condition)
 | 
						|
                break
 | 
						|
 | 
						|
        #print(current_condition, parens, sub_part)
 | 
						|
 | 
						|
        # prepare for subcondition
 | 
						|
        if "(" in part:
 | 
						|
            # keep track of nested parentheses
 | 
						|
            if parens == -1:
 | 
						|
                parens = 0
 | 
						|
            for char in part:
 | 
						|
                if char == "(":
 | 
						|
                    parens += 1
 | 
						|
            
 | 
						|
            # add to sub part
 | 
						|
            if sub_part == "":
 | 
						|
                sub_part = part
 | 
						|
            else:
 | 
						|
                sub_part += f" {part}"
 | 
						|
            #if not ")" in part:
 | 
						|
            continue
 | 
						|
 | 
						|
        # end of subcondition
 | 
						|
        if ")" in part:
 | 
						|
            # read every character in case of multiple closing parentheses
 | 
						|
            for char in part:
 | 
						|
                if char == ")":
 | 
						|
                    parens -= 1
 | 
						|
 | 
						|
            sub_part += f" {part}"
 | 
						|
 | 
						|
            # if reached end of parentheses, handle subcondition
 | 
						|
            if parens == 0:
 | 
						|
                #print(current_condition, sub_part)
 | 
						|
                parens = -1
 | 
						|
 | 
						|
                try:
 | 
						|
                    parts[index+1]
 | 
						|
                except IndexError:
 | 
						|
                    #print("END OF LOGIC")
 | 
						|
                    if len(parens_conditions) > 0:
 | 
						|
                        parens_conditions.append(build_logic_subconditions(current_condition, sub_part))
 | 
						|
                        #print("PARENS:", parens_conditions)
 | 
						|
 | 
						|
                        temp_conditions: List[List[str]] = []
 | 
						|
 | 
						|
                        for i in parens_conditions[0]:
 | 
						|
                            for j in parens_conditions[1]:
 | 
						|
                                temp_conditions.append(i + j)
 | 
						|
 | 
						|
                        parens_conditions.pop(0)
 | 
						|
                        parens_conditions.pop(0)
 | 
						|
 | 
						|
                        while len(parens_conditions) > 0:
 | 
						|
                            temp_conditions2 = temp_conditions
 | 
						|
                            temp_conditions = []
 | 
						|
                            for k in temp_conditions2:
 | 
						|
                                for l in parens_conditions[0]:
 | 
						|
                                    temp_conditions.append(k + l)
 | 
						|
                            
 | 
						|
                            parens_conditions.pop(0)
 | 
						|
 | 
						|
                        #print("TEMP:", remove_duplicates(temp_conditions))
 | 
						|
                        all_conditions += temp_conditions
 | 
						|
                    else:
 | 
						|
                        all_conditions += build_logic_subconditions(current_condition, sub_part)
 | 
						|
                else:
 | 
						|
                    #print("NEXT PARTS:", parts[index+1], parts[index+2])
 | 
						|
                    if parts[index+1] == "&&":
 | 
						|
                        parens_conditions.append(build_logic_subconditions(current_condition, sub_part))
 | 
						|
                        #print("PARENS:", parens_conditions)
 | 
						|
                    else:
 | 
						|
                        if len(parens_conditions) > 0:
 | 
						|
                            parens_conditions.append(build_logic_subconditions(current_condition, sub_part))
 | 
						|
                            #print("PARENS:", parens_conditions)
 | 
						|
 | 
						|
                            temp_conditions: List[List[str]] = []
 | 
						|
 | 
						|
                            for i in parens_conditions[0]:
 | 
						|
                                for j in parens_conditions[1]:
 | 
						|
                                    temp_conditions.append(i + j)
 | 
						|
 | 
						|
                            parens_conditions.pop(0)
 | 
						|
                            parens_conditions.pop(0)
 | 
						|
 | 
						|
                            while len(parens_conditions) > 0:
 | 
						|
                                temp_conditions2 = temp_conditions
 | 
						|
                                temp_conditions = []
 | 
						|
                                for k in temp_conditions2:
 | 
						|
                                    for l in parens_conditions[0]:
 | 
						|
                                        temp_conditions.append(k + l)
 | 
						|
                                
 | 
						|
                                parens_conditions.pop(0)
 | 
						|
 | 
						|
                            #print("TEMP:", remove_duplicates(temp_conditions))
 | 
						|
                            all_conditions += temp_conditions
 | 
						|
                        else:
 | 
						|
                            all_conditions += build_logic_subconditions(current_condition, sub_part)
 | 
						|
 | 
						|
                    current_index = index+2
 | 
						|
                    
 | 
						|
                    current_condition = []
 | 
						|
                    sub_part = ""
 | 
						|
                    
 | 
						|
            continue
 | 
						|
 | 
						|
        # collect all parts until reaching end of parentheses
 | 
						|
        if parens > 0:
 | 
						|
            sub_part += f" {part}"
 | 
						|
            continue
 | 
						|
 | 
						|
        current_condition.append(part)
 | 
						|
 | 
						|
        # continue with current condition
 | 
						|
        if parts[index+1] == "&&":
 | 
						|
            current_index = index+2
 | 
						|
            continue
 | 
						|
        
 | 
						|
        # add condition to list and start new one
 | 
						|
        elif parts[index+1] == "||":
 | 
						|
            if len(parens_conditions) > 0:
 | 
						|
                for i in parens_conditions:
 | 
						|
                    for j in i:
 | 
						|
                        all_conditions.append(j + current_condition)
 | 
						|
                parens_conditions = []
 | 
						|
            else:    
 | 
						|
                all_conditions.append(current_condition)
 | 
						|
            current_condition = []
 | 
						|
            current_index = index+2
 | 
						|
            continue
 | 
						|
        
 | 
						|
    return remove_duplicates(all_conditions)
 | 
						|
 | 
						|
 | 
						|
def build_logic_subconditions(current_condition: List[str], subcondition: str) -> List[List[str]]:
 | 
						|
    #print("STARTED SUBCONDITION", current_condition, subcondition)
 | 
						|
    subconditions = build_logic_conditions(subcondition[1:-1])
 | 
						|
    final_conditions = []
 | 
						|
 | 
						|
    for condition in subconditions:
 | 
						|
        final_condition = current_condition + condition
 | 
						|
        final_conditions.append(final_condition)
 | 
						|
 | 
						|
    #print("ENDED SUBCONDITION")
 | 
						|
    #print(final_conditions)
 | 
						|
    return final_conditions
 | 
						|
 | 
						|
 | 
						|
def remove_duplicates(conditions: List[List[str]]) -> List[List[str]]:
 | 
						|
    final_conditions: List[List[str]] = []
 | 
						|
    for condition in conditions:
 | 
						|
        final_conditions.append(list(dict.fromkeys(condition)))
 | 
						|
 | 
						|
    return final_conditions
 | 
						|
 | 
						|
 | 
						|
def handle_door_visibility(door: Dict[str, Any]) -> Dict[str, Any]:
 | 
						|
    if door.get("visibilityFlags") == None:
 | 
						|
        return door
 | 
						|
    else:
 | 
						|
        flags: List[str] = str(door.get("visibilityFlags")).split(", ")
 | 
						|
        #print(flags)
 | 
						|
        temp_flags: List[str] = []
 | 
						|
        this_door: bool = False
 | 
						|
        #required_doors: str = ""
 | 
						|
 | 
						|
        if "ThisDoor" in flags:
 | 
						|
            this_door = True
 | 
						|
 | 
						|
        #if "requiredDoors" in flags:
 | 
						|
        #    required_doors: str = " || ".join(door.get("requiredDoors"))
 | 
						|
 | 
						|
        if "DoubleJump" in flags:
 | 
						|
            temp_flags.append("DoubleJump")
 | 
						|
 | 
						|
        if "NormalLogic" in flags:
 | 
						|
            temp_flags.append("NormalLogic")
 | 
						|
 | 
						|
        if "NormalLogicAndDoubleJump" in flags:
 | 
						|
            temp_flags.append("NormalLogicAndDoubleJump")
 | 
						|
 | 
						|
        if "HardLogic" in flags:
 | 
						|
            temp_flags.append("HardLogic")
 | 
						|
 | 
						|
        if "HardLogicAndDoubleJump" in flags:
 | 
						|
            temp_flags.append("HardLogicAndDoubleJump")
 | 
						|
 | 
						|
        if "EnemySkips" in flags:
 | 
						|
            temp_flags.append("EnemySkips")
 | 
						|
 | 
						|
        if "EnemySkipsAndDoubleJump" in flags:
 | 
						|
            temp_flags.append("EnemySkipsAndDoubleJump")
 | 
						|
 | 
						|
        # remove duplicates
 | 
						|
        temp_flags = list(dict.fromkeys(temp_flags))
 | 
						|
 | 
						|
        original_logic: str = door.get("logic")
 | 
						|
        temp_logic: str = ""
 | 
						|
 | 
						|
        if this_door:
 | 
						|
            temp_logic = door.get("id")
 | 
						|
 | 
						|
        if temp_flags != []:
 | 
						|
            if temp_logic != "":
 | 
						|
                temp_logic += " || "
 | 
						|
            temp_logic += ' && '.join(temp_flags)
 | 
						|
 | 
						|
        if temp_logic != "" and original_logic != None:
 | 
						|
            if len(original_logic.split()) == 1:
 | 
						|
                if len(temp_logic.split()) == 1:
 | 
						|
                    door["logic"] = f"{temp_logic} && {original_logic}"
 | 
						|
                else:
 | 
						|
                    door["logic"] = f"({temp_logic}) && {original_logic}"
 | 
						|
            else:
 | 
						|
                if len(temp_logic.split()) == 1:
 | 
						|
                    door["logic"] = f"{temp_logic} && ({original_logic})"
 | 
						|
                else:
 | 
						|
                    door["logic"] = f"({temp_logic}) && ({original_logic})"
 | 
						|
        elif temp_logic != "" and original_logic == None:
 | 
						|
            door["logic"] = temp_logic
 | 
						|
        
 | 
						|
        return door
 | 
						|
 | 
						|
 | 
						|
def get_state_provider_for_condition(condition: List[str]) -> str:
 | 
						|
    for item in condition:
 | 
						|
        if (item[0] == "D" and item[3] == "Z" and item[6] == "S")\
 | 
						|
        or (item[0] == "D" and item[3] == "B" and item[4] == "Z" and item[7] == "S"):
 | 
						|
            return item
 | 
						|
    return None
 | 
						|
 | 
						|
 | 
						|
def parse_args() -> argparse.Namespace:
 | 
						|
    parser = argparse.ArgumentParser()
 | 
						|
    parser.add_argument('-l', '--local', action="store_true", help="Use local files in the same directory instead of reading resource files from the BrandenEK/Blasphemous-Randomizer repository.")
 | 
						|
    args = parser.parse_args()
 | 
						|
    return args
 | 
						|
 | 
						|
 | 
						|
def main(args: argparse.Namespace):
 | 
						|
    doors = []
 | 
						|
    locations = []
 | 
						|
 | 
						|
    if (args.local):
 | 
						|
        doors = load_resource_local("doors.json")
 | 
						|
        locations = load_resource_local("locations_items.json")
 | 
						|
    
 | 
						|
    else:
 | 
						|
        doors = load_resource_from_web("https://raw.githubusercontent.com/BrandenEK/Blasphemous-Randomizer/main/resources/data/Randomizer/doors.json")
 | 
						|
        locations = load_resource_from_web("https://raw.githubusercontent.com/BrandenEK/Blasphemous-Randomizer/main/resources/data/Randomizer/locations_items.json")
 | 
						|
 | 
						|
    original_connections: Dict[str, str] = {}
 | 
						|
    rooms: Dict[str, List[str]] = {}
 | 
						|
    output: Dict[str, Any] = {}
 | 
						|
    logic_objects: List[Dict[str, Any]] = []
 | 
						|
 | 
						|
    for door in doors:
 | 
						|
         if door.get("originalDoor") != None:
 | 
						|
            if not door.get("id") in original_connections:
 | 
						|
                original_connections[door.get("id")] = door.get("originalDoor")
 | 
						|
                original_connections[door.get("originalDoor")] = door.get("id")
 | 
						|
 | 
						|
            room: str = get_room_from_door(door.get("originalDoor"))
 | 
						|
            if not room in rooms.keys():
 | 
						|
                rooms[room] = [door.get("id")]
 | 
						|
            else:
 | 
						|
                rooms[room].append(door.get("id"))
 | 
						|
 | 
						|
    def flip_doors_in_condition(condition: List[str]) -> List[str]:
 | 
						|
        new_condition = []
 | 
						|
        for item in condition:
 | 
						|
            if item in original_connections:
 | 
						|
                new_condition.append(original_connections[item])
 | 
						|
            else:
 | 
						|
                new_condition.append(item)
 | 
						|
 | 
						|
        return new_condition
 | 
						|
    
 | 
						|
    for room in rooms.keys():
 | 
						|
        obj = {
 | 
						|
            "Name": room,
 | 
						|
            "Logic": [],
 | 
						|
            "Handling": "Default"
 | 
						|
        }
 | 
						|
 | 
						|
        for door in rooms[room]:
 | 
						|
            logic = {
 | 
						|
                "StateProvider": door,
 | 
						|
                "Conditions": [],
 | 
						|
                "StateModifiers": []
 | 
						|
            }
 | 
						|
            obj["Logic"].append(logic)
 | 
						|
        
 | 
						|
        logic_objects.append(obj)
 | 
						|
 | 
						|
    for door in doors:
 | 
						|
        if door.get("direction") == 5:
 | 
						|
            continue
 | 
						|
 | 
						|
        handling: str = "Transition"
 | 
						|
        if "Cell" in door.get("id"):
 | 
						|
            handling = "Default"
 | 
						|
        obj = {
 | 
						|
            "Name": door.get("id"),
 | 
						|
            "Logic": [],
 | 
						|
            "Handling": handling
 | 
						|
        }
 | 
						|
 | 
						|
        visibility_flags: List[str] = []
 | 
						|
        if door.get("visibilityFlags") != None:
 | 
						|
            visibility_flags = str(door.get("visibilityFlags")).split(", ")
 | 
						|
            if "1" in visibility_flags:
 | 
						|
                visibility_flags.remove("1")
 | 
						|
                visibility_flags.append("ThisDoor")
 | 
						|
 | 
						|
        required_doors: List[str] = []
 | 
						|
        if door.get("requiredDoors"):
 | 
						|
            required_doors = door.get("requiredDoors")
 | 
						|
 | 
						|
        if len(visibility_flags) > 0:
 | 
						|
            for flag in visibility_flags:
 | 
						|
                if flag == "RequiredDoors":
 | 
						|
                    continue
 | 
						|
 | 
						|
                if flag == "ThisDoor":
 | 
						|
                    flag = original_connections[door.get("id")]
 | 
						|
                
 | 
						|
                if door.get("logic") != None:
 | 
						|
                    logic: str = door.get("logic")
 | 
						|
                    logic = f"{flag} && ({logic})"
 | 
						|
                    logic = preprocess_logic(True, door.get("id"), logic)
 | 
						|
                    conditions = build_logic_conditions(logic)
 | 
						|
                    for condition in conditions:
 | 
						|
                        condition = flip_doors_in_condition(condition)
 | 
						|
                        state_provider: str = get_room_from_door(door.get("id"))
 | 
						|
 | 
						|
                        if get_state_provider_for_condition(condition) != None:
 | 
						|
                            state_provider = get_state_provider_for_condition(condition)
 | 
						|
                            condition.remove(state_provider)
 | 
						|
 | 
						|
                        logic = {
 | 
						|
                            "StateProvider": state_provider,
 | 
						|
                            "Conditions": condition,
 | 
						|
                            "StateModifiers": []
 | 
						|
                        }
 | 
						|
                        obj["Logic"].append(logic)
 | 
						|
                else:
 | 
						|
                    logic = {
 | 
						|
                        "StateProvider": get_room_from_door(door.get("id")),
 | 
						|
                        "Conditions": [flag],
 | 
						|
                        "StateModifiers": []
 | 
						|
                    }
 | 
						|
                    obj["Logic"].append(logic)
 | 
						|
            
 | 
						|
            if "RequiredDoors" in visibility_flags:
 | 
						|
                for d in required_doors:
 | 
						|
                    flipped = original_connections[d]
 | 
						|
                    if door.get("logic") != None:
 | 
						|
                        logic: str = preprocess_logic(True, door.get("id"), door.get("logic"))
 | 
						|
                        conditions = build_logic_conditions(logic)
 | 
						|
                        for condition in conditions:
 | 
						|
                            condition = flip_doors_in_condition(condition)
 | 
						|
                            state_provider: str = flipped
 | 
						|
 | 
						|
                            if flipped in condition:
 | 
						|
                                condition.remove(flipped)
 | 
						|
 | 
						|
                            logic = {
 | 
						|
                                "StateProvider": state_provider,
 | 
						|
                                "Conditions": condition,
 | 
						|
                                "StateModifiers": []
 | 
						|
                            }
 | 
						|
                            obj["Logic"].append(logic)
 | 
						|
                    else:
 | 
						|
                        logic = {
 | 
						|
                            "StateProvider": flipped,
 | 
						|
                            "Conditions": [],
 | 
						|
                            "StateModifiers": []
 | 
						|
                        }
 | 
						|
                        obj["Logic"].append(logic)
 | 
						|
 | 
						|
        else:
 | 
						|
            if door.get("logic") != None:
 | 
						|
                logic: str = preprocess_logic(True, door.get("id"), door.get("logic"))
 | 
						|
                conditions = build_logic_conditions(logic)
 | 
						|
                for condition in conditions:
 | 
						|
                    condition = flip_doors_in_condition(condition)
 | 
						|
                    stateProvider: str = get_room_from_door(door.get("id"))
 | 
						|
 | 
						|
                    if get_state_provider_for_condition(condition) != None:
 | 
						|
                        stateProvider = get_state_provider_for_condition(condition)
 | 
						|
                        condition.remove(stateProvider)
 | 
						|
 | 
						|
                    logic = {
 | 
						|
                        "StateProvider": stateProvider,
 | 
						|
                        "Conditions": condition,
 | 
						|
                        "StateModifiers": []
 | 
						|
                    }
 | 
						|
                    obj["Logic"].append(logic)
 | 
						|
            else:
 | 
						|
                logic = {
 | 
						|
                    "StateProvider": get_room_from_door(door.get("id")),
 | 
						|
                    "Conditions": [],
 | 
						|
                    "StateModifiers": []
 | 
						|
                }
 | 
						|
                obj["Logic"].append(logic)
 | 
						|
 | 
						|
        logic_objects.append(obj)
 | 
						|
 | 
						|
    for location in locations:
 | 
						|
        obj = {
 | 
						|
            "Name": location.get("id"),
 | 
						|
            "Logic": [],
 | 
						|
            "Handling": "Location"
 | 
						|
        }
 | 
						|
 | 
						|
        if location.get("logic") != None:
 | 
						|
            for condition in build_logic_conditions(preprocess_logic(False, location.get("id"), location.get("logic"))):
 | 
						|
                condition = flip_doors_in_condition(condition)
 | 
						|
                stateProvider: str = location.get("room")
 | 
						|
 | 
						|
                if get_state_provider_for_condition(condition) != None:
 | 
						|
                    stateProvider = get_state_provider_for_condition(condition)
 | 
						|
                    condition.remove(stateProvider)
 | 
						|
 | 
						|
                if stateProvider == "Initial":
 | 
						|
                    stateProvider = None
 | 
						|
 | 
						|
                logic = {
 | 
						|
                    "StateProvider": stateProvider,
 | 
						|
                    "Conditions": condition,
 | 
						|
                    "StateModifiers": []
 | 
						|
                }
 | 
						|
                obj["Logic"].append(logic)
 | 
						|
        else:
 | 
						|
            stateProvider: str = location.get("room")
 | 
						|
            if stateProvider == "Initial":
 | 
						|
                stateProvider = None
 | 
						|
            logic = {
 | 
						|
                "StateProvider": stateProvider,
 | 
						|
                "Conditions": [],
 | 
						|
                "StateModifiers": []
 | 
						|
            }
 | 
						|
            obj["Logic"].append(logic)
 | 
						|
 | 
						|
        logic_objects.append(obj)
 | 
						|
 | 
						|
    output["LogicObjects"] = logic_objects
 | 
						|
        
 | 
						|
    with open("StringWorldDefinition.json", "w") as file:
 | 
						|
        print("Writing to StringWorldDefinition.json")
 | 
						|
        file.write(json.dumps(output, indent=4))
 | 
						|
 | 
						|
 | 
						|
if __name__ == "__main__":
 | 
						|
    main(parse_args())
 |