178 lines
		
	
	
		
			8.7 KiB
		
	
	
	
		
			Python
		
	
	
	
			
		
		
	
	
			178 lines
		
	
	
		
			8.7 KiB
		
	
	
	
		
			Python
		
	
	
	
from typing import Dict, List
 | 
						|
import random
 | 
						|
 | 
						|
import worlds.smz3.TotalSMZ3.Region as Region
 | 
						|
import worlds.smz3.TotalSMZ3.Config as Config
 | 
						|
import worlds.smz3.TotalSMZ3.Item as Item
 | 
						|
import worlds.smz3.TotalSMZ3.Location as Location
 | 
						|
 | 
						|
from worlds.smz3.TotalSMZ3.Regions.Zelda.CastleTower import CastleTower
 | 
						|
from worlds.smz3.TotalSMZ3.Regions.Zelda.EasternPalace import EasternPalace
 | 
						|
from worlds.smz3.TotalSMZ3.Regions.Zelda.DesertPalace import DesertPalace
 | 
						|
from worlds.smz3.TotalSMZ3.Regions.Zelda.TowerOfHera import TowerOfHera
 | 
						|
from worlds.smz3.TotalSMZ3.Regions.Zelda.PalaceOfDarkness import PalaceOfDarkness
 | 
						|
from worlds.smz3.TotalSMZ3.Regions.Zelda.SwampPalace import SwampPalace
 | 
						|
from worlds.smz3.TotalSMZ3.Regions.Zelda.SkullWoods import SkullWoods
 | 
						|
from worlds.smz3.TotalSMZ3.Regions.Zelda.ThievesTown import ThievesTown
 | 
						|
from worlds.smz3.TotalSMZ3.Regions.Zelda.IcePalace import IcePalace
 | 
						|
from worlds.smz3.TotalSMZ3.Regions.Zelda.MiseryMire import MiseryMire
 | 
						|
from worlds.smz3.TotalSMZ3.Regions.Zelda.TurtleRock import TurtleRock
 | 
						|
from worlds.smz3.TotalSMZ3.Regions.Zelda.GanonsTower import GanonsTower
 | 
						|
from worlds.smz3.TotalSMZ3.Regions.Zelda.LightWorld.DeathMountain.West import West as LightWorldDeathMountainWest
 | 
						|
from worlds.smz3.TotalSMZ3.Regions.Zelda.LightWorld.DeathMountain.East import East as LightWorldDeathMountainEast
 | 
						|
from worlds.smz3.TotalSMZ3.Regions.Zelda.LightWorld.NorthWest import NorthWest as LightWorldNorthWest
 | 
						|
from worlds.smz3.TotalSMZ3.Regions.Zelda.LightWorld.NorthEast import NorthEast as LightWorldNorthEast
 | 
						|
from worlds.smz3.TotalSMZ3.Regions.Zelda.LightWorld.South import South as LightWorldSouth
 | 
						|
from worlds.smz3.TotalSMZ3.Regions.Zelda.HyruleCastle import HyruleCastle
 | 
						|
from worlds.smz3.TotalSMZ3.Regions.Zelda.DarkWorld.DeathMountain.West import West as DarkWorldDeathMountainWest
 | 
						|
from worlds.smz3.TotalSMZ3.Regions.Zelda.DarkWorld.DeathMountain.East import East as DarkWorldDeathMountainEast
 | 
						|
from worlds.smz3.TotalSMZ3.Regions.Zelda.DarkWorld.NorthWest import NorthWest as DarkWorldNorthWest
 | 
						|
from worlds.smz3.TotalSMZ3.Regions.Zelda.DarkWorld.NorthEast import NorthEast as DarkWorldNorthEast
 | 
						|
from worlds.smz3.TotalSMZ3.Regions.Zelda.DarkWorld.South import South as DarkWorldSouth
 | 
						|
from worlds.smz3.TotalSMZ3.Regions.Zelda.DarkWorld.Mire import Mire as DarkWorldMire
 | 
						|
from worlds.smz3.TotalSMZ3.Regions.SuperMetroid.Crateria.Central import Central
 | 
						|
from worlds.smz3.TotalSMZ3.Regions.SuperMetroid.Crateria.West import West as CrateriaWest 
 | 
						|
from worlds.smz3.TotalSMZ3.Regions.SuperMetroid.Crateria.East import East as CrateriaEast
 | 
						|
from worlds.smz3.TotalSMZ3.Regions.SuperMetroid.Brinstar.Blue import Blue
 | 
						|
