SM and SMZ3 apworld support (#1677)

This commit is contained in:
lordlou 2023-04-08 16:52:34 -04:00 committed by GitHub
parent f4035b8621
commit 84402a1b55
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
86 changed files with 522 additions and 445 deletions

View File

@ -72,6 +72,8 @@ apworlds: set = {
"Minecraft", "Minecraft",
"The Messenger", "The Messenger",
"Links Awakening DX", "Links Awakening DX",
"Super Metroid",
"SMZ3",
} }

View File

@ -118,7 +118,7 @@ class SMSNIClient(SNIClient):
snes_buffered_write(ctx, SM_SEND_QUEUE_RCOUNT, snes_buffered_write(ctx, SM_SEND_QUEUE_RCOUNT,
bytes([recv_index & 0xFF, (recv_index >> 8) & 0xFF])) bytes([recv_index & 0xFF, (recv_index >> 8) & 0xFF]))
from worlds.sm import locations_start_id from . import locations_start_id
location_id = locations_start_id + item_index location_id = locations_start_id + item_index
ctx.locations_checked.add(location_id) ctx.locations_checked.add(location_id)
@ -133,8 +133,8 @@ class SMSNIClient(SNIClient):
item_out_ptr = data[0] | (data[1] << 8) item_out_ptr = data[0] | (data[1] << 8)
from worlds.sm import items_start_id from . import items_start_id
from worlds.sm import locations_start_id from . import locations_start_id
if item_out_ptr < len(ctx.items_received): if item_out_ptr < len(ctx.items_received):
item = ctx.items_received[item_out_ptr] item = ctx.items_received[item_out_ptr]
item_id = item.item - items_start_id item_id = item.item - items_start_id

View File

@ -1,8 +1,8 @@
def create_regions(self, world, player: int): def create_regions(self, world, player: int):
from . import create_region from . import create_region
from BaseClasses import Entrance from BaseClasses import Entrance
from worlds.sm.variaRandomizer.logic.logic import Logic from .variaRandomizer.logic.logic import Logic
from worlds.sm.variaRandomizer.graph.vanilla.graph_locations import locationsDict from .variaRandomizer.graph.vanilla.graph_locations import locationsDict
regions = [] regions = []
for accessPoint in Logic.accessPoints: for accessPoint in Logic.accessPoints:

View File

@ -5,6 +5,7 @@ import json
import Utils import Utils
from Utils import read_snes_rom from Utils import read_snes_rom
from worlds.Files import APDeltaPatch from worlds.Files import APDeltaPatch
from .variaRandomizer.utils.utils import openFile
SMJUHASH = '21f3e98df4780ee1c667b84e57d88675' SMJUHASH = '21f3e98df4780ee1c667b84e57d88675'
SM_ROM_MAX_PLAYERID = 65535 SM_ROM_MAX_PLAYERID = 65535
@ -43,7 +44,7 @@ def get_base_rom_path(file_name: str = "") -> str:
return file_name return file_name
def get_sm_symbols(sym_json_path) -> dict: def get_sm_symbols(sym_json_path) -> dict:
with open(sym_json_path, "r") as stream: with openFile(sym_json_path, "r") as stream:
symbols = json.load(stream) symbols = json.load(stream)
symboltable = {} symboltable = {}
for name, sixdigitaddr in symbols.items(): for name, sixdigitaddr in symbols.items():

View File

@ -1,7 +1,7 @@
from ..generic.Rules import set_rule, add_rule from worlds.generic.Rules import set_rule, add_rule
from worlds.sm.variaRandomizer.graph.vanilla.graph_locations import locationsDict from .variaRandomizer.graph.vanilla.graph_locations import locationsDict
from worlds.sm.variaRandomizer.logic.logic import Logic from .variaRandomizer.logic.logic import Logic
def evalSMBool(smbool, maxDiff): def evalSMBool(smbool, maxDiff):
return smbool.bool == True and smbool.difficulty <= maxDiff return smbool.bool == True and smbool.difficulty <= maxDiff

View File

