167 lines
8.4 KiB
Python
167 lines
8.4 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
|
|
|
|
def Items(self):
|
|
return [l.Item for l in self.Locations if l.Item != None]
|
|
|
|
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),
|
|
Central(self, self.Config),
|
|
CrateriaWest(self, self.Config),
|
|
CrateriaEast(self, self.Config),
|
|
Blue(self, self.Config),
|
|
Green(self, self.Config),
|
|
Kraid(self, self.Config),
|
|
Pink(self, self.Config),
|
|
Red(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),
|
|
WreckedShip(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 CanAquire(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 CanAquireAll(self, items: Item.Progression, *rewards: Region.RewardType):
|
|
for region in self.Regions:
|
|
if issubclass(type(region), Region.IReward):
|
|
if (region.Reward in rewards):
|
|
if not region.CanComplete(items):
|
|
return False
|
|
return True
|
|
|
|
# return all(region.CanComplete(items) for region in self.Regions if (isinstance(region, Region.IReward) and region.Reward in rewards))
|
|
|
|
def Setup(self, rnd: random):
|
|
self.SetMedallions(rnd)
|
|
self.SetRewards(rnd)
|
|
|
|
def SetMedallions(self, rnd: random):
|
|
medallionMap = {0: Item.ItemType.Bombos, 1: Item.ItemType.Ether, 2: Item.ItemType.Quake}
|
|
regionList = [region for region in self.Regions if isinstance(region, Region.IMedallionAccess)]
|
|
for region in regionList:
|
|
region.Medallion = medallionMap[rnd.randint(0, 2)]
|
|
|
|
def SetRewards(self, rnd: random):
|
|
rewards = [
|
|
Region.RewardType.PendantGreen, Region.RewardType.PendantNonGreen, Region.RewardType.PendantNonGreen, Region.RewardType.CrystalRed, Region.RewardType.CrystalRed,
|
|
Region.RewardType.CrystalBlue, Region.RewardType.CrystalBlue, Region.RewardType.CrystalBlue, Region.RewardType.CrystalBlue, Region.RewardType.CrystalBlue
|
|
]
|
|
rnd.shuffle(rewards)
|
|
regionList = [region for region in self.Regions if isinstance(region, Region.IReward) and region.Reward == Region.RewardType.Null]
|
|
for region in regionList:
|
|
region.Reward = rewards[0]
|
|
rewards.remove(region.Reward)
|
|
|