from worlds.smz3.TotalSMZ3.Regions.SuperMetroid.Brinstar.Green import Green
 | 
						|
from worlds.smz3.TotalSMZ3.Regions.SuperMetroid.Brinstar.Kraid import Kraid
 | 
						|
from worlds.smz3.TotalSMZ3.Regions.SuperMetroid.Brinstar.Pink import Pink
 | 
						|
from worlds.smz3.TotalSMZ3.Regions.SuperMetroid.Brinstar.Red import Red
 | 
						|
from worlds.smz3.TotalSMZ3.Regions.SuperMetroid.Maridia.Outer import Outer
 | 
						|
from worlds.smz3.TotalSMZ3.Regions.SuperMetroid.Maridia.Inner import Inner
 | 
						|
from worlds.smz3.TotalSMZ3.Regions.SuperMetroid.NorfairUpper.West import West as NorfairUpperWest
 | 
						|
from worlds.smz3.TotalSMZ3.Regions.SuperMetroid.NorfairUpper.East import East as NorfairUpperEast
 | 
						|
from worlds.smz3.TotalSMZ3.Regions.SuperMetroid.NorfairUpper.Crocomire import Crocomire
 | 
						|
from worlds.smz3.TotalSMZ3.Regions.SuperMetroid.NorfairLower.West import West as NorfairLowerWest
 | 
						|
from worlds.smz3.TotalSMZ3.Regions.SuperMetroid.NorfairLower.East import East as NorfairLowerEast
 | 
						|
from worlds.smz3.TotalSMZ3.Regions.SuperMetroid.WreckedShip import WreckedShip
 | 
						|
 | 
						|
