804 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			804 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
from enum import Enum
 | 
						|
import re
 | 
						|
import copy
 | 
						|
from typing import List
 | 
						|
 | 
						|
from worlds.smz3.TotalSMZ3.Config import Config, SMLogic
 | 
						|
 | 
						|
class ItemType(Enum):
 | 
						|
    Nothing = 0
 | 
						|
    MapHC = 0x7F
 | 
						|
    MapEP = 0x7D
 | 
						|
    MapDP = 0x7C
 | 
						|
    MapTH = 0x75
 | 
						|
    MapPD = 0x79
 | 
						|
    MapSP = 0x7A
 | 
						|
    MapSW = 0x77
 | 
						|
    MapTT = 0x74
 | 
						|
    MapIP = 0x76
 | 
						|
    MapMM = 0x78
 | 
						|
    MapTR = 0x73
 | 
						|
    MapGT = 0x72
 | 
						|
 | 
						|
    CompassEP = 0x8D
 | 
						|
    CompassDP = 0x8C
 | 
						|
    CompassTH = 0x85
 | 
						|
    CompassPD = 0x89
 | 
						|
    CompassSP = 0x8A
 | 
						|
    CompassSW = 0x87
 | 
						|
    CompassTT = 0x84
 | 
						|
    CompassIP = 0x86
 | 
						|
    CompassMM = 0x88
 | 
						|
    CompassTR = 0x83
 | 
						|
    CompassGT = 0x82
 | 
						|
 | 
						|
    BigKeyEP = 0x9D
 | 
						|
    BigKeyDP = 0x9C
 | 
						|
    BigKeyTH = 0x95
 | 
						|
    BigKeyPD = 0x99
 | 
						|
    BigKeySP = 0x9A
 | 
						|
    BigKeySW = 0x97
 | 
						|
    BigKeyTT = 0x94
 | 
						|
    BigKeyIP = 0x96
 | 
						|
    BigKeyMM = 0x98
 | 
						|
    BigKeyTR = 0x93
 | 
						|
    BigKeyGT = 0x92       
 | 
						|
    
 | 
						|
    KeyHC = 0xA0
 | 
						|
    KeyCT = 0xA4
 | 
						|
    KeyDP = 0xA3
 | 
						|
    KeyTH = 0xAA
 | 
						|
    KeyPD = 0xA6
 | 
						|
    KeySP = 0xA5
 | 
						|
    KeySW = 0xA8
 | 
						|
    KeyTT = 0xAB
 | 
						|
    KeyIP = 0xA9
 | 
						|
    KeyMM = 0xA7
 | 
						|
    KeyTR = 0xAC
 | 
						|
    KeyGT = 0xAD
 | 
						|
 | 
						|
    Key = 0x24
 | 
						|
    Compass = 0x25
 | 
						|
    BigKey = 0x32
 | 
						|
    Map = 0x33
 | 
						|
 | 
						|
    Something = 0x6B
 | 
						|
 | 
						|
    ProgressiveTunic = 0x60
 | 
						|
    ProgressiveShield = 0x5F
 | 
						|
    ProgressiveSword = 0x5E
 | 
						|
    Bow = 0x0B
 | 
						|
    SilverArrows = 0x58
 | 
						|
    BlueBoomerang = 0x0C
 | 
						|
    RedBoomerang = 0x2A
 | 
						|
    Hookshot = 0x0A
 | 
						|
    Mushroom = 0x29
 | 
						|
    Powder = 0x0D
 | 
						|
    Firerod = 0x07
 | 
						|
    Icerod = 0x08
 | 
						|
    Bombos = 0x0f
 | 
						|
    Ether = 0x10
 | 
						|
    Quake = 0x11
 | 
						|
    Lamp = 0x12
 | 
						|
    Hammer = 0x09
 | 
						|
    Shovel = 0x13
 | 
						|
    Flute = 0x14
 | 
						|
    Bugnet = 0x21
 | 
						|
    Book = 0x1D
 | 
						|
    Bottle = 0x16
 | 
						|
    Somaria = 0x15
 | 
						|
    Byrna = 0x18
 | 
						|
    Cape = 0x19
 | 
						|
    Mirror = 0x1A
 | 
						|
    Boots = 0x4B
 | 
						|
    ProgressiveGlove = 0x61
 | 
						|
    Flippers = 0x1E
 | 
						|
    MoonPearl = 0x1F
 | 
						|
    HalfMagic = 0x4E
 | 
						|
    HeartPiece = 0x17
 | 
						|
    HeartContainer = 0x3E
 | 
						|
    HeartContainerRefill = 0x3F
 | 
						|
    ThreeBombs = 0x28
 | 
						|
    Arrow = 0x43
 | 
						|
    TenArrows = 0x44
 | 
						|
    OneRupee = 0x34
 | 
						|
    FiveRupees = 0x35
 | 
						|
    TwentyRupees = 0x36
 | 
						|
    TwentyRupees2 = 0x47
 | 
						|
    FiftyRupees = 0x41
 | 
						|
    OneHundredRupees = 0x40
 | 
						|
    ThreeHundredRupees = 0x46
 | 
						|
    BombUpgrade5 = 0x51
 | 
						|
    BombUpgrade10 = 0x52
 | 
						|
    ArrowUpgrade5 = 0x53
 | 
						|
    ArrowUpgrade10 = 0x54
 | 
						|
 | 
						|
    CardCrateriaL1 = 0xD0
 | 
						|
    CardCrateriaL2 = 0xD1
 | 
						|
    CardCrateriaBoss = 0xD2
 | 
						|
    CardBrinstarL1 = 0xD3
 | 
						|
    CardBrinstarL2 = 0xD4
 | 
						|
    CardBrinstarBoss = 0xD5
 | 
						|
    CardNorfairL1 = 0xD6
 | 
						|
    CardNorfairL2 = 0xD7
 | 
						|
    CardNorfairBoss = 0xD8
 | 
						|
    CardMaridiaL1 = 0xD9
 | 
						|
    CardMaridiaL2 = 0xDA
 | 
						|
    CardMaridiaBoss = 0xDB
 | 
						|
    CardWreckedShipL1 = 0xDC
 | 
						|
    CardWreckedShipBoss = 0xDD
 | 
						|
    CardLowerNorfairL1 = 0xDE
 | 
						|
    CardLowerNorfairBoss = 0xDF
 | 
						|
 | 
						|
    SmMapBrinstar = 0xCA
 | 
						|
    SmMapWreckedShip = 0xCB
 | 
						|
    SmMapMaridia = 0xCC
 | 
						|
    SmMapLowerNorfair = 0xCD
 | 
						|
 | 
						|
    Missile = 0xC2
 | 
						|
    Super = 0xC3
 | 
						|
    PowerBomb = 0xC4
 | 
						|
    Grapple = 0xB0
 | 
						|
    XRay = 0xB1
 | 
						|
    ETank = 0xC0
 | 
						|
    ReserveTank = 0xC1
 | 
						|
    Charge = 0xBB
 | 
						|
    Ice = 0xBC
 | 
						|
    Wave = 0xBD
 | 
						|
    Spazer = 0xBE
 | 
						|
    Plasma = 0xBF
 | 
						|
    Varia = 0xB2
 | 
						|
    Gravity = 0xB6
 | 
						|
    Morph = 0xB4
 | 
						|
    Bombs = 0xB9
 | 
						|
    SpringBall = 0xB3
 | 
						|
    ScrewAttack = 0xB5
 | 
						|
    HiJump = 0xB7
 | 
						|
    SpaceJump = 0xB8
 | 
						|
    SpeedBooster = 0xBA
 | 
						|
 | 
						|
    BottleWithRedPotion = 0x2B
 | 
						|
    BottleWithGreenPotion = 0x2C
 | 
						|
    BottleWithBluePotion = 0x2D
 | 
						|
    BottleWithFairy = 0x3D
 | 
						|
    BottleWithBee = 0x3C
 | 
						|
    BottleWithGoldBee = 0x48
 | 
						|
    RedContent = 0x2E
 | 
						|
    GreenContent = 0x2F
 | 
						|
    BlueContent = 0x30
 | 
						|
    BeeContent = 0x0E
 | 
						|
 | 
						|