@ -7,6 +7,9 @@ import threading
import base64 import base64
from typing import Any, Dict, Iterable, List, Set, TextIO, TypedDict from typing import Any, Dict, Iterable, List, Set, TextIO, TypedDict
from BaseClasses import Region, Entrance, Location, MultiWorld, Item, ItemClassification, CollectionState, Tutorial
from worlds.AutoWorld import World, AutoLogicRegister, WebWorld
logger = logging.getLogger("Super Metroid") logger = logging.getLogger("Super Metroid")
from .Regions import create_regions from .Regions import create_regions
@ -16,20 +19,18 @@ from .Client import SMSNIClient
from .Rom import get_base_rom_path, SM_ROM_MAX_PLAYERID, SM_ROM_PLAYERDATA_COUNT, SMDeltaPatch, get_sm_symbols from .Rom import get_base_rom_path, SM_ROM_MAX_PLAYERID, SM_ROM_PLAYERDATA_COUNT, SMDeltaPatch, get_sm_symbols
import Utils import Utils
from BaseClasses import Region, Entrance, Location, MultiWorld, Item, ItemClassification, CollectionState, Tutorial from .variaRandomizer.logic.smboolmanager import SMBoolManager
from ..AutoWorld import World, AutoLogicRegister, WebWorld from .variaRandomizer.graph.vanilla.graph_locations import locationsDict
from .variaRandomizer.graph.graph_utils import getAccessPoint
from worlds.sm.variaRandomizer.logic.smboolmanager import SMBoolManager from .variaRandomizer.rando.ItemLocContainer import ItemLocation
from worlds.sm.variaRandomizer.graph.vanilla.graph_locations import locationsDict from .variaRandomizer.rando.Items import ItemManager
from worlds.sm.variaRandomizer.graph.graph_utils import getAccessPoint from .variaRandomizer.utils.parameters import *
from worlds.sm.variaRandomizer.rando.ItemLocContainer import ItemLocation from .variaRandomizer.utils.utils import openFile
from worlds.sm.variaRandomizer.rando.Items import ItemManager from .variaRandomizer.logic.logic import Logic
from worlds.sm.variaRandomizer.utils.parameters import * from .variaRandomizer.randomizer import VariaRandomizer
from worlds.sm.variaRandomizer.logic.logic import Logic from .variaRandomizer.utils.doorsmanager import DoorsManager
from worlds.sm.variaRandomizer.randomizer import VariaRandomizer from .variaRandomizer.rom.rom_patches import RomPatches
from worlds.sm.variaRandomizer.utils.doorsmanager import DoorsManager from .variaRandomizer.graph.graph_utils import GraphUtils
from worlds.sm.variaRandomizer.rom.rom_patches import RomPatches
from worlds.sm.variaRandomizer.graph.graph_utils import GraphUtils
class SMCollectionState(metaclass=AutoLogicRegister): class SMCollectionState(metaclass=AutoLogicRegister):
@ -279,14 +280,14 @@ class SMWorld(World):
# first apply the sm multiworld code patch named 'basepatch' (also has empty tables that we'll overwrite), # first apply the sm multiworld code patch named 'basepatch' (also has empty tables that we'll overwrite),
# + apply some patches from varia that we want to be always-on. # + apply some patches from varia that we want to be always-on.
# basepatch and variapatches are both generated from https://github.com/lordlou/SMBasepatch # basepatch and variapatches are both generated from https://github.com/lordlou/SMBasepatch
romPatcher.applyIPSPatch(os.path.join(os.path.dirname(__file__), romPatcher.applyIPSPatch("/".join((os.path.dirname(self.__file__),
"data", "SMBasepatch_prebuilt", "multiworld-basepatch.ips")) "data", "SMBasepatch_prebuilt", "multiworld-basepatch.ips")))
romPatcher.applyIPSPatch(os.path.join(os.path.dirname(__file__), romPatcher.applyIPSPatch("/".join((os.path.dirname(self.__file__),
"data", "SMBasepatch_prebuilt", "variapatches.ips")) "data", "SMBasepatch_prebuilt", "variapatches.ips")))
def APPostPatchRom(self, romPatcher): def APPostPatchRom(self, romPatcher):
symbols = get_sm_symbols(os.path.join(os.path.dirname(__file__), symbols = get_sm_symbols("/".join((os.path.dirname(self.__file__),
"data", "SMBasepatch_prebuilt", "sm-basepatch-symbols.json")) "data", "SMBasepatch_prebuilt", "sm-basepatch-symbols.json")))
# gather all player ids and names relevant to this rom, then write player name and player id data tables # gather all player ids and names relevant to this rom, then write player name and player id data tables
playerIdSet: Set[int] = {0} # 0 is for "Archipelago" server playerIdSet: Set[int] = {0} # 0 is for "Archipelago" server
@ -376,7 +377,7 @@ class SMWorld(World):
idx = 0 idx = 0
offworldSprites: List[ByteEdit] = [] offworldSprites: List[ByteEdit] = []
for itemSprite in itemSprites: for itemSprite in itemSprites:
with open(os.path.join(os.path.dirname(__file__), "data", "custom_sprite", itemSprite["fileName"]), 'rb') as stream: with openFile("/".join((os.path.dirname(self.__file__), "data", "custom_sprite", itemSprite["fileName"])), 'rb') as stream:
buffer = bytearray(stream.read()) buffer = bytearray(stream.read())
offworldSprites.append({"sym": symbols[itemSprite["paletteSymbolName"]], offworldSprites.append({"sym": symbols[itemSprite["paletteSymbolName"]],
"offset": 0, "offset": 0,

View File

@ -1,9 +1,9 @@
import copy, logging import copy, logging
from operator import attrgetter from operator import attrgetter
from worlds.sm.variaRandomizer.utils import log from ..utils import log
from worlds.sm.variaRandomizer.logic.smbool import SMBool, smboolFalse from ..logic.smbool import SMBool, smboolFalse
from worlds.sm.variaRandomizer.utils.parameters import infinity from ..utils.parameters import infinity
from worlds.sm.variaRandomizer.logic.helpers import Bosses from ..logic.helpers import Bosses
class Path(object): class Path(object):
__slots__ = ( 'path', 'pdiff', 'distance' ) __slots__ = ( 'path', 'pdiff', 'distance' )

View File

@ -1,10 +1,10 @@
import copy import copy
import random import random
from worlds.sm.variaRandomizer.logic.logic import Logic from ..logic.logic import Logic
from worlds.sm.variaRandomizer.utils.parameters import Knows from ..utils.parameters import Knows
from worlds.sm.variaRandomizer.graph.location import locationsDict from ..graph.location import locationsDict
from worlds.sm.variaRandomizer.rom.rom import snes_to_pc from ..rom.rom import snes_to_pc
from worlds.sm.variaRandomizer.utils import log from ..utils import log
# order expected by ROM patches # order expected by ROM patches
graphAreas = [ graphAreas = [

View File

@ -1,4 +1,4 @@
from worlds.sm.variaRandomizer.utils.parameters import infinity from ..utils.parameters import infinity
import copy import copy
class Location: class Location:

View File

@ -1,9 +1,9 @@
from worlds.sm.variaRandomizer.graph.graph import AccessPoint from ...graph.graph import AccessPoint
from worlds.sm.variaRandomizer.utils.parameters import Settings from ...utils.parameters import Settings
from worlds.sm.variaRandomizer.rom.rom_patches import RomPatches from ...rom.rom_patches import RomPatches
from worlds.sm.variaRandomizer.logic.smbool import SMBool from ...logic.smbool import SMBool
from worlds.sm.variaRandomizer.logic.helpers import Bosses from ...logic.helpers import Bosses
from worlds.sm.variaRandomizer.logic.cache import Cache from ...logic.cache import Cache
# all access points and traverse functions # all access points and traverse functions
accessPoints = [ accessPoints = [

View File

@ -1,11 +1,11 @@
from math import ceil from math import ceil
from worlds.sm.variaRandomizer.logic.smbool import SMBool from ...logic.smbool import SMBool
from worlds.sm.variaRandomizer.logic.helpers import Helpers, Bosses from ...logic.helpers import Helpers, Bosses
from worlds.sm.variaRandomizer.logic.cache import Cache from ...logic.cache import Cache
from worlds.sm.variaRandomizer.rom.rom_patches import RomPatches from ...rom.rom_patches import RomPatches
from worlds.sm.variaRandomizer.graph.graph_utils import getAccessPoint from ...graph.graph_utils import getAccessPoint
from worlds.sm.variaRandomizer.utils.parameters import Settings from ...utils.parameters import Settings
class HelpersGraph(Helpers): class HelpersGraph(Helpers):
def __init__(self, smbm): def __init__(self, smbm):

View File

@ -1,8 +1,8 @@
from worlds.sm.variaRandomizer.logic.helpers import Bosses from ...logic.helpers import Bosses
from worlds.sm.variaRandomizer.utils.parameters import Settings from ...utils.parameters import Settings
from worlds.sm.variaRandomizer.rom.rom_patches import RomPatches from ...rom.rom_patches import RomPatches
from worlds.sm.variaRandomizer.logic.smbool import SMBool from ...logic.smbool import SMBool
from worlds.sm.variaRandomizer.graph.location import locationsDict from ...graph.location import locationsDict
locationsDict["Energy Tank, Gauntlet"].AccessFrom = { locationsDict["Energy Tank, Gauntlet"].AccessFrom = {
'Landing Site': lambda sm: SMBool(True) 'Landing Site': lambda sm: SMBool(True)

View File

@ -1,11 +1,11 @@
import math import math
from worlds.sm.variaRandomizer.logic.cache import Cache from ..logic.cache import Cache
from worlds.sm.variaRandomizer.logic.smbool import SMBool, smboolFalse from ..logic.smbool import SMBool, smboolFalse
from worlds.sm.variaRandomizer.utils.parameters import Settings, easy, medium, diff2text from ..utils.parameters import Settings, easy, medium, diff2text
from worlds.sm.variaRandomizer.rom.rom_patches import RomPatches from ..rom.rom_patches import RomPatches
from worlds.sm.variaRandomizer.utils.utils import normalizeRounding from ..utils.utils import normalizeRounding
class Helpers(object): class Helpers(object):

View File

@ -4,20 +4,20 @@ class Logic(object):
@staticmethod @staticmethod
def factory(implementation): def factory(implementation):
if implementation == 'vanilla': if implementation == 'vanilla':
from worlds.sm.variaRandomizer.graph.vanilla.graph_helpers import HelpersGraph from ..graph.vanilla.graph_helpers import HelpersGraph
from worlds.sm.variaRandomizer.graph.vanilla.graph_access import accessPoints from ..graph.vanilla.graph_access import accessPoints
from worlds.sm.variaRandomizer.graph.vanilla.graph_locations import locations from ..graph.vanilla.graph_locations import locations
from worlds.sm.variaRandomizer.graph.vanilla.graph_locations import LocationsHelper from ..graph.vanilla.graph_locations import LocationsHelper
Logic.locations = locations Logic.locations = locations
Logic.accessPoints = accessPoints Logic.accessPoints = accessPoints
Logic.HelpersGraph = HelpersGraph Logic.HelpersGraph = HelpersGraph
Logic.patches = implementation Logic.patches = implementation
Logic.LocationsHelper = LocationsHelper Logic.LocationsHelper = LocationsHelper
elif implementation == 'rotation': elif implementation == 'rotation':
from worlds.sm.variaRandomizer.graph.rotation.graph_helpers import HelpersGraph from ..graph.rotation.graph_helpers import HelpersGraph
from worlds.sm.variaRandomizer.graph.rotation.graph_access import accessPoints from ..graph.rotation.graph_access import accessPoints
from worlds.sm.variaRandomizer.graph.rotation.graph_locations import locations from ..graph.rotation.graph_locations import locations
from worlds.sm.variaRandomizer.graph.rotation.graph_locations import LocationsHelper from ..graph.rotation.graph_locations import LocationsHelper
Logic.locations = locations Logic.locations = locations
Logic.accessPoints = accessPoints Logic.accessPoints = accessPoints
Logic.HelpersGraph = HelpersGraph Logic.HelpersGraph = HelpersGraph

View File

@ -1,11 +1,11 @@
# object to handle the smbools and optimize them # object to handle the smbools and optimize them
from worlds.sm.variaRandomizer.logic.cache import Cache from ..logic.cache import Cache
from worlds.sm.variaRandomizer.logic.smbool import SMBool, smboolFalse from ..logic.smbool import SMBool, smboolFalse
from worlds.sm.variaRandomizer.logic.helpers import Bosses from ..logic.helpers import Bosses
from worlds.sm.variaRandomizer.logic.logic import Logic from ..logic.logic import Logic
from worlds.sm.variaRandomizer.utils.doorsmanager import DoorsManager from ..utils.doorsmanager import DoorsManager
from worlds.sm.variaRandomizer.utils.parameters import Knows, isKnows from ..utils.parameters import Knows, isKnows
import logging import logging
import sys import sys

View File

@ -1,17 +1,18 @@
import os, importlib import importlib
from worlds.sm.variaRandomizer.logic.logic import Logic from ..logic.logic import Logic
from worlds.sm.variaRandomizer.patches.common.patches import patches, additional_PLMs from ..patches.common.patches import patches, additional_PLMs
from worlds.sm.variaRandomizer.utils.parameters import appDir from ..utils.parameters import appDir
from ..utils.utils import listDir, exists
class PatchAccess(object): class PatchAccess(object):
def __init__(self): def __init__(self):
# load all ips patches # load all ips patches
self.patchesPath = {} self.patchesPath = {}
commonDir = os.path.join(appDir, 'worlds/sm/variaRandomizer/patches/common/ips/') commonDir = "/".join((appDir, 'worlds/sm/variaRandomizer/patches/common/ips'))
for patch in os.listdir(commonDir): for patch in listDir(commonDir):
self.patchesPath[patch] = commonDir self.patchesPath[patch] = commonDir
logicDir = os.path.join(appDir, 'worlds/sm/variaRandomizer/patches/{}/ips/'.format(Logic.patches)) logicDir = "/".join((appDir, 'worlds/sm/variaRandomizer/patches/{}/ips'.format(Logic.patches)))
for patch in os.listdir(logicDir): for patch in listDir(logicDir):
self.patchesPath[patch] = logicDir self.patchesPath[patch] = logicDir
# load dict patches # load dict patches
@ -27,10 +28,10 @@ class PatchAccess(object):
def getPatchPath(self, patch): def getPatchPath(self, patch):
# is patch preloaded # is patch preloaded
if patch in self.patchesPath: if patch in self.patchesPath:
return os.path.join(self.patchesPath[patch], patch) return "/".join((self.patchesPath[patch], patch))
else: else:
# patchs from varia_repository used by the customizer for permalinks # patchs from varia_repository used by the customizer for permalinks
if os.path.exists(patch): if exists(patch):
return patch return patch
else: else:
raise Exception("unknown patch: {}".format(patch)) raise Exception("unknown patch: {}".format(patch))

View File

@ -1,7 +1,7 @@
import random import random
from worlds.sm.variaRandomizer.utils import log from ..utils import log
from worlds.sm.variaRandomizer.utils.utils import getRangeDict, chooseFromRange from ..utils.utils import getRangeDict, chooseFromRange
from worlds.sm.variaRandomizer.rando.ItemLocContainer import ItemLocation from ..rando.ItemLocContainer import ItemLocation
# helper object to choose item/loc # helper object to choose item/loc
class Choice(object): class Choice(object):

View File

@ -1,14 +1,14 @@
import copy, time, random import copy, time, random
from worlds.sm.variaRandomizer.utils import log from ..utils import log
from worlds.sm.variaRandomizer.logic.cache import RequestCache from ..logic.cache import RequestCache
from worlds.sm.variaRandomizer.rando.RandoServices import RandoServices from ..rando.RandoServices import RandoServices
from worlds.sm.variaRandomizer.rando.Choice import ItemThenLocChoice from ..rando.Choice import ItemThenLocChoice
from worlds.sm.variaRandomizer.rando.RandoServices import ComebackCheckType from ..rando.RandoServices import ComebackCheckType
from worlds.sm.variaRandomizer.rando.ItemLocContainer import ItemLocation, getItemLocationsStr from ..rando.ItemLocContainer import ItemLocation, getItemLocationsStr
from worlds.sm.variaRandomizer.utils.parameters import infinity from ..utils.parameters import infinity
from worlds.sm.variaRandomizer.logic.helpers import diffValue2txt from ..logic.helpers import diffValue2txt
from worlds.sm.variaRandomizer.graph.graph_utils import GraphUtils from ..graph.graph_utils import GraphUtils
# base class for fillers. a filler responsibility is to fill a given # base class for fillers. a filler responsibility is to fill a given
# ItemLocContainer while a certain condition is fulfilled (usually # ItemLocContainer while a certain condition is fulfilled (usually

View File

@ -1,9 +1,9 @@
import random, copy import random, copy
from worlds.sm.variaRandomizer.utils import log from ..utils import log
from worlds.sm.variaRandomizer.graph.graph_utils import GraphUtils, vanillaTransitions, vanillaBossesTransitions, escapeSource, escapeTargets from ..graph.graph_utils import GraphUtils, vanillaTransitions, vanillaBossesTransitions, escapeSource, escapeTargets
from worlds.sm.variaRandomizer.logic.logic import Logic from ..logic.logic import Logic
from worlds.sm.variaRandomizer.graph.graph import AccessGraphRando as AccessGraph from ..graph.graph import AccessGraphRando as AccessGraph
# creates graph and handles randomized escape # creates graph and handles randomized escape
class GraphBuilder(object): class GraphBuilder(object):

View File

@ -1,8 +1,8 @@
import copy import copy
from worlds.sm.variaRandomizer.utils import log from ..utils import log
from worlds.sm.variaRandomizer.logic.smbool import SMBool, smboolFalse from ..logic.smbool import SMBool, smboolFalse
from worlds.sm.variaRandomizer.logic.smboolmanager import SMBoolManager from ..logic.smboolmanager import SMBoolManager
from collections import Counter from collections import Counter
class ItemLocation(object): class ItemLocation(object):

View File

@ -1,5 +1,5 @@
from worlds.sm.variaRandomizer.utils.utils import randGaussBounds, getRangeDict, chooseFromRange from ..utils.utils import randGaussBounds, getRangeDict, chooseFromRange
from worlds.sm.variaRandomizer.utils import log from ..utils import log
import logging, copy, random import logging, copy, random
class Item: class Item:

View File

@ -1,16 +1,16 @@
import sys, random, time import sys, random, time
from worlds.sm.variaRandomizer.utils import log from ..utils import log
from worlds.sm.variaRandomizer.logic.logic import Logic from ..logic.logic import Logic
from worlds.sm.variaRandomizer.graph.graph_utils import GraphUtils, getAccessPoint from ..graph.graph_utils import GraphUtils, getAccessPoint
from worlds.sm.variaRandomizer.rando.Restrictions import Restrictions from ..rando.Restrictions import Restrictions
from worlds.sm.variaRandomizer.rando.RandoServices import RandoServices from ..rando.RandoServices import RandoServices
from worlds.sm.variaRandomizer.rando.GraphBuilder import GraphBuilder from ..rando.GraphBuilder import GraphBuilder
from worlds.sm.variaRandomizer.rando.RandoSetup import RandoSetup from ..rando.RandoSetup import RandoSetup
from worlds.sm.variaRandomizer.rando.Items import ItemManager from ..rando.Items import ItemManager
from worlds.sm.variaRandomizer.rando.ItemLocContainer import ItemLocation from ..rando.ItemLocContainer import ItemLocation
from worlds.sm.variaRandomizer.utils.vcr import VCR from ..utils.vcr import VCR
from worlds.sm.variaRandomizer.utils.doorsmanager import DoorsManager from ..utils.doorsmanager import DoorsManager
# entry point for rando execution ("randomize" method) # entry point for rando execution ("randomize" method)
class RandoExec(object): class RandoExec(object):

View File

@ -1,10 +1,10 @@
import copy, random, sys, logging, os import copy, random, sys, logging, os
from enum import Enum, unique from enum import Enum, unique
from worlds.sm.variaRandomizer.utils import log from ..utils import log
from worlds.sm.variaRandomizer.utils.parameters import infinity from ..utils.parameters import infinity
from worlds.sm.variaRandomizer.rando.ItemLocContainer import getLocListStr, getItemListStr, getItemLocStr, ItemLocation from ..rando.ItemLocContainer import getLocListStr, getItemListStr, getItemLocStr, ItemLocation
from worlds.sm.variaRandomizer.logic.helpers import Bosses from ..logic.helpers import Bosses
# used to specify whether we want to come back from locations # used to specify whether we want to come back from locations
@unique @unique

View File

@ -1,9 +1,9 @@
import sys, random import sys, random
from collections import defaultdict from collections import defaultdict
from worlds.sm.variaRandomizer.rando.Items import ItemManager from ..rando.Items import ItemManager
from worlds.sm.variaRandomizer.utils.utils import getRangeDict, chooseFromRange from ..utils.utils import getRangeDict, chooseFromRange
from worlds.sm.variaRandomizer.rando.ItemLocContainer import ItemLocation from ..rando.ItemLocContainer import ItemLocation
# Holder for settings and a few utility functions related to them # Holder for settings and a few utility functions related to them
# (especially for plando/rando). # (especially for plando/rando).

View File

@ -1,15 +1,15 @@
import copy, random import copy, random
from worlds.sm.variaRandomizer.utils import log from ..utils import log
from worlds.sm.variaRandomizer.utils.utils import randGaussBounds from ..utils.utils import randGaussBounds
from worlds.sm.variaRandomizer.logic.smbool import SMBool, smboolFalse from ..logic.smbool import SMBool, smboolFalse
from worlds.sm.variaRandomizer.logic.smboolmanager import SMBoolManager from ..logic.smboolmanager import SMBoolManager
from worlds.sm.variaRandomizer.logic.helpers import Bosses from ..logic.helpers import Bosses
from worlds.sm.variaRandomizer.graph.graph_utils import getAccessPoint, GraphUtils from ..graph.graph_utils import getAccessPoint, GraphUtils
from worlds.sm.variaRandomizer.rando.Filler import FrontFiller from ..rando.Filler import FrontFiller
from worlds.sm.variaRandomizer.rando.ItemLocContainer import ItemLocContainer, getLocListStr, ItemLocation, getItemListStr from ..rando.ItemLocContainer import ItemLocContainer, getLocListStr, ItemLocation, getItemListStr
from worlds.sm.variaRandomizer.rando.Restrictions import Restrictions from ..rando.Restrictions import Restrictions
from worlds.sm.variaRandomizer.utils.parameters import infinity from ..utils.parameters import infinity
# checks init conditions for the randomizer: processes super fun settings, graph, start location, special restrictions # checks init conditions for the randomizer: processes super fun settings, graph, start location, special restrictions
# the entry point is createItemLocContainer # the entry point is createItemLocContainer

View File

@ -1,7 +1,7 @@
import copy, random import copy, random
from worlds.sm.variaRandomizer.utils import log from ..utils import log
from worlds.sm.variaRandomizer.graph.graph_utils import getAccessPoint from ..graph.graph_utils import getAccessPoint
from worlds.sm.variaRandomizer.rando.ItemLocContainer import getLocListStr from ..rando.ItemLocContainer import getLocListStr
# Holds settings related to item placement restrictions. # Holds settings related to item placement restrictions.
# canPlaceAtLocation is the main entry point here # canPlaceAtLocation is the main entry point here

View File

@ -3,19 +3,19 @@
from Utils import output_path from Utils import output_path
import argparse, os.path, json, sys, shutil, random, copy, requests import argparse, os.path, json, sys, shutil, random, copy, requests
from worlds.sm.variaRandomizer.rando.RandoSettings import RandoSettings, GraphSettings from .rando.RandoSettings import RandoSettings, GraphSettings
from worlds.sm.variaRandomizer.rando.RandoExec import RandoExec from .rando.RandoExec import RandoExec
from worlds.sm.variaRandomizer.graph.graph_utils import GraphUtils, getAccessPoint from .graph.graph_utils import GraphUtils, getAccessPoint
from worlds.sm.variaRandomizer.utils.parameters import Controller, easy, medium, hard, harder, hardcore, mania, infinity, text2diff, appDir from .utils.parameters import Controller, easy, medium, hard, harder, hardcore, mania, infinity, text2diff, appDir
from worlds.sm.variaRandomizer.rom.rom_patches import RomPatches from .rom.rom_patches import RomPatches
from worlds.sm.variaRandomizer.rom.rompatcher import RomPatcher from .rom.rompatcher import RomPatcher
from worlds.sm.variaRandomizer.utils.utils import PresetLoader, loadRandoPreset, getDefaultMultiValues, getPresetDir from .utils.utils import PresetLoader, loadRandoPreset, getDefaultMultiValues, getPresetDir
from worlds.sm.variaRandomizer.utils.version import displayedVersion from .utils.version import displayedVersion
from worlds.sm.variaRandomizer.utils.doorsmanager import DoorsManager from .utils.doorsmanager import DoorsManager
from worlds.sm.variaRandomizer.logic.logic import Logic from .logic.logic import Logic
from worlds.sm.variaRandomizer.utils import log from .utils import log
from worlds.sm.Options import StartLocation from ..Options import StartLocation
# we need to know the logic before doing anything else # we need to know the logic before doing anything else
def getLogic(): def getLogic():
@ -327,8 +327,8 @@ class VariaRandomizer:
preset = loadRandoPreset(world, self.player, args) preset = loadRandoPreset(world, self.player, args)
# use the skill preset from the rando preset # use the skill preset from the rando preset
if preset is not None and preset != 'custom' and preset != 'varia_custom' and args.paramsFileName is None: if preset is not None and preset != 'custom' and preset != 'varia_custom' and args.paramsFileName is None:
args.paramsFileName = os.path.join(appDir, getPresetDir(preset), preset+".json") args.paramsFileName = "/".join((appDir, getPresetDir(preset), preset+".json"))
# if diff preset given, load it # if diff preset given, load it
if args.paramsFileName is not None: if args.paramsFileName is not None:
PresetLoader.factory(args.paramsFileName).load(self.player) PresetLoader.factory(args.paramsFileName).load(self.player)
@ -353,7 +353,7 @@ class VariaRandomizer:
raise Exception("Got error {} {} {} from trying to fetch varia custom preset named {}".format(response.status_code, response.reason, response.text, preset_name)) raise Exception("Got error {} {} {} from trying to fetch varia custom preset named {}".format(response.status_code, response.reason, response.text, preset_name))
else: else:
preset = 'default' preset = 'default'
PresetLoader.factory(os.path.join(appDir, getPresetDir('casual'), 'casual.json')).load(self.player) PresetLoader.factory("/".join((appDir, getPresetDir('casual'), 'casual.json'))).load(self.player)

View File

@ -1,6 +1,6 @@
import itertools import itertools
from worlds.sm.variaRandomizer.utils.utils import range_union from ..utils.utils import range_union, openFile
# adapted from ips-util for python 3.2 (https://pypi.org/project/ips-util/) # adapted from ips-util for python 3.2 (https://pypi.org/project/ips-util/)
class IPS_Patch(object): class IPS_Patch(object):
@ -25,7 +25,7 @@ class IPS_Patch(object):
@staticmethod @staticmethod
def load(filename): def load(filename):
loaded_patch = IPS_Patch() loaded_patch = IPS_Patch()
with open(filename, 'rb') as file: with openFile(filename, 'rb') as file:
header = file.read(5) header = file.read(5)
if header != b'PATCH': if header != b'PATCH':
raise Exception('Not a valid IPS patch file!') raise Exception('Not a valid IPS patch file!')

View File

@ -1,6 +1,6 @@
import base64 import base64
from worlds.sm.variaRandomizer.rom.ips import IPS_Patch from ..rom.ips import IPS_Patch
def pc_to_snes(pcaddress): def pc_to_snes(pcaddress):
snesaddress=(((pcaddress<<1)&0x7F0000)|(pcaddress&0x7FFF)|0x8000)|0x800000 snesaddress=(((pcaddress<<1)&0x7F0000)|(pcaddress&0x7FFF)|0x8000)|0x800000

View File

@ -1,4 +1,4 @@
from worlds.sm.variaRandomizer.logic.smbool import SMBool from ..logic.smbool import SMBool
# layout patches added by randomizers # layout patches added by randomizers
class RomPatches: class RomPatches:

View File

@ -1,13 +1,13 @@
import os, random, re import os, random, re
from worlds.sm.variaRandomizer.rando.Items import ItemManager from ..rando.Items import ItemManager
from worlds.sm.variaRandomizer.rom.ips import IPS_Patch from ..rom.ips import IPS_Patch
from worlds.sm.variaRandomizer.utils.doorsmanager import DoorsManager from ..utils.doorsmanager import DoorsManager
from worlds.sm.variaRandomizer.graph.graph_utils import GraphUtils, getAccessPoint, locIdsByAreaAddresses from ..graph.graph_utils import GraphUtils, getAccessPoint, locIdsByAreaAddresses
from worlds.sm.variaRandomizer.logic.logic import Logic from ..logic.logic import Logic
from worlds.sm.variaRandomizer.rom.rom import RealROM, snes_to_pc, pc_to_snes from ..rom.rom import RealROM, snes_to_pc, pc_to_snes
from worlds.sm.variaRandomizer.patches.patchaccess import PatchAccess from ..patches.patchaccess import PatchAccess
from worlds.sm.variaRandomizer.utils.parameters import appDir from ..utils.parameters import appDir
from worlds.sm.variaRandomizer.utils import log from ..utils import log
def getWord(w): def getWord(w):
return (w & 0x00FF, (w & 0xFF00) >> 8) return (w & 0x00FF, (w & 0xFF00) >> 8)

View File

@ -1,10 +1,10 @@
import random import random
import copy import copy
from worlds.sm.variaRandomizer.logic.smbool import SMBool from ..logic.smbool import SMBool
from worlds.sm.variaRandomizer.rom.rom_patches import RomPatches from ..rom.rom_patches import RomPatches
import logging import logging
from worlds.sm.variaRandomizer.utils import log from ..utils import log
LOG = log.get('DoorsManager') LOG = log.get('DoorsManager')
colorsList = ['red', 'green', 'yellow', 'wave', 'spazer', 'plasma', 'ice'] colorsList = ['red', 'green', 'yellow', 'wave', 'spazer', 'plasma', 'ice']

View File

@ -1,4 +1,4 @@
from worlds.sm.variaRandomizer.logic.smbool import SMBool from ..logic.smbool import SMBool
import os import os
import sys import sys
from pathlib import Path from pathlib import Path
@ -61,7 +61,7 @@ def diff4solver(difficulty):
return "mania" return "mania"
# allow multiple local repo # allow multiple local repo
appDir = Path(__file__).parents[4] appDir = str(Path(__file__).parents[4])
def isKnows(knows): def isKnows(knows):
return knows[0:len('__')] != '__' and knows[0] == knows[0].upper() return knows[0:len('__')] != '__' and knows[0] == knows[0].upper()

View File

@ -1,8 +1,59 @@
import io
import os, json, re, random import os, json, re, random
import pathlib
import sys
from typing import Any
import zipfile
from worlds.sm.variaRandomizer.utils.parameters import Knows, Settings, Controller, isKnows, isSettings, isButton from ..utils.parameters import Knows, Settings, Controller, isKnows, isSettings, isButton
from worlds.sm.variaRandomizer.utils.parameters import easy, medium, hard, harder, hardcore, mania, text2diff from ..utils.parameters import easy, medium, hard, harder, hardcore, mania, text2diff
from worlds.sm.variaRandomizer.logic.smbool import SMBool from ..logic.smbool import SMBool
# support for AP world
isAPWorld = ".apworld" in sys.modules[__name__].__file__
def getZipFile():
filename = sys.modules[__name__].__file__
apworldExt = ".apworld"
zipPath = pathlib.Path(filename[:filename.index(apworldExt) + len(apworldExt)])
return (zipfile.ZipFile(zipPath), zipPath.stem)
def openFile(resource: str, mode: str = "r", encoding: None = None):
if isAPWorld:
(zipFile, stem) = getZipFile()
with zipFile as zf:
zipFilePath = resource[resource.index(stem + "/"):]
if mode == 'rb':
return zf.open(zipFilePath, 'r')
else:
return io.TextIOWrapper(zf.open(zipFilePath, mode), encoding)
else:
return open(resource, mode)
def listDir(resource: str):
if isAPWorld:
(zipFile, stem) = getZipFile()
with zipFile as zf:
zipFilePath = resource[resource.index(stem + "/"):]
path = zipfile.Path(zf, zipFilePath + "/")
files = [f.at[len(zipFilePath)+1:] for f in path.iterdir()]
return files
else:
return os.listdir(resource)
def exists(resource: str):
if isAPWorld:
(zipFile, stem) = getZipFile()
with zipFile as zf:
if (stem in resource):
zipFilePath = resource[resource.index(stem + "/"):]
path = zipfile.Path(zf, zipFilePath)
return path.exists()
else:
return False
else:
return os.path.exists(resource)
def isStdPreset(preset): def isStdPreset(preset):
return preset in ['newbie', 'casual', 'regular', 'veteran', 'expert', 'master', 'samus', 'solution', 'Season_Races', 'SMRAT2021'] return preset in ['newbie', 'casual', 'regular', 'veteran', 'expert', 'master', 'samus', 'solution', 'Season_Races', 'SMRAT2021']
@ -253,7 +304,7 @@ class PresetLoader(object):
class PresetLoaderJson(PresetLoader): class PresetLoaderJson(PresetLoader):
# when called from the test suite # when called from the test suite
def __init__(self, jsonFileName): def __init__(self, jsonFileName):
with open(jsonFileName) as jsonFile: with openFile(jsonFileName) as jsonFile:
self.params = json.load(jsonFile) self.params = json.load(jsonFile)
super(PresetLoaderJson, self).__init__() super(PresetLoaderJson, self).__init__()
@ -264,7 +315,7 @@ class PresetLoaderDict(PresetLoader):
super(PresetLoaderDict, self).__init__() super(PresetLoaderDict, self).__init__()
def getDefaultMultiValues(): def getDefaultMultiValues():
from worlds.sm.variaRandomizer.graph.graph_utils import GraphUtils from ..graph.graph_utils import GraphUtils
defaultMultiValues = { defaultMultiValues = {
'startLocation': GraphUtils.getStartAccessPointNames(), 'startLocation': GraphUtils.getStartAccessPointNames(),
'majorsSplit': ['Full', 'FullWithHUD', 'Major', 'Chozo', 'Scavenger'], 'majorsSplit': ['Full', 'FullWithHUD', 'Major', 'Chozo', 'Scavenger'],

View File

@ -86,8 +86,8 @@ class SMZ3SNIClient(SNIClient):
recv_index += 1 recv_index += 1
snes_buffered_write(ctx, SMZ3_RECV_PROGRESS_ADDR + 0x680, bytes([recv_index & 0xFF, (recv_index >> 8) & 0xFF])) snes_buffered_write(ctx, SMZ3_RECV_PROGRESS_ADDR + 0x680, bytes([recv_index & 0xFF, (recv_index >> 8) & 0xFF]))
from worlds.smz3.TotalSMZ3.Location import locations_start_id from .TotalSMZ3.Location import locations_start_id
from worlds.smz3 import convertLocSMZ3IDToAPID from . import convertLocSMZ3IDToAPID
location_id = locations_start_id + convertLocSMZ3IDToAPID(item_index) location_id = locations_start_id + convertLocSMZ3IDToAPID(item_index)
ctx.locations_checked.add(location_id) ctx.locations_checked.add(location_id)
@ -101,7 +101,7 @@ class SMZ3SNIClient(SNIClient):
item_out_ptr = data[2] | (data[3] << 8) item_out_ptr = data[2] | (data[3] << 8)
from worlds.smz3.TotalSMZ3.Item import items_start_id from .TotalSMZ3.Item import items_start_id
if item_out_ptr < len(ctx.items_received): if item_out_ptr < len(ctx.items_received):
item = ctx.items_received[item_out_ptr] item = ctx.items_received[item_out_ptr]
item_id = item.item - items_start_id item_id = item.item - items_start_id

View File

@ -3,7 +3,7 @@ import re
import copy import copy
from typing import List from typing import List
from worlds.smz3.TotalSMZ3.Config import Config, SMLogic from .Config import Config, SMLogic
class ItemType(Enum): class ItemType(Enum):
Nothing = 0 Nothing = 0
@ -787,15 +787,15 @@ class Progression:
return self.Flute and self.CanLiftHeavy() return self.Flute and self.CanLiftHeavy()
def CanAccessMaridiaPortal(self, world): def CanAccessMaridiaPortal(self, world):
import worlds.smz3.TotalSMZ3.Region from .Region import RewardType
if (world.Config.SMLogic == SMLogic.Normal): if (world.Config.SMLogic == SMLogic.Normal):
return self.MoonPearl and self.Flippers and \ return self.MoonPearl and self.Flippers and \
self.Gravity and self.Morph and \ self.Gravity and self.Morph and \
(world.CanAcquire(self, worlds.smz3.TotalSMZ3.Region.RewardType.Agahnim) or self.Hammer and self.CanLiftLight() or self.CanLiftHeavy()) (world.CanAcquire(self, RewardType.Agahnim) or self.Hammer and self.CanLiftLight() or self.CanLiftHeavy())
else: else:
return self.MoonPearl and self.Flippers and \ return self.MoonPearl and self.Flippers and \
(self.CanSpringBallJump() or self.HiJump or self.Gravity) and self.Morph and \ (self.CanSpringBallJump() or self.HiJump or self.Gravity) and self.Morph and \
(world.CanAcquire(self, worlds.smz3.TotalSMZ3.Region.RewardType.Agahnim) or self.Hammer and self.CanLiftLight() or self.CanLiftHeavy()) (world.CanAcquire(self, RewardType.Agahnim) or self.Hammer and self.CanLiftLight() or self.CanLiftHeavy())
# Start of AP integration # Start of AP integration
items_start_id = 84000 items_start_id = 84000

View File

@ -1,8 +1,8 @@
from enum import Enum from enum import Enum
from typing import List, Callable from typing import List, Callable
from worlds.smz3.TotalSMZ3.Item import Progression from .Item import Progression
import worlds.smz3.TotalSMZ3.Region as Region from . import Region
import worlds.smz3.TotalSMZ3.World as World from . import World
class LocationType(Enum): class LocationType(Enum):
Regular = 0 Regular = 0

View File

@ -4,30 +4,30 @@ from typing import Any, Callable, List, Sequence
import random import random
import typing import typing
from BaseClasses import Location from BaseClasses import Location
from worlds.smz3.TotalSMZ3.Item import Item, ItemType from .Item import Item, ItemType
from worlds.smz3.TotalSMZ3.Location import LocationType from .Location import LocationType
from worlds.smz3.TotalSMZ3.Region import IReward, RewardType, SMRegion, Z3Region from .Region import IReward, RewardType, SMRegion, Z3Region
from worlds.smz3.TotalSMZ3.Regions.Zelda.EasternPalace import EasternPalace from .Regions.Zelda.EasternPalace import EasternPalace
from worlds.smz3.TotalSMZ3.Regions.Zelda.DesertPalace import DesertPalace from .Regions.Zelda.DesertPalace import DesertPalace
from worlds.smz3.TotalSMZ3.Regions.Zelda.TowerOfHera import TowerOfHera from .Regions.Zelda.TowerOfHera import TowerOfHera
from worlds.smz3.TotalSMZ3.Regions.Zelda.PalaceOfDarkness import PalaceOfDarkness from .Regions.Zelda.PalaceOfDarkness import PalaceOfDarkness
from worlds.smz3.TotalSMZ3.Regions.Zelda.SwampPalace import SwampPalace from .Regions.Zelda.SwampPalace import SwampPalace
from worlds.smz3.TotalSMZ3.Regions.Zelda.SkullWoods import SkullWoods from .Regions.Zelda.SkullWoods import SkullWoods
from worlds.smz3.TotalSMZ3.Regions.Zelda.ThievesTown import ThievesTown from .Regions.Zelda.ThievesTown import ThievesTown
from worlds.smz3.TotalSMZ3.Regions.Zelda.IcePalace import IcePalace from .Regions.Zelda.IcePalace import IcePalace
from worlds.smz3.TotalSMZ3.Regions.Zelda.MiseryMire import MiseryMire from .Regions.Zelda.MiseryMire import MiseryMire
from worlds.smz3.TotalSMZ3.Regions.Zelda.TurtleRock import TurtleRock from .Regions.Zelda.TurtleRock import TurtleRock
from worlds.smz3.TotalSMZ3.Regions.Zelda.GanonsTower import GanonsTower from .Regions.Zelda.GanonsTower import GanonsTower
from worlds.smz3.TotalSMZ3.Regions.SuperMetroid.Brinstar.Kraid import Kraid from .Regions.SuperMetroid.Brinstar.Kraid import Kraid
from worlds.smz3.TotalSMZ3.Regions.SuperMetroid.WreckedShip import WreckedShip from .Regions.SuperMetroid.WreckedShip import WreckedShip
from worlds.smz3.TotalSMZ3.Regions.SuperMetroid.Maridia.Inner import Inner from .Regions.SuperMetroid.Maridia.Inner import Inner
from worlds.smz3.TotalSMZ3.Regions.SuperMetroid.NorfairLower.East import East from .Regions.SuperMetroid.NorfairLower.East import East
from worlds.smz3.TotalSMZ3.Text.StringTable import StringTable from .Text.StringTable import StringTable
from worlds.smz3.TotalSMZ3.World import World from .World import World
from worlds.smz3.TotalSMZ3.Config import Config, OpenTourian, Goal from .Config import Config, OpenTourian, Goal
from worlds.smz3.TotalSMZ3.Text.Texts import Texts from .Text.Texts import Texts
from worlds.smz3.TotalSMZ3.Text.Dialog import Dialog from .Text.Dialog import Dialog
class KeycardPlaque: class KeycardPlaque:
Level1 = 0xe0 Level1 = 0xe0
@ -147,7 +147,7 @@ class Patch:
return {patch[0]:patch[1] for patch in self.patches} return {patch[0]:patch[1] for patch in self.patches}
def WriteMedallions(self): def WriteMedallions(self):
from worlds.smz3.TotalSMZ3.WorldState import Medallion from .WorldState import Medallion
turtleRock = next(region for region in self.myWorld.Regions if isinstance(region, TurtleRock)) turtleRock = next(region for region in self.myWorld.Regions if isinstance(region, TurtleRock))
miseryMire = next(region for region in self.myWorld.Regions if isinstance(region, MiseryMire)) miseryMire = next(region for region in self.myWorld.Regions if isinstance(region, MiseryMire))

View File

@ -1,7 +1,6 @@
from enum import Enum from enum import Enum
from typing import Dict, List from typing import Dict, List
from worlds.smz3.TotalSMZ3.Config import * from .Config import *
from worlds.smz3.TotalSMZ3.Item import Item, ItemType
class RewardType(Enum): class RewardType(Enum):
Null = 0 Null = 0
@ -28,7 +27,7 @@ class IMedallionAccess:
Medallion = None Medallion = None
class Region: class Region:
import worlds.smz3.TotalSMZ3.Location as Location from . import Location
Name: str Name: str
Area: str Area: str

View File

@ -1,6 +1,6 @@
from worlds.smz3.TotalSMZ3.Region import SMRegion from ....Region import SMRegion
from worlds.smz3.TotalSMZ3.Config import Config, SMLogic from ....Config import Config, SMLogic
from worlds.smz3.TotalSMZ3.Location import Location, LocationType from ....Location import Location, LocationType
class Blue(SMRegion): class Blue(SMRegion):
Name = "Brinstar Blue" Name = "Brinstar Blue"

View File

@ -1,7 +1,7 @@
from worlds.smz3.TotalSMZ3.Region import SMRegion from ....Region import SMRegion
from worlds.smz3.TotalSMZ3.Config import Config, SMLogic from ....Config import Config, SMLogic
from worlds.smz3.TotalSMZ3.Location import Location, LocationType from ....Location import Location, LocationType
from worlds.smz3.TotalSMZ3.Item import Progression from ....Item import Progression
class Green(SMRegion): class Green(SMRegion):
Name = "Brinstar Green" Name = "Brinstar Green"

View File

@ -1,7 +1,7 @@
from worlds.smz3.TotalSMZ3.Region import SMRegion, IReward, RewardType from ....Region import SMRegion, IReward, RewardType
from worlds.smz3.TotalSMZ3.Config import Config from ....Config import Config
from worlds.smz3.TotalSMZ3.Location import Location, LocationType from ....Location import Location, LocationType
from worlds.smz3.TotalSMZ3.Item import Progression from ....Item import Progression
class Kraid(SMRegion, IReward): class Kraid(SMRegion, IReward):
Name = "Brinstar Kraid" Name = "Brinstar Kraid"

View File

@ -1,7 +1,7 @@
from worlds.smz3.TotalSMZ3.Region import SMRegion from ....Region import SMRegion
from worlds.smz3.TotalSMZ3.Config import Config, SMLogic from ....Config import Config, SMLogic
from worlds.smz3.TotalSMZ3.Location import Location, LocationType from ....Location import Location, LocationType
from worlds.smz3.TotalSMZ3.Item import Progression from ....Item import Progression
class Pink(SMRegion): class Pink(SMRegion):
Name = "Brinstar Pink" Name = "Brinstar Pink"

View File

@ -1,7 +1,7 @@
from worlds.smz3.TotalSMZ3.Region import SMRegion from ....Region import SMRegion
from worlds.smz3.TotalSMZ3.Config import Config, SMLogic from ....Config import Config, SMLogic
from worlds.smz3.TotalSMZ3.Location import Location, LocationType from ....Location import Location, LocationType
from worlds.smz3.TotalSMZ3.Item import Progression from ....Item import Progression
class Red(SMRegion): class Red(SMRegion):
Name = "Brinstar Red" Name = "Brinstar Red"

View File

@ -1,6 +1,6 @@
from worlds.smz3.TotalSMZ3.Region import SMRegion from ....Region import SMRegion
from worlds.smz3.TotalSMZ3.Config import Config, SMLogic from ....Config import Config, SMLogic
from worlds.smz3.TotalSMZ3.Location import Location, LocationType from ....Location import Location, LocationType
class Central(SMRegion): class Central(SMRegion):
Name = "Crateria Central" Name = "Crateria Central"

View File

@ -1,7 +1,7 @@
from worlds.smz3.TotalSMZ3.Region import SMRegion from ....Region import SMRegion
from worlds.smz3.TotalSMZ3.Config import Config, SMLogic from ....Config import Config, SMLogic
from worlds.smz3.TotalSMZ3.Location import Location, LocationType from ....Location import Location, LocationType
from worlds.smz3.TotalSMZ3.Item import Progression from ....Item import Progression
class East(SMRegion): class East(SMRegion):
Name = "Crateria East" Name = "Crateria East"

View File

@ -1,7 +1,7 @@
from worlds.smz3.TotalSMZ3.Region import SMRegion from ....Region import SMRegion
from worlds.smz3.TotalSMZ3.Config import Config, SMLogic from ....Config import Config, SMLogic
from worlds.smz3.TotalSMZ3.Location import Location, LocationType from ....Location import Location, LocationType
from worlds.smz3.TotalSMZ3.Item import Progression from ....Item import Progression
class West(SMRegion): class West(SMRegion):
Name = "Crateria West" Name = "Crateria West"

View File

@ -1,7 +1,7 @@
from worlds.smz3.TotalSMZ3.Region import SMRegion, IReward, RewardType from ....Region import SMRegion, IReward, RewardType
from worlds.smz3.TotalSMZ3.Config import Config, SMLogic from ....Config import Config, SMLogic
from worlds.smz3.TotalSMZ3.Location import Location, LocationType from ....Location import Location, LocationType
from worlds.smz3.TotalSMZ3.Item import Progression from ....Item import Progression
class Inner(SMRegion, IReward): class Inner(SMRegion, IReward):
Name = "Maridia Inner" Name = "Maridia Inner"

View File

@ -1,7 +1,7 @@
from worlds.smz3.TotalSMZ3.Region import SMRegion from ....Region import SMRegion
from worlds.smz3.TotalSMZ3.Config import Config, SMLogic from ....Config import Config, SMLogic
from worlds.smz3.TotalSMZ3.Location import Location, LocationType from ....Location import Location, LocationType
from worlds.smz3.TotalSMZ3.Item import Progression from ....Item import Progression
class Outer(SMRegion): class Outer(SMRegion):
Name = "Maridia Outer" Name = "Maridia Outer"

View File

@ -1,7 +1,7 @@
from worlds.smz3.TotalSMZ3.Region import SMRegion, IReward, RewardType from ....Region import SMRegion, IReward, RewardType
from worlds.smz3.TotalSMZ3.Config import Config, SMLogic from ....Config import Config, SMLogic
from worlds.smz3.TotalSMZ3.Location import Location, LocationType from ....Location import Location, LocationType
from worlds.smz3.TotalSMZ3.Item import Progression from ....Item import Progression
class East(SMRegion, IReward): class East(SMRegion, IReward):
Name = "Norfair Lower East" Name = "Norfair Lower East"

View File

@ -1,7 +1,7 @@
from worlds.smz3.TotalSMZ3.Region import SMRegion from ....Region import SMRegion
from worlds.smz3.TotalSMZ3.Config import Config, SMLogic from ....Config import Config, SMLogic
from worlds.smz3.TotalSMZ3.Location import Location, LocationType from ....Location import Location, LocationType
from worlds.smz3.TotalSMZ3.Item import Progression from ....Item import Progression
class West(SMRegion): class West(SMRegion):
Name = "Norfair Lower West" Name = "Norfair Lower West"

View File

@ -1,7 +1,7 @@
from worlds.smz3.TotalSMZ3.Region import SMRegion from ....Region import SMRegion
from worlds.smz3.TotalSMZ3.Config import Config, SMLogic from ....Config import Config, SMLogic
from worlds.smz3.TotalSMZ3.Location import Location, LocationType from ....Location import Location, LocationType
from worlds.smz3.TotalSMZ3.Item import Progression from ....Item import Progression
class Crocomire(SMRegion): class Crocomire(SMRegion):
Name = "Norfair Upper Crocomire" Name = "Norfair Upper Crocomire"

View File

@ -1,7 +1,7 @@
from worlds.smz3.TotalSMZ3.Region import SMRegion from ....Region import SMRegion
from worlds.smz3.TotalSMZ3.Config import Config, SMLogic from ....Config import Config, SMLogic
from worlds.smz3.TotalSMZ3.Location import Location, LocationType from ....Location import Location, LocationType
from worlds.smz3.TotalSMZ3.Item import Progression from ....Item import Progression
class East(SMRegion): class East(SMRegion):
Name = "Norfair Upper East" Name = "Norfair Upper East"

View File

@ -1,7 +1,7 @@
from worlds.smz3.TotalSMZ3.Region import SMRegion from ....Region import SMRegion
from worlds.smz3.TotalSMZ3.Config import Config, SMLogic from ....Config import Config, SMLogic
from worlds.smz3.TotalSMZ3.Location import Location, LocationType from ....Location import Location, LocationType
from worlds.smz3.TotalSMZ3.Item import Progression from ....Item import Progression
class West(SMRegion): class West(SMRegion):
Name = "Norfair Upper West" Name = "Norfair Upper West"

View File

@ -1,7 +1,7 @@
from worlds.smz3.TotalSMZ3.Region import SMRegion, IReward, RewardType from ...Region import SMRegion, IReward, RewardType
from worlds.smz3.TotalSMZ3.Config import Config, SMLogic from ...Config import Config, SMLogic
from worlds.smz3.TotalSMZ3.Location import Location, LocationType from ...Location import Location, LocationType
from worlds.smz3.TotalSMZ3.Item import Progression from ...Item import Progression
class WreckedShip(SMRegion, IReward): class WreckedShip(SMRegion, IReward):
Name = "Wrecked Ship" Name = "Wrecked Ship"

View File

@ -1,7 +1,7 @@
from worlds.smz3.TotalSMZ3.Region import Z3Region, RewardType, IReward from ...Region import Z3Region, RewardType, IReward
from worlds.smz3.TotalSMZ3.Config import Config from ...Config import Config
from worlds.smz3.TotalSMZ3.Location import Location, LocationType from ...Location import Location, LocationType
from worlds.smz3.TotalSMZ3.Item import Progression, ItemType from ...Item import Progression, ItemType
class CastleTower(Z3Region, IReward): class CastleTower(Z3Region, IReward):
Name = "Castle Tower" Name = "Castle Tower"

View File

@ -1,7 +1,7 @@
from worlds.smz3.TotalSMZ3.Region import Z3Region from .....Region import Z3Region
from worlds.smz3.TotalSMZ3.Config import Config from .....Config import Config
from worlds.smz3.TotalSMZ3.Location import Location, LocationType from .....Location import Location, LocationType
from worlds.smz3.TotalSMZ3.Item import Progression from .....Item import Progression
class East(Z3Region): class East(Z3Region):
Name = "Dark World Death Mountain East" Name = "Dark World Death Mountain East"

View File

@ -1,6 +1,6 @@
from worlds.smz3.TotalSMZ3.Region import Z3Region from .....Region import Z3Region
from worlds.smz3.TotalSMZ3.Config import Config from .....Config import Config
from worlds.smz3.TotalSMZ3.Location import Location, LocationType from .....Location import Location, LocationType
class West(Z3Region): class West(Z3Region):
Name = "Dark World Death Mountain West" Name = "Dark World Death Mountain West"

View File

@ -1,7 +1,7 @@
from worlds.smz3.TotalSMZ3.Region import Z3Region from ....Region import Z3Region
from worlds.smz3.TotalSMZ3.Config import Config from ....Config import Config
from worlds.smz3.TotalSMZ3.Location import Location, LocationType from ....Location import Location, LocationType
from worlds.smz3.TotalSMZ3.Item import Progression from ....Item import Progression
class Mire(Z3Region): class Mire(Z3Region):
Name = "Dark World Mire" Name = "Dark World Mire"

View File

@ -1,7 +1,7 @@
from worlds.smz3.TotalSMZ3.Region import Z3Region, RewardType from ....Region import Z3Region, RewardType
from worlds.smz3.TotalSMZ3.Config import Config from ....Config import Config
from worlds.smz3.TotalSMZ3.Location import Location, LocationType from ....Location import Location, LocationType
from worlds.smz3.TotalSMZ3.Item import Progression from ....Item import Progression
class NorthEast(Z3Region): class NorthEast(Z3Region):
Name = "Dark World North East" Name = "Dark World North East"

View File

@ -1,7 +1,7 @@
from worlds.smz3.TotalSMZ3.Region import Z3Region, RewardType from ....Region import Z3Region, RewardType
from worlds.smz3.TotalSMZ3.Config import Config from ....Config import Config
from worlds.smz3.TotalSMZ3.Location import Location, LocationType from ....Location import Location, LocationType
from worlds.smz3.TotalSMZ3.Item import Progression from ....Item import Progression
class NorthWest(Z3Region): class NorthWest(Z3Region):
Name = "Dark World North West" Name = "Dark World North West"

View File

@ -1,7 +1,7 @@
from worlds.smz3.TotalSMZ3.Region import Z3Region, RewardType from ....Region import Z3Region, RewardType
from worlds.smz3.TotalSMZ3.Config import Config from ....Config import Config
from worlds.smz3.TotalSMZ3.Location import Location, LocationType from ....Location import Location, LocationType
from worlds.smz3.TotalSMZ3.Item import Progression from ....Item import Progression
class South(Z3Region): class South(Z3Region):
Name = "Dark World South" Name = "Dark World South"

View File

@ -1,7 +1,7 @@
from worlds.smz3.TotalSMZ3.Region import Z3Region, RewardType, IReward from ...Region import Z3Region, RewardType, IReward
from worlds.smz3.TotalSMZ3.Config import Config from ...Config import Config
from worlds.smz3.TotalSMZ3.Location import Location, LocationType from ...Location import Location, LocationType
from worlds.smz3.TotalSMZ3.Item import ItemType, Progression from ...Item import ItemType, Progression
class DesertPalace(Z3Region, IReward): class DesertPalace(Z3Region, IReward):
Name = "Desert Palace" Name = "Desert Palace"

View File

@ -1,7 +1,7 @@
from worlds.smz3.TotalSMZ3.Region import Z3Region, RewardType, IReward from ...Region import Z3Region, RewardType, IReward
from worlds.smz3.TotalSMZ3.Config import Config from ...Config import Config
from worlds.smz3.TotalSMZ3.Location import Location, LocationType from ...Location import Location, LocationType
from worlds.smz3.TotalSMZ3.Item import Progression, ItemType from ...Item import Progression, ItemType
class EasternPalace(Z3Region, IReward): class EasternPalace(Z3Region, IReward):
Name = "Eastern Palace" Name = "Eastern Palace"

View File

@ -1,8 +1,8 @@
from typing import List from typing import List
from worlds.smz3.TotalSMZ3.Region import Z3Region, RewardType from ...Region import Z3Region, RewardType
from worlds.smz3.TotalSMZ3.Config import Config, GameMode, KeyShuffle from ...Config import Config, GameMode, KeyShuffle
from worlds.smz3.TotalSMZ3.Location import Location, LocationType from ...Location import Location, LocationType
from worlds.smz3.TotalSMZ3.Item import Item, Progression, ItemType from ...Item import Item, Progression, ItemType
class GanonsTower(Z3Region): class GanonsTower(Z3Region):
Name = "Ganon's Tower" Name = "Ganon's Tower"

View File

@ -1,8 +1,8 @@
from typing import List from typing import List
from worlds.smz3.TotalSMZ3.Region import Z3Region from ...Region import Z3Region
from worlds.smz3.TotalSMZ3.Config import Config from ...Config import Config
from worlds.smz3.TotalSMZ3.Location import Location, LocationType from ...Location import Location, LocationType
from worlds.smz3.TotalSMZ3.Item import ItemType from ...Item import ItemType
class HyruleCastle(Z3Region): class HyruleCastle(Z3Region):
Name = "Hyrule Castle" Name = "Hyrule Castle"

View File

@ -1,8 +1,8 @@
from typing import List from typing import List
from worlds.smz3.TotalSMZ3.Region import Z3Region, RewardType, IReward from ...Region import Z3Region, RewardType, IReward
from worlds.smz3.TotalSMZ3.Config import Config from ...Config import Config
from worlds.smz3.TotalSMZ3.Location import Location, LocationType from ...Location import Location, LocationType
from worlds.smz3.TotalSMZ3.Item import Progression, ItemType from ...Item import Progression, ItemType
class IcePalace(Z3Region, IReward): class IcePalace(Z3Region, IReward):
Name = "Ice Palace" Name = "Ice Palace"

View File

@ -1,7 +1,7 @@
from worlds.smz3.TotalSMZ3.Region import Z3Region from .....Region import Z3Region
from worlds.smz3.TotalSMZ3.Config import Config from .....Config import Config
from worlds.smz3.TotalSMZ3.Location import Location, LocationType from .....Location import Location, LocationType
from worlds.smz3.TotalSMZ3.Item import Progression from .....Item import Progression
class East(Z3Region): class East(Z3Region):
Name = "Light World Death Mountain East" Name = "Light World Death Mountain East"

View File

@ -1,7 +1,7 @@
from worlds.smz3.TotalSMZ3.Region import Z3Region from .....Region import Z3Region
from worlds.smz3.TotalSMZ3.Config import Config from .....Config import Config
from worlds.smz3.TotalSMZ3.Location import Location, LocationType from .....Location import Location, LocationType
from worlds.smz3.TotalSMZ3.Item import Progression from .....Item import Progression
class West(Z3Region): class West(Z3Region):
Name = "Light World Death Mountain West" Name = "Light World Death Mountain West"

View File

@ -1,6 +1,6 @@
from worlds.smz3.TotalSMZ3.Region import Z3Region, RewardType from ....Region import Z3Region, RewardType
from worlds.smz3.TotalSMZ3.Config import Config from ....Config import Config
from worlds.smz3.TotalSMZ3.Location import Location, LocationType from ....Location import Location, LocationType
class NorthEast(Z3Region): class NorthEast(Z3Region):
Name = "Light World North East" Name = "Light World North East"

View File

@ -1,6 +1,6 @@
from worlds.smz3.TotalSMZ3.Region import Z3Region, RewardType from ....Region import Z3Region, RewardType
from worlds.smz3.TotalSMZ3.Config import Config from ....Config import Config
from worlds.smz3.TotalSMZ3.Location import Location, LocationType from ....Location import Location, LocationType
class NorthWest(Z3Region): class NorthWest(Z3Region):
Name = "Light World North West" Name = "Light World North West"

View File

@ -1,6 +1,6 @@
from worlds.smz3.TotalSMZ3.Region import Z3Region from ....Region import Z3Region
from worlds.smz3.TotalSMZ3.Config import Config from ....Config import Config
from worlds.smz3.TotalSMZ3.Location import Location, LocationType from ....Location import Location, LocationType
class South(Z3Region): class South(Z3Region):
Name = "Light World South" Name = "Light World South"

View File

@ -1,8 +1,8 @@
from typing import List from typing import List
from worlds.smz3.TotalSMZ3.Region import Z3Region, RewardType, IReward, IMedallionAccess from ...Region import Z3Region, RewardType, IReward, IMedallionAccess
from worlds.smz3.TotalSMZ3.Config import Config from ...Config import Config
from worlds.smz3.TotalSMZ3.Location import Location, LocationType from ...Location import Location, LocationType
from worlds.smz3.TotalSMZ3.Item import Progression, ItemType from ...Item import Progression, ItemType
class MiseryMire(Z3Region, IReward, IMedallionAccess): class MiseryMire(Z3Region, IReward, IMedallionAccess):
Name = "Misery Mire" Name = "Misery Mire"
@ -35,7 +35,7 @@ class MiseryMire(Z3Region, IReward, IMedallionAccess):
# // Need "CanKillManyEnemies" if implementing swordless # // Need "CanKillManyEnemies" if implementing swordless
def CanEnter(self, items: Progression): def CanEnter(self, items: Progression):
from worlds.smz3.TotalSMZ3.WorldState import Medallion from ...WorldState import Medallion
return (items.Bombos if self.Medallion == Medallion.Bombos else ( return (items.Bombos if self.Medallion == Medallion.Bombos else (
items.Ether if self.Medallion == Medallion.Ether else items.Quake)) and items.Sword and \ items.Ether if self.Medallion == Medallion.Ether else items.Quake)) and items.Sword and \
items.MoonPearl and (items.Boots or items.Hookshot) and \ items.MoonPearl and (items.Boots or items.Hookshot) and \

View File

@ -1,8 +1,8 @@
from typing import List from typing import List
from worlds.smz3.TotalSMZ3.Region import Z3Region, RewardType, IReward from ...Region import Z3Region, RewardType, IReward
from worlds.smz3.TotalSMZ3.Config import Config from ...Config import Config
from worlds.smz3.TotalSMZ3.Location import Location, LocationType from ...Location import Location, LocationType
from worlds.smz3.TotalSMZ3.Item import Progression, ItemType from ...Item import Progression, ItemType
class PalaceOfDarkness(Z3Region, IReward): class PalaceOfDarkness(Z3Region, IReward):
Name = "Palace of Darkness" Name = "Palace of Darkness"

View File

@ -1,8 +1,8 @@
from typing import List from typing import List
from worlds.smz3.TotalSMZ3.Region import Z3Region, RewardType, IReward from ...Region import Z3Region, RewardType, IReward
from worlds.smz3.TotalSMZ3.Config import Config from ...Config import Config
from worlds.smz3.TotalSMZ3.Location import Location, LocationType from ...Location import Location, LocationType
from worlds.smz3.TotalSMZ3.Item import Progression, ItemType from ...Item import Progression, ItemType
class SkullWoods(Z3Region, IReward): class SkullWoods(Z3Region, IReward):
Name = "Skull Woods" Name = "Skull Woods"

View File

@ -1,8 +1,8 @@
from typing import List from typing import List
from worlds.smz3.TotalSMZ3.Region import Z3Region, RewardType, IReward from ...Region import Z3Region, RewardType, IReward
from worlds.smz3.TotalSMZ3.Config import Config from ...Config import Config
from worlds.smz3.TotalSMZ3.Location import Location, LocationType from ...Location import Location, LocationType
from worlds.smz3.TotalSMZ3.Item import Progression, ItemType from ...Item import Progression, ItemType
class SwampPalace(Z3Region, IReward): class SwampPalace(Z3Region, IReward):
Name = "Swamp Palace" Name = "Swamp Palace"

View File

@ -1,8 +1,8 @@
from typing import List from typing import List
from worlds.smz3.TotalSMZ3.Region import Z3Region, RewardType, IReward from ...Region import Z3Region, RewardType, IReward
from worlds.smz3.TotalSMZ3.Config import Config from ...Config import Config
from worlds.smz3.TotalSMZ3.Location import Location, LocationType from ...Location import Location, LocationType
from worlds.smz3.TotalSMZ3.Item import Progression, ItemType from ...Item import Progression, ItemType
class ThievesTown(Z3Region, IReward): class ThievesTown(Z3Region, IReward):
Name = "Thieves' Town" Name = "Thieves' Town"

View File

@ -1,8 +1,8 @@
from typing import List from typing import List
from worlds.smz3.TotalSMZ3.Region import Z3Region, RewardType, IReward from ...Region import Z3Region, RewardType, IReward
from worlds.smz3.TotalSMZ3.Config import Config from ...Config import Config
from worlds.smz3.TotalSMZ3.Location import Location, LocationType from ...Location import Location, LocationType
from worlds.smz3.TotalSMZ3.Item import Progression, ItemType from ...Item import Progression, ItemType
class TowerOfHera(Z3Region, IReward): class TowerOfHera(Z3Region, IReward):
Name = "Tower of Hera" Name = "Tower of Hera"

View File

@ -1,8 +1,8 @@
from typing import List from typing import List
from worlds.smz3.TotalSMZ3.Region import Z3Region, RewardType, IReward, IMedallionAccess from ...Region import Z3Region, RewardType, IReward, IMedallionAccess
from worlds.smz3.TotalSMZ3.Config import Config from ...Config import Config
from worlds.smz3.TotalSMZ3.Location import Location, LocationType from ...Location import Location, LocationType
from worlds.smz3.TotalSMZ3.Item import Progression, ItemType from ...Item import Progression, ItemType
class TurtleRock(Z3Region, IReward, IMedallionAccess): class TurtleRock(Z3Region, IReward, IMedallionAccess):
Name = "Turtle Rock" Name = "Turtle Rock"
@ -47,7 +47,7 @@ class TurtleRock(Z3Region, IReward, IMedallionAccess):
return items.Firerod and items.Icerod return items.Firerod and items.Icerod
def CanEnter(self, items: Progression): def CanEnter(self, items: Progression):
from worlds.smz3.TotalSMZ3.WorldState import Medallion from ...WorldState import Medallion
return (items.Bombos if self.Medallion == Medallion.Bombos else ( return (items.Bombos if self.Medallion == Medallion.Bombos else (
items.Ether if self.Medallion == Medallion.Ether else items.Quake)) and items.Sword and \ items.Ether if self.Medallion == Medallion.Ether else items.Quake)) and items.Sword and \
items.MoonPearl and items.CanLiftHeavy() and items.Hammer and items.Somaria and \ items.MoonPearl and items.CanLiftHeavy() and items.Hammer and items.Somaria and \

View File

@ -158,7 +158,7 @@ class Dialog:
value = Dialog.letters.get(c, None) value = Dialog.letters.get(c, None)
return value if value else [ 0xFF ] return value if value else [ 0xFF ]
#region letter bytes lookup #regions letter bytes lookup
letters = { letters = {
' ' : [ 0x4F ], ' ' : [ 0x4F ],

View File

@ -1,15 +1,15 @@
 
from typing import Any, List from typing import Any, List
import copy import copy
from worlds.smz3.TotalSMZ3.Text.Dialog import Dialog from ..Text.Dialog import Dialog
from worlds.smz3.TotalSMZ3.Text.Texts import text_folder from ..Text.Texts import openFile
from Utils import unsafe_parse_yaml from Utils import unsafe_parse_yaml
class StringTable: class StringTable:
@staticmethod @staticmethod
def ParseEntries(resource: str): def ParseEntries(resource: str):
with open(resource, 'rb') as f: with openFile(resource, 'rb') as f:
yaml = str(f.read(), "utf-8") yaml = str(f.read(), "utf-8")
content = unsafe_parse_yaml(yaml) content = unsafe_parse_yaml(yaml)
@ -23,7 +23,7 @@ class StringTable:
else: raise Exception(f"Did not expect an object of type {type(value)}") else: raise Exception(f"Did not expect an object of type {type(value)}")
return result return result
template = ParseEntries.__func__(text_folder + "/Scripts/StringTable.yaml") template = ParseEntries.__func__("smz3/TotalSMZ3/Text/Scripts/StringTable.yaml")
def __init__(self): def __init__(self):
self.entries = copy.deepcopy(StringTable.template) self.entries = copy.deepcopy(StringTable.template)

View File

@ -1,30 +1,49 @@
from typing import Any, List import io
from worlds.smz3.TotalSMZ3.Region import Region from pathlib import Path
from worlds.smz3.TotalSMZ3.Regions.Zelda.GanonsTower import GanonsTower import sys
from worlds.smz3.TotalSMZ3.Item import Item, ItemType from typing import Any, List
import zipfile
from ..Region import Region
from ..Regions.Zelda.GanonsTower import GanonsTower
from ..Item import Item, ItemType
from Utils import unsafe_parse_yaml from Utils import unsafe_parse_yaml
import random import random
import os import os
text_folder = os.path.dirname(__file__) text_folder = Path(__file__).parents[3]
def openFile(resource: str, mode: str = "r", encoding: None = None):
filename = sys.modules[__name__].__file__
apworldExt = ".apworld"
game = "smz3/"
if apworldExt in filename:
zip_path = Path(filename[:filename.index(apworldExt) + len(apworldExt)])
with zipfile.ZipFile(zip_path) as zf:
zipFilePath = resource[resource.index(game):]
if mode == 'rb':
return zf.open(zipFilePath, 'r')
else:
return io.TextIOWrapper(zf.open(zipFilePath, 'r'), encoding)
else:
return open(os.path.join(text_folder, resource), mode)
class Texts: class Texts:
@staticmethod @staticmethod
def ParseYamlScripts(resource: str): def ParseYamlScripts(resource: str):
with open(resource, 'rb') as f: with openFile(resource, 'rb') as f:
yaml = str(f.read(), "utf-8") yaml = str(f.read(), "utf-8")
return unsafe_parse_yaml(yaml) return unsafe_parse_yaml(yaml)
@staticmethod @staticmethod
def ParseTextScript(resource: str): def ParseTextScript(resource: str):
with open(resource, 'r', encoding="utf-8-sig") as file: with openFile(resource, 'r') as file:
return [text.rstrip('\n') for text in file.read().replace("\r", "").split("---\n") if text] return [text.rstrip('\n') for text in file.read().replace("\r", "").split("---\n") if text]
scripts: Any = ParseYamlScripts.__func__(text_folder + "/Scripts/General.yaml") scripts: Any = ParseYamlScripts.__func__("smz3/TotalSMZ3/Text/Scripts/General.yaml")
blind: List[str] = ParseTextScript.__func__(text_folder + "/Scripts/Blind.txt") blind: List[str] = ParseTextScript.__func__("smz3/TotalSMZ3/Text/Scripts/Blind.txt")
ganon: List[str] = ParseTextScript.__func__(text_folder + "/Scripts/Ganon.txt") ganon: List[str] = ParseTextScript.__func__("smz3/TotalSMZ3/Text/Scripts/Ganon.txt")
tavernMan: List[str] = ParseTextScript.__func__(text_folder + "/Scripts/TavernMan.txt") tavernMan: List[str] = ParseTextScript.__func__("smz3/TotalSMZ3/Text/Scripts/TavernMan.txt")
triforceRoom: List[str] = ParseTextScript.__func__(text_folder + "/Scripts/TriforceRoom.txt") triforceRoom: List[str] = ParseTextScript.__func__("smz3/TotalSMZ3/Text/Scripts/TriforceRoom.txt")
@staticmethod @staticmethod
def SahasrahlaReveal(dungeon: Region): def SahasrahlaReveal(dungeon: Region):

View File

@ -1,51 +1,51 @@
from typing import Dict, List from typing import Dict, List
import random import random
import worlds.smz3.TotalSMZ3.Region as Region from . import Region
import worlds.smz3.TotalSMZ3.Config as Config from . import Config
import worlds.smz3.TotalSMZ3.Item as Item from . import Item
import worlds.smz3.TotalSMZ3.Location as Location from . import Location
from worlds.smz3.TotalSMZ3.Regions.Zelda.CastleTower import CastleTower from .Regions.Zelda.CastleTower import CastleTower
from worlds.smz3.TotalSMZ3.Regions.Zelda.EasternPalace import EasternPalace from .Regions.Zelda.EasternPalace import EasternPalace
from worlds.smz3.TotalSMZ3.Regions.Zelda.DesertPalace import DesertPalace from .Regions.Zelda.DesertPalace import DesertPalace
from worlds.smz3.TotalSMZ3.Regions.Zelda.TowerOfHera import TowerOfHera from .Regions.Zelda.TowerOfHera import TowerOfHera
from worlds.smz3.TotalSMZ3.Regions.Zelda.PalaceOfDarkness import PalaceOfDarkness from .Regions.Zelda.PalaceOfDarkness import PalaceOfDarkness
from worlds.smz3.TotalSMZ3.Regions.Zelda.SwampPalace import SwampPalace from .Regions.Zelda.SwampPalace import SwampPalace
from worlds.smz3.TotalSMZ3.Regions.Zelda.SkullWoods import SkullWoods from .Regions.Zelda.SkullWoods import SkullWoods
from worlds.smz3.TotalSMZ3.Regions.Zelda.ThievesTown import ThievesTown from .Regions.Zelda.ThievesTown import ThievesTown
from worlds.smz3.TotalSMZ3.Regions.Zelda.IcePalace import IcePalace from .Regions.Zelda.IcePalace import IcePalace
from worlds.smz3.TotalSMZ3.Regions.Zelda.MiseryMire import MiseryMire from .Regions.Zelda.MiseryMire import MiseryMire
from worlds.smz3.TotalSMZ3.Regions.Zelda.TurtleRock import TurtleRock from .Regions.Zelda.TurtleRock import TurtleRock
from worlds.smz3.TotalSMZ3.Regions.Zelda.GanonsTower import GanonsTower from .Regions.Zelda.GanonsTower import GanonsTower
from worlds.smz3.TotalSMZ3.Regions.Zelda.LightWorld.DeathMountain.West import West as LightWorldDeathMountainWest from .Regions.Zelda.LightWorld.DeathMountain.West import West as LightWorldDeathMountainWest
from worlds.smz3.TotalSMZ3.Regions.Zelda.LightWorld.DeathMountain.East import East as LightWorldDeathMountainEast from .Regions.Zelda.LightWorld.DeathMountain.East import East as LightWorldDeathMountainEast
from worlds.smz3.TotalSMZ3.Regions.Zelda.LightWorld.NorthWest import NorthWest as LightWorldNorthWest from .Regions.Zelda.LightWorld.NorthWest import NorthWest as LightWorldNorthWest
from worlds.smz3.TotalSMZ3.Regions.Zelda.LightWorld.NorthEast import NorthEast as LightWorldNorthEast from .Regions.Zelda.LightWorld.NorthEast import NorthEast as LightWorldNorthEast
from worlds.smz3.TotalSMZ3.Regions.Zelda.LightWorld.South import South as LightWorldSouth from .Regions.Zelda.LightWorld.South import South as LightWorldSouth
from worlds.smz3.TotalSMZ3.Regions.Zelda.HyruleCastle import HyruleCastle from .Regions.Zelda.HyruleCastle import HyruleCastle
from worlds.smz3.TotalSMZ3.Regions.Zelda.DarkWorld.DeathMountain.West import West as DarkWorldDeathMountainWest from .Regions.Zelda.DarkWorld.DeathMountain.West import West as DarkWorldDeathMountainWest
from worlds.smz3.TotalSMZ3.Regions.Zelda.DarkWorld.DeathMountain.East import East as DarkWorldDeathMountainEast from .Regions.Zelda.DarkWorld.DeathMountain.East import East as DarkWorldDeathMountainEast
from worlds.smz3.TotalSMZ3.Regions.Zelda.DarkWorld.NorthWest import NorthWest as DarkWorldNorthWest from .Regions.Zelda.DarkWorld.NorthWest import NorthWest as DarkWorldNorthWest
from worlds.smz3.TotalSMZ3.Regions.Zelda.DarkWorld.NorthEast import NorthEast as DarkWorldNorthEast from .Regions.Zelda.DarkWorld.NorthEast import NorthEast as DarkWorldNorthEast
from worlds.smz3.TotalSMZ3.Regions.Zelda.DarkWorld.South import South as DarkWorldSouth from .Regions.Zelda.DarkWorld.South import South as DarkWorldSouth
from worlds.smz3.TotalSMZ3.Regions.Zelda.DarkWorld.Mire import Mire as DarkWorldMire from .Regions.Zelda.DarkWorld.Mire import Mire as DarkWorldMire
from worlds.smz3.TotalSMZ3.Regions.SuperMetroid.Crateria.Central import Central from .Regions.SuperMetroid.Crateria.Central import Central
from worlds.smz3.TotalSMZ3.Regions.SuperMetroid.Crateria.West import West as CrateriaWest from .Regions.SuperMetroid.Crateria.West import West as CrateriaWest
from worlds.smz3.TotalSMZ3.Regions.SuperMetroid.Crateria.East import East as CrateriaEast from .Regions.SuperMetroid.Crateria.East import East as CrateriaEast
from worlds.smz3.TotalSMZ3.Regions.SuperMetroid.Brinstar.Blue import Blue from .Regions.SuperMetroid.Brinstar.Blue import Blue
from worlds.smz3.TotalSMZ3.Regions.SuperMetroid.Brinstar.Green import Green from .Regions.SuperMetroid.Brinstar.Green import Green
from worlds.smz3.TotalSMZ3.Regions.SuperMetroid.Brinstar.Kraid import Kraid from .Regions.SuperMetroid.Brinstar.Kraid import Kraid
from worlds.smz3.TotalSMZ3.Regions.SuperMetroid.Brinstar.Pink import Pink from .Regions.SuperMetroid.Brinstar.Pink import Pink
from worlds.smz3.TotalSMZ3.Regions.SuperMetroid.Brinstar.Red import Red from .Regions.SuperMetroid.Brinstar.Red import Red
from worlds.smz3.TotalSMZ3.Regions.SuperMetroid.Maridia.Outer import Outer from .Regions.SuperMetroid.Maridia.Outer import Outer
from worlds.smz3.TotalSMZ3.Regions.SuperMetroid.Maridia.Inner import Inner from .Regions.SuperMetroid.Maridia.Inner import Inner
from worlds.smz3.TotalSMZ3.Regions.SuperMetroid.NorfairUpper.West import West as NorfairUpperWest from .Regions.SuperMetroid.NorfairUpper.West import West as NorfairUpperWest
from worlds.smz3.TotalSMZ3.Regions.SuperMetroid.NorfairUpper.East import East as NorfairUpperEast from .Regions.SuperMetroid.NorfairUpper.East import East as NorfairUpperEast
from worlds.smz3.TotalSMZ3.Regions.SuperMetroid.NorfairUpper.Crocomire import Crocomire from .Regions.SuperMetroid.NorfairUpper.Crocomire import Crocomire
from worlds.smz3.TotalSMZ3.Regions.SuperMetroid.NorfairLower.West import West as NorfairLowerWest from .Regions.SuperMetroid.NorfairLower.West import West as NorfairLowerWest
from worlds.smz3.TotalSMZ3.Regions.SuperMetroid.NorfairLower.East import East as NorfairLowerEast from .Regions.SuperMetroid.NorfairLower.East import East as NorfairLowerEast
from worlds.smz3.TotalSMZ3.Regions.SuperMetroid.WreckedShip import WreckedShip from .Regions.SuperMetroid.WreckedShip import WreckedShip
class World: class World:
Locations: List[Location.Location] Locations: List[Location.Location]

View File

@ -2,9 +2,9 @@ from enum import Enum
from typing import List from typing import List
from copy import copy from copy import copy
from worlds.smz3.TotalSMZ3.Patch import DropPrize from .Patch import DropPrize
from worlds.smz3.TotalSMZ3.Region import RewardType from .Region import RewardType
from worlds.smz3.TotalSMZ3.Config import OpenTower, GanonVulnerable, OpenTourian from .Config import OpenTower, GanonVulnerable, OpenTourian
class Medallion(Enum): class Medallion(Enum):
Bombos = 0 Bombos = 0

View File

@ -8,16 +8,17 @@ from typing import Dict, Set, TextIO
from BaseClasses import Region, Entrance, Location, MultiWorld, Item, ItemClassification, CollectionState, \ from BaseClasses import Region, Entrance, Location, MultiWorld, Item, ItemClassification, CollectionState, \
Tutorial Tutorial
from worlds.generic.Rules import set_rule from worlds.generic.Rules import set_rule
from worlds.smz3.TotalSMZ3.Item import ItemType from .TotalSMZ3.Item import ItemType
import worlds.smz3.TotalSMZ3.Item as TotalSMZ3Item from .TotalSMZ3 import Item as TotalSMZ3Item
from worlds.smz3.TotalSMZ3.World import World as TotalSMZ3World from .TotalSMZ3.World import World as TotalSMZ3World
from worlds.smz3.TotalSMZ3.Regions.Zelda.GanonsTower import GanonsTower from .TotalSMZ3.Regions.Zelda.GanonsTower import GanonsTower
from worlds.smz3.TotalSMZ3.Config import Config, GameMode, Goal, KeyShuffle, MorphLocation, SMLogic, SwordLocation, Z3Logic, OpenTower, GanonVulnerable, OpenTourian from .TotalSMZ3.Config import Config, GameMode, Goal, KeyShuffle, MorphLocation, SMLogic, SwordLocation, Z3Logic, OpenTower, GanonVulnerable, OpenTourian
from worlds.smz3.TotalSMZ3.Location import LocationType, locations_start_id, Location as TotalSMZ3Location from .TotalSMZ3.Location import LocationType, locations_start_id, Location as TotalSMZ3Location
from worlds.smz3.TotalSMZ3.Patch import Patch as TotalSMZ3Patch, getWord, getWordArray from .TotalSMZ3.Patch import Patch as TotalSMZ3Patch, getWord, getWordArray
from worlds.smz3.TotalSMZ3.WorldState import WorldState from .TotalSMZ3.WorldState import WorldState
from worlds.smz3.TotalSMZ3.Region import IReward, IMedallionAccess from .TotalSMZ3.Region import IReward, IMedallionAccess
from ..AutoWorld import World, AutoLogicRegister, WebWorld from .TotalSMZ3.Text.Texts import openFile
from worlds.AutoWorld import World, AutoLogicRegister, WebWorld
from .Client import SMZ3SNIClient from .Client import SMZ3SNIClient
from .Rom import get_base_rom_bytes, SMZ3DeltaPatch from .Rom import get_base_rom_bytes, SMZ3DeltaPatch
from .ips import IPS_Patch from .ips import IPS_Patch
@ -272,7 +273,7 @@ class SMZ3World(World):
idx = 0 idx = 0
offworldSprites = {} offworldSprites = {}
for fileName in itemSprites: for fileName in itemSprites:
with open(world_folder + "/data/custom_sprite/" + fileName, 'rb') as stream: with openFile(world_folder + "/data/custom_sprite/" + fileName, 'rb') as stream:
buffer = bytearray(stream.read()) buffer = bytearray(stream.read())
offworldSprites[0x04Eff2 + 10*((0x6B + 0x40) + idx)] = bytearray(getWordArray(itemSpritesAddress[idx])) + buffer[0:8] offworldSprites[0x04Eff2 + 10*((0x6B + 0x40) + idx)] = bytearray(getWordArray(itemSpritesAddress[idx])) + buffer[0:8]
offworldSprites[0x090000 + itemSpritesAddress[idx]] = buffer[8:264] offworldSprites[0x090000 + itemSpritesAddress[idx]] = buffer[8:264]

View File

@ -1,5 +1,7 @@
import itertools import itertools
from .TotalSMZ3.Text.Texts import openFile
def range_union(ranges): def range_union(ranges):
ret = [] ret = []
for rg in sorted([[r.start, r.stop] for r in ranges]): for rg in sorted([[r.start, r.stop] for r in ranges]):
@ -33,7 +35,7 @@ class IPS_Patch(object):
@staticmethod @staticmethod
def load(filename): def load(filename):
loaded_patch = IPS_Patch() loaded_patch = IPS_Patch()
with open(filename, 'rb') as file: with openFile(filename, 'rb') as file:
header = file.read(5) header = file.read(5)
if header != b'PATCH': if header != b'PATCH':
raise Exception('Not a valid IPS patch file!') raise Exception('Not a valid IPS patch file!')