class World:
 | 
						|
    Locations: List[Location.Location]
 | 
						|
    Regions: List[Region.Region]
 | 
						|
    Config: Config.Config
 | 
						|
    Player: str
 | 
						|
    Guid: str
 | 
						|
    Id: int
 | 
						|
    WorldState = None
 | 
						|
 | 
						|
    @property
 | 
						|
    def TowerCrystals(self):
 | 
						|
        return 7 if self.WorldState is None else self.WorldState.TowerCrystals
 | 
						|
 | 
						|
    @property
 | 
						|
    def GanonCrystals(self):
 | 
						|
        return  7 if self.WorldState is None else self.WorldState.GanonCrystals
 | 
						|
 | 
						|
    @property
 | 
						|
    def TourianBossTokens(self):
 | 
						|
        return 4 if self.WorldState is None else self.WorldState.TourianBossTokens
 | 
						|
 | 
						|
    def Items(self):
 | 
						|
        return [l.Item for l in self.Locations if l.Item != None]
 | 
						|
 | 
						|
    ForwardSearch: bool = False
 | 
						|
 | 
						|
    rewardLookup: Dict[int, List[Region.IReward]]
 | 
						|
    locationLookup: Dict[str, Location.Location]
 | 
						|
    regionLookup: Dict[str, Region.Region]
 | 
						|
 | 
						|
    def GetLocation(self, name:str): return self.locationLookup[name]
 | 
						|
    def GetRegion(self, name:str): return self.regionLookup[name]
 | 
						|
 | 
						|
    def __init__(self, config: Config, player: str, id: int, guid: str):
 | 
						|
        self.Config = config
 | 
						|
        self.Player = player
 | 
						|
        self.Id = id
 | 
						|
        self.Guid = guid
 | 
						|
 | 
						|
        self.Regions = [
 | 
						|
            CastleTower(self, self.Config),
 | 
						|
            EasternPalace(self, self.Config),
 | 
						|
            DesertPalace(self, self.Config),
 | 
						|
            TowerOfHera(self, self.Config),
 | 
						|
            PalaceOfDarkness(self, self.Config),
 | 
						|
            SwampPalace(self, self.Config),
 | 
						|
            SkullWoods(self, self.Config),
 | 
						|
            ThievesTown(self, self.Config),
 | 
						|
            IcePalace(self, self.Config),
 | 
						|
            MiseryMire(self, self.Config),
 | 
						|
            TurtleRock(self, self.Config),
 | 
						|
            GanonsTower(self, self.Config),
 | 
						|
            LightWorldDeathMountainWest(self, self.Config),
 | 
						|
            LightWorldDeathMountainEast(self, self.Config),
 | 
						|
            LightWorldNorthWest(self, self.Config),
 | 
						|
            LightWorldNorthEast(self, self.Config),
 | 
						|
            LightWorldSouth(self, self.Config),
 | 
						|
            HyruleCastle(self, self.Config),
 | 
						|
            DarkWorldDeathMountainWest(self, self.Config),
 | 
						|
            DarkWorldDeathMountainEast(self, self.Config),
 | 
						|
            DarkWorldNorthWest(self, self.Config),
 | 
						|
            DarkWorldNorthEast(self, self.Config),
 | 
						|
            DarkWorldSouth(self, self.Config),
 | 
						|
            DarkWorldMire(self, self.Config),
 | 
						|
            CrateriaWest(self, self.Config),
 | 
						|
            Central(self, self.Config),
 | 
						|
            CrateriaEast(self, self.Config),
 | 
						|
            Blue(self, self.Config),
 | 
						|
            Green(self, self.Config),
 | 
						|
            Pink(self, self.Config),
 | 
						|
            Red(self, self.Config),
 | 
						|
            Kraid(self, self.Config),
 | 
						|
            WreckedShip(self, self.Config),
 | 
						|
            Outer(self, self.Config),
 | 
						|
            Inner(self, self.Config),
 | 
						|
            NorfairUpperWest(self, self.Config),
 | 
						|
            NorfairUpperEast(self, self.Config),
 | 
						|
            Crocomire(self, self.Config),
 | 
						|
            NorfairLowerWest(self, self.Config),
 | 
						|
            NorfairLowerEast(self, self.Config)
 | 
						|
        ]
 | 
						|
 | 
						|
        self.Locations = []
 | 
						|
        for r in self.Regions:
 | 
						|
            self.Locations = self.Locations + r.Locations
 | 
						|
 | 
						|
        self.regionLookup = {r.Name:r for r in self.Regions}
 | 
						|
        self.locationLookup = {loc.Name:loc for loc in self.Locations}
 | 
						|
        
 | 
						|
        for region in self.Regions:
 | 
						|
            region.GenerateLocationLookup()
 | 
						|
 | 
						|
 | 
						|
    def CanEnter(self, regionName: str, items: Item.Progression):
 | 
						|
        region = self.regionLookup[regionName]
 | 
						|
        if (region == None):
 | 
						|
            raise Exception(f"World.CanEnter: Invalid region name {regionName}", f'{regionName=}'.partition('=')[0])
 | 
						|
        return region.CanEnter(items)
 | 
						|
 | 
						|
    def CanAcquire(self, items: Item.Progression, reward: Region.RewardType):
 | 
						|
        return next(iter([region for region in self.Regions if isinstance(region, Region.IReward) and region.Reward == reward])).CanComplete(items)
 | 
						|
 | 
						|
    def CanAcquireAll(self, items: Item.Progression, rewardsMask: Region.RewardType):
 | 
						|
        return all(region.CanComplete(items) for region in self.rewardLookup[rewardsMask.value])
 | 
						|
 | 
						|
    def CanAcquireAtLeast(self, amount, items: Item.Progression, rewardsMask: Region.RewardType):
 | 
						|
            return len([region for region in self.rewardLookup[rewardsMask.value] if region.CanComplete(items)]) >= amount
 | 
						|
 | 
						|
    def Setup(self, state):
 | 
						|
        self.WorldState = state
 | 
						|
        self.SetMedallions(state.Medallions)
 | 
						|
        self.SetRewards(state.Rewards)
 | 
						|
        self.SetRewardLookup()
 | 
						|
 | 
						|
    def SetRewards(self, rewards: List):
 | 
						|
        regions = [region for region in self.Regions if isinstance(region, Region.IReward) and region.Reward == Region.RewardType.Null]
 | 
						|
        for (region, reward) in zip(regions, rewards):
 | 
						|
            region.Reward = reward
 | 
						|
 | 
						|
    def SetMedallions(self, medallions: List):
 | 
						|
        self.GetRegion("Misery Mire").Medallion = medallions[0]
 | 
						|
        self.GetRegion("Turtle Rock").Medallion = medallions[1]
 | 
						|
 | 
						|
    def SetRewardLookup(self):
 | 
						|
        #/* Generate a lookup of all possible regions for any given reward combination for faster lookup later */
 | 
						|
        self.rewardLookup: Dict[int, Region.IReward] = {}
 | 
						|
        for i in range(0, 512):
 | 
						|
            self.rewardLookup[i] = [region for region in self.Regions if isinstance(region, Region.IReward) and (region.Reward.value & i) != 0]
 |