class Item:
 | 
						|
    Name: str
 | 
						|
    Type: ItemType
 | 
						|
    Progression: bool
 | 
						|
 | 
						|
    dungeon = re.compile("^(BigKey|Key|Map|Compass)")
 | 
						|
    bigKey = re.compile("^BigKey")
 | 
						|
    key = re.compile("^Key")
 | 
						|
    map = re.compile("^Map")
 | 
						|
    compass = re.compile("^Compass")
 | 
						|
    keycard = re.compile("^Card")
 | 
						|
    smMap = re.compile("^SmMap")
 | 
						|
 | 
						|
    def IsDungeonItem(self): return self.dungeon.match(self.Type.name)
 | 
						|
    def IsBigKey(self): return self.bigKey.match(self.Type.name)
 | 
						|
    def IsKey(self): return self.key.match(self.Type.name)
 | 
						|
    def IsMap(self): return self.map.match(self.Type.name)
 | 
						|
    def IsCompass(self): return self.compass.match(self.Type.name)
 | 
						|
    def IsKeycard(self): return self.keycard.match(self.Type.name)
 | 
						|
    def IsSmMap(self): return self.smMap.match(self.Type.name)
 | 
						|
 | 
						|
    def Is(self, type: ItemType, world):
 | 
						|
        return self.Type == type and self.World == world
 | 
						|
 | 
						|
    def IsNot(self, type: ItemType, world):
 | 
						|
        return not self.Is(type, world)
 | 
						|
 | 
						|
    def __init__(self, itemType: ItemType, world = None):
 | 
						|
        self.Type = itemType
 | 
						|
        self.World = world
 | 
						|
        self.Progression = False
 | 
						|
        #self.Name = itemType.GetDescription()
 | 
						|
 | 
						|
    @staticmethod
 | 
						|
    def Nothing(world):
 | 
						|
        return Item(ItemType.Nothing, world)
 | 
						|
 | 
						|
    @staticmethod
 | 
						|
    def AddRange(itemPool, count, item):
 | 
						|
        for i in range(count):
 | 
						|
            itemPool.append(copy.copy(item))
 | 
						|
 | 
						|
    @staticmethod
 | 
						|
    def CreateProgressionPool(world):
 | 
						|
        itemPool = [
 | 
						|
            Item(ItemType.ProgressiveShield),
 | 
						|
            Item(ItemType.ProgressiveShield),
 | 
						|
            Item(ItemType.ProgressiveShield),
 | 
						|
            Item(ItemType.ProgressiveSword),
 | 
						|
            Item(ItemType.ProgressiveSword),
 | 
						|
            Item(ItemType.Bow),
 | 
						|
            Item(ItemType.Hookshot),
 | 
						|
            Item(ItemType.Mushroom),
 | 
						|
            Item(ItemType.Powder),
 | 
						|
            Item(ItemType.Firerod),
 | 
						|
            Item(ItemType.Icerod),
 | 
						|
            Item(ItemType.Bombos),
 | 
						|
            Item(ItemType.Ether),
 | 
						|
            Item(ItemType.Quake),
 | 
						|
            Item(ItemType.Lamp),
 | 
						|
            Item(ItemType.Hammer),
 | 
						|
            Item(ItemType.Shovel),
 | 
						|
            Item(ItemType.Flute),
 | 
						|
            Item(ItemType.Bugnet),
 | 
						|
            Item(ItemType.Book),
 | 
						|
            Item(ItemType.Bottle),
 | 
						|
            Item(ItemType.Somaria),
 | 
						|
            Item(ItemType.Byrna),
 | 
						|
            Item(ItemType.Cape),
 | 
						|
            Item(ItemType.Mirror),
 | 
						|
            Item(ItemType.Boots),
 | 
						|
            Item(ItemType.ProgressiveGlove),
 | 
						|
            Item(ItemType.ProgressiveGlove),
 | 
						|
            Item(ItemType.Flippers),
 | 
						|
            Item(ItemType.MoonPearl),
 | 
						|
            Item(ItemType.HalfMagic),
 | 
						|
 | 
						|
            Item(ItemType.Grapple),
 | 
						|
            Item(ItemType.Charge),
 | 
						|
            Item(ItemType.Ice),
 | 
						|
            Item(ItemType.Wave),
 | 
						|
            Item(ItemType.Plasma),
 | 
						|
            Item(ItemType.Varia),
 | 
						|
            Item(ItemType.Gravity),
 | 
						|
            Item(ItemType.Morph),
 | 
						|
            Item(ItemType.Bombs),
 | 
						|
            Item(ItemType.SpringBall),
 | 
						|
            Item(ItemType.ScrewAttack),
 | 
						|
            Item(ItemType.HiJump),
 | 
						|
            Item(ItemType.SpaceJump),
 | 
						|
            Item(ItemType.SpeedBooster),
 | 
						|
 | 
						|
            Item(ItemType.Missile),
 | 
						|
            Item(ItemType.Super),
 | 
						|
            Item(ItemType.PowerBomb),
 | 
						|
            Item(ItemType.PowerBomb),
 | 
						|
            Item(ItemType.ETank),
 | 
						|
            Item(ItemType.ETank),
 | 
						|
            Item(ItemType.ETank),
 | 
						|
            Item(ItemType.ETank),
 | 
						|
            Item(ItemType.ETank),
 | 
						|
 | 
						|
            Item(ItemType.ReserveTank),
 | 
						|
            Item(ItemType.ReserveTank),
 | 
						|
            Item(ItemType.ReserveTank),
 | 
						|
            Item(ItemType.ReserveTank),
 | 
						|
        ]
 | 
						|
 | 
						|
        for item in itemPool:
 | 
						|
            item.Progression = True
 | 
						|
            item.World = world
 | 
						|
        return itemPool
 | 
						|
 | 
						|
    @staticmethod
 | 
						|
    def CreateNicePool(world):
 | 
						|
        itemPool = [
 | 
						|
            Item(ItemType.ProgressiveTunic),
 | 
						|
            Item(ItemType.ProgressiveTunic),
 | 
						|
            Item(ItemType.ProgressiveSword),
 | 
						|
            Item(ItemType.ProgressiveSword),
 | 
						|
            Item(ItemType.SilverArrows),
 | 
						|
            Item(ItemType.BlueBoomerang),
 | 
						|
            Item(ItemType.RedBoomerang),
 | 
						|
            Item(ItemType.Bottle),
 | 
						|
            Item(ItemType.Bottle),
 | 
						|
            Item(ItemType.Bottle),
 | 
						|
            Item(ItemType.HeartContainerRefill),
 | 
						|
 | 
						|
            Item(ItemType.Spazer),
 | 
						|
            Item(ItemType.XRay),
 | 
						|
        ]
 | 
						|
 | 
						|
        Item.AddRange(itemPool, 10, Item(ItemType.HeartContainer, world))
 | 
						|
 | 
						|
        for item in itemPool:
 | 
						|
            item.World = world
 | 
						|
        return itemPool
 | 
						|
 | 
						|
    @staticmethod
 | 
						|
    def CreateJunkPool(world):
 | 
						|
        itemPool = [
 | 
						|
            Item(ItemType.Arrow),
 | 
						|
            Item(ItemType.OneHundredRupees)
 | 
						|
        ]
 | 
						|
 | 
						|
        Item.AddRange(itemPool, 24, Item(ItemType.HeartPiece))
 | 
						|
        Item.AddRange(itemPool, 8, Item(ItemType.TenArrows))
 | 
						|
        Item.AddRange(itemPool, 13, Item(ItemType.ThreeBombs))
 | 
						|
        Item.AddRange(itemPool, 4, Item(ItemType.ArrowUpgrade5))
 | 
						|
        Item.AddRange(itemPool, 4, Item(ItemType.BombUpgrade5))
 | 
						|
        Item.AddRange(itemPool, 2, Item(ItemType.OneRupee))
 | 
						|
        Item.AddRange(itemPool, 4, Item(ItemType.FiveRupees))
 | 
						|
        Item.AddRange(itemPool, 21 if world.Config.Keysanity else 28, Item(ItemType.TwentyRupees))
 | 
						|
        Item.AddRange(itemPool, 7, Item(ItemType.FiftyRupees))
 | 
						|
        Item.AddRange(itemPool, 5, Item(ItemType.ThreeHundredRupees))
 | 
						|
 | 
						|
        Item.AddRange(itemPool, 9, Item(ItemType.ETank))
 | 
						|
        Item.AddRange(itemPool, 39, Item(ItemType.Missile))
 | 
						|
        Item.AddRange(itemPool, 15, Item(ItemType.Super))
 | 
						|
        Item.AddRange(itemPool, 8, Item(ItemType.PowerBomb))
 | 
						|
 | 
						|
        for item in itemPool:
 | 
						|
            item.World = world
 | 
						|
 | 
						|
        return itemPool
 | 
						|
 | 
						|
    # The order of the dungeon pool is significant
 | 
						|
    @staticmethod
 | 
						|
    def CreateDungeonPool(world):
 | 
						|
        itemPool = [Item(ItemType.BigKeyGT)]
 | 
						|
        Item.AddRange(itemPool, 4, Item(ItemType.KeyGT))
 | 
						|
        if (not world.Config.Keysanity):
 | 
						|
            itemPool += [
 | 
						|
                Item(ItemType.MapGT),
 | 
						|
                Item(ItemType.CompassGT),
 | 
						|
                ]
 | 
						|
        itemPool += [
 | 
						|
            Item(ItemType.BigKeyEP),
 | 
						|
            Item(ItemType.BigKeyDP),
 | 
						|
            Item(ItemType.BigKeyTH),
 | 
						|
            Item(ItemType.BigKeyPD),
 | 
						|
            Item(ItemType.BigKeySP),
 | 
						|
            Item(ItemType.BigKeySW),
 | 
						|
            Item(ItemType.BigKeyTT),
 | 
						|
            Item(ItemType.BigKeyIP),
 | 
						|
            Item(ItemType.BigKeyMM),
 | 
						|
            Item(ItemType.BigKeyTR),
 | 
						|
        ]
 | 
						|
 | 
						|
        Item.AddRange(itemPool, 1, Item(ItemType.KeyHC))
 | 
						|
        Item.AddRange(itemPool, 2, Item(ItemType.KeyCT))
 | 
						|
        Item.AddRange(itemPool, 1, Item(ItemType.KeyDP))
 | 
						|
        Item.AddRange(itemPool, 1, Item(ItemType.KeyTH))
 | 
						|
        Item.AddRange(itemPool, 6, Item(ItemType.KeyPD))
 | 
						|
        Item.AddRange(itemPool, 1, Item(ItemType.KeySP))
 | 
						|
        Item.AddRange(itemPool, 3, Item(ItemType.KeySW))
 | 
						|
        Item.AddRange(itemPool, 1, Item(ItemType.KeyTT))
 | 
						|
        Item.AddRange(itemPool, 2, Item(ItemType.KeyIP))
 | 
						|
        Item.AddRange(itemPool, 3, Item(ItemType.KeyMM))
 | 
						|
        Item.AddRange(itemPool, 4, Item(ItemType.KeyTR))
 | 
						|
 | 
						|
        itemPool += [
 | 
						|
            Item(ItemType.MapEP),
 | 
						|
            Item(ItemType.MapDP),
 | 
						|
            Item(ItemType.MapTH),
 | 
						|
            Item(ItemType.MapPD),
 | 
						|
            Item(ItemType.MapSP),
 | 
						|
            Item(ItemType.MapSW),
 | 
						|
            Item(ItemType.MapTT),
 | 
						|
            Item(ItemType.MapIP),
 | 
						|
            Item(ItemType.MapMM),
 | 
						|
            Item(ItemType.MapTR),
 | 
						|
        ]
 | 
						|
        if (not world.Config.Keysanity):
 | 
						|
            itemPool += [
 | 
						|
                Item(ItemType.MapHC),
 | 
						|
                Item(ItemType.CompassEP),
 | 
						|
                Item(ItemType.CompassDP),
 | 
						|
                Item(ItemType.CompassTH),
 | 
						|
                Item(ItemType.CompassPD),
 | 
						|
                Item(ItemType.CompassSP),
 | 
						|
                Item(ItemType.CompassSW),
 | 
						|
                Item(ItemType.CompassTT),
 | 
						|
                Item(ItemType.CompassIP),
 | 
						|
                Item(ItemType.CompassMM),
 | 
						|
                Item(ItemType.CompassTR),
 | 
						|
            ]
 | 
						|
 | 
						|
        for item in itemPool:
 | 
						|
            item.World = world
 | 
						|
 | 
						|
        return itemPool
 | 
						|
 | 
						|
    @staticmethod
 | 
						|
    def CreateKeycards(world):
 | 
						|
        itemPool =  [
 | 
						|
            Item(ItemType.CardCrateriaL1, world),
 | 
						|
            Item(ItemType.CardCrateriaL2, world),
 | 
						|
            Item(ItemType.CardCrateriaBoss, world),
 | 
						|
            Item(ItemType.CardBrinstarL1, world),
 | 
						|
            Item(ItemType.CardBrinstarL2, world),
 | 
						|
            Item(ItemType.CardBrinstarBoss, world),
 | 
						|
            Item(ItemType.CardNorfairL1, world),
 | 
						|
            Item(ItemType.CardNorfairL2, world),
 | 
						|
            Item(ItemType.CardNorfairBoss, world),
 | 
						|
            Item(ItemType.CardMaridiaL1, world),
 | 
						|
            Item(ItemType.CardMaridiaL2, world),
 | 
						|
            Item(ItemType.CardMaridiaBoss, world),
 | 
						|
            Item(ItemType.CardWreckedShipL1, world),
 | 
						|
            Item(ItemType.CardWreckedShipBoss, world),
 | 
						|
            Item(ItemType.CardLowerNorfairL1, world),
 | 
						|
            Item(ItemType.CardLowerNorfairBoss, world),
 | 
						|
        ]
 | 
						|
 | 
						|
        for item in itemPool:
 | 
						|
            item.Progression = True
 | 
						|
            item.World = world
 | 
						|
 | 
						|
        return itemPool
 | 
						|
 | 
						|
    @staticmethod
 | 
						|
    def CreateSmMaps(world):
 | 
						|
        itemPool =  [
 | 
						|
            Item(ItemType.SmMapBrinstar, world),
 | 
						|
            Item(ItemType.SmMapWreckedShip, world),
 | 
						|
            Item(ItemType.SmMapMaridia, world),
 | 
						|
            Item(ItemType.SmMapLowerNorfair, world)
 | 
						|
        ]
 | 
						|
 | 
						|
        for item in itemPool:
 | 
						|
            item.Progression = True
 | 
						|
            item.World = world
 | 
						|
 | 
						|
        return itemPool
 | 
						|
 | 
						|
    @staticmethod
 | 
						|
    def Get(items, itemType:ItemType):
 | 
						|
        item = next((i for i in items if i.Type == itemType), None)
 | 
						|
        if (item == None):
 | 
						|
            raise Exception(f"Could not find an item of type {itemType}")
 | 
						|
        return item
 | 
						|
 | 
						|
    @staticmethod
 | 
						|
    def Get(items, itemType:ItemType, world):
 | 
						|
        item = next((i for i in items if i.Is(itemType, world)), None)
 | 
						|
        if (item == None):
 | 
						|
            raise Exception(f"Could not find an item of type {itemType} in world {world.Id}")
 | 
						|
        return item
 | 
						|
 | 
						|
class Progression:
 | 
						|
    BigKeyEP: bool
 | 
						|
    BigKeyDP: bool
 | 
						|
    BigKeyTH: bool
 | 
						|
    BigKeyPD: bool
 | 
						|
    BigKeySP: bool
 | 
						|
    BigKeySW: bool
 | 
						|
    BigKeyTT: bool
 | 
						|
    BigKeyIP: bool
 | 
						|
    BigKeyMM: bool
 | 
						|
    BigKeyTR: bool
 | 
						|
    BigKeyGT: bool
 | 
						|
    KeyHC: bool
 | 
						|
    KeyDP: bool
 | 
						|
    KeyTH: bool
 | 
						|
    KeySP: bool
 | 
						|
    KeyTT: bool
 | 
						|
    KeyCT: bool
 | 
						|
    KeyPD: bool
 | 
						|
    KeySW: bool
 | 
						|
    KeyIP: bool
 | 
						|
    KeyMM: bool
 | 
						|
    KeyTR: bool
 | 
						|
    KeyGT: bool
 | 
						|
    CardCrateriaL1: bool
 | 
						|
    CardCrateriaL2: bool
 | 
						|
    CardCrateriaBoss: bool
 | 
						|
    CardBrinstarL1: bool
 | 
						|
    CardBrinstarL2: bool
 | 
						|
    CardBrinstarBoss: bool
 | 
						|
    CardNorfairL1: bool
 | 
						|
    CardNorfairL2: bool
 | 
						|
    CardNorfairBoss: bool
 | 
						|
    CardMaridiaL1: bool
 | 
						|
    CardMaridiaL2: bool
 | 
						|
    CardMaridiaBoss: bool
 | 
						|
    CardWreckedShipL1: bool
 | 
						|
    CardWreckedShipBoss: bool
 | 
						|
    CardLowerNorfairL1: bool
 | 
						|
    CardLowerNorfairBoss: bool
 | 
						|
    def CanBlockLasers(self): return self.shield >= 3
 | 
						|
    Sword: bool
 | 
						|
    MasterSword: bool
 | 
						|
    Bow: bool
 | 
						|
    Hookshot: bool
 | 
						|
    Mushroom: bool
 | 
						|
    Powder: bool
 | 
						|
    Firerod: bool
 | 
						|
    Icerod: bool
 | 
						|
    Bombos: bool
 | 
						|
    Ether: bool
 | 
						|
    Quake: bool
 | 
						|
    Lamp: bool
 | 
						|
    Hammer: bool
 | 
						|
    Shovel: bool
 | 
						|
    Flute: bool
 | 
						|
    Book: bool
 | 
						|
    Bottle: bool
 | 
						|
    Somaria: bool
 | 
						|
    Byrna: bool
 | 
						|
    Cape: bool
 | 
						|
    Mirror: bool
 | 
						|
    Boots: bool
 | 
						|
    Glove: bool
 | 
						|
    Mitt: bool
 | 
						|
    Flippers: bool
 | 
						|
    MoonPearl: bool
 | 
						|
    HalfMagic: bool
 | 
						|
    Grapple: bool
 | 
						|
    Charge: bool
 | 
						|
    Ice: bool
 | 
						|
    Wave: bool
 | 
						|
    Plasma: bool
 | 
						|
    Varia: bool
 | 
						|
    Gravity: bool
 | 
						|
    Morph: bool
 | 
						|
    Bombs: bool
 | 
						|
    SpringBall: bool
 | 
						|
    ScrewAttack: bool
 | 
						|
    HiJump: bool
 | 
						|
    SpaceJump: bool
 | 
						|
    SpeedBooster: bool
 | 
						|
    Missile: bool
 | 
						|
    Super: bool
 | 
						|
    PowerBomb: bool
 | 
						|
    TwoPowerBombs: bool
 | 
						|
    ETank: int
 | 
						|
    ReserveTank: int
 | 
						|
 | 
						|
    shield: int
 | 
						|
 | 
						|
    itemMapping = [
 | 
						|
        ItemType.BigKeyEP,
 | 
						|
        ItemType.BigKeyDP,
 | 
						|
        ItemType.BigKeyTH,
 | 
						|
        ItemType.BigKeyPD,
 | 
						|
        ItemType.BigKeySP,
 | 
						|
        ItemType.BigKeySW,
 | 
						|
        ItemType.BigKeyTT,
 | 
						|
        ItemType.BigKeyIP,
 | 
						|
        ItemType.BigKeyMM,
 | 
						|
        ItemType.BigKeyTR,
 | 
						|
        ItemType.BigKeyGT,
 | 
						|
        ItemType.KeyHC,
 | 
						|
        ItemType.KeyDP,
 | 
						|
        ItemType.KeyTH,
 | 
						|
        ItemType.KeySP,
 | 
						|
        ItemType.KeyTT,
 | 
						|
        ItemType.CardCrateriaL1,
 | 
						|
        ItemType.CardCrateriaL2,
 | 
						|
        ItemType.CardCrateriaBoss,
 | 
						|
        ItemType.CardBrinstarL1,
 | 
						|
        ItemType.CardBrinstarL2,
 | 
						|
        ItemType.CardBrinstarBoss,
 | 
						|
        ItemType.CardNorfairL1,
 | 
						|
        ItemType.CardNorfairL2,
 | 
						|
        ItemType.CardNorfairBoss,
 | 
						|
        ItemType.CardMaridiaL1,
 | 
						|
        ItemType.CardMaridiaL2,
 | 
						|
        ItemType.CardMaridiaBoss,
 | 
						|
        ItemType.CardWreckedShipL1,
 | 
						|
        ItemType.CardWreckedShipBoss,
 | 
						|
        ItemType.CardLowerNorfairL1,
 | 
						|
        ItemType.CardLowerNorfairBoss,
 | 
						|
        ItemType.Bow,
 | 
						|
        ItemType.Hookshot,
 | 
						|
        ItemType.Mushroom,
 | 
						|
        ItemType.Powder,
 | 
						|
        ItemType.Firerod,
 | 
						|
        ItemType.Icerod,
 | 
						|
        ItemType.Bombos,
 | 
						|
        ItemType.Ether,
 | 
						|
        ItemType.Quake,
 | 
						|
        ItemType.Lamp,
 | 
						|
        ItemType.Hammer,
 | 
						|
        ItemType.Shovel,
 | 
						|
        ItemType.Flute,
 | 
						|
        ItemType.Book,
 | 
						|
        ItemType.Bottle,
 | 
						|
        ItemType.Somaria,
 | 
						|
        ItemType.Byrna,
 | 
						|
        ItemType.Cape,
 | 
						|
        ItemType.Mirror,
 | 
						|
        ItemType.Boots,
 | 
						|
        ItemType.Flippers,
 | 
						|
        ItemType.MoonPearl,
 | 
						|
        ItemType.HalfMagic,
 | 
						|
        ItemType.Grapple,
 | 
						|
        ItemType.Charge,
 | 
						|
        ItemType.Ice,
 | 
						|
        ItemType.Wave,
 | 
						|
        ItemType.Plasma,
 | 
						|
        ItemType.Varia,
 | 
						|
        ItemType.Gravity,
 | 
						|
        ItemType.Morph,
 | 
						|
        ItemType.Bombs,
 | 
						|
        ItemType.SpringBall,
 | 
						|
        ItemType.ScrewAttack,
 | 
						|
        ItemType.HiJump,
 | 
						|
        ItemType.SpaceJump,
 | 
						|
        ItemType.SpeedBooster,
 | 
						|
        ItemType.Missile,
 | 
						|
        ItemType.Super,
 | 
						|
    ]
 | 
						|
 | 
						|
    def __init__(self, items):
 | 
						|
        for item in Progression.itemMapping:
 | 
						|
            setattr(self, item.name, False)
 | 
						|
        self.KeyCT = 0
 | 
						|
        self.KeyPD = 0
 | 
						|
        self.KeySW = 0
 | 
						|
        self.KeyIP = 0
 | 
						|
        self.KeyMM = 0
 | 
						|
        self.KeyTR = 0
 | 
						|
        self.KeyGT = 0
 | 
						|
        self.ETank = 0
 | 
						|
        self.ReserveTank = 0
 | 
						|
        self.shield = 0
 | 
						|
        self.MasterSword = False
 | 
						|
        self.Sword = False
 | 
						|
        self.Mitt = False
 | 
						|
        self.Glove = False
 | 
						|
        self.TwoPowerBombs = False
 | 
						|
        self.PowerBomb = False
 | 
						|
        self.Add(items)
 | 
						|
 | 
						|
    def Add(self, items:List[Item]):
 | 
						|
        for item in items:
 | 
						|
            found = item.Type in Progression.itemMapping
 | 
						|
            if found:
 | 
						|
                setattr(self, item.Type.name, True)
 | 
						|
                continue
 | 
						|
 | 
						|
            if (item.Type == ItemType.KeyCT):
 | 
						|
                self.KeyCT += 1
 | 
						|
            elif (item.Type == ItemType.KeyPD):
 | 
						|
                self.KeyPD += 1
 | 
						|
            elif (item.Type == ItemType.KeySW):
 | 
						|
                self.KeySW += 1
 | 
						|
            elif (item.Type == ItemType.KeyIP):
 | 
						|
                self.KeyIP += 1
 | 
						|
            elif (item.Type == ItemType.KeyMM):
 | 
						|
                self.KeyMM += 1
 | 
						|
            elif (item.Type == ItemType.KeyTR):
 | 
						|
                self.KeyTR += 1
 | 
						|
            elif (item.Type == ItemType.KeyGT):
 | 
						|
                self.KeyGT += 1
 | 
						|
            elif (item.Type == ItemType.ETank):
 | 
						|
                self.ETank += 1
 | 
						|
            elif (item.Type == ItemType.ReserveTank):
 | 
						|
                self.ReserveTank += 1
 | 
						|
            elif (item.Type == ItemType.KeyPD):
 | 
						|
                self.shield += 1
 | 
						|
            elif (item.Type == ItemType.ProgressiveSword):
 | 
						|
                self.MasterSword = self.Sword
 | 
						|
                self.Sword = True
 | 
						|
            elif (item.Type == ItemType.ProgressiveGlove):
 | 
						|
                self.Mitt = self.Glove
 | 
						|
                self.Glove = True
 | 
						|
            elif (item.Type == ItemType.PowerBomb):
 | 
						|
                self.TwoPowerBombs = self.PowerBomb
 | 
						|
                self.PowerBomb = True     
 | 
						|
 | 
						|
    def Remove(self, items:List[Item]):
 | 
						|
        for item in items:
 | 
						|
            found = item.Type in Progression.itemMapping
 | 
						|
            if found:
 | 
						|
                setattr(self, item.Type.name, False)
 | 
						|
                continue
 | 
						|
 | 
						|
            if (item.Type == ItemType.KeyCT):
 | 
						|
                self.KeyCT -= 1
 | 
						|
            elif (item.Type == ItemType.KeyPD):
 | 
						|
                self.KeyPD -= 1
 | 
						|
            elif (item.Type == ItemType.KeySW):
 | 
						|
                self.KeySW -= 1
 | 
						|
            elif (item.Type == ItemType.KeyIP):
 | 
						|
                self.KeyIP -= 1
 | 
						|
            elif (item.Type == ItemType.KeyMM):
 | 
						|
                self.KeyMM -= 1
 | 
						|
            elif (item.Type == ItemType.KeyTR):
 | 
						|
                self.KeyTR -= 1
 | 
						|
            elif (item.Type == ItemType.KeyGT):
 | 
						|
                self.KeyGT -= 1
 | 
						|
            elif (item.Type == ItemType.ETank):
 | 
						|
                self.ETank -= 1
 | 
						|
            elif (item.Type == ItemType.ReserveTank):
 | 
						|
                self.ReserveTank -= 1
 | 
						|
            elif (item.Type == ItemType.KeyPD):
 | 
						|
                self.shield -= 1
 | 
						|
            elif (item.Type == ItemType.ProgressiveSword):
 | 
						|
                self.Sword = self.MasterSword
 | 
						|
                self.MasterSword = False
 | 
						|
            elif (item.Type == ItemType.ProgressiveGlove):
 | 
						|
                self.Glove = self.Mitt
 | 
						|
                self.Mitt = False
 | 
						|
            elif (item.Type == ItemType.PowerBomb):
 | 
						|
                self.PowerBomb = self.TwoPowerBombs
 | 
						|
                self.TwoPowerBombs = False           
 | 
						|
 | 
						|
    def CanLiftLight(self): return self.Glove
 | 
						|
 | 
						|
    def CanLiftHeavy(self): return self.Mitt
 | 
						|
 | 
						|
    def CanLightTorches(self): return self.Firerod or self.Lamp
 | 
						|
 | 
						|
    def CanMeltFreezors(self): return self.Firerod or self.Bombos and self.Sword
 | 
						|
 | 
						|
    def CanExtendMagic(self, bars:int = 2): return (2 if self.HalfMagic else 1) * (2 if self.Bottle else 1) >= bars
 | 
						|
 | 
						|
    def CanKillManyEnemies(self):
 | 
						|
        return self.Sword or self.Hammer or self.Bow or self.Firerod or \
 | 
						|
                self.Somaria or self.Byrna and self.CanExtendMagic()
 | 
						|
 | 
						|
    def CanAccessDeathMountainPortal(self):
 | 
						|
        return (self.CanDestroyBombWalls() or self.SpeedBooster) and self.Super and self.Morph
 | 
						|
        
 | 
						|
 | 
						|
    def CanAccessDarkWorldPortal(self, config: Config):
 | 
						|
        if (config.SMLogic == SMLogic.Normal):
 | 
						|
            return self.CardMaridiaL1 and self.CardMaridiaL2 and self.CanUsePowerBombs() and self.Super and self.Gravity and self.SpeedBooster
 | 
						|
        else:
 | 
						|
            return self.CardMaridiaL1 and self.CardMaridiaL2 and self.CanUsePowerBombs() and self.Super and \
 | 
						|
                (self.Charge or self.Super and self.Missile) and \
 | 
						|
                (self.Gravity or self.HiJump and self.Ice and self.Grapple) and \
 | 
						|
                (self.Ice or self.Gravity and self.SpeedBooster)
 | 
						|
 | 
						|
 | 
						|
    def CanAccessMiseryMirePortal(self, config: Config):
 | 
						|
        if (config.SMLogic == SMLogic.Normal):
 | 
						|
            return (self.CardNorfairL2 or (self.SpeedBooster and self.Wave)) and self.Varia and self.Super and self.Gravity and self.SpaceJump and self.CanUsePowerBombs()
 | 
						|
        else:
 | 
						|
            return (self.CardNorfairL2 or self.SpeedBooster) and self.Varia and self.Super and \
 | 
						|
                    (self.CanFly() or self.HiJump or self.SpeedBooster or self.CanSpringBallJump() or self.Ice) \
 | 
						|
                    and (self.Gravity or self.HiJump) and self.CanUsePowerBombs() 
 | 
						|
 | 
						|
    def CanIbj(self):
 | 
						|
            return self.Morph and self.Bombs
 | 
						|
 | 
						|
    def CanFly(self):
 | 
						|
            return self.SpaceJump or self.CanIbj()
 | 
						|
 | 
						|
    def CanUsePowerBombs(self):
 | 
						|
            return self.Morph and self.PowerBomb
 | 
						|
 | 
						|
    def CanPassBombPassages(self):
 | 
						|
            return self.Morph and (self.Bombs or self.PowerBomb)
 | 
						|
 | 
						|
    def CanDestroyBombWalls(self):
 | 
						|
            return self.CanPassBombPassages() or self.ScrewAttack
 | 
						|
 | 
						|
    def CanSpringBallJump(self):
 | 
						|
            return self.Morph and self.SpringBall
 | 
						|
 | 
						|
    def CanHellRun(self):
 | 
						|
            return self.Varia or self.HasEnergyReserves(5)
 | 
						|
 | 
						|
    def HasEnergyReserves(self, amount: int):
 | 
						|
            return (self.ETank + self.ReserveTank) >= amount
 | 
						|
 | 
						|
    def CanOpenRedDoors(self):
 | 
						|
            return self.Missile or self.Super
 | 
						|
 | 
						|
    def CanAccessNorfairUpperPortal(self):
 | 
						|
            return self.Flute or self.CanLiftLight() and self.Lamp
 | 
						|
 | 
						|
    def CanAccessNorfairLowerPortal(self):
 | 
						|
            return self.Flute and self.CanLiftHeavy()
 | 
						|
 | 
						|
    def CanAccessMaridiaPortal(self, world):
 | 
						|
        import worlds.smz3.TotalSMZ3.Region
 | 
						|
        if (world.Config.SMLogic == SMLogic.Normal):
 | 
						|
            return self.MoonPearl and self.Flippers 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())
 | 
						|
        else:
 | 
						|
            return self.MoonPearl and self.Flippers 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())
 | 
						|
 | 
						|
# Start of AP integration
 | 
						|
items_start_id = 84000
 | 
						|
 | 
						|
lookup_id_to_name = { items_start_id + enum.value : enum.name for enum in ItemType }
 | 
						|
lookup_name_to_id = { item_name : item_id for item_id, item_name in lookup_id_to_name.items() } |