Yoshi's Island: Implement New Game (#2141)

Co-authored-by: Silvris <58583688+Silvris@users.noreply.github.com>
Co-authored-by: Alchav <59858495+Alchav@users.noreply.github.com>
Co-authored-by: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com>
Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com>
This commit is contained in:
PinkSwitch 2024-03-22 15:35:00 -05:00 committed by GitHub
parent aaa3472d5d
commit 355223b8f0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 4559 additions and 0 deletions

View File

@ -64,6 +64,7 @@ Currently, the following games are supported:
* Zork Grand Inquisitor
* Castlevania 64
* A Short Hike
* Yoshi's Island
For setup and instructions check out our [tutorials page](https://archipelago.gg/tutorial/).
Downloads can be found at [Releases](https://github.com/ArchipelagoMW/Archipelago/releases), including compiled

View File

@ -191,6 +191,9 @@
# The Witness
/worlds/witness/ @NewSoupVi @blastron
# Yoshi's Island
/worlds/yoshisisland/ @PinkSwitch
# Zillion
/worlds/zillion/ @beauxq

View File

@ -189,6 +189,11 @@ Root: HKCR; Subkey: "{#MyAppName}advnpatch"; ValueData: "Arc
Root: HKCR; Subkey: "{#MyAppName}advnpatch\DefaultIcon"; ValueData: "{app}\ArchipelagoAdventureClient.exe,0"; ValueType: string; ValueName: "";
Root: HKCR; Subkey: "{#MyAppName}advnpatch\shell\open\command"; ValueData: """{app}\ArchipelagoAdventureClient.exe"" ""%1"""; ValueType: string; ValueName: "";
Root: HKCR; Subkey: ".apyi"; ValueData: "{#MyAppName}yipatch"; Flags: uninsdeletevalue; ValueType: string; ValueName: "";
Root: HKCR; Subkey: "{#MyAppName}yipatch"; ValueData: "Archipelago Yoshi's Island Patch"; Flags: uninsdeletekey; ValueType: string; ValueName: "";
Root: HKCR; Subkey: "{#MyAppName}yipatch\DefaultIcon"; ValueData: "{app}\ArchipelagoSNIClient.exe,0"; ValueType: string; ValueName: "";
Root: HKCR; Subkey: "{#MyAppName}yipatch\shell\open\command"; ValueData: """{app}\ArchipelagoSNIClient.exe"" ""%1"""; ValueType: string; ValueName: "";
Root: HKCR; Subkey: ".archipelago"; ValueData: "{#MyAppName}multidata"; Flags: uninsdeletevalue; ValueType: string; ValueName: "";
Root: HKCR; Subkey: "{#MyAppName}multidata"; ValueData: "Archipelago Server Data"; Flags: uninsdeletekey; ValueType: string; ValueName: "";
Root: HKCR; Subkey: "{#MyAppName}multidata\DefaultIcon"; ValueData: "{app}\ArchipelagoServer.exe,0"; ValueType: string; ValueName: "";

View File

@ -0,0 +1,144 @@
import logging
import struct
import typing
import time
from struct import pack
from NetUtils import ClientStatus, color
from worlds.AutoSNIClient import SNIClient
if typing.TYPE_CHECKING:
from SNIClient import SNIContext
snes_logger = logging.getLogger("SNES")
ROM_START = 0x000000
WRAM_START = 0xF50000
WRAM_SIZE = 0x20000
SRAM_START = 0xE00000
YOSHISISLAND_ROMHASH_START = 0x007FC0
ROMHASH_SIZE = 0x15
ITEMQUEUE_HIGH = WRAM_START + 0x1465
ITEM_RECEIVED = WRAM_START + 0x1467
DEATH_RECEIVED = WRAM_START + 0x7E23B0
GAME_MODE = WRAM_START + 0x0118
YOSHI_STATE = SRAM_START + 0x00AC
DEATHLINK_ADDR = ROM_START + 0x06FC8C
DEATHMUSIC_FLAG = WRAM_START + 0x004F
DEATHFLAG = WRAM_START + 0x00DB
DEATHLINKRECV = WRAM_START + 0x00E0
GOALFLAG = WRAM_START + 0x14B6
VALID_GAME_STATES = [0x0F, 0x10, 0x2C]
class YoshisIslandSNIClient(SNIClient):
game = "Yoshi's Island"
async def deathlink_kill_player(self, ctx: "SNIContext") -> None:
from SNIClient import DeathState, snes_buffered_write, snes_flush_writes, snes_read
game_state = await snes_read(ctx, GAME_MODE, 0x1)
if game_state[0] != 0x0F:
return
yoshi_state = await snes_read(ctx, YOSHI_STATE, 0x1)
if yoshi_state[0] != 0x00:
return
snes_buffered_write(ctx, WRAM_START + 0x026A, bytes([0x01]))
snes_buffered_write(ctx, WRAM_START + 0x00E0, bytes([0x01]))
await snes_flush_writes(ctx)
ctx.death_state = DeathState.dead
ctx.last_death_link = time.time()
async def validate_rom(self, ctx: "SNIContext") -> bool:
from SNIClient import snes_read
rom_name = await snes_read(ctx, YOSHISISLAND_ROMHASH_START, ROMHASH_SIZE)
if rom_name is None or rom_name[:7] != b"YOSHIAP":
return False
ctx.game = self.game
ctx.items_handling = 0b111 # remote items
ctx.rom = rom_name
death_link = await snes_read(ctx, DEATHLINK_ADDR, 1)
if death_link:
await ctx.update_death_link(bool(death_link[0] & 0b1))
return True
async def game_watcher(self, ctx: "SNIContext") -> None:
from SNIClient import snes_buffered_write, snes_flush_writes, snes_read
game_mode = await snes_read(ctx, GAME_MODE, 0x1)
item_received = await snes_read(ctx, ITEM_RECEIVED, 0x1)
game_music = await snes_read(ctx, DEATHMUSIC_FLAG, 0x1)
goal_flag = await snes_read(ctx, GOALFLAG, 0x1)
if "DeathLink" in ctx.tags and ctx.last_death_link + 1 < time.time():
death_flag = await snes_read(ctx, DEATHFLAG, 0x1)
deathlink_death = await snes_read(ctx, DEATHLINKRECV, 0x1)
currently_dead = (game_music[0] == 0x07 or game_mode[0] == 0x12 or
(death_flag[0] == 0x00 and game_mode[0] == 0x11)) and deathlink_death[0] == 0x00
await ctx.handle_deathlink_state(currently_dead)
if game_mode is None:
return
elif goal_flag[0] != 0x00:
await ctx.send_msgs([{"cmd": "StatusUpdate", "status": ClientStatus.CLIENT_GOAL}])
ctx.finished_game = True
elif game_mode[0] not in VALID_GAME_STATES:
return
elif item_received[0] > 0x00:
return
from .Rom import item_values
rom = await snes_read(ctx, YOSHISISLAND_ROMHASH_START, ROMHASH_SIZE)
if rom != ctx.rom:
ctx.rom = None
return
new_checks = []
from .Rom import location_table
location_ram_data = await snes_read(ctx, WRAM_START + 0x1440, 0x80)
for loc_id, loc_data in location_table.items():
if loc_id not in ctx.locations_checked:
data = location_ram_data[loc_data[0] - 0x1440]
masked_data = data & (1 << loc_data[1])
bit_set = masked_data != 0
invert_bit = ((len(loc_data) >= 3) and loc_data[2])
if bit_set != invert_bit:
new_checks.append(loc_id)
for new_check_id in new_checks:
ctx.locations_checked.add(new_check_id)
location = ctx.location_names[new_check_id]
total_locations = len(ctx.missing_locations) + len(ctx.checked_locations)
snes_logger.info(f"New Check: {location} ({len(ctx.locations_checked)}/{total_locations})")
await ctx.send_msgs([{"cmd": "LocationChecks", "locations": [new_check_id]}])
recv_count = await snes_read(ctx, ITEMQUEUE_HIGH, 2)
recv_index = struct.unpack("H", recv_count)[0]
if recv_index < len(ctx.items_received):
item = ctx.items_received[recv_index]
recv_index += 1
logging.info("Received %s from %s (%s) (%d/%d in list)" % (
color(ctx.item_names[item.item], "red", "bold"),
color(ctx.player_names[item.player], "yellow"),
ctx.location_names[item.location], recv_index, len(ctx.items_received)))
snes_buffered_write(ctx, ITEMQUEUE_HIGH, pack("H", recv_index))
if item.item in item_values:
item_count = await snes_read(ctx, WRAM_START + item_values[item.item][0], 0x1)
increment = item_values[item.item][1]
new_item_count = item_count[0]
if increment > 1:
new_item_count = increment
else:
new_item_count += increment
snes_buffered_write(ctx, WRAM_START + item_values[item.item][0], bytes([new_item_count]))
await snes_flush_writes(ctx)

View File

@ -0,0 +1,122 @@
from typing import Dict, Set, Tuple, NamedTuple, Optional
from BaseClasses import ItemClassification
class ItemData(NamedTuple):
category: str
code: Optional[int]
classification: ItemClassification
amount: Optional[int] = 1
item_table: Dict[str, ItemData] = {
"! Switch": ItemData("Items", 0x302050, ItemClassification.progression),
"Dashed Platform": ItemData("Items", 0x302051, ItemClassification.progression),
"Dashed Stairs": ItemData("Items", 0x302052, ItemClassification.progression),
"Beanstalk": ItemData("Items", 0x302053, ItemClassification.progression),
"Helicopter Morph": ItemData("Morphs", 0x302054, ItemClassification.progression),
"Spring Ball": ItemData("Items", 0x302055, ItemClassification.progression),
"Large Spring Ball": ItemData("Items", 0x302056, ItemClassification.progression),
"Arrow Wheel": ItemData("Items", 0x302057, ItemClassification.progression),
"Vanishing Arrow Wheel": ItemData("Items", 0x302058, ItemClassification.progression),
"Mole Tank Morph": ItemData("Morphs", 0x302059, ItemClassification.progression),
"Watermelon": ItemData("Items", 0x30205A, ItemClassification.progression),
"Ice Melon": ItemData("Items", 0x30205B, ItemClassification.progression),
"Fire Melon": ItemData("Items", 0x30205C, ItemClassification.progression),
"Super Star": ItemData("Items", 0x30205D, ItemClassification.progression),
"Car Morph": ItemData("Morphs", 0x30205E, ItemClassification.progression),
"Flashing Eggs": ItemData("Items", 0x30205F, ItemClassification.progression),
"Giant Eggs": ItemData("Items", 0x302060, ItemClassification.progression),
"Egg Launcher": ItemData("Items", 0x302061, ItemClassification.progression),
"Egg Plant": ItemData("Items", 0x302062, ItemClassification.progression),
"Submarine Morph": ItemData("Morphs", 0x302063, ItemClassification.progression),
"Chomp Rock": ItemData("Items", 0x302064, ItemClassification.progression),
"Poochy": ItemData("Items", 0x302065, ItemClassification.progression),
"Platform Ghost": ItemData("Items", 0x302066, ItemClassification.progression),
"Skis": ItemData("Items", 0x302067, ItemClassification.progression),
"Train Morph": ItemData("Morphs", 0x302068, ItemClassification.progression),
"Key": ItemData("Items", 0x302069, ItemClassification.progression),
"Middle Ring": ItemData("Items", 0x30206A, ItemClassification.progression),
"Bucket": ItemData("Items", 0x30206B, ItemClassification.progression),
"Tulip": ItemData("Items", 0x30206C, ItemClassification.progression),
"Egg Capacity Upgrade": ItemData("Items", 0x30206D, ItemClassification.progression, 5),
"Secret Lens": ItemData("Items", 0x302081, ItemClassification.progression),
"World 1 Gate": ItemData("Gates", 0x30206E, ItemClassification.progression),
"World 2 Gate": ItemData("Gates", 0x30206F, ItemClassification.progression),
"World 3 Gate": ItemData("Gates", 0x302070, ItemClassification.progression),
"World 4 Gate": ItemData("Gates", 0x302071, ItemClassification.progression),
"World 5 Gate": ItemData("Gates", 0x302072, ItemClassification.progression),
"World 6 Gate": ItemData("Gates", 0x302073, ItemClassification.progression),
"Extra 1": ItemData("Panels", 0x302074, ItemClassification.progression),
"Extra 2": ItemData("Panels", 0x302075, ItemClassification.progression),
"Extra 3": ItemData("Panels", 0x302076, ItemClassification.progression),
"Extra 4": ItemData("Panels", 0x302077, ItemClassification.progression),
"Extra 5": ItemData("Panels", 0x302078, ItemClassification.progression),
"Extra 6": ItemData("Panels", 0x302079, ItemClassification.progression),
"Extra Panels": ItemData("Panels", 0x30207A, ItemClassification.progression),
"Bonus 1": ItemData("Panels", 0x30207B, ItemClassification.progression),
"Bonus 2": ItemData("Panels", 0x30207C, ItemClassification.progression),
"Bonus 3": ItemData("Panels", 0x30207D, ItemClassification.progression),
"Bonus 4": ItemData("Panels", 0x30207E, ItemClassification.progression),
"Bonus 5": ItemData("Panels", 0x30207F, ItemClassification.progression),
"Bonus 6": ItemData("Panels", 0x302080, ItemClassification.progression),
"Bonus Panels": ItemData("Panels", 0x302082, ItemClassification.progression),
"Anytime Egg": ItemData("Consumable", 0x302083, ItemClassification.useful, 0),
"Anywhere Pow": ItemData("Consumable", 0x302084, ItemClassification.filler, 0),
"Winged Cloud Maker": ItemData("Consumable", 0x302085, ItemClassification.filler, 0),
"Pocket Melon": ItemData("Consumable", 0x302086, ItemClassification.filler, 0),
"Pocket Fire Melon": ItemData("Consumable", 0x302087, ItemClassification.filler, 0),
"Pocket Ice Melon": ItemData("Consumable", 0x302088, ItemClassification.filler, 0),
"Magnifying Glass": ItemData("Consumable", 0x302089, ItemClassification.filler, 0),
"+10 Stars": ItemData("Consumable", 0x30208A, ItemClassification.useful, 0),
"+20 Stars": ItemData("Consumable", 0x30208B, ItemClassification.useful, 0),
"1-Up": ItemData("Lives", 0x30208C, ItemClassification.filler, 0),
"2-Up": ItemData("Lives", 0x30208D, ItemClassification.filler, 0),
"3-Up": ItemData("Lives", 0x30208E, ItemClassification.filler, 0),
"10-Up": ItemData("Lives", 0x30208F, ItemClassification.filler, 5),
"Bonus Consumables": ItemData("Events", None, ItemClassification.progression, 0),
"Bandit Consumables": ItemData("Events", None, ItemClassification.progression, 0),
"Bandit Watermelons": ItemData("Events", None, ItemClassification.progression, 0),
"Fuzzy Trap": ItemData("Traps", 0x302090, ItemClassification.trap, 0),
"Reversal Trap": ItemData("Traps", 0x302091, ItemClassification.trap, 0),
"Darkness Trap": ItemData("Traps", 0x302092, ItemClassification.trap, 0),
"Freeze Trap": ItemData("Traps", 0x302093, ItemClassification.trap, 0),
"Boss Clear": ItemData("Events", None, ItemClassification.progression, 0),
"Piece of Luigi": ItemData("Items", 0x302095, ItemClassification.progression, 0),
"Saved Baby Luigi": ItemData("Events", None, ItemClassification.progression, 0)
}
filler_items: Tuple[str, ...] = (
"Anytime Egg",
"Anywhere Pow",
"Winged Cloud Maker",
"Pocket Melon",
"Pocket Fire Melon",
"Pocket Ice Melon",
"Magnifying Glass",
"+10 Stars",
"+20 Stars",
"1-Up",
"2-Up",
"3-Up"
)
trap_items: Tuple[str, ...] = (
"Fuzzy Trap",
"Reversal Trap",
"Darkness Trap",
"Freeze Trap"
)
def get_item_names_per_category() -> Dict[str, Set[str]]:
categories: Dict[str, Set[str]] = {}
for name, data in item_table.items():
if data.category != "Events":
categories.setdefault(data.category, set()).add(name)
return categories

View File

@ -0,0 +1,355 @@
from typing import List, Optional, NamedTuple, TYPE_CHECKING
from .Options import PlayerGoal, MinigameChecks
from worlds.generic.Rules import CollectionRule
if TYPE_CHECKING:
from . import YoshisIslandWorld
from .level_logic import YoshiLogic
class LocationData(NamedTuple):
region: str
name: str
code: Optional[int]
LevelID: int
rule: CollectionRule = lambda state: True
def get_locations(world: Optional["YoshisIslandWorld"]) -> List[LocationData]:
if world:
logic = YoshiLogic(world)
location_table: List[LocationData] = [
LocationData("1-1", "Make Eggs, Throw Eggs: Red Coins", 0x305020, 0x00),
LocationData("1-1", "Make Eggs, Throw Eggs: Flowers", 0x305021, 0x00),
LocationData("1-1", "Make Eggs, Throw Eggs: Stars", 0x305022, 0x00),
LocationData("1-1", "Make Eggs, Throw Eggs: Level Clear", 0x305023, 0x00),
LocationData("1-2", "Watch Out Below!: Red Coins", 0x305024, 0x01),
LocationData("1-2", "Watch Out Below!: Flowers", 0x305025, 0x01),
LocationData("1-2", "Watch Out Below!: Stars", 0x305026, 0x01),
LocationData("1-2", "Watch Out Below!: Level Clear", 0x305027, 0x01),
LocationData("1-3", "The Cave Of Chomp Rock: Red Coins", 0x305028, 0x02),
LocationData("1-3", "The Cave Of Chomp Rock: Flowers", 0x305029, 0x02),
LocationData("1-3", "The Cave Of Chomp Rock: Stars", 0x30502A, 0x02),
LocationData("1-3", "The Cave Of Chomp Rock: Level Clear", 0x30502B, 0x02),
LocationData("1-4", "Burt The Bashful's Fort: Red Coins", 0x30502C, 0x03),
LocationData("1-4", "Burt The Bashful's Fort: Flowers", 0x30502D, 0x03),
LocationData("1-4", "Burt The Bashful's Fort: Stars", 0x30502E, 0x03),
LocationData("1-4", "Burt The Bashful's Fort: Level Clear", 0x30502F, 0x03, lambda state: logic._14CanFightBoss(state)),
LocationData("Burt The Bashful's Boss Room", "Burt The Bashful's Boss Room", None, 0x03, lambda state: logic._14Boss(state)),
LocationData("1-5", "Hop! Hop! Donut Lifts: Red Coins", 0x305031, 0x04),
LocationData("1-5", "Hop! Hop! Donut Lifts: Flowers", 0x305032, 0x04),
LocationData("1-5", "Hop! Hop! Donut Lifts: Stars", 0x305033, 0x04),
LocationData("1-5", "Hop! Hop! Donut Lifts: Level Clear", 0x305034, 0x04),
LocationData("1-6", "Shy-Guys On Stilts: Red Coins", 0x305035, 0x05),
LocationData("1-6", "Shy-Guys On Stilts: Flowers", 0x305036, 0x05),
LocationData("1-6", "Shy-Guys On Stilts: Stars", 0x305037, 0x05),
LocationData("1-6", "Shy-Guys On Stilts: Level Clear", 0x305038, 0x05),
LocationData("1-7", "Touch Fuzzy Get Dizzy: Red Coins", 0x305039, 0x06),
LocationData("1-7", "Touch Fuzzy Get Dizzy: Flowers", 0x30503A, 0x06),
LocationData("1-7", "Touch Fuzzy Get Dizzy: Stars", 0x30503B, 0x06),
LocationData("1-7", "Touch Fuzzy Get Dizzy: Level Clear", 0x30503C, 0x06),
LocationData("1-7", "Touch Fuzzy Get Dizzy: Gather Coins", None, 0x06, lambda state: logic._17Game(state)),
LocationData("1-8", "Salvo The Slime's Castle: Red Coins", 0x30503D, 0x07),
LocationData("1-8", "Salvo The Slime's Castle: Flowers", 0x30503E, 0x07),
LocationData("1-8", "Salvo The Slime's Castle: Stars", 0x30503F, 0x07),
LocationData("1-8", "Salvo The Slime's Castle: Level Clear", 0x305040, 0x07, lambda state: logic._18CanFightBoss(state)),
LocationData("Salvo The Slime's Boss Room", "Salvo The Slime's Boss Room", None, 0x07, lambda state: logic._18Boss(state)),
LocationData("1-Bonus", "Flip Cards", None, 0x09),
############################################################################################
LocationData("2-1", "Visit Koopa And Para-Koopa: Red Coins", 0x305041, 0x0C),
LocationData("2-1", "Visit Koopa And Para-Koopa: Flowers", 0x305042, 0x0C),
LocationData("2-1", "Visit Koopa And Para-Koopa: Stars", 0x305043, 0x0C),
LocationData("2-1", "Visit Koopa And Para-Koopa: Level Clear", 0x305044, 0x0C),
LocationData("2-2", "The Baseball Boys: Red Coins", 0x305045, 0x0D),
LocationData("2-2", "The Baseball Boys: Flowers", 0x305046, 0x0D),
LocationData("2-2", "The Baseball Boys: Stars", 0x305047, 0x0D),
LocationData("2-2", "The Baseball Boys: Level Clear", 0x305048, 0x0D),
LocationData("2-3", "What's Gusty Taste Like?: Red Coins", 0x305049, 0x0E),
LocationData("2-3", "What's Gusty Taste Like?: Flowers", 0x30504A, 0x0E),
LocationData("2-3", "What's Gusty Taste Like?: Stars", 0x30504B, 0x0E),
LocationData("2-3", "What's Gusty Taste Like?: Level Clear", 0x30504C, 0x0E),
LocationData("2-4", "Bigger Boo's Fort: Red Coins", 0x30504D, 0x0F),
LocationData("2-4", "Bigger Boo's Fort: Flowers", 0x30504E, 0x0F),
LocationData("2-4", "Bigger Boo's Fort: Stars", 0x30504F, 0x0F),
LocationData("2-4", "Bigger Boo's Fort: Level Clear", 0x305050, 0x0F, lambda state: logic._24CanFightBoss(state)),
LocationData("Bigger Boo's Boss Room", "Bigger Boo's Boss Room", None, 0x0F, lambda state: logic._24Boss(state)),
LocationData("2-5", "Watch Out For Lakitu: Red Coins", 0x305051, 0x10),
LocationData("2-5", "Watch Out For Lakitu: Flowers", 0x305052, 0x10),
LocationData("2-5", "Watch Out For Lakitu: Stars", 0x305053, 0x10),
LocationData("2-5", "Watch Out For Lakitu: Level Clear", 0x305054, 0x10),
LocationData("2-6", "The Cave Of The Mystery Maze: Red Coins", 0x305055, 0x11),
LocationData("2-6", "The Cave Of The Mystery Maze: Flowers", 0x305056, 0x11),
LocationData("2-6", "The Cave Of The Mystery Maze: Stars", 0x305057, 0x11),
LocationData("2-6", "The Cave Of The Mystery Maze: Level Clear", 0x305058, 0x11),
LocationData("2-6", "The Cave Of the Mystery Maze: Seed Spitting Contest", None, 0x11, lambda state: logic._26Game(state)),
LocationData("2-7", "Lakitu's Wall: Red Coins", 0x305059, 0x12),
LocationData("2-7", "Lakitu's Wall: Flowers", 0x30505A, 0x12),
LocationData("2-7", "Lakitu's Wall: Stars", 0x30505B, 0x12),
LocationData("2-7", "Lakitu's Wall: Level Clear", 0x30505C, 0x12),
LocationData("2-7", "Lakitu's Wall: Gather Coins", None, 0x12, lambda state: logic._27Game(state)),
LocationData("2-8", "The Potted Ghost's Castle: Red Coins", 0x30505D, 0x13),
LocationData("2-8", "The Potted Ghost's Castle: Flowers", 0x30505E, 0x13),
LocationData("2-8", "The Potted Ghost's Castle: Stars", 0x30505F, 0x13),
LocationData("2-8", "The Potted Ghost's Castle: Level Clear", 0x305060, 0x13, lambda state: logic._28CanFightBoss(state)),
LocationData("Roger The Ghost's Boss Room", "Roger The Ghost's Boss Room", None, 0x13, lambda state: logic._28Boss(state)),
###############################################################################################
LocationData("3-1", "Welcome To Monkey World!: Red Coins", 0x305061, 0x18),
LocationData("3-1", "Welcome To Monkey World!: Flowers", 0x305062, 0x18),
LocationData("3-1", "Welcome To Monkey World!: Stars", 0x305063, 0x18),
LocationData("3-1", "Welcome To Monkey World!: Level Clear", 0x305064, 0x18),
LocationData("3-2", "Jungle Rhythm...: Red Coins", 0x305065, 0x19),
LocationData("3-2", "Jungle Rhythm...: Flowers", 0x305066, 0x19),
LocationData("3-2", "Jungle Rhythm...: Stars", 0x305067, 0x19),
LocationData("3-2", "Jungle Rhythm...: Level Clear", 0x305068, 0x19),
LocationData("3-3", "Nep-Enuts' Domain: Red Coins", 0x305069, 0x1A),
LocationData("3-3", "Nep-Enuts' Domain: Flowers", 0x30506A, 0x1A),
LocationData("3-3", "Nep-Enuts' Domain: Stars", 0x30506B, 0x1A),
LocationData("3-3", "Nep-Enuts' Domain: Level Clear", 0x30506C, 0x1A),
LocationData("3-4", "Prince Froggy's Fort: Red Coins", 0x30506D, 0x1B),
LocationData("3-4", "Prince Froggy's Fort: Flowers", 0x30506E, 0x1B),
LocationData("3-4", "Prince Froggy's Fort: Stars", 0x30506F, 0x1B),
LocationData("3-4", "Prince Froggy's Fort: Level Clear", 0x305070, 0x1B, lambda state: logic._34CanFightBoss(state)),
LocationData("Prince Froggy's Boss Room", "Prince Froggy's Boss Room", None, 0x1B, lambda state: logic._34Boss(state)),
LocationData("3-5", "Jammin' Through The Trees: Red Coins", 0x305071, 0x1C),
LocationData("3-5", "Jammin' Through The Trees: Flowers", 0x305072, 0x1C),
LocationData("3-5", "Jammin' Through The Trees: Stars", 0x305073, 0x1C),
LocationData("3-5", "Jammin' Through The Trees: Level Clear", 0x305074, 0x1C),
LocationData("3-6", "The Cave Of Harry Hedgehog: Red Coins", 0x305075, 0x1D),
LocationData("3-6", "The Cave Of Harry Hedgehog: Flowers", 0x305076, 0x1D),
LocationData("3-6", "The Cave Of Harry Hedgehog: Stars", 0x305077, 0x1D),
LocationData("3-6", "The Cave Of Harry Hedgehog: Level Clear", 0x305078, 0x1D),
LocationData("3-7", "Monkeys' Favorite Lake: Red Coins", 0x305079, 0x1E),
LocationData("3-7", "Monkeys' Favorite Lake: Flowers", 0x30507A, 0x1E),
LocationData("3-7", "Monkeys' Favorite Lake: Stars", 0x30507B, 0x1E),
LocationData("3-7", "Monkeys' Favorite Lake: Level Clear", 0x30507C, 0x1E),
LocationData("3-8", "Naval Piranha's Castle: Red Coins", 0x30507D, 0x1F),
LocationData("3-8", "Naval Piranha's Castle: Flowers", 0x30507E, 0x1F),
LocationData("3-8", "Naval Piranha's Castle: Stars", 0x30507F, 0x1F),
LocationData("3-8", "Naval Piranha's Castle: Level Clear", 0x305080, 0x1F, lambda state: logic._38CanFightBoss(state)),
LocationData("Naval Piranha's Boss Room", "Naval Piranha's Boss Room", None, 0x1F, lambda state: logic._38Boss(state)),
LocationData("3-Bonus", "Drawing Lots", None, 0x21),
##############################################################################################
LocationData("4-1", "GO! GO! MARIO!!: Red Coins", 0x305081, 0x24),
LocationData("4-1", "GO! GO! MARIO!!: Flowers", 0x305082, 0x24),
LocationData("4-1", "GO! GO! MARIO!!: Stars", 0x305083, 0x24),
LocationData("4-1", "GO! GO! MARIO!!: Level Clear", 0x305084, 0x24),
LocationData("4-2", "The Cave Of The Lakitus: Red Coins", 0x305085, 0x25),
LocationData("4-2", "The Cave Of The Lakitus: Flowers", 0x305086, 0x25),
LocationData("4-2", "The Cave Of The Lakitus: Stars", 0x305087, 0x25),
LocationData("4-2", "The Cave Of The Lakitus: Level Clear", 0x305088, 0x25),
LocationData("4-3", "Don't Look Back!: Red Coins", 0x305089, 0x26),
LocationData("4-3", "Don't Look Back!: Flowers", 0x30508A, 0x26),
LocationData("4-3", "Don't Look Back!: Stars", 0x30508B, 0x26),
LocationData("4-3", "Don't Look Back!: Level Clear", 0x30508C, 0x26),
LocationData("4-4", "Marching Milde's Fort: Red Coins", 0x30508D, 0x27),
LocationData("4-4", "Marching Milde's Fort: Flowers", 0x30508E, 0x27),
LocationData("4-4", "Marching Milde's Fort: Stars", 0x30508F, 0x27),
LocationData("4-4", "Marching Milde's Fort: Level Clear", 0x305090, 0x27, lambda state: logic._44CanFightBoss(state)),
LocationData("Marching Milde's Boss Room", "Marching Milde's Boss Room", None, 0x27, lambda state: logic._44Boss(state)),
LocationData("4-5", "Chomp Rock Zone: Red Coins", 0x305091, 0x28),
LocationData("4-5", "Chomp Rock Zone: Flowers", 0x305092, 0x28),
LocationData("4-5", "Chomp Rock Zone: Stars", 0x305093, 0x28),
LocationData("4-5", "Chomp Rock Zone: Level Clear", 0x305094, 0x28),
LocationData("4-6", "Lake Shore Paradise: Red Coins", 0x305095, 0x29),
LocationData("4-6", "Lake Shore Paradise: Flowers", 0x305096, 0x29),
LocationData("4-6", "Lake Shore Paradise: Stars", 0x305097, 0x29),
LocationData("4-6", "Lake Shore Paradise: Level Clear", 0x305098, 0x29),
LocationData("4-7", "Ride Like The Wind: Red Coins", 0x305099, 0x2A),
LocationData("4-7", "Ride Like The Wind: Flowers", 0x30509A, 0x2A),
LocationData("4-7", "Ride Like The Wind: Stars", 0x30509B, 0x2A),
LocationData("4-7", "Ride Like The Wind: Level Clear", 0x30509C, 0x2A),
LocationData("4-7", "Ride Like The Wind: Gather Coins", None, 0x2A, lambda state: logic._47Game(state)),
LocationData("4-8", "Hookbill The Koopa's Castle: Red Coins", 0x30509D, 0x2B),
LocationData("4-8", "Hookbill The Koopa's Castle: Flowers", 0x30509E, 0x2B),
LocationData("4-8", "Hookbill The Koopa's Castle: Stars", 0x30509F, 0x2B),
LocationData("4-8", "Hookbill The Koopa's Castle: Level Clear", 0x3050A0, 0x2B, lambda state: logic._48CanFightBoss(state)),
LocationData("Hookbill The Koopa's Boss Room", "Hookbill The Koopa's Boss Room", None, 0x2B, lambda state: logic._48Boss(state)),
LocationData("4-Bonus", "Match Cards", None, 0x2D),
######################################################################################################
LocationData("5-1", "BLIZZARD!!!: Red Coins", 0x3050A1, 0x30),
LocationData("5-1", "BLIZZARD!!!: Flowers", 0x3050A2, 0x30),
LocationData("5-1", "BLIZZARD!!!: Stars", 0x3050A3, 0x30),
LocationData("5-1", "BLIZZARD!!!: Level Clear", 0x3050A4, 0x30),
LocationData("5-2", "Ride The Ski Lifts: Red Coins", 0x3050A5, 0x31),
LocationData("5-2", "Ride The Ski Lifts: Flowers", 0x3050A6, 0x31),
LocationData("5-2", "Ride The Ski Lifts: Stars", 0x3050A7, 0x31),
LocationData("5-2", "Ride The Ski Lifts: Level Clear", 0x3050A8, 0x31),
LocationData("5-3", "Danger - Icy Conditions Ahead: Red Coins", 0x3050A9, 0x32),
LocationData("5-3", "Danger - Icy Conditions Ahead: Flowers", 0x3050AA, 0x32),
LocationData("5-3", "Danger - Icy Conditions Ahead: Stars", 0x3050AB, 0x32),
LocationData("5-3", "Danger - Icy Conditions Ahead: Level Clear", 0x3050AC, 0x32),
LocationData("5-4", "Sluggy The Unshaven's Fort: Red Coins", 0x3050AD, 0x33),
LocationData("5-4", "Sluggy The Unshaven's Fort: Flowers", 0x3050AE, 0x33),
LocationData("5-4", "Sluggy The Unshaven's Fort: Stars", 0x3050AF, 0x33),
LocationData("5-4", "Sluggy The Unshaven's Fort: Level Clear", 0x3050B0, 0x33, lambda state: logic._54CanFightBoss(state)),
LocationData("Sluggy The Unshaven's Boss Room", "Sluggy The Unshaven's Boss Room", None, 0x33, lambda state: logic._54Boss(state)),
LocationData("5-5", "Goonie Rides!: Red Coins", 0x3050B1, 0x34),
LocationData("5-5", "Goonie Rides!: Flowers", 0x3050B2, 0x34),
LocationData("5-5", "Goonie Rides!: Stars", 0x3050B3, 0x34),
LocationData("5-5", "Goonie Rides!: Level Clear", 0x3050B4, 0x34),
LocationData("5-6", "Welcome To Cloud World: Red Coins", 0x3050B5, 0x35),
LocationData("5-6", "Welcome To Cloud World: Flowers", 0x3050B6, 0x35),
LocationData("5-6", "Welcome To Cloud World: Stars", 0x3050B7, 0x35),
LocationData("5-6", "Welcome To Cloud World: Level Clear", 0x3050B8, 0x35),
LocationData("5-7", "Shifting Platforms Ahead: Red Coins", 0x3050B9, 0x36),
LocationData("5-7", "Shifting Platforms Ahead: Flowers", 0x3050BA, 0x36),
LocationData("5-7", "Shifting Platforms Ahead: Stars", 0x3050BB, 0x36),
LocationData("5-7", "Shifting Platforms Ahead: Level Clear", 0x3050BC, 0x36),
LocationData("5-8", "Raphael The Raven's Castle: Red Coins", 0x3050BD, 0x37),
LocationData("5-8", "Raphael The Raven's Castle: Flowers", 0x3050BE, 0x37),
LocationData("5-8", "Raphael The Raven's Castle: Stars", 0x3050BF, 0x37),
LocationData("5-8", "Raphael The Raven's Castle: Level Clear", 0x3050C0, 0x37, lambda state: logic._58CanFightBoss(state)),
LocationData("Raphael The Raven's Boss Room", "Raphael The Raven's Boss Room", None, 0x37, lambda state: logic._58Boss(state)),
######################################################################################################
LocationData("6-1", "Scary Skeleton Goonies!: Red Coins", 0x3050C1, 0x3C),
LocationData("6-1", "Scary Skeleton Goonies!: Flowers", 0x3050C2, 0x3C),
LocationData("6-1", "Scary Skeleton Goonies!: Stars", 0x3050C3, 0x3C),
LocationData("6-1", "Scary Skeleton Goonies!: Level Clear", 0x3050C4, 0x3C),
LocationData("6-2", "The Cave Of The Bandits: Red Coins", 0x3050C5, 0x3D),
LocationData("6-2", "The Cave Of The Bandits: Flowers", 0x3050C6, 0x3D),
LocationData("6-2", "The Cave Of The Bandits: Stars", 0x3050C7, 0x3D),
LocationData("6-2", "The Cave Of The Bandits: Level Clear", 0x3050C8, 0x3D),
LocationData("6-3", "Beware The Spinning Logs: Red Coins", 0x3050C9, 0x3E),
LocationData("6-3", "Beware The Spinning Logs: Flowers", 0x3050CA, 0x3E),
LocationData("6-3", "Beware The Spinning Logs: Stars", 0x3050CB, 0x3E),
LocationData("6-3", "Beware The Spinning Logs: Level Clear", 0x3050CC, 0x3E),
LocationData("6-4", "Tap-Tap The Red Nose's Fort: Red Coins", 0x3050CD, 0x3F),
LocationData("6-4", "Tap-Tap The Red Nose's Fort: Flowers", 0x3050CE, 0x3F),
LocationData("6-4", "Tap-Tap The Red Nose's Fort: Stars", 0x3050CF, 0x3F),
LocationData("6-4", "Tap-Tap The Red Nose's Fort: Level Clear", 0x3050D0, 0x3F, lambda state: logic._64CanFightBoss(state)),
LocationData("Tap-Tap The Red Nose's Boss Room", "Tap-Tap The Red Nose's Boss Room", None, 0x3F, lambda state: logic._64Boss(state)),
LocationData("6-5", "The Very Loooooong Cave: Red Coins", 0x3050D1, 0x40),
LocationData("6-5", "The Very Loooooong Cave: Flowers", 0x3050D2, 0x40),
LocationData("6-5", "The Very Loooooong Cave: Stars", 0x3050D3, 0x40),
LocationData("6-5", "The Very Loooooong Cave: Level Clear", 0x3050D4, 0x40),
LocationData("6-6", "The Deep, Underground Maze: Red Coins", 0x3050D5, 0x41),
LocationData("6-6", "The Deep, Underground Maze: Flowers", 0x3050D6, 0x41),
LocationData("6-6", "The Deep, Underground Maze: Stars", 0x3050D7, 0x41),
LocationData("6-6", "The Deep, Underground Maze: Level Clear", 0x3050D8, 0x41),
LocationData("6-7", "KEEP MOVING!!!!: Red Coins", 0x3050D9, 0x42),
LocationData("6-7", "KEEP MOVING!!!!: Flowers", 0x3050DA, 0x42),
LocationData("6-7", "KEEP MOVING!!!!: Stars", 0x3050DB, 0x42),
LocationData("6-7", "KEEP MOVING!!!!: Level Clear", 0x3050DC, 0x42),
LocationData("6-8", "King Bowser's Castle: Red Coins", 0x3050DD, 0x43),
LocationData("6-8", "King Bowser's Castle: Flowers", 0x3050DE, 0x43),
LocationData("6-8", "King Bowser's Castle: Stars", 0x3050DF, 0x43)
]
if not world or world.options.extras_enabled:
location_table += [
LocationData("1-Extra", "Poochy Ain't Stupid: Red Coins", 0x3050E0, 0x08),
LocationData("1-Extra", "Poochy Ain't Stupid: Flowers", 0x3050E1, 0x08),
LocationData("1-Extra", "Poochy Ain't Stupid: Stars", 0x3050E2, 0x08),
LocationData("1-Extra", "Poochy Ain't Stupid: Level Clear", 0x3050E3, 0x08),
LocationData("2-Extra", "Hit That Switch!!: Red Coins", 0x3050E4, 0x14),
LocationData("2-Extra", "Hit That Switch!!: Flowers", 0x3050E5, 0x14),
LocationData("2-Extra", "Hit That Switch!!: Stars", 0x3050E6, 0x14),
LocationData("2-Extra", "Hit That Switch!!: Level Clear", 0x3050E7, 0x14),
LocationData("3-Extra", "More Monkey Madness: Red Coins", 0x3050E8, 0x20),
LocationData("3-Extra", "More Monkey Madness: Flowers", 0x3050E9, 0x20),
LocationData("3-Extra", "More Monkey Madness: Stars", 0x3050EA, 0x20),
LocationData("3-Extra", "More Monkey Madness: Level Clear", 0x3050EB, 0x20),
LocationData("4-Extra", "The Impossible? Maze: Red Coins", 0x3050EC, 0x2C),
LocationData("4-Extra", "The Impossible? Maze: Flowers", 0x3050ED, 0x2C),
LocationData("4-Extra", "The Impossible? Maze: Stars", 0x3050EE, 0x2C),
LocationData("4-Extra", "The Impossible? Maze: Level Clear", 0x3050EF, 0x2C),
LocationData("5-Extra", "Kamek's Revenge: Red Coins", 0x3050F0, 0x38),
LocationData("5-Extra", "Kamek's Revenge: Flowers", 0x3050F1, 0x38),
LocationData("5-Extra", "Kamek's Revenge: Stars", 0x3050F2, 0x38),
LocationData("5-Extra", "Kamek's Revenge: Level Clear", 0x3050F3, 0x38),
LocationData("6-Extra", "Castles - Masterpiece Set: Red Coins", 0x3050F4, 0x44),
LocationData("6-Extra", "Castles - Masterpiece Set: Flowers", 0x3050F5, 0x44),
LocationData("6-Extra", "Castles - Masterpiece Set: Stars", 0x3050F6, 0x44),
LocationData("6-Extra", "Castles - Masterpiece Set: Level Clear", 0x3050F7, 0x44),
]
if not world or world.options.minigame_checks in {MinigameChecks.option_bandit_games, MinigameChecks.option_both}:
location_table += [
LocationData("1-3", "The Cave Of Chomp Rock: Bandit Game", 0x3050F8, 0x02, lambda state: logic._13Game(state)),
LocationData("1-7", "Touch Fuzzy Get Dizzy: Bandit Game", 0x3050F9, 0x06, lambda state: logic._17Game(state)),
LocationData("2-1", "Visit Koopa And Para-Koopa: Bandit Game", 0x3050FA, 0x0C, lambda state: logic._21Game(state)),
LocationData("2-3", "What's Gusty Taste Like?: Bandit Game", 0x3050FB, 0x0E, lambda state: logic._23Game(state)),
LocationData("2-6", "The Cave Of The Mystery Maze: Bandit Game", 0x3050FC, 0x11, lambda state: logic._26Game(state)),
LocationData("2-7", "Lakitu's Wall: Bandit Game", 0x3050FD, 0x12, lambda state: logic._27Game(state)),
LocationData("3-2", "Jungle Rhythm...: Bandit Game", 0x3050FE, 0x19, lambda state: logic._32Game(state)),
LocationData("3-7", "Monkeys' Favorite Lake: Bandit Game", 0x3050FF, 0x1E, lambda state: logic._37Game(state)),
LocationData("4-2", "The Cave Of The Lakitus: Bandit Game", 0x305100, 0x25, lambda state: logic._42Game(state)),
LocationData("4-6", "Lake Shore Paradise: Bandit Game", 0x305101, 0x29, lambda state: logic._46Game(state)),
LocationData("4-7", "Ride Like The Wind: Bandit Game", 0x305102, 0x2A, lambda state: logic._47Game(state)),
LocationData("5-1", "BLIZZARD!!!: Bandit Game", 0x305103, 0x30, lambda state: logic._51Game(state)),
LocationData("6-1", "Scary Skeleton Goonies!: Bandit Game", 0x305104, 0x3C, lambda state: logic._61Game(state)),
LocationData("6-7", "KEEP MOVING!!!!: Bandit Game", 0x305105, 0x42, lambda state: logic._67Game(state)),
]
if not world or world.options.minigame_checks in {MinigameChecks.option_bonus_games, MinigameChecks.option_both}:
location_table += [
LocationData("1-Bonus", "Flip Cards: Victory", 0x305106, 0x09),
LocationData("2-Bonus", "Scratch And Match: Victory", 0x305107, 0x15),
LocationData("3-Bonus", "Drawing Lots: Victory", 0x305108, 0x21),
LocationData("4-Bonus", "Match Cards: Victory", 0x305109, 0x2D),
LocationData("5-Bonus", "Roulette: Victory", 0x30510A, 0x39),
LocationData("6-Bonus", "Slot Machine: Victory", 0x30510B, 0x45),
]
if not world or world.options.goal == PlayerGoal.option_luigi_hunt:
location_table += [
LocationData("Overworld", "Reconstituted Luigi", None, 0x00, lambda state: logic.reconstitute_luigi(state)),
]
if not world or world.options.goal == PlayerGoal.option_bowser:
location_table += [
LocationData("Bowser's Room", "King Bowser's Castle: Level Clear", None, 0x43, lambda state: logic._68Clear(state)),
]
return location_table

View File

@ -0,0 +1,296 @@
from dataclasses import dataclass
from Options import Toggle, DefaultOnToggle, DeathLink, Choice, Range, PerGameCommonOptions
class ExtrasEnabled(Toggle):
"""If enabled, the more difficult Extra stages will be added into logic. Otherwise, they will be inaccessible."""
display_name = "Include Extra Stages"
class SplitExtras(Toggle):
"""If enabled, Extra stages will be unlocked individually. Otherwise, there will be a single 'Extra Panels' item that unlocks all of them."""
display_name = "Split Extra Stages"
class SplitBonus(Toggle):
"""If enabled, Bonus Games will be unlocked individually. Otherwise, there will be a single 'Bonus Panels' item that unlocks all of them."""
display_name = "Split Bonus Games"
class ObjectVis(Choice):
"""This will determine the default visibility of objects revealed by the Magnifying Glass.
Strict Logic will expect the Secret Lens or a Magnifying Glass to interact with hidden clouds containing stars if they are not set to visible by default."""
display_name = "Hidden Object Visibility"
option_none = 0
option_coins_only = 1
option_clouds_only = 2
option_full = 3
default = 1
class SoftlockPrevention(DefaultOnToggle):
"""If enabled, hold R + X to warp to the last used Middle Ring, or the start of the level if none have been activated."""
display_name = "Softlock Prevention Code"
class StageLogic(Choice):
"""This determines what logic mode the stages will use.
Strict: Best for casual players or those new to playing Yoshi's Island in AP. Level requirements won't expect anything too difficult of the player.
Loose: Recommended for veterans of the original game. Won't expect anything too difficult, but may expect unusual platforming or egg throws.
Expert: Logic may expect advanced knowledge or memorization of level layouts, as well as jumps the player may only have one chance to make without restarting."""
display_name = "Stage Logic"
option_strict = 0
option_loose = 1
option_expert = 2
# option_glitched = 3
default = 0
class ShuffleMiddleRings(Toggle):
"""If enabled, Middle Rings will be added to the item pool."""
display_name = "Shuffle Middle Rings"
class ShuffleSecretLens(Toggle):
"""If enabled, the Secret Lens will be added to the item pool.
The Secret Lens will act as a permanent Magnifying Glass."""
display_name = "Add Secret Lens"
class DisableAutoScrollers(Toggle):
"""If enabled, will disable autoscrolling during levels, except during levels which cannot function otherwise."""
display_name = "Disable Autoscrolling"
class ItemLogic(Toggle):
"""This will enable logic to expect consumables to be used from the inventory in place of some major items.
Logic will expect you to have access to an Overworld bonus game, or a bandit game to get the necessary items.
Logic will NOT expect grinding end-of-level bonus games, or any inventory consumables received from checks.
Casual logic will only expect consumables from Overworld games; Loose and Expert may expect them from bandit games."""
display_name = "Consumable Logic"
class MinigameChecks(Choice):
"""This will set minigame victories to give Archipelago checks.
This will not randomize minigames amongst themselves, and is compatible with item logic.
Bonus games will be expected to be cleared from the Overworld, not the end of levels.
Additionally, 1-Up bonus games will accept any profit as a victory."""
display_name = "Minigame Reward Checks"
option_none = 0
option_bandit_games = 1
option_bonus_games = 2
option_both = 3
default = 0
class StartingWorld(Choice):
"""This sets which world you start in. Other worlds can be accessed by receiving a Gate respective to that world."""
display_name = "Starting World"
option_world_1 = 0
option_world_2 = 1
option_world_3 = 2
option_world_4 = 3
option_world_5 = 4
option_world_6 = 5
default = 0
class StartingLives(Range):
"""This sets the amount of lives Yoshi will have upon loading the game."""
display_name = "Starting Life Count"
range_start = 1
range_end = 999
default = 3
class PlayerGoal(Choice):
"""This sets the goal. Bowser goal requires defeating Bowser at the end of 6-8, while Luigi Hunt requires collecting all required Luigi Pieces."""
display_name = "Goal"
option_bowser = 0
option_luigi_hunt = 1
default = 0
class LuigiPiecesReq(Range):
"""This will set how many Luigi Pieces are required to trigger a victory."""
display_name = "Luigi Pieces Required"
range_start = 1
range_end = 100
default = 25
class LuigiPiecesAmt(Range):
"""This will set how many Luigi Pieces are in the item pool.
If the number in the pool is lower than the number required,
the amount in the pool will be randomized, with the minimum being the amount required."""
display_name = "Amount of Luigi Pieces"
range_start = 1
range_end = 100
default = 50
class FinalLevelBosses(Range):
"""This sets how many bosses need to be defeated to access 6-8.
You can check this in-game by pressing SELECT while in any level."""
display_name = "Bosses Required for 6-8 Unlock"
range_start = 0
range_end = 11
default = 5
class FinalBossBosses(Range):
"""This sets how many bosses need to be defeated to access the boss of 6-8.
You can check this in-game by pressing SELECT while in any level."""
display_name = "Bosses Required for 6-8 Clear"
range_start = 0
range_end = 11
default = 0
class BowserDoor(Choice):
"""This will set which route you take through 6-8.
Manual: You go through the door that you hit with an egg, as normal.
Doors: Route will be forced to be the door chosen here, regardless of which door you hit.
Gauntlet: You will be forced to go through all 4 routes in order before the final hallway."""
display_name = "Bowser's Castle Doors"
option_manual = 0
option_door_1 = 1
option_door_2 = 2
option_door_3 = 3
option_door_4 = 4
option_gauntlet = 5
default = 0
class BossShuffle(Toggle):
"""This whill shuffle which boss each boss door will lead to. Each boss can only appear once, and Baby Bowser is left alone."""
display_name = "Boss Shuffle"
class LevelShuffle(Choice):
"""Disabled: All levels will appear in their normal location.
Bosses Guranteed: All worlds will have a boss on -4 and -8.
Full: Worlds may have more than 2 or no bosses in them.
Regardless of the setting, 6-8 and Extra stages are not shuffled."""
display_name = "Level Shuffle"
option_disabled = 0
option_bosses_guranteed = 1
option_full = 2
default = 0
class YoshiColors(Choice):
"""Sets the Yoshi color for each level.
Normal will use the vanilla colors.
Random order will generate a random order of colors that will be used in each level. The stage 1 color will be used for Extra stages, and 6-8.
Random color will generate a random color for each stage.
Singularity will use a single color defined under 'Singularity Yoshi Color' for use in all stages."""
display_name = "Yoshi Colors"
option_normal = 0
option_random_order = 1
option_random_color = 2
option_singularity = 3
default = 0
class SinguColor(Choice):
"""Sets which color Yoshi will be if Yoshi Colors is set to singularity."""
display_name = "Singularity Yoshi Color"
option_green = 0
option_pink = 1
option_cyan = 3
option_yellow = 2
option_purple = 4
option_brown = 5
option_red = 6
option_blue = 7
default = 0
class BabySound(Choice):
"""Change the sound that Baby Mario makes when not on Yoshi."""
display_name = "Mario Sound Effect"
option_normal = 0
option_disabled = 1
option_random_sound_effect = 2
default = 0
class TrapsEnabled(Toggle):
"""Will place traps into the item pool.
Traps have a variety of negative effects, and will only replace filler items."""
display_name = "Traps Enabled"
class TrapPercent(Range):
"""Percentage of the item pool that becomes replaced with traps."""
display_name = "Trap Chance"
range_start = 0
range_end = 100
default = 10
# class EnableScrets(Range):
# """This sets the amount of lives Yoshi will have upon loading the game."""
# display_name = "Starting Life Count"
# range_start = 1
# range_end = 255
# default = 3
# class BackgroundColors(Range):
# """This sets the amount of lives Yoshi will have upon loading the game."""
# display_name = "Starting Life Count"
# range_start = 1
# range_end = 255
# default = 3
# class Foreground Colors(Range):
# """This sets the amount of lives Yoshi will have upon loading the game."""
# display_name = "Starting Life Count"
# range_start = 1
# range_end = 255
# default = 3
# class Music Shuffle(Range):
# """This sets the amount of lives Yoshi will have upon loading the game."""
# display_name = "Starting Life Count"
# range_start = 1
# range_end = 255
# default = 3
# class Star Loss Rate(Range):
# """This sets the amount of lives Yoshi will have upon loading the game."""
# display_name = "Starting Life Count"
# range_start = 1
# range_end = 255
# default = 3
@dataclass
class YoshisIslandOptions(PerGameCommonOptions):
starting_world: StartingWorld
starting_lives: StartingLives
goal: PlayerGoal
luigi_pieces_required: LuigiPiecesReq
luigi_pieces_in_pool: LuigiPiecesAmt
extras_enabled: ExtrasEnabled
minigame_checks: MinigameChecks
split_extras: SplitExtras
split_bonus: SplitBonus
hidden_object_visibility: ObjectVis
add_secretlens: ShuffleSecretLens
shuffle_midrings: ShuffleMiddleRings
stage_logic: StageLogic
item_logic: ItemLogic
disable_autoscroll: DisableAutoScrollers
softlock_prevention: SoftlockPrevention
castle_open_condition: FinalLevelBosses
castle_clear_condition: FinalBossBosses
bowser_door_mode: BowserDoor
level_shuffle: LevelShuffle
boss_shuffle: BossShuffle
yoshi_colors: YoshiColors
yoshi_singularity_color: SinguColor
baby_mario_sound: BabySound
traps_enabled: TrapsEnabled
trap_percent: TrapPercent
death_link: DeathLink

View File

@ -0,0 +1,248 @@
from typing import List, Dict, TYPE_CHECKING
from BaseClasses import Region, Location
from .Locations import LocationData
from .Options import MinigameChecks
from .level_logic import YoshiLogic
from .setup_bosses import BossReqs
if TYPE_CHECKING:
from . import YoshisIslandWorld
class YoshisIslandLocation(Location):
game: str = "Yoshi's Island"
level_id: int
def __init__(self, player: int, name: str = " ", address: int = None, parent=None, level_id: int = None):
super().__init__(player, name, address, parent)
self.level_id = level_id
def init_areas(world: "YoshisIslandWorld", locations: List[LocationData]) -> None:
multiworld = world.multiworld
player = world.player
logic = YoshiLogic(world)
locations_per_region = get_locations_per_region(locations)
regions = [
create_region(world, player, locations_per_region, "Menu"),
create_region(world, player, locations_per_region, "Overworld"),
create_region(world, player, locations_per_region, "World 1"),
create_region(world, player, locations_per_region, "World 2"),
create_region(world, player, locations_per_region, "World 3"),
create_region(world, player, locations_per_region, "World 4"),
create_region(world, player, locations_per_region, "World 5"),
create_region(world, player, locations_per_region, "World 6"),
create_region(world, player, locations_per_region, "1-1"),
create_region(world, player, locations_per_region, "1-2"),
create_region(world, player, locations_per_region, "1-3"),
create_region(world, player, locations_per_region, "1-4"),
create_region(world, player, locations_per_region, "Burt The Bashful's Boss Room"),
create_region(world, player, locations_per_region, "1-5"),
create_region(world, player, locations_per_region, "1-6"),
create_region(world, player, locations_per_region, "1-7"),
create_region(world, player, locations_per_region, "1-8"),
create_region(world, player, locations_per_region, "Salvo The Slime's Boss Room"),
create_region(world, player, locations_per_region, "2-1"),
create_region(world, player, locations_per_region, "2-2"),
create_region(world, player, locations_per_region, "2-3"),
create_region(world, player, locations_per_region, "2-4"),
create_region(world, player, locations_per_region, "Bigger Boo's Boss Room"),
create_region(world, player, locations_per_region, "2-5"),
create_region(world, player, locations_per_region, "2-6"),
create_region(world, player, locations_per_region, "2-7"),
create_region(world, player, locations_per_region, "2-8"),
create_region(world, player, locations_per_region, "Roger The Ghost's Boss Room"),
create_region(world, player, locations_per_region, "3-1"),
create_region(world, player, locations_per_region, "3-2"),
create_region(world, player, locations_per_region, "3-3"),
create_region(world, player, locations_per_region, "3-4"),
create_region(world, player, locations_per_region, "Prince Froggy's Boss Room"),
create_region(world, player, locations_per_region, "3-5"),
create_region(world, player, locations_per_region, "3-6"),
create_region(world, player, locations_per_region, "3-7"),
create_region(world, player, locations_per_region, "3-8"),
create_region(world, player, locations_per_region, "Naval Piranha's Boss Room"),
create_region(world, player, locations_per_region, "4-1"),
create_region(world, player, locations_per_region, "4-2"),
create_region(world, player, locations_per_region, "4-3"),
create_region(world, player, locations_per_region, "4-4"),
create_region(world, player, locations_per_region, "Marching Milde's Boss Room"),
create_region(world, player, locations_per_region, "4-5"),
create_region(world, player, locations_per_region, "4-6"),
create_region(world, player, locations_per_region, "4-7"),
create_region(world, player, locations_per_region, "4-8"),
create_region(world, player, locations_per_region, "Hookbill The Koopa's Boss Room"),
create_region(world, player, locations_per_region, "5-1"),
create_region(world, player, locations_per_region, "5-2"),
create_region(world, player, locations_per_region, "5-3"),
create_region(world, player, locations_per_region, "5-4"),
create_region(world, player, locations_per_region, "Sluggy The Unshaven's Boss Room"),
create_region(world, player, locations_per_region, "5-5"),
create_region(world, player, locations_per_region, "5-6"),
create_region(world, player, locations_per_region, "5-7"),
create_region(world, player, locations_per_region, "5-8"),
create_region(world, player, locations_per_region, "Raphael The Raven's Boss Room"),
create_region(world, player, locations_per_region, "6-1"),
create_region(world, player, locations_per_region, "6-2"),
create_region(world, player, locations_per_region, "6-3"),
create_region(world, player, locations_per_region, "6-4"),
create_region(world, player, locations_per_region, "Tap-Tap The Red Nose's Boss Room"),
create_region(world, player, locations_per_region, "6-5"),
create_region(world, player, locations_per_region, "6-6"),
create_region(world, player, locations_per_region, "6-7"),
create_region(world, player, locations_per_region, "6-8"),
create_region(world, player, locations_per_region, "Bowser's Room"),
]
if world.options.extras_enabled:
regions.insert(68, create_region(world, player, locations_per_region, "6-Extra"))
regions.insert(58, create_region(world, player, locations_per_region, "5-Extra"))
regions.insert(48, create_region(world, player, locations_per_region, "4-Extra"))
regions.insert(38, create_region(world, player, locations_per_region, "3-Extra"))
regions.insert(28, create_region(world, player, locations_per_region, "2-Extra"))
regions.insert(18, create_region(world, player, locations_per_region, "1-Extra"))
if world.options.minigame_checks in {MinigameChecks.option_bonus_games, MinigameChecks.option_both}:
regions.insert(74, create_region(world, player, locations_per_region, "6-Bonus"))
regions.insert(63, create_region(world, player, locations_per_region, "5-Bonus"))
regions.insert(52, create_region(world, player, locations_per_region, "4-Bonus"))
regions.insert(41, create_region(world, player, locations_per_region, "3-Bonus"))
regions.insert(29, create_region(world, player, locations_per_region, "2-Bonus"))
regions.insert(19, create_region(world, player, locations_per_region, "1-Bonus"))
multiworld.regions += regions
connect_starting_region(world)
bosses = BossReqs(world)
multiworld.get_region("Overworld", player).add_exits(
["World 1", "World 2", "World 3", "World 4", "World 5", "World 6"],
{
"World 1": lambda state: state.has("World 1 Gate", player),
"World 2": lambda state: state.has("World 2 Gate", player),
"World 3": lambda state: state.has("World 3 Gate", player),
"World 4": lambda state: state.has("World 4 Gate", player),
"World 5": lambda state: state.has("World 5 Gate", player),
"World 6": lambda state: state.has("World 6 Gate", player)
}
)
for cur_world in range(1, 7):
for cur_level in range(8):
if cur_world != 6 or cur_level != 7:
multiworld.get_region(f"World {cur_world}", player).add_exits(
[world.level_location_list[(cur_world - 1) * 8 + cur_level]]
)
multiworld.get_region("1-4", player).add_exits([world.boss_order[0]],{world.boss_order[0]: lambda state: logic._14Clear(state)})
multiworld.get_region("1-8", player).add_exits([world.boss_order[1]],{world.boss_order[1]: lambda state: logic._18Clear(state)})
multiworld.get_region("2-4", player).add_exits([world.boss_order[2]],{world.boss_order[2]: lambda state: logic._24Clear(state)})
multiworld.get_region("2-8", player).add_exits([world.boss_order[3]],{world.boss_order[3]: lambda state: logic._28Clear(state)})
multiworld.get_region("3-4", player).add_exits([world.boss_order[4]],{world.boss_order[4]: lambda state: logic._34Clear(state)})
multiworld.get_region("3-8", player).add_exits([world.boss_order[5]],{world.boss_order[5]: lambda state: logic._38Clear(state)})
multiworld.get_region("4-4", player).add_exits([world.boss_order[6]],{world.boss_order[6]: lambda state: logic._44Clear(state)})
multiworld.get_region("4-8", player).add_exits([world.boss_order[7]],{world.boss_order[7]: lambda state: logic._48Clear(state)})
multiworld.get_region("5-4", player).add_exits([world.boss_order[8]],{world.boss_order[8]: lambda state: logic._54Clear(state)})
multiworld.get_region("5-8", player).add_exits([world.boss_order[9]],{world.boss_order[9]: lambda state: logic._58Clear(state)})
multiworld.get_region("World 6", player).add_exits(["6-8"],{"6-8": lambda state: bosses.castle_access(state)})
multiworld.get_region("6-4", player).add_exits([world.boss_order[10]],{world.boss_order[10]: lambda state: logic._64Clear(state)})
multiworld.get_region("6-8", player).add_exits(["Bowser's Room"],{"Bowser's Room": lambda state: bosses.castle_clear(state)})
if world.options.extras_enabled:
multiworld.get_region("World 1", player).add_exits(
["1-Extra"],
{"1-Extra": lambda state: state.has_any({"Extra Panels", "Extra 1"}, player)}
)
multiworld.get_region("World 2", player).add_exits(
["2-Extra"],
{"2-Extra": lambda state: state.has_any({"Extra Panels", "Extra 2"}, player)}
)
multiworld.get_region(
"World 3", player).add_exits(["3-Extra"],
{"3-Extra": lambda state: state.has_any({"Extra Panels", "Extra 3"}, player)}
)
multiworld.get_region("World 4", player).add_exits(
["4-Extra"],
{"4-Extra": lambda state: state.has_any({"Extra Panels", "Extra 4"}, player)}
)
multiworld.get_region("World 5", player).add_exits(
["5-Extra"],
{"5-Extra": lambda state: state.has_any({"Extra Panels", "Extra 5"}, player)}
)
multiworld.get_region("World 6", player).add_exits(
["6-Extra"],
{"6-Extra": lambda state: state.has_any({"Extra Panels", "Extra 6"}, player)}
)
if world.options.minigame_checks in {MinigameChecks.option_bonus_games, MinigameChecks.option_both}:
multiworld.get_region("World 1", player).add_exits(
["1-Bonus"],
{"1-Bonus": lambda state: state.has_any({"Bonus Panels", "Bonus 1"}, player)}
)
multiworld.get_region("World 2", player).add_exits(
["2-Bonus"],
{"2-Bonus": lambda state: state.has_any({"Bonus Panels", "Bonus 2"}, player)}
)
multiworld.get_region("World 3", player).add_exits(
["3-Bonus"],
{"3-Bonus": lambda state: state.has_any({"Bonus Panels", "Bonus 3"}, player)}
)
multiworld.get_region("World 4", player).add_exits(
["4-Bonus"],
{"4-Bonus": lambda state: state.has_any({"Bonus Panels", "Bonus 4"}, player)}
)
multiworld.get_region("World 5", player).add_exits(
["5-Bonus"],
{"5-Bonus": lambda state: state.has_any({"Bonus Panels", "Bonus 5"}, player)}
)
multiworld.get_region("World 6", player).add_exits(
["6-Bonus"],
{"6-Bonus": lambda state: state.has_any({"Bonus Panels", "Bonus 6"}, player)}
)
def create_location(player: int, location_data: LocationData, region: Region) -> Location:
location = YoshisIslandLocation(player, location_data.name, location_data.code, region)
location.access_rule = location_data.rule
location.level_id = location_data.LevelID
return location
def create_region(world: "YoshisIslandWorld", player: int, locations_per_region: Dict[str, List[LocationData]], name: str) -> Region:
region = Region(name, player, world.multiworld)
if name in locations_per_region:
for location_data in locations_per_region[name]:
location = create_location(player, location_data, region)
region.locations.append(location)
return region
def connect_starting_region(world: "YoshisIslandWorld") -> None:
multiworld = world.multiworld
player = world.player
menu = multiworld.get_region("Menu", player)
world_main = multiworld.get_region("Overworld", player)
starting_region = multiworld.get_region(f"World {world.options.starting_world + 1}", player)
menu.connect(world_main, "Start Game")
world_main.connect(starting_region, "Overworld")
def get_locations_per_region(locations: List[LocationData]) -> Dict[str, List[LocationData]]:
per_region: Dict[str, List[LocationData]] = {}
for location in locations:
per_region.setdefault(location.region, []).append(location)
return per_region

1230
worlds/yoshisisland/Rom.py Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,612 @@
from .level_logic import YoshiLogic
from worlds.generic.Rules import set_rule
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from . import YoshisIslandWorld
def set_easy_rules(world: "YoshisIslandWorld") -> None:
logic = YoshiLogic(world)
player = world.player
set_rule(world.multiworld.get_location("Make Eggs, Throw Eggs: Red Coins", player), lambda state: state.has_all({"Dashed Stairs", "Beanstalk"}, player))
set_rule(world.multiworld.get_location("Make Eggs, Throw Eggs: Flowers", player), lambda state: state.has_all({"Dashed Stairs", "Beanstalk"}, player))
set_rule(world.multiworld.get_location("Make Eggs, Throw Eggs: Stars", player), lambda state: state.has_all({"Tulip", "Beanstalk", "Dashed Stairs"}, player))
set_rule(world.multiworld.get_location("Make Eggs, Throw Eggs: Level Clear", player), lambda state: state.has("Beanstalk", player))
set_rule(world.multiworld.get_location("Watch Out Below!: Red Coins", player), lambda state: state.has_all({"Large Spring Ball", "Helicopter Morph"}, player))
set_rule(world.multiworld.get_location("Watch Out Below!: Flowers", player), lambda state: state.has_all({"Large Spring Ball", "Helicopter Morph"}, player))
set_rule(world.multiworld.get_location("Watch Out Below!: Stars", player), lambda state: state.has("Large Spring Ball", player) and logic.has_midring(state))
set_rule(world.multiworld.get_location("Watch Out Below!: Level Clear", player), lambda state: state.has("Large Spring Ball", player))
set_rule(world.multiworld.get_location("The Cave Of Chomp Rock: Red Coins", player), lambda state: state.has("Chomp Rock", player))
set_rule(world.multiworld.get_location("The Cave Of Chomp Rock: Flowers", player), lambda state: state.has("Chomp Rock", player))
set_rule(world.multiworld.get_location("Burt The Bashful's Fort: Red Coins", player), lambda state: state.has("Spring Ball", player))
set_rule(world.multiworld.get_location("Burt The Bashful's Fort: Flowers", player), lambda state: state.has_all({"Spring Ball", "Key"}, player) and (state.has("Egg Capacity Upgrade", player, 3) or logic.combat_item(state)))
set_rule(world.multiworld.get_location("Burt The Bashful's Fort: Stars", player), lambda state: state.has("Spring Ball", player) and (logic.has_midring(state) or state.has("Key", player)))
set_rule(world.multiworld.get_location("Hop! Hop! Donut Lifts: Stars", player), lambda state: logic.has_midring(state) or logic.cansee_clouds(state))
set_rule(world.multiworld.get_location("Shy-Guys On Stilts: Red Coins", player), lambda state: state.has_all({"Large Spring Ball", "Flashing Eggs", "Mole Tank Morph", "! Switch"}, player))
set_rule(world.multiworld.get_location("Shy-Guys On Stilts: Flowers", player), lambda state: state.has("Large Spring Ball", player))
set_rule(world.multiworld.get_location("Shy-Guys On Stilts: Stars", player), lambda state: (logic.has_midring(state) and state.has("Tulip", player) or logic.has_midring(state) and state.has("Beanstalk", player)) and state.has("Large Spring Ball", player))
set_rule(world.multiworld.get_location("Shy-Guys On Stilts: Level Clear", player), lambda state: state.has_all({"Large Spring Ball", "Beanstalk"}, player))
set_rule(world.multiworld.get_location("Touch Fuzzy Get Dizzy: Red Coins", player), lambda state: state.has_all({"Flashing Eggs", "Spring Ball", "Chomp Rock", "Beanstalk"}, player))
set_rule(world.multiworld.get_location("Touch Fuzzy Get Dizzy: Stars", player), lambda state: logic.has_midring(state) or (logic.cansee_clouds and state.has_all({"Spring Ball", "Chomp Rock", "Beanstalk"}, player)))
set_rule(world.multiworld.get_location("Salvo The Slime's Castle: Red Coins", player), lambda state: state.has("Platform Ghost", player))
set_rule(world.multiworld.get_location("Salvo The Slime's Castle: Flowers", player), lambda state: state.has("Platform Ghost", player))
set_rule(world.multiworld.get_location("Salvo The Slime's Castle: Stars", player), lambda state: logic.has_midring(state) and (state.has("Platform Ghost", player) or state.has_all({"Arrow Wheel", "Key"}, player)))
set_rule(world.multiworld.get_location("Visit Koopa And Para-Koopa: Red Coins", player), lambda state: state.has_all({"Poochy", "Large Spring Ball", "Spring Ball"}, player))
set_rule(world.multiworld.get_location("Visit Koopa And Para-Koopa: Flowers", player), lambda state: state.has_all({"Super Star", "Large Spring Ball"}, player))
set_rule(world.multiworld.get_location("Visit Koopa And Para-Koopa: Stars", player), lambda state: state.has("Large Spring Ball", player) and logic.has_midring(state))
set_rule(world.multiworld.get_location("Visit Koopa And Para-Koopa: Level Clear", player), lambda state: state.has("Large Spring Ball", player))
set_rule(world.multiworld.get_location("The Baseball Boys: Red Coins", player), lambda state: state.has_all({"Beanstalk", "Super Star", "Egg Launcher", "Large Spring Ball", "Mole Tank Morph"}, player))
set_rule(world.multiworld.get_location("The Baseball Boys: Flowers", player), lambda state: state.has_all({"Beanstalk", "Super Star", "Egg Launcher", "Large Spring Ball", "Spring Ball"}, player))
set_rule(world.multiworld.get_location("The Baseball Boys: Stars", player), lambda state: (logic.has_midring(state) and (state.has("Tulip", player))) and state.has_all({"Beanstalk", "Super Star", "Large Spring Ball", "Egg Launcher"}, player))
set_rule(world.multiworld.get_location("The Baseball Boys: Level Clear", player), lambda state: state.has_all({"Beanstalk", "Super Star", "Egg Launcher", "Large Spring Ball"}, player))
set_rule(world.multiworld.get_location("What's Gusty Taste Like?: Red Coins", player), lambda state: state.has("! Switch", player))
set_rule(world.multiworld.get_location("What's Gusty Taste Like?: Flowers", player), lambda state: state.has_any({"Large Spring Ball", "Super Star"}, player))
set_rule(world.multiworld.get_location("What's Gusty Taste Like?: Level Clear", player), lambda state: state.has_any({"Large Spring Ball", "Super Star"}, player))
set_rule(world.multiworld.get_location("Bigger Boo's Fort: Red Coins", player), lambda state: state.has_all({"! Switch", "Key", "Dashed Stairs"}, player))
set_rule(world.multiworld.get_location("Bigger Boo's Fort: Flowers", player), lambda state: state.has_all({"! Switch", "Key", "Dashed Stairs"}, player))
set_rule(world.multiworld.get_location("Bigger Boo's Fort: Stars", player), lambda state: state.has_all({"! Switch", "Key", "Dashed Stairs"}, player) and logic.has_midring(state))
set_rule(world.multiworld.get_location("Watch Out For Lakitu: Red Coins", player), lambda state: state.has("Chomp Rock", player))
set_rule(world.multiworld.get_location("Watch Out For Lakitu: Flowers", player), lambda state: state.has_all({"Key", "Train Morph", "Chomp Rock"}, player))
set_rule(world.multiworld.get_location("Watch Out For Lakitu: Level Clear", player), lambda state: state.has("Chomp Rock", player))
set_rule(world.multiworld.get_location("The Cave Of The Mystery Maze: Red Coins", player), lambda state: state.has("Large Spring Ball", player))
set_rule(world.multiworld.get_location("The Cave Of The Mystery Maze: Flowers", player), lambda state: state.has_all({"Large Spring Ball", "Egg Launcher"}, player))
set_rule(world.multiworld.get_location("The Cave Of The Mystery Maze: Stars", player), lambda state: state.has("Large Spring Ball", player) and logic.has_midring(state))
set_rule(world.multiworld.get_location("The Cave Of The Mystery Maze: Level Clear", player), lambda state: state.has("Large Spring Ball", player))
set_rule(world.multiworld.get_location("Lakitu's Wall: Red Coins", player), lambda state: (state.has_any({"Dashed Platform", "Giant Eggs"}, player) or logic.combat_item(state)) and state.has("Large Spring Ball", player))
set_rule(world.multiworld.get_location("Lakitu's Wall: Flowers", player), lambda state: state.has_all({"Large Spring Ball", "! Switch"}, player) and (logic.combat_item(state) or state.has("Giant Eggs", player)))
set_rule(world.multiworld.get_location("Lakitu's Wall: Stars", player), lambda state: state.has("Giant Eggs", player) and logic.has_midring(state))
set_rule(world.multiworld.get_location("Lakitu's Wall: Level Clear", player), lambda state: state.has_all({"Large Spring Ball", "Car Morph"}, player))
set_rule(world.multiworld.get_location("The Potted Ghost's Castle: Red Coins", player), lambda state: state.has_all({"Arrow Wheel", "Key"}, player) and (state.has("Egg Capacity Upgrade", player, 1)))
set_rule(world.multiworld.get_location("The Potted Ghost's Castle: Flowers", player), lambda state: state.has_all({"Arrow Wheel", "Train Morph", "Key"}, player) and (state.has("Egg Capacity Upgrade", player, 1)))
set_rule(world.multiworld.get_location("The Potted Ghost's Castle: Stars", player), lambda state: state.has_all({"Arrow Wheel", "Key"}, player) and logic.has_midring(state) and (state.has("Egg Capacity Upgrade", player, 1)))
set_rule(world.multiworld.get_location("Welcome To Monkey World!: Stars", player), lambda state: logic.has_midring(state))
set_rule(world.multiworld.get_location("Jungle Rhythm...: Red Coins", player), lambda state: state.has_all({"Dashed Stairs", "Spring Ball"}, player))
set_rule(world.multiworld.get_location("Jungle Rhythm...: Flowers", player), lambda state: state.has_all({"Dashed Stairs", "Spring Ball"}, player))
set_rule(world.multiworld.get_location("Jungle Rhythm...: Stars", player), lambda state: logic.has_midring(state) and state.has("Tulip", player))
set_rule(world.multiworld.get_location("Jungle Rhythm...: Level Clear", player), lambda state: state.has_all({"Dashed Stairs", "Spring Ball"}, player))
set_rule(world.multiworld.get_location("Nep-Enuts' Domain: Red Coins", player), lambda state: state.has_all({"Submarine Morph", "Helicopter Morph"}, player))
set_rule(world.multiworld.get_location("Nep-Enuts' Domain: Flowers", player), lambda state: state.has_all({"Submarine Morph", "Helicopter Morph"}, player))
set_rule(world.multiworld.get_location("Nep-Enuts' Domain: Stars", player), lambda state: logic.has_midring(state) or state.has_all({"Submarine Morph", "Helicopter Morph"}, player))
set_rule(world.multiworld.get_location("Nep-Enuts' Domain: Level Clear", player), lambda state: state.has_all({"Submarine Morph", "Helicopter Morph"}, player))
set_rule(world.multiworld.get_location("Prince Froggy's Fort: Red Coins", player), lambda state: state.has("Submarine Morph", player))
set_rule(world.multiworld.get_location("Prince Froggy's Fort: Flowers", player), lambda state: (state.has("Egg Capacity Upgrade", player, 5) or logic.combat_item(state)) and (state.has("Dashed Platform", player)))
set_rule(world.multiworld.get_location("Prince Froggy's Fort: Stars", player), lambda state: logic.has_midring(state))
set_rule(world.multiworld.get_location("Jammin' Through The Trees: Flowers", player), lambda state: state.has("Watermelon", player) or logic.melon_item(state))
set_rule(world.multiworld.get_location("Jammin' Through The Trees: Stars", player), lambda state: ((logic.has_midring(state) or state.has("Tulip", player)) and logic.cansee_clouds(state)) or logic.has_midring(state) and state.has("Tulip", player))
set_rule(world.multiworld.get_location("The Cave Of Harry Hedgehog: Red Coins", player), lambda state: state.has_all({"Chomp Rock", "Beanstalk", "Mole Tank Morph", "Large Spring Ball"}, player))
set_rule(world.multiworld.get_location("The Cave Of Harry Hedgehog: Flowers", player), lambda state: state.has_all({"Chomp Rock", "Beanstalk", "Mole Tank Morph", "Large Spring Ball", "! Switch"}, player))
set_rule(world.multiworld.get_location("The Cave Of Harry Hedgehog: Stars", player), lambda state: state.has_all({"Tulip", "Large Spring Ball", "Dashed Stairs", "Chomp Rock", "Beanstalk", "Mole Tank Morph"}, player) and logic.has_midring(state))
set_rule(world.multiworld.get_location("The Cave Of Harry Hedgehog: Level Clear", player), lambda state: state.has_all({"Chomp Rock", "Large Spring Ball", "Key"}, player))
set_rule(world.multiworld.get_location("Monkeys' Favorite Lake: Red Coins", player), lambda state: state.has_all({"! Switch", "Submarine Morph", "Large Spring Ball", "Beanstalk"}, player))
set_rule(world.multiworld.get_location("Monkeys' Favorite Lake: Flowers", player), lambda state: state.has_all({"Beanstalk", "Large Spring Ball"}, player))
set_rule(world.multiworld.get_location("Monkeys' Favorite Lake: Stars", player), lambda state: state.has("Large Spring Ball", player))
set_rule(world.multiworld.get_location("Monkeys' Favorite Lake: Level Clear", player), lambda state: state.has("Large Spring Ball", player))
set_rule(world.multiworld.get_location("Naval Piranha's Castle: Red Coins", player), lambda state: (state.has("Egg Capacity Upgrade", player, 3) or logic.combat_item(state)))
set_rule(world.multiworld.get_location("Naval Piranha's Castle: Flowers", player), lambda state: (state.has("Egg Capacity Upgrade", player, 3) or logic.combat_item(state)))
set_rule(world.multiworld.get_location("Naval Piranha's Castle: Stars", player), lambda state: logic.has_midring(state) and state.has("Tulip", player))
set_rule(world.multiworld.get_location("GO! GO! MARIO!!: Red Coins", player), lambda state: state.has("Super Star", player))
set_rule(world.multiworld.get_location("GO! GO! MARIO!!: Flowers", player), lambda state: state.has("Super Star", player))
set_rule(world.multiworld.get_location("GO! GO! MARIO!!: Stars", player), lambda state: logic.has_midring(state) or (state.has("Tulip", player) and logic.cansee_clouds(state)))
set_rule(world.multiworld.get_location("GO! GO! MARIO!!: Level Clear", player), lambda state: state.has("Super Star", player))
set_rule(world.multiworld.get_location("The Cave Of The Lakitus: Red Coins", player), lambda state: state.has_all({"Large Spring Ball", "! Switch", "Egg Launcher"}, player))
set_rule(world.multiworld.get_location("The Cave Of The Lakitus: Flowers", player), lambda state: state.has_all({"Large Spring Ball", "Egg Launcher"}, player))
set_rule(world.multiworld.get_location("The Cave Of The Lakitus: Stars", player), lambda state: state.has_all({"Large Spring Ball", "Spring Ball"}, player))
set_rule(world.multiworld.get_location("The Cave Of The Lakitus: Level Clear", player), lambda state: state.has("Large Spring Ball", player))
set_rule(world.multiworld.get_location("Don't Look Back!: Red Coins", player), lambda state: state.has_all({"Helicopter Morph", "! Switch", "Large Spring Ball"}, player))
set_rule(world.multiworld.get_location("Don't Look Back!: Flowers", player), lambda state: state.has_all({"! Switch", "Large Spring Ball"}, player))
set_rule(world.multiworld.get_location("Don't Look Back!: Stars", player), lambda state: (logic.has_midring(state) and state.has("Tulip", player)) and state.has("! Switch", player))
set_rule(world.multiworld.get_location("Don't Look Back!: Level Clear", player), lambda state: state.has("! Switch", player))
set_rule(world.multiworld.get_location("Marching Milde's Fort: Red Coins", player), lambda state: state.has_all({"Dashed Stairs", "Vanishing Arrow Wheel", "Arrow Wheel", "Bucket", "Key"}, player) and (state.has("Egg Capacity Upgrade", player, 1) or logic.combat_item(state)))
set_rule(world.multiworld.get_location("Marching Milde's Fort: Flowers", player), lambda state: state.has_all({"Dashed Stairs", "Vanishing Arrow Wheel", "Arrow Wheel", "Bucket"}, player) and (state.has("Egg Capacity Upgrade", player, 1) or logic.combat_item(state)))
set_rule(world.multiworld.get_location("Marching Milde's Fort: Stars", player), lambda state: state.has("Dashed Stairs", player) and (logic.has_midring(state) or state.has("Vanishing Arrow Wheel", player) or logic.cansee_clouds(state)))
set_rule(world.multiworld.get_location("Chomp Rock Zone: Red Coins", player), lambda state: state.has_all({"Large Spring Ball", "Chomp Rock"}, player))
set_rule(world.multiworld.get_location("Chomp Rock Zone: Flowers", player), lambda state: state.has_all({"Chomp Rock", "! Switch", "Spring Ball", "Dashed Platform"}, player))
set_rule(world.multiworld.get_location("Chomp Rock Zone: Stars", player), lambda state: state.has_all({"Chomp Rock", "! Switch", "Spring Ball", "Dashed Platform"}, player))
set_rule(world.multiworld.get_location("Lake Shore Paradise: Red Coins", player), lambda state: state.has_any({"Large Spring Ball", "Spring Ball"}, player) and (state.has("Egg Plant", player) or logic.combat_item(state)))
set_rule(world.multiworld.get_location("Lake Shore Paradise: Flowers", player), lambda state: state.has_any({"Large Spring Ball", "Spring Ball"}, player) and (state.has("Egg Plant", player) or logic.combat_item(state)))
set_rule(world.multiworld.get_location("Lake Shore Paradise: Stars", player), lambda state: (logic.has_midring(state) or (state.has("Tulip", player) and logic.cansee_clouds(state))) and (state.has("Egg Plant", player) or logic.combat_item(state)))
set_rule(world.multiworld.get_location("Lake Shore Paradise: Level Clear", player), lambda state: state.has("Egg Plant", player) or logic.combat_item(state))
set_rule(world.multiworld.get_location("Ride Like The Wind: Red Coins", player), lambda state: state.has("Large Spring Ball", player))
set_rule(world.multiworld.get_location("Ride Like The Wind: Flowers", player), lambda state: state.has("Large Spring Ball", player))
set_rule(world.multiworld.get_location("Ride Like The Wind: Stars", player), lambda state: (logic.has_midring(state) and state.has("Helicopter Morph", player)) and state.has("Large Spring Ball", player))
set_rule(world.multiworld.get_location("Ride Like The Wind: Level Clear", player), lambda state: state.has("Large Spring Ball", player))
set_rule(world.multiworld.get_location("Hookbill The Koopa's Castle: Red Coins", player), lambda state: state.has_all({"Dashed Stairs", "Vanishing Arrow Wheel", "Key"}, player))
set_rule(world.multiworld.get_location("Hookbill The Koopa's Castle: Flowers", player), lambda state: state.has_all({"Dashed Stairs", "Vanishing Arrow Wheel", "Key"}, player))
set_rule(world.multiworld.get_location("Hookbill The Koopa's Castle: Stars", player), lambda state: logic.has_midring(state) and (state.has_any({"Dashed Stairs", "Vanishing Arrow Wheel"}, player)))
set_rule(world.multiworld.get_location("BLIZZARD!!!: Red Coins", player), lambda state: state.has_all({"Helicopter Morph", "Dashed Stairs"}, player))
set_rule(world.multiworld.get_location("BLIZZARD!!!: Stars", player), lambda state: logic.cansee_clouds(state) or ((logic.has_midring(state) and state.has("Dashed Stairs", player)) or state.has("Tulip", player)))
set_rule(world.multiworld.get_location("Ride The Ski Lifts: Stars", player), lambda state: logic.has_midring(state) or state.has("Super Star", player))
set_rule(world.multiworld.get_location("Danger - Icy Conditions Ahead: Red Coins", player), lambda state: (state.has("Fire Melon", player) or logic.melon_item(state)) and (state.has_all({"Bucket", "Spring Ball", "Super Star", "Skis", "Dashed Platform"}, player)))
set_rule(world.multiworld.get_location("Danger - Icy Conditions Ahead: Flowers", player), lambda state: (state.has("Fire Melon", player) or logic.melon_item(state)) and state.has_all({"Spring Ball", "Skis", "Dashed Platform"}, player))
set_rule(world.multiworld.get_location("Danger - Icy Conditions Ahead: Stars", player), lambda state: (logic.has_midring(state) and (state.has("Fire Melon", player) or logic.melon_item(state))) and state.has("Spring Ball", player))
set_rule(world.multiworld.get_location("Danger - Icy Conditions Ahead: Level Clear", player), lambda state: state.has_all({"Spring Ball", "Skis", "Dashed Platform"}, player))
set_rule(world.multiworld.get_location("Sluggy The Unshaven's Fort: Red Coins", player), lambda state: state.has_all({"Dashed Stairs", "Dashed Platform", "Platform Ghost"}, player))
set_rule(world.multiworld.get_location("Sluggy The Unshaven's Fort: Flowers", player), lambda state: state.has_all({"Dashed Stairs", "Platform Ghost", "Dashed Platform"}, player))
set_rule(world.multiworld.get_location("Sluggy The Unshaven's Fort: Stars", player), lambda state: ((state.has_all({"Dashed Stairs", "Platform Ghost"}, player)) and logic.has_midring(state)) or (logic.cansee_clouds(state) and state.has("Dashed Stairs", player) and state.has("Dashed Platform", player)))
set_rule(world.multiworld.get_location("Goonie Rides!: Red Coins", player), lambda state: state.has_all({"Helicopter Morph", "! Switch"}, player))
set_rule(world.multiworld.get_location("Goonie Rides!: Flowers", player), lambda state: state.has_all({"Helicopter Morph", "! Switch"}, player))
set_rule(world.multiworld.get_location("Goonie Rides!: Stars", player), lambda state: logic.has_midring(state))
set_rule(world.multiworld.get_location("Goonie Rides!: Level Clear", player), lambda state: state.has_all({"Helicopter Morph", "! Switch"}, player))
set_rule(world.multiworld.get_location("Welcome To Cloud World: Stars", player), lambda state: logic.has_midring(state) or state.has("Tulip", player))
set_rule(world.multiworld.get_location("Shifting Platforms Ahead: Red Coins", player), lambda state: state.has("Egg Capacity Upgrade", player, 1) or logic.combat_item(state))
set_rule(world.multiworld.get_location("Shifting Platforms Ahead: Flowers", player), lambda state: state.has("Egg Capacity Upgrade", player, 1) or logic.combat_item(state))
set_rule(world.multiworld.get_location("Shifting Platforms Ahead: Stars", player), lambda state: logic.has_midring(state))
set_rule(world.multiworld.get_location("Raphael The Raven's Castle: Red Coins", player), lambda state: state.has_all({"Arrow Wheel", "Train Morph"}, player))
set_rule(world.multiworld.get_location("Raphael The Raven's Castle: Flowers", player), lambda state: state.has_all({"Arrow Wheel", "Train Morph"}, player))
set_rule(world.multiworld.get_location("Raphael The Raven's Castle: Stars", player), lambda state: logic.has_midring(state) and state.has("Arrow Wheel", player))
set_rule(world.multiworld.get_location("Scary Skeleton Goonies!: Red Coins", player), lambda state: state.has_all({"Dashed Platform", "Large Spring Ball"}, player))
set_rule(world.multiworld.get_location("Scary Skeleton Goonies!: Flowers", player), lambda state: state.has_all({"Dashed Platform", "Large Spring Ball"}, player))
set_rule(world.multiworld.get_location("Scary Skeleton Goonies!: Stars", player), lambda state: state.has("Dashed Platform", player) and logic.has_midring(state))
set_rule(world.multiworld.get_location("Scary Skeleton Goonies!: Level Clear", player), lambda state: state.has_all({"Dashed Platform", "Large Spring Ball"}, player))
set_rule(world.multiworld.get_location("The Cave Of The Bandits: Red Coins", player), lambda state: state.has("Super Star", player))
set_rule(world.multiworld.get_location("The Cave Of The Bandits: Flowers", player), lambda state: state.has("Super Star", player))
set_rule(world.multiworld.get_location("The Cave Of The Bandits: Stars", player), lambda state: logic.cansee_clouds(state) or logic.has_midring(state))
set_rule(world.multiworld.get_location("The Cave Of The Bandits: Level Clear", player), lambda state: state.has("Super Star", player))
set_rule(world.multiworld.get_location("Tap-Tap The Red Nose's Fort: Red Coins", player), lambda state: state.has_all({"Spring Ball", "Large Spring Ball", "Egg Plant", "Key"}, player) and (state.has("Egg Capacity Upgrade", player, 3) or logic.combat_item(state)))
set_rule(world.multiworld.get_location("Tap-Tap The Red Nose's Fort: Flowers", player), lambda state: state.has_all({"Spring Ball", "Large Spring Ball", "Egg Plant", "Key"}, player) and (state.has("Egg Capacity Upgrade", player, 3) or logic.combat_item(state)))
set_rule(world.multiworld.get_location("Tap-Tap The Red Nose's Fort: Stars", player), lambda state: logic.has_midring(state) and state.has_all({"Spring Ball", "Large Spring Ball", "Egg Plant", "Key"}, player))
set_rule(world.multiworld.get_location("The Very Loooooong Cave: Red Coins", player), lambda state: state.has("Chomp Rock", player) and (state.has("Egg Capacity Upgrade", player, 3) or logic.combat_item(state)))
set_rule(world.multiworld.get_location("The Very Loooooong Cave: Flowers", player), lambda state: state.has("Chomp Rock", player) and (state.has("Egg Capacity Upgrade", player, 3) or logic.combat_item(state)))
set_rule(world.multiworld.get_location("The Very Loooooong Cave: Stars", player), lambda state: state.has("Chomp Rock", player) and (state.has("Egg Capacity Upgrade", player, 3) or logic.combat_item(state)) and logic.has_midring(state))
set_rule(world.multiworld.get_location("The Deep, Underground Maze: Red Coins", player), lambda state: state.has_all({"Chomp Rock", "Key", "Large Spring Ball"}, player))
set_rule(world.multiworld.get_location("The Deep, Underground Maze: Flowers", player), lambda state: state.has_all({"Chomp Rock", "Key", "Large Spring Ball"}, player))
set_rule(world.multiworld.get_location("The Deep, Underground Maze: Stars", player), lambda state: state.has_all({"Chomp Rock", "Tulip", "Key"}, player) or (logic.has_midring(state) and state.has_all({"Key", "Chomp Rock", "Large Spring Ball"}, player)))
set_rule(world.multiworld.get_location("The Deep, Underground Maze: Level Clear", player), lambda state: state.has_all({"Chomp Rock", "Key", "Large Spring Ball", "Dashed Platform"}, player))
set_rule(world.multiworld.get_location("KEEP MOVING!!!!: Red Coins", player), lambda state: (state.has("Egg Capacity Upgrade", player, 1) or logic.combat_item(state)))
set_rule(world.multiworld.get_location("KEEP MOVING!!!!: Flowers", player), lambda state: state.has("Egg Plant", player))
set_rule(world.multiworld.get_location("KEEP MOVING!!!!: Stars", player), lambda state: logic.has_midring(state))
set_rule(world.multiworld.get_location("King Bowser's Castle: Red Coins", player), lambda state: state.has_all({"Helicopter Morph", "Egg Plant"}, player) and logic._68CollectibleRoute(state))
set_rule(world.multiworld.get_location("King Bowser's Castle: Flowers", player), lambda state: state.has_all({"Helicopter Morph", "Egg Plant"}, player) and logic._68CollectibleRoute(state))
set_rule(world.multiworld.get_location("King Bowser's Castle: Stars", player), lambda state: state.has_all({"Helicopter Morph", "Egg Plant"}, player) and logic._68Route(state))
set_easy_extra_rules(world)
def set_easy_extra_rules(world: "YoshisIslandWorld") -> None:
player = world.player
logic = YoshiLogic(world)
if not world.options.extras_enabled:
return
set_rule(world.multiworld.get_location("Poochy Ain't Stupid: Red Coins", player), lambda state: state.has("Poochy", player))
set_rule(world.multiworld.get_location("Poochy Ain't Stupid: Flowers", player), lambda state: state.has("Poochy", player))
set_rule(world.multiworld.get_location("Poochy Ain't Stupid: Stars", player), lambda state: state.has("Poochy", player))
set_rule(world.multiworld.get_location("Poochy Ain't Stupid: Level Clear", player), lambda state: state.has("Poochy", player))
set_rule(world.multiworld.get_location("Hit That Switch!!: Red Coins", player), lambda state: state.has_all({"Large Spring Ball", "! Switch"}, player))
set_rule(world.multiworld.get_location("Hit That Switch!!: Flowers", player), lambda state: state.has_all({"Large Spring Ball", "! Switch"}, player))
set_rule(world.multiworld.get_location("Hit That Switch!!: Level Clear", player), lambda state: state.has_all({"Large Spring Ball", "! Switch"}, player))
set_rule(world.multiworld.get_location("The Impossible? Maze: Red Coins", player), lambda state: state.has_all({"Spring Ball", "Large Spring Ball", "Mole Tank Morph", "Helicopter Morph", "Flashing Eggs"}, player))
set_rule(world.multiworld.get_location("The Impossible? Maze: Flowers", player), lambda state: state.has_all({"Spring Ball", "Large Spring Ball", "Mole Tank Morph", "Helicopter Morph"}, player))
set_rule(world.multiworld.get_location("The Impossible? Maze: Stars", player), lambda state: state.has_all({"Spring Ball", "Large Spring Ball", "Mole Tank Morph"}, player))
set_rule(world.multiworld.get_location("The Impossible? Maze: Level Clear", player), lambda state: state.has_all({"Spring Ball", "Large Spring Ball", "Mole Tank Morph", "Helicopter Morph"}, player))
set_rule(world.multiworld.get_location("Kamek's Revenge: Red Coins", player), lambda state: state.has_all({"Key", "Skis", "Helicopter Morph", "! Switch"}, player) and logic.has_midring(state))
set_rule(world.multiworld.get_location("Kamek's Revenge: Flowers", player), lambda state: state.has_all({"Key", "Skis", "Helicopter Morph", "! Switch"}, player) and logic.has_midring(state))
set_rule(world.multiworld.get_location("Kamek's Revenge: Stars", player), lambda state: state.has("! Switch", player) and logic.has_midring(state))
set_rule(world.multiworld.get_location("Kamek's Revenge: Level Clear", player), lambda state: state.has_all({"Key", "Skis", "! Switch", "Helicopter Morph"}, player))
set_rule(world.multiworld.get_location("Castles - Masterpiece Set: Red Coins", player), lambda state: (state.has("Egg Capacity Upgrade", player, 2) or logic.combat_item(state)) and state.has(("Large Spring Ball"), player))
set_rule(world.multiworld.get_location("Castles - Masterpiece Set: Flowers", player), lambda state: (state.has("Egg Capacity Upgrade", player, 2) or logic.combat_item(state)) and state.has(("Large Spring Ball"), player))
set_rule(world.multiworld.get_location("Castles - Masterpiece Set: Stars", player), lambda state: logic.has_midring(state) and state.has(("Large Spring Ball"), player))
set_rule(world.multiworld.get_location("Castles - Masterpiece Set: Level Clear", player), lambda state: (state.has("Egg Capacity Upgrade", player, 2) or logic.combat_item(state)) and state.has(("Large Spring Ball"), player))
def set_normal_rules(world: "YoshisIslandWorld") -> None:
logic = YoshiLogic(world)
player = world.player
set_rule(world.multiworld.get_location("Make Eggs, Throw Eggs: Red Coins", player), lambda state: state.has("Dashed Stairs", player))
set_rule(world.multiworld.get_location("Make Eggs, Throw Eggs: Flowers", player), lambda state: state.has("Dashed Stairs", player))
set_rule(world.multiworld.get_location("Make Eggs, Throw Eggs: Stars", player), lambda state: state.has_any({"Tulip", "Dashed Stairs"}, player))
set_rule(world.multiworld.get_location("Watch Out Below!: Red Coins", player), lambda state: state.has("Helicopter Morph", player))
set_rule(world.multiworld.get_location("Watch Out Below!: Flowers", player), lambda state: state.has("Helicopter Morph", player))
set_rule(world.multiworld.get_location("Watch Out Below!: Stars", player), lambda state: logic.has_midring(state))
set_rule(world.multiworld.get_location("Burt The Bashful's Fort: Red Coins", player), lambda state: state.has("Spring Ball", player))
set_rule(world.multiworld.get_location("Burt The Bashful's Fort: Flowers", player), lambda state: state.has_all({"Spring Ball", "Key"}, player) and (state.has("Egg Capacity Upgrade", player, 3) or logic.combat_item(state)))
set_rule(world.multiworld.get_location("Burt The Bashful's Fort: Stars", player), lambda state: state.has("Spring Ball", player))
set_rule(world.multiworld.get_location("Burt The Bashful's Fort: Level Clear", player), lambda state: logic._14CanFightBoss(state))
set_rule(world.multiworld.get_location("Shy-Guys On Stilts: Red Coins", player), lambda state: state.has_all({"Large Spring Ball", "Flashing Eggs", "Mole Tank Morph", "! Switch"}, player))
set_rule(world.multiworld.get_location("Shy-Guys On Stilts: Flowers", player), lambda state: state.has("Large Spring Ball", player))
set_rule(world.multiworld.get_location("Shy-Guys On Stilts: Stars", player), lambda state: (logic.has_midring(state) and state.has_any(["Tulip", "Beanstalk"], player)) or (state.has_all(["Tulip", "Beanstalk", "Large Spring Ball"], player)))
set_rule(world.multiworld.get_location("Shy-Guys On Stilts: Level Clear", player), lambda state: state.has_all({"Large Spring Ball", "Beanstalk"}, player))
set_rule(world.multiworld.get_location("Touch Fuzzy Get Dizzy: Red Coins", player), lambda state: state.has_all({"Flashing Eggs", "Spring Ball", "Chomp Rock", "Beanstalk"}, player))
set_rule(world.multiworld.get_location("Touch Fuzzy Get Dizzy: Stars", player), lambda state: logic.has_midring(state) or (logic.cansee_clouds and state.has_all({"Spring Ball", "Chomp Rock", "Beanstalk"}, player)))
set_rule(world.multiworld.get_location("Salvo The Slime's Castle: Red Coins", player), lambda state: state.has("Platform Ghost", player))
set_rule(world.multiworld.get_location("Salvo The Slime's Castle: Flowers", player), lambda state: state.has("Platform Ghost", player))
set_rule(world.multiworld.get_location("Salvo The Slime's Castle: Stars", player), lambda state: logic.has_midring(state) and (state.has("Platform Ghost", player) or state.has_all({"Arrow Wheel", "Key"}, player)))
set_rule(world.multiworld.get_location("Visit Koopa And Para-Koopa: Red Coins", player), lambda state: state.has_all({"Poochy", "Large Spring Ball", "Spring Ball"}, player))
set_rule(world.multiworld.get_location("Visit Koopa And Para-Koopa: Flowers", player), lambda state: state.has_all({"Super Star", "Large Spring Ball"}, player))
set_rule(world.multiworld.get_location("Visit Koopa And Para-Koopa: Stars", player), lambda state: state.has("Large Spring Ball", player) and logic.has_midring(state))
set_rule(world.multiworld.get_location("Visit Koopa And Para-Koopa: Level Clear", player), lambda state: state.has("Large Spring Ball", player))
set_rule(world.multiworld.get_location("The Baseball Boys: Red Coins", player), lambda state: state.has_all({"Beanstalk", "Super Star", "Large Spring Ball", "Mole Tank Morph"}, player))
set_rule(world.multiworld.get_location("The Baseball Boys: Flowers", player), lambda state: state.has_all({"Super Star", "Large Spring Ball", "Beanstalk", "Spring Ball"}, player))
set_rule(world.multiworld.get_location("The Baseball Boys: Stars", player), lambda state: (logic.has_midring(state) or (state.has("Tulip", player))) and state.has_all({"Beanstalk", "Large Spring Ball"}, player))
set_rule(world.multiworld.get_location("The Baseball Boys: Level Clear", player), lambda state: state.has_all({"Beanstalk", "Super Star", "Large Spring Ball"}, player))
set_rule(world.multiworld.get_location("What's Gusty Taste Like?: Red Coins", player), lambda state: state.has("! Switch", player))
set_rule(world.multiworld.get_location("Bigger Boo's Fort: Red Coins", player), lambda state: state.has_all({"! Switch", "Key", "Dashed Stairs"}, player))
set_rule(world.multiworld.get_location("Bigger Boo's Fort: Flowers", player), lambda state: state.has_all({"! Switch", "Key", "Dashed Stairs"}, player))
set_rule(world.multiworld.get_location("Bigger Boo's Fort: Stars", player), lambda state: state.has_all({"! Switch", "Dashed Stairs"}, player))
set_rule(world.multiworld.get_location("Watch Out For Lakitu: Flowers", player), lambda state: state.has_all({"Key", "Train Morph"}, player))
set_rule(world.multiworld.get_location("The Cave Of The Mystery Maze: Red Coins", player), lambda state: state.has("Large Spring Ball", player))
set_rule(world.multiworld.get_location("The Cave Of The Mystery Maze: Flowers", player), lambda state: state.has_all({"Large Spring Ball", "Egg Launcher"}, player))
set_rule(world.multiworld.get_location("The Cave Of The Mystery Maze: Stars", player), lambda state: state.has("Large Spring Ball", player))
set_rule(world.multiworld.get_location("The Cave Of The Mystery Maze: Level Clear", player), lambda state: state.has("Large Spring Ball", player))
set_rule(world.multiworld.get_location("Lakitu's Wall: Flowers", player), lambda state: state.has_all({"Large Spring Ball", "! Switch"}, player) and (logic.combat_item(state) or state.has("Giant Eggs", player)))
set_rule(world.multiworld.get_location("Lakitu's Wall: Stars", player), lambda state: state.has("Giant Eggs", player) or logic.has_midring(state))
set_rule(world.multiworld.get_location("The Potted Ghost's Castle: Red Coins", player), lambda state: state.has_all({"Arrow Wheel", "Key"}, player))
set_rule(world.multiworld.get_location("The Potted Ghost's Castle: Flowers", player), lambda state: state.has_all({"Arrow Wheel", "Key", "Train Morph"}, player))
set_rule(world.multiworld.get_location("The Potted Ghost's Castle: Stars", player), lambda state: state.has("Arrow Wheel", player) and (logic.has_midring(state) or state.has("Key", player)))
set_rule(world.multiworld.get_location("Welcome To Monkey World!: Stars", player), lambda state: logic.has_midring(state))
set_rule(world.multiworld.get_location("Jungle Rhythm...: Red Coins", player), lambda state: state.has("Dashed Stairs", player))
set_rule(world.multiworld.get_location("Jungle Rhythm...: Flowers", player), lambda state: state.has("Dashed Stairs", player))
set_rule(world.multiworld.get_location("Jungle Rhythm...: Stars", player), lambda state: logic.has_midring(state) and state.has("Tulip", player))
set_rule(world.multiworld.get_location("Jungle Rhythm...: Level Clear", player), lambda state: state.has("Dashed Stairs", player))
set_rule(world.multiworld.get_location("Nep-Enuts' Domain: Red Coins", player), lambda state: state.has_all({"Submarine Morph", "Helicopter Morph"}, player))
set_rule(world.multiworld.get_location("Nep-Enuts' Domain: Flowers", player), lambda state: state.has_all({"Submarine Morph", "Helicopter Morph"}, player))
set_rule(world.multiworld.get_location("Nep-Enuts' Domain: Level Clear", player), lambda state: state.has_all({"Submarine Morph", "Helicopter Morph"}, player))
set_rule(world.multiworld.get_location("Prince Froggy's Fort: Red Coins", player), lambda state: state.has("Submarine Morph", player))
set_rule(world.multiworld.get_location("Prince Froggy's Fort: Flowers", player), lambda state: (state.has("Egg Capacity Upgrade", player, 5) or logic.combat_item(state)) and (state.has("Dashed Platform", player) or logic.has_midring(state)))
set_rule(world.multiworld.get_location("Prince Froggy's Fort: Stars", player), lambda state: logic.has_midring(state))
set_rule(world.multiworld.get_location("Jammin' Through The Trees: Flowers", player), lambda state: state.has("Watermelon", player) or logic.melon_item(state))
set_rule(world.multiworld.get_location("The Cave Of Harry Hedgehog: Red Coins", player), lambda state: state.has_any({"Dashed Stairs", "Beanstalk"}, player) and state.has_all({"Mole Tank Morph", "Large Spring Ball"}, player))
set_rule(world.multiworld.get_location("The Cave Of Harry Hedgehog: Flowers", player), lambda state: state.has_any({"Dashed Stairs", "Beanstalk"}, player) and state.has_all({"! Switch", "Mole Tank Morph", "Large Spring Ball"}, player))
set_rule(world.multiworld.get_location("The Cave Of Harry Hedgehog: Stars", player), lambda state: (state.has_any({"Dashed Stairs", "Beanstalk"}, player) and state.has_all({"Mole Tank Morph", "Large Spring Ball"}, player)) and (logic.has_midring(state) or state.has("Tulip", player)))
set_rule(world.multiworld.get_location("The Cave Of Harry Hedgehog: Level Clear", player), lambda state: state.has_all({"Large Spring Ball", "Key"}, player))
set_rule(world.multiworld.get_location("Monkeys' Favorite Lake: Red Coins", player), lambda state: state.has_all({"! Switch", "Submarine Morph", "Large Spring Ball", "Beanstalk"}, player))
set_rule(world.multiworld.get_location("Monkeys' Favorite Lake: Flowers", player), lambda state: state.has("Beanstalk", player))
set_rule(world.multiworld.get_location("Naval Piranha's Castle: Red Coins", player), lambda state: (state.has("Egg Capacity Upgrade", player, 1) or logic.combat_item(state)))
set_rule(world.multiworld.get_location("Naval Piranha's Castle: Flowers", player), lambda state: (state.has("Egg Capacity Upgrade", player, 1) or logic.combat_item(state)))
set_rule(world.multiworld.get_location("Naval Piranha's Castle: Stars", player), lambda state: (logic.has_midring(state) and state.has("Tulip", player)) and state.has("Egg Capacity Upgrade", player, 1))
set_rule(world.multiworld.get_location("GO! GO! MARIO!!: Red Coins", player), lambda state: state.has("Super Star", player))
set_rule(world.multiworld.get_location("GO! GO! MARIO!!: Flowers", player), lambda state: state.has("Super Star", player))
set_rule(world.multiworld.get_location("GO! GO! MARIO!!: Stars", player), lambda state: state.has("Super Star", player))
set_rule(world.multiworld.get_location("GO! GO! MARIO!!: Level Clear", player), lambda state: state.has("Super Star", player))
set_rule(world.multiworld.get_location("The Cave Of The Lakitus: Red Coins", player), lambda state: state.has_all({"Large Spring Ball", "! Switch", "Egg Launcher"}, player))
set_rule(world.multiworld.get_location("The Cave Of The Lakitus: Flowers", player), lambda state: state.has_all({"Large Spring Ball", "Egg Launcher"}, player))
set_rule(world.multiworld.get_location("The Cave Of The Lakitus: Stars", player), lambda state: state.has("Large Spring Ball", player))
set_rule(world.multiworld.get_location("The Cave Of The Lakitus: Level Clear", player), lambda state: state.has("Large Spring Ball", player))
set_rule(world.multiworld.get_location("Don't Look Back!: Red Coins", player), lambda state: state.has_all({"Helicopter Morph", "! Switch", "Large Spring Ball"}, player))
set_rule(world.multiworld.get_location("Don't Look Back!: Flowers", player), lambda state: state.has("Large Spring Ball", player))
set_rule(world.multiworld.get_location("Don't Look Back!: Stars", player), lambda state: (logic.has_midring(state) or state.has("Tulip", player)) and state.has("! Switch", player))
set_rule(world.multiworld.get_location("Don't Look Back!: Level Clear", player), lambda state: state.has("! Switch", player))
set_rule(world.multiworld.get_location("Marching Milde's Fort: Red Coins", player), lambda state: state.has_all({"Dashed Stairs", "Vanishing Arrow Wheel", "Arrow Wheel", "Bucket", "Key"}, player))
set_rule(world.multiworld.get_location("Marching Milde's Fort: Flowers", player), lambda state: state.has_all({"Dashed Stairs", "Vanishing Arrow Wheel", "Arrow Wheel", "Bucket"}, player))
set_rule(world.multiworld.get_location("Marching Milde's Fort: Stars", player), lambda state: state.has("Dashed Stairs", player))
set_rule(world.multiworld.get_location("Chomp Rock Zone: Red Coins", player), lambda state: state.has_all({"Large Spring Ball", "Chomp Rock"}, player))
set_rule(world.multiworld.get_location("Chomp Rock Zone: Flowers", player), lambda state: state.has_all({"Chomp Rock", "! Switch", "Dashed Platform"}, player))
set_rule(world.multiworld.get_location("Chomp Rock Zone: Stars", player), lambda state: state.has_all({"Chomp Rock", "! Switch", "Dashed Platform"}, player))
set_rule(world.multiworld.get_location("Lake Shore Paradise: Red Coins", player), lambda state: state.has("Egg Plant", player) or logic.combat_item(state))
set_rule(world.multiworld.get_location("Lake Shore Paradise: Flowers", player), lambda state: state.has("Egg Plant", player) or logic.combat_item(state))
set_rule(world.multiworld.get_location("Lake Shore Paradise: Stars", player), lambda state: (logic.has_midring(state) or (state.has("Tulip", player) and logic.cansee_clouds(state))) and (state.has("Egg Plant", player) or logic.combat_item(state)))
set_rule(world.multiworld.get_location("Lake Shore Paradise: Level Clear", player), lambda state: state.has("Egg Plant", player) or logic.combat_item(state))
set_rule(world.multiworld.get_location("Ride Like The Wind: Red Coins", player), lambda state: state.has("Large Spring Ball", player))
set_rule(world.multiworld.get_location("Ride Like The Wind: Flowers", player), lambda state: state.has("Large Spring Ball", player))
set_rule(world.multiworld.get_location("Ride Like The Wind: Stars", player), lambda state: (logic.has_midring(state) or state.has("Helicopter Morph", player)) and state.has("Large Spring Ball", player))
set_rule(world.multiworld.get_location("Ride Like The Wind: Level Clear", player), lambda state: state.has("Large Spring Ball", player))
set_rule(world.multiworld.get_location("Hookbill The Koopa's Castle: Red Coins", player), lambda state: state.has_all({"Dashed Stairs", "Vanishing Arrow Wheel", "Key"}, player))
set_rule(world.multiworld.get_location("Hookbill The Koopa's Castle: Flowers", player), lambda state: state.has_all({"Dashed Stairs", "Vanishing Arrow Wheel", "Key"}, player))
set_rule(world.multiworld.get_location("Hookbill The Koopa's Castle: Stars", player), lambda state: logic.has_midring(state) or (state.has_any({"Dashed Stairs", "Vanishing Arrow Wheel"}, player)))
set_rule(world.multiworld.get_location("BLIZZARD!!!: Red Coins", player), lambda state: state.has_any({"Dashed Stairs", "Ice Melon"}, player) and (state.has("Egg Capacity Upgrade", player, 1) or logic.combat_item(state) or state.has("Helicopter Morph", player)))
set_rule(world.multiworld.get_location("Danger - Icy Conditions Ahead: Red Coins", player), lambda state: (state.has("Fire Melon", player) or logic.melon_item(state)) and (state.has_all({"Spring Ball", "Skis"}, player)) and (state.has("Super Star", player) or logic.melon_item(state)))
set_rule(world.multiworld.get_location("Danger - Icy Conditions Ahead: Flowers", player), lambda state: (state.has("Fire Melon", player) or logic.melon_item(state)) and state.has_all({"Spring Ball", "Skis"}, player))
set_rule(world.multiworld.get_location("Danger - Icy Conditions Ahead: Stars", player), lambda state: (logic.has_midring(state) and (state.has("Fire Melon", player) or logic.melon_item(state))) or (logic.has_midring(state) and (state.has_all({"Tulip", "Dashed Platform"}, player))))
set_rule(world.multiworld.get_location("Danger - Icy Conditions Ahead: Level Clear", player), lambda state: state.has_all({"Spring Ball", "Skis"}, player))
set_rule(world.multiworld.get_location("Sluggy The Unshaven's Fort: Red Coins", player), lambda state: state.has_all({"Dashed Stairs", "Dashed Platform", "Platform Ghost"}, player))
set_rule(world.multiworld.get_location("Sluggy The Unshaven's Fort: Flowers", player), lambda state: state.has_all({"Dashed Stairs", "Platform Ghost", "Dashed Platform"}, player))
set_rule(world.multiworld.get_location("Sluggy The Unshaven's Fort: Stars", player), lambda state: ((state.has_all({"Dashed Stairs", "Platform Ghost"}, player))) or (logic.cansee_clouds(state) and state.has("Dashed Stairs", player)))
set_rule(world.multiworld.get_location("Goonie Rides!: Red Coins", player), lambda state: state.has("Helicopter Morph", player))
set_rule(world.multiworld.get_location("Goonie Rides!: Flowers", player), lambda state: state.has_all({"Helicopter Morph", "! Switch"}, player))
set_rule(world.multiworld.get_location("Shifting Platforms Ahead: Stars", player), lambda state: logic.has_midring(state))
set_rule(world.multiworld.get_location("Raphael The Raven's Castle: Red Coins", player), lambda state: state.has_all({"Arrow Wheel", "Train Morph"}, player))
set_rule(world.multiworld.get_location("Raphael The Raven's Castle: Flowers", player), lambda state: state.has_all({"Arrow Wheel", "Train Morph"}, player))
set_rule(world.multiworld.get_location("Raphael The Raven's Castle: Stars", player), lambda state: logic.has_midring(state))
set_rule(world.multiworld.get_location("Scary Skeleton Goonies!: Red Coins", player), lambda state: state.has("Large Spring Ball", player))
set_rule(world.multiworld.get_location("Scary Skeleton Goonies!: Flowers", player), lambda state: state.has("Large Spring Ball", player))
set_rule(world.multiworld.get_location("Scary Skeleton Goonies!: Stars", player), lambda state: logic.has_midring(state))
set_rule(world.multiworld.get_location("Scary Skeleton Goonies!: Level Clear", player), lambda state: state.has("Large Spring Ball", player))
set_rule(world.multiworld.get_location("The Cave Of The Bandits: Red Coins", player), lambda state: state.has("Super Star", player))
set_rule(world.multiworld.get_location("The Cave Of The Bandits: Flowers", player), lambda state: state.has("Super Star", player))
set_rule(world.multiworld.get_location("The Cave Of The Bandits: Level Clear", player), lambda state: state.has("Super Star", player))
set_rule(world.multiworld.get_location("Tap-Tap The Red Nose's Fort: Red Coins", player), lambda state: state.has_all({"Large Spring Ball", "Egg Plant", "Key"}, player) and (state.has("Egg Capacity Upgrade", player, 2) or logic.combat_item(state)))
set_rule(world.multiworld.get_location("Tap-Tap The Red Nose's Fort: Flowers", player), lambda state: state.has_all({"Large Spring Ball", "Egg Plant", "Key"}, player) and (state.has("Egg Capacity Upgrade", player, 2) or logic.combat_item(state)))
set_rule(world.multiworld.get_location("Tap-Tap The Red Nose's Fort: Stars", player), lambda state: logic.has_midring(state) and state.has_all({"Spring Ball", "Egg Plant", "Key"}, player))
set_rule(world.multiworld.get_location("The Very Loooooong Cave: Red Coins", player), lambda state: state.has("Chomp Rock", player) and (state.has("Egg Capacity Upgrade", player, 2) or logic.combat_item(state)))
set_rule(world.multiworld.get_location("The Very Loooooong Cave: Flowers", player), lambda state: state.has("Chomp Rock", player) and (state.has("Egg Capacity Upgrade", player, 2) or logic.combat_item(state)))
set_rule(world.multiworld.get_location("The Very Loooooong Cave: Stars", player), lambda state: state.has("Chomp Rock", player) and (state.has("Egg Capacity Upgrade", player, 2) or logic.combat_item(state)) and logic.has_midring(state))
set_rule(world.multiworld.get_location("The Deep, Underground Maze: Red Coins", player), lambda state: state.has_all({"Chomp Rock", "Key", "Large Spring Ball"}, player))
set_rule(world.multiworld.get_location("The Deep, Underground Maze: Flowers", player), lambda state: state.has_all({"Chomp Rock", "Key", "Large Spring Ball"}, player))
set_rule(world.multiworld.get_location("The Deep, Underground Maze: Stars", player), lambda state: state.has_all({"Chomp Rock", "Tulip", "Key"}, player) or (logic.has_midring(state) and state.has_all({"Key", "Chomp Rock", "Large Spring Ball"}, player)))
set_rule(world.multiworld.get_location("The Deep, Underground Maze: Level Clear", player), lambda state: state.has_all({"Key", "Large Spring Ball", "Dashed Platform"}, player) and (logic.combat_item(state) or state.has("Chomp Rock", player)))
set_rule(world.multiworld.get_location("KEEP MOVING!!!!: Stars", player), lambda state: logic.has_midring(state))
set_rule(world.multiworld.get_location("King Bowser's Castle: Red Coins", player), lambda state: state.has_all({"Helicopter Morph", "Egg Plant"}, player) and logic._68CollectibleRoute(state))
set_rule(world.multiworld.get_location("King Bowser's Castle: Flowers", player), lambda state: state.has_all({"Helicopter Morph", "Egg Plant"}, player) and logic._68CollectibleRoute(state))
set_rule(world.multiworld.get_location("King Bowser's Castle: Stars", player), lambda state: state.has_all({"Helicopter Morph", "Egg Plant"}, player) and logic._68Route(state))
set_normal_extra_rules(world)
def set_normal_extra_rules(world: "YoshisIslandWorld") -> None:
player = world.player
logic = YoshiLogic(world)
if not world.options.extras_enabled:
return
set_rule(world.multiworld.get_location("Poochy Ain't Stupid: Red Coins", player), lambda state: state.has("Poochy", player))
set_rule(world.multiworld.get_location("Poochy Ain't Stupid: Flowers", player), lambda state: state.has("Poochy", player))
set_rule(world.multiworld.get_location("Poochy Ain't Stupid: Stars", player), lambda state: state.has("Poochy", player))
set_rule(world.multiworld.get_location("Poochy Ain't Stupid: Level Clear", player), lambda state: state.has("Poochy", player))
set_rule(world.multiworld.get_location("Hit That Switch!!: Red Coins", player), lambda state: state.has_all({"Large Spring Ball", "! Switch"}, player))
set_rule(world.multiworld.get_location("Hit That Switch!!: Flowers", player), lambda state: state.has_all({"Large Spring Ball", "! Switch"}, player))
set_rule(world.multiworld.get_location("Hit That Switch!!: Level Clear", player), lambda state: state.has_all({"Large Spring Ball", "! Switch"}, player))
set_rule(world.multiworld.get_location("The Impossible? Maze: Red Coins", player), lambda state: state.has_all({"Spring Ball", "Large Spring Ball", "Mole Tank Morph", "Helicopter Morph", "Flashing Eggs"}, player))
set_rule(world.multiworld.get_location("The Impossible? Maze: Flowers", player), lambda state: state.has_all({"Spring Ball", "Large Spring Ball", "Mole Tank Morph", "Helicopter Morph"}, player))
set_rule(world.multiworld.get_location("The Impossible? Maze: Stars", player), lambda state: state.has_all({"Spring Ball", "Large Spring Ball", "Mole Tank Morph"}, player))
set_rule(world.multiworld.get_location("The Impossible? Maze: Level Clear", player), lambda state: state.has_all({"Spring Ball", "Large Spring Ball", "Mole Tank Morph", "Helicopter Morph"}, player))
set_rule(world.multiworld.get_location("Kamek's Revenge: Red Coins", player), lambda state: state.has_all({"Key", "Skis", "Helicopter Morph", "! Switch"}, player) and logic.has_midring(state))
set_rule(world.multiworld.get_location("Kamek's Revenge: Flowers", player), lambda state: state.has_all({"Key", "Skis", "Helicopter Morph", "! Switch"}, player) and logic.has_midring(state))
set_rule(world.multiworld.get_location("Kamek's Revenge: Stars", player), lambda state: state.has("! Switch", player) or logic.has_midring(state))
set_rule(world.multiworld.get_location("Kamek's Revenge: Level Clear", player), lambda state: state.has_all({"Key", "Skis", "Helicopter Morph"}, player))
set_rule(world.multiworld.get_location("Castles - Masterpiece Set: Red Coins", player), lambda state: (state.has("Egg Capacity Upgrade", player, 1) or logic.combat_item(state)) and state.has(("Large Spring Ball"), player))
set_rule(world.multiworld.get_location("Castles - Masterpiece Set: Flowers", player), lambda state: (state.has("Egg Capacity Upgrade", player, 1) or logic.combat_item(state)) and state.has(("Large Spring Ball"), player))
set_rule(world.multiworld.get_location("Castles - Masterpiece Set: Stars", player), lambda state: logic.has_midring(state) or state.has(("Large Spring Ball"), player))
set_rule(world.multiworld.get_location("Castles - Masterpiece Set: Level Clear", player), lambda state: (state.has("Egg Capacity Upgrade", player, 1) or logic.combat_item(state)) and state.has(("Large Spring Ball"), player))
def set_hard_rules(world: "YoshisIslandWorld"):
logic = YoshiLogic(world)
player = world.player
set_rule(world.multiworld.get_location("Burt The Bashful's Fort: Red Coins", player), lambda state: state.has("Spring Ball", player))
set_rule(world.multiworld.get_location("Burt The Bashful's Fort: Flowers", player), lambda state: state.has_all({"Spring Ball", "Key"}, player) and (state.has("Egg Capacity Upgrade", player, 3) or logic.combat_item(state)))
set_rule(world.multiworld.get_location("Burt The Bashful's Fort: Stars", player), lambda state: state.has("Spring Ball", player))
set_rule(world.multiworld.get_location("Shy-Guys On Stilts: Red Coins", player), lambda state: state.has_all({"Large Spring Ball", "Flashing Eggs", "Mole Tank Morph", "! Switch"}, player))
set_rule(world.multiworld.get_location("Shy-Guys On Stilts: Level Clear", player), lambda state: state.has("Large Spring Ball", player))
set_rule(world.multiworld.get_location("Touch Fuzzy Get Dizzy: Red Coins", player), lambda state: state.has_all({"Flashing Eggs", "Spring Ball", "Chomp Rock", "Beanstalk"}, player))
set_rule(world.multiworld.get_location("Salvo The Slime's Castle: Red Coins", player), lambda state: state.has("Platform Ghost", player))
set_rule(world.multiworld.get_location("Salvo The Slime's Castle: Flowers", player), lambda state: state.has("Platform Ghost", player))
set_rule(world.multiworld.get_location("Visit Koopa And Para-Koopa: Red Coins", player), lambda state: state.has("Large Spring Ball", player) and (state.has("Poochy", player) or logic.melon_item(state)))
set_rule(world.multiworld.get_location("Visit Koopa And Para-Koopa: Flowers", player), lambda state: state.has_all({"Super Star", "Large Spring Ball"}, player))
set_rule(world.multiworld.get_location("Visit Koopa And Para-Koopa: Stars", player), lambda state: state.has("Large Spring Ball", player))
set_rule(world.multiworld.get_location("Visit Koopa And Para-Koopa: Level Clear", player), lambda state: state.has("Large Spring Ball", player))
set_rule(world.multiworld.get_location("The Baseball Boys: Red Coins", player), lambda state: state.has("Mole Tank Morph", player) and (state.has_any({"Ice Melon", "Large Spring Ball"}, player) or logic.melon_item(state)))
set_rule(world.multiworld.get_location("The Baseball Boys: Flowers", player), lambda state: (state.has_any({"Ice Melon", "Large Spring Ball"}, player) or logic.melon_item(state)))
set_rule(world.multiworld.get_location("The Baseball Boys: Level Clear", player), lambda state: (state.has_any({"Ice Melon", "Large Spring Ball"}, player) or logic.melon_item(state)))
set_rule(world.multiworld.get_location("What's Gusty Taste Like?: Red Coins", player), lambda state: state.has("! Switch", player))
set_rule(world.multiworld.get_location("Bigger Boo's Fort: Red Coins", player), lambda state: state.has_all({"! Switch", "Key"}, player))
set_rule(world.multiworld.get_location("Bigger Boo's Fort: Flowers", player), lambda state: state.has_all({"! Switch", "Key"}, player))
set_rule(world.multiworld.get_location("Bigger Boo's Fort: Stars", player), lambda state: state.has("! Switch", player))
set_rule(world.multiworld.get_location("Watch Out For Lakitu: Flowers", player), lambda state: state.has_all({"Key", "Train Morph"}, player))
set_rule(world.multiworld.get_location("The Cave Of The Mystery Maze: Red Coins", player), lambda state: state.has("Large Spring Ball", player))
set_rule(world.multiworld.get_location("The Cave Of The Mystery Maze: Flowers", player), lambda state: state.has("Large Spring Ball", player))
set_rule(world.multiworld.get_location("The Cave Of The Mystery Maze: Level Clear", player), lambda state: state.has("Large Spring Ball", player))
set_rule(world.multiworld.get_location("Lakitu's Wall: Flowers", player), lambda state: state.has("! Switch", player))
set_rule(world.multiworld.get_location("Lakitu's Wall: Stars", player), lambda state: state.has("Giant Eggs", player) or logic.has_midring(state))
set_rule(world.multiworld.get_location("The Potted Ghost's Castle: Red Coins", player), lambda state: state.has_all({"Arrow Wheel", "Key"}, player))
set_rule(world.multiworld.get_location("The Potted Ghost's Castle: Flowers", player), lambda state: state.has_all({"Arrow Wheel", "Key", "Train Morph"}, player))
set_rule(world.multiworld.get_location("The Potted Ghost's Castle: Stars", player), lambda state: state.has("Arrow Wheel", player))
set_rule(world.multiworld.get_location("Welcome To Monkey World!: Stars", player), lambda state: logic.has_midring(state))
set_rule(world.multiworld.get_location("Jungle Rhythm...: Red Coins", player), lambda state: state.has("Dashed Stairs", player))
set_rule(world.multiworld.get_location("Jungle Rhythm...: Flowers", player), lambda state: state.has("Dashed Stairs", player))
set_rule(world.multiworld.get_location("Jungle Rhythm...: Stars", player), lambda state: logic.has_midring(state) and state.has("Tulip", player))
set_rule(world.multiworld.get_location("Jungle Rhythm...: Level Clear", player), lambda state: state.has("Dashed Stairs", player))
set_rule(world.multiworld.get_location("Nep-Enuts' Domain: Red Coins", player), lambda state: state.has_all({"Submarine Morph", "Helicopter Morph"}, player))
set_rule(world.multiworld.get_location("Nep-Enuts' Domain: Flowers", player), lambda state: state.has_all({"Submarine Morph", "Helicopter Morph"}, player))
set_rule(world.multiworld.get_location("Nep-Enuts' Domain: Level Clear", player), lambda state: state.has_all({"Submarine Morph", "Helicopter Morph"}, player))
set_rule(world.multiworld.get_location("Prince Froggy's Fort: Red Coins", player), lambda state: state.has("Submarine Morph", player))
set_rule(world.multiworld.get_location("Prince Froggy's Fort: Flowers", player), lambda state: (state.has("Egg Capacity Upgrade", player, 5) or logic.combat_item(state)))
set_rule(world.multiworld.get_location("The Cave Of Harry Hedgehog: Red Coins", player), lambda state: state.has("Mole Tank Morph", player))
set_rule(world.multiworld.get_location("The Cave Of Harry Hedgehog: Flowers", player), lambda state: state.has_all({"Mole Tank Morph", "! Switch"}, player))
set_rule(world.multiworld.get_location("The Cave Of Harry Hedgehog: Stars", player), lambda state: logic.has_midring(state) or state.has("Tulip", player))
set_rule(world.multiworld.get_location("The Cave Of Harry Hedgehog: Level Clear", player), lambda state: state.has_all({"Large Spring Ball", "Key"}, player))
set_rule(world.multiworld.get_location("Monkeys' Favorite Lake: Red Coins", player), lambda state: state.has_all({"! Switch", "Submarine Morph"}, player))
set_rule(world.multiworld.get_location("GO! GO! MARIO!!: Red Coins", player), lambda state: state.has("Super Star", player))
set_rule(world.multiworld.get_location("GO! GO! MARIO!!: Flowers", player), lambda state: state.has("Super Star", player))
set_rule(world.multiworld.get_location("GO! GO! MARIO!!: Level Clear", player), lambda state: state.has("Super Star", player))
set_rule(world.multiworld.get_location("The Cave Of The Lakitus: Red Coins", player), lambda state: state.has_all({"! Switch", "Egg Launcher"}, player))
set_rule(world.multiworld.get_location("The Cave Of The Lakitus: Flowers", player), lambda state: state.has("Egg Launcher", player))
set_rule(world.multiworld.get_location("Don't Look Back!: Red Coins", player), lambda state: state.has_all({"Helicopter Morph", "Large Spring Ball"}, player))
set_rule(world.multiworld.get_location("Don't Look Back!: Flowers", player), lambda state: state.has("Large Spring Ball", player))
set_rule(world.multiworld.get_location("Don't Look Back!: Stars", player), lambda state: logic.has_midring(state) or state.has("Tulip", player))
set_rule(world.multiworld.get_location("Marching Milde's Fort: Red Coins", player), lambda state: state.has_all({"Dashed Stairs", "Vanishing Arrow Wheel", "Arrow Wheel", "Bucket", "Key"}, player))
set_rule(world.multiworld.get_location("Marching Milde's Fort: Flowers", player), lambda state: state.has_all({"Dashed Stairs", "Vanishing Arrow Wheel", "Arrow Wheel", "Bucket"}, player))
set_rule(world.multiworld.get_location("Marching Milde's Fort: Stars", player), lambda state: state.has("Dashed Stairs", player))
set_rule(world.multiworld.get_location("Chomp Rock Zone: Red Coins", player), lambda state: state.has("Large Spring Ball", player))
set_rule(world.multiworld.get_location("Chomp Rock Zone: Flowers", player), lambda state: state.has_all({"Chomp Rock", "! Switch"}, player))
set_rule(world.multiworld.get_location("Chomp Rock Zone: Stars", player), lambda state: state.has_all({"Chomp Rock", "! Switch"}, player))
set_rule(world.multiworld.get_location("Lake Shore Paradise: Stars", player), lambda state: (logic.has_midring(state) or (state.has("Tulip", player) and logic.cansee_clouds(state))))
set_rule(world.multiworld.get_location("Ride Like The Wind: Red Coins", player), lambda state: state.has("Large Spring Ball", player))
set_rule(world.multiworld.get_location("Ride Like The Wind: Flowers", player), lambda state: state.has("Large Spring Ball", player))
set_rule(world.multiworld.get_location("Ride Like The Wind: Stars", player), lambda state: (logic.has_midring(state) or state.has("Helicopter Morph", player)) and state.has("Large Spring Ball", player))
set_rule(world.multiworld.get_location("Ride Like The Wind: Level Clear", player), lambda state: state.has("Large Spring Ball", player))
set_rule(world.multiworld.get_location("Hookbill The Koopa's Castle: Red Coins", player), lambda state: state.has_all({"Key", "Dashed Stairs"}, player))
set_rule(world.multiworld.get_location("Hookbill The Koopa's Castle: Flowers", player), lambda state: state.has_all({"Dashed Stairs", "Key"}, player))
set_rule(world.multiworld.get_location("Danger - Icy Conditions Ahead: Red Coins", player), lambda state: (state.has("Fire Melon", player) or logic.melon_item(state)) and (state.has_all({"Spring Ball", "Skis"}, player)) and (state.has("Super Star", player) or logic.melon_item(state)))
set_rule(world.multiworld.get_location("Danger - Icy Conditions Ahead: Flowers", player), lambda state: (state.has("Fire Melon", player) or logic.melon_item(state)) and state.has_all({"Spring Ball", "Skis"}, player))
set_rule(world.multiworld.get_location("Danger - Icy Conditions Ahead: Stars", player), lambda state: (logic.has_midring(state) and (state.has("Fire Melon", player) or logic.melon_item(state))) or (logic.has_midring(state) and (state.has_all({"Tulip", "Dashed Platform"}, player))))
set_rule(world.multiworld.get_location("Danger - Icy Conditions Ahead: Level Clear", player), lambda state: state.has_all({"Spring Ball", "Skis"}, player))
set_rule(world.multiworld.get_location("Sluggy The Unshaven's Fort: Red Coins", player), lambda state: state.has_all({"Dashed Stairs", "Dashed Platform", "Platform Ghost"}, player))
set_rule(world.multiworld.get_location("Sluggy The Unshaven's Fort: Flowers", player), lambda state: state.has_all({"Dashed Stairs", "Platform Ghost"}, player))
set_rule(world.multiworld.get_location("Shifting Platforms Ahead: Stars", player), lambda state: logic.has_midring(state))
set_rule(world.multiworld.get_location("Raphael The Raven's Castle: Red Coins", player), lambda state: state.has_all({"Arrow Wheel", "Train Morph"}, player))
set_rule(world.multiworld.get_location("Raphael The Raven's Castle: Flowers", player), lambda state: state.has_all({"Arrow Wheel", "Train Morph"}, player))
set_rule(world.multiworld.get_location("Scary Skeleton Goonies!: Red Coins", player), lambda state: state.has("Large Spring Ball", player))
set_rule(world.multiworld.get_location("Scary Skeleton Goonies!: Flowers", player), lambda state: state.has("Large Spring Ball", player))
set_rule(world.multiworld.get_location("Scary Skeleton Goonies!: Stars", player), lambda state: logic.has_midring(state))
set_rule(world.multiworld.get_location("Scary Skeleton Goonies!: Level Clear", player), lambda state: state.has("Large Spring Ball", player))
set_rule(world.multiworld.get_location("The Cave Of The Bandits: Red Coins", player), lambda state: state.has("Super Star", player))
set_rule(world.multiworld.get_location("The Cave Of The Bandits: Flowers", player), lambda state: state.has("Super Star", player))
set_rule(world.multiworld.get_location("The Cave Of The Bandits: Level Clear", player), lambda state: state.has("Super Star", player))
set_rule(world.multiworld.get_location("Tap-Tap The Red Nose's Fort: Red Coins", player), lambda state: state.has_all({"Egg Plant", "Key"}, player) and (state.has("Egg Capacity Upgrade", player, 1) or logic.combat_item(state)))
set_rule(world.multiworld.get_location("Tap-Tap The Red Nose's Fort: Flowers", player), lambda state: state.has_all({"Egg Plant", "Key"}, player) and (state.has("Egg Capacity Upgrade", player, 1) or logic.combat_item(state)))
set_rule(world.multiworld.get_location("Tap-Tap The Red Nose's Fort: Stars", player), lambda state: state.has("Egg Plant", player) and state.has("Key", player))
set_rule(world.multiworld.get_location("The Very Loooooong Cave: Stars", player), lambda state: logic.has_midring(state))
set_rule(world.multiworld.get_location("The Deep, Underground Maze: Red Coins", player), lambda state: state.has_all({"Key", "Large Spring Ball"}, player) and (logic.combat_item(state) or state.has("Chomp Rock", player)))
set_rule(world.multiworld.get_location("The Deep, Underground Maze: Flowers", player), lambda state: state.has_all({"Key", "Large Spring Ball"}, player) and (logic.combat_item(state) or state.has("Chomp Rock", player)))
set_rule(world.multiworld.get_location("The Deep, Underground Maze: Stars", player), lambda state: state.has_all({"Chomp Rock", "Key"}, player))
set_rule(world.multiworld.get_location("The Deep, Underground Maze: Level Clear", player), lambda state: state.has_all({"Key", "Large Spring Ball", "Dashed Platform"}, player) and (logic.combat_item(state) or state.has("Chomp Rock", player)))
set_rule(world.multiworld.get_location("KEEP MOVING!!!!: Stars", player), lambda state: logic.has_midring(state))
set_rule(world.multiworld.get_location("King Bowser's Castle: Red Coins", player), lambda state: state.has("Helicopter Morph", player) and logic._68CollectibleRoute(state))
set_rule(world.multiworld.get_location("King Bowser's Castle: Flowers", player), lambda state: state.has("Helicopter Morph", player) and logic._68CollectibleRoute(state))
set_rule(world.multiworld.get_location("King Bowser's Castle: Stars", player), lambda state: state.has("Helicopter Morph", player) and logic._68Route(state))
set_hard_extra_rules(world)
def set_hard_extra_rules(world: "YoshisIslandWorld") -> None:
player = world.player
logic = YoshiLogic(world)
if not world.options.extras_enabled:
return
set_rule(world.multiworld.get_location("Poochy Ain't Stupid: Red Coins", player), lambda state: state.has("Poochy", player))
set_rule(world.multiworld.get_location("Poochy Ain't Stupid: Flowers", player), lambda state: state.has("Poochy", player))
set_rule(world.multiworld.get_location("Poochy Ain't Stupid: Stars", player), lambda state: state.has("Poochy", player))
set_rule(world.multiworld.get_location("Poochy Ain't Stupid: Level Clear", player), lambda state: state.has("Poochy", player))
set_rule(world.multiworld.get_location("Hit That Switch!!: Red Coins", player), lambda state: state.has_all({"Large Spring Ball", "! Switch"}, player))
set_rule(world.multiworld.get_location("Hit That Switch!!: Flowers", player), lambda state: state.has_all({"Large Spring Ball", "! Switch"}, player))
set_rule(world.multiworld.get_location("Hit That Switch!!: Level Clear", player), lambda state: state.has_all({"Large Spring Ball", "! Switch"}, player))
set_rule(world.multiworld.get_location("The Impossible? Maze: Red Coins", player), lambda state: state.has_all({"Spring Ball", "Large Spring Ball", "Mole Tank Morph", "Helicopter Morph", "Flashing Eggs"}, player))
set_rule(world.multiworld.get_location("The Impossible? Maze: Flowers", player), lambda state: state.has_all({"Spring Ball", "Large Spring Ball", "Mole Tank Morph", "Helicopter Morph"}, player))
set_rule(world.multiworld.get_location("The Impossible? Maze: Stars", player), lambda state: state.has_all({"Spring Ball", "Large Spring Ball", "Mole Tank Morph"}, player))
set_rule(world.multiworld.get_location("The Impossible? Maze: Level Clear", player), lambda state: state.has_all({"Spring Ball", "Large Spring Ball", "Mole Tank Morph", "Helicopter Morph"}, player))
set_rule(world.multiworld.get_location("Kamek's Revenge: Red Coins", player), lambda state: state.has_all({"Key", "Skis", "Helicopter Morph"}, player))
set_rule(world.multiworld.get_location("Kamek's Revenge: Flowers", player), lambda state: state.has_all({"Key", "Skis", "Helicopter Morph", "! Switch"}, player))
set_rule(world.multiworld.get_location("Kamek's Revenge: Stars", player), lambda state: state.has("! Switch", player) or logic.has_midring(state))
set_rule(world.multiworld.get_location("Kamek's Revenge: Level Clear", player), lambda state: state.has_all({"Key", "Skis", "Helicopter Morph"}, player))
set_rule(world.multiworld.get_location("Castles - Masterpiece Set: Red Coins", player), lambda state: state.has(("Large Spring Ball"), player))
set_rule(world.multiworld.get_location("Castles - Masterpiece Set: Flowers", player), lambda state: state.has(("Large Spring Ball"), player))
set_rule(world.multiworld.get_location("Castles - Masterpiece Set: Stars", player), lambda state: True)
set_rule(world.multiworld.get_location("Castles - Masterpiece Set: Level Clear", player), lambda state: state.has(("Large Spring Ball"), player))

View File

@ -0,0 +1,388 @@
import base64
import os
import typing
import threading
from typing import List, Set, TextIO, Dict
from BaseClasses import Item, MultiWorld, Tutorial, ItemClassification
from worlds.AutoWorld import World, WebWorld
import settings
from .Items import get_item_names_per_category, item_table, filler_items, trap_items
from .Locations import get_locations
from .Regions import init_areas
from .Options import YoshisIslandOptions, PlayerGoal, ObjectVis, StageLogic, MinigameChecks
from .setup_game import setup_gamevars
from .Client import YoshisIslandSNIClient
from .Rules import set_easy_rules, set_normal_rules, set_hard_rules
from .Rom import LocalRom, patch_rom, get_base_rom_path, YoshisIslandDeltaPatch, USHASH
class YoshisIslandSettings(settings.Group):
class RomFile(settings.SNESRomPath):
"""File name of the Yoshi's Island 1.0 US rom"""
description = "Yoshi's Island ROM File"
copy_to = "Super Mario World 2 - Yoshi's Island (U).sfc"
md5s = [USHASH]
rom_file: RomFile = RomFile(RomFile.copy_to)
class YoshisIslandWeb(WebWorld):
theme = "ocean"
setup_en = Tutorial(
"Multiworld Setup Guide",
"A guide to setting up the Yoshi's Island randomizer"
"and connecting to an Archipelago server.",
"English",
"setup_en.md",
"setup/en",
["Pink Switch"]
)
tutorials = [setup_en]
class YoshisIslandWorld(World):
"""
Yoshi's Island is a 2D platforming game.
During a delivery, Bowser's evil ward, Kamek, attacked the stork, kidnapping Luigi and dropping Mario onto Yoshi's Island.
As Yoshi, you must run, jump, and throw eggs to escort the baby Mario across the island to defeat Bowser and reunite the two brothers with their parents.
"""
game = "Yoshi's Island"
option_definitions = YoshisIslandOptions
required_client_version = (0, 4, 4)
item_name_to_id = {item: item_table[item].code for item in item_table}
location_name_to_id = {location.name: location.code for location in get_locations(None)}
item_name_groups = get_item_names_per_category()
web = YoshisIslandWeb()
settings: typing.ClassVar[YoshisIslandSettings]
# topology_present = True
options_dataclass = YoshisIslandOptions
options: YoshisIslandOptions
locked_locations: List[str]
set_req_bosses: str
lives_high: int
lives_low: int
castle_bosses: int
bowser_bosses: int
baby_mario_sfx: int
leader_color: int
boss_order: list
boss_burt: int
luigi_count: int
rom_name: bytearray
def __init__(self, multiworld: MultiWorld, player: int):
self.rom_name_available_event = threading.Event()
super().__init__(multiworld, player)
self.locked_locations = []
@classmethod
def stage_assert_generate(cls, multiworld: MultiWorld) -> None:
rom_file = get_base_rom_path()
if not os.path.exists(rom_file):
raise FileNotFoundError(rom_file)
def fill_slot_data(self) -> Dict[str, List[int]]:
return {
"world_1": self.world_1_stages,
"world_2": self.world_2_stages,
"world_3": self.world_3_stages,
"world_4": self.world_4_stages,
"world_5": self.world_5_stages,
"world_6": self.world_6_stages
}
def write_spoiler_header(self, spoiler_handle: TextIO) -> None:
spoiler_handle.write(f"Burt The Bashful's Boss Door: {self.boss_order[0]}\n")
spoiler_handle.write(f"Salvo The Slime's Boss Door: {self.boss_order[1]}\n")
spoiler_handle.write(f"Bigger Boo's Boss Door: {self.boss_order[2]}\n")
spoiler_handle.write(f"Roger The Ghost's Boss Door: {self.boss_order[3]}\n")
spoiler_handle.write(f"Prince Froggy's Boss Door: {self.boss_order[4]}\n")
spoiler_handle.write(f"Naval Piranha's Boss Door: {self.boss_order[5]}\n")
spoiler_handle.write(f"Marching Milde's Boss Door: {self.boss_order[6]}\n")
spoiler_handle.write(f"Hookbill The Koopa's Boss Door: {self.boss_order[7]}\n")
spoiler_handle.write(f"Sluggy The Unshaven's Boss Door: {self.boss_order[8]}\n")
spoiler_handle.write(f"Raphael The Raven's Boss Door: {self.boss_order[9]}\n")
spoiler_handle.write(f"Tap-Tap The Red Nose's Boss Door: {self.boss_order[10]}\n")
spoiler_handle.write(f"\nLevels:\n1-1: {self.level_name_list[0]}\n")
spoiler_handle.write(f"1-2: {self.level_name_list[1]}\n")
spoiler_handle.write(f"1-3: {self.level_name_list[2]}\n")
spoiler_handle.write(f"1-4: {self.level_name_list[3]}\n")
spoiler_handle.write(f"1-5: {self.level_name_list[4]}\n")
spoiler_handle.write(f"1-6: {self.level_name_list[5]}\n")
spoiler_handle.write(f"1-7: {self.level_name_list[6]}\n")
spoiler_handle.write(f"1-8: {self.level_name_list[7]}\n")
spoiler_handle.write(f"\n2-1: {self.level_name_list[8]}\n")
spoiler_handle.write(f"2-2: {self.level_name_list[9]}\n")
spoiler_handle.write(f"2-3: {self.level_name_list[10]}\n")
spoiler_handle.write(f"2-4: {self.level_name_list[11]}\n")
spoiler_handle.write(f"2-5: {self.level_name_list[12]}\n")
spoiler_handle.write(f"2-6: {self.level_name_list[13]}\n")
spoiler_handle.write(f"2-7: {self.level_name_list[14]}\n")
spoiler_handle.write(f"2-8: {self.level_name_list[15]}\n")
spoiler_handle.write(f"\n3-1: {self.level_name_list[16]}\n")
spoiler_handle.write(f"3-2: {self.level_name_list[17]}\n")
spoiler_handle.write(f"3-3: {self.level_name_list[18]}\n")
spoiler_handle.write(f"3-4: {self.level_name_list[19]}\n")
spoiler_handle.write(f"3-5: {self.level_name_list[20]}\n")
spoiler_handle.write(f"3-6: {self.level_name_list[21]}\n")
spoiler_handle.write(f"3-7: {self.level_name_list[22]}\n")
spoiler_handle.write(f"3-8: {self.level_name_list[23]}\n")
spoiler_handle.write(f"\n4-1: {self.level_name_list[24]}\n")
spoiler_handle.write(f"4-2: {self.level_name_list[25]}\n")
spoiler_handle.write(f"4-3: {self.level_name_list[26]}\n")
spoiler_handle.write(f"4-4: {self.level_name_list[27]}\n")
spoiler_handle.write(f"4-5: {self.level_name_list[28]}\n")
spoiler_handle.write(f"4-6: {self.level_name_list[29]}\n")
spoiler_handle.write(f"4-7: {self.level_name_list[30]}\n")
spoiler_handle.write(f"4-8: {self.level_name_list[31]}\n")
spoiler_handle.write(f"\n5-1: {self.level_name_list[32]}\n")
spoiler_handle.write(f"5-2: {self.level_name_list[33]}\n")
spoiler_handle.write(f"5-3: {self.level_name_list[34]}\n")
spoiler_handle.write(f"5-4: {self.level_name_list[35]}\n")
spoiler_handle.write(f"5-5: {self.level_name_list[36]}\n")
spoiler_handle.write(f"5-6: {self.level_name_list[37]}\n")
spoiler_handle.write(f"5-7: {self.level_name_list[38]}\n")
spoiler_handle.write(f"5-8: {self.level_name_list[39]}\n")
spoiler_handle.write(f"\n6-1: {self.level_name_list[40]}\n")
spoiler_handle.write(f"6-2: {self.level_name_list[41]}\n")
spoiler_handle.write(f"6-3: {self.level_name_list[42]}\n")
spoiler_handle.write(f"6-4: {self.level_name_list[43]}\n")
spoiler_handle.write(f"6-5: {self.level_name_list[44]}\n")
spoiler_handle.write(f"6-6: {self.level_name_list[45]}\n")
spoiler_handle.write(f"6-7: {self.level_name_list[46]}\n")
spoiler_handle.write("6-8: King Bowser's Castle")
def create_item(self, name: str) -> Item:
data = item_table[name]
return Item(name, data.classification, data.code, self.player)
def create_regions(self) -> None:
init_areas(self, get_locations(self))
def get_filler_item_name(self) -> str:
trap_chance: int = self.options.trap_percent.value
if self.random.random() < (trap_chance / 100) and self.options.traps_enabled:
return self.random.choice(trap_items)
else:
return self.random.choice(filler_items)
def set_rules(self) -> None:
rules_per_difficulty = {
0: set_easy_rules,
1: set_normal_rules,
2: set_hard_rules
}
rules_per_difficulty[self.options.stage_logic.value](self)
self.multiworld.completion_condition[self.player] = lambda state: state.has("Saved Baby Luigi", self.player)
self.get_location("Burt The Bashful's Boss Room").place_locked_item(self.create_item("Boss Clear"))
self.get_location("Salvo The Slime's Boss Room").place_locked_item(self.create_item("Boss Clear"))
self.get_location("Bigger Boo's Boss Room", ).place_locked_item(self.create_item("Boss Clear"))
self.get_location("Roger The Ghost's Boss Room").place_locked_item(self.create_item("Boss Clear"))
self.get_location("Prince Froggy's Boss Room").place_locked_item(self.create_item("Boss Clear"))
self.get_location("Naval Piranha's Boss Room").place_locked_item(self.create_item("Boss Clear"))
self.get_location("Marching Milde's Boss Room").place_locked_item(self.create_item("Boss Clear"))
self.get_location("Hookbill The Koopa's Boss Room").place_locked_item(self.create_item("Boss Clear"))
self.get_location("Sluggy The Unshaven's Boss Room").place_locked_item(self.create_item("Boss Clear"))
self.get_location("Raphael The Raven's Boss Room").place_locked_item(self.create_item("Boss Clear"))
self.get_location("Tap-Tap The Red Nose's Boss Room").place_locked_item(self.create_item("Boss Clear"))
if self.options.goal == PlayerGoal.option_luigi_hunt:
self.get_location("Reconstituted Luigi").place_locked_item(self.create_item("Saved Baby Luigi"))
else:
self.get_location("King Bowser's Castle: Level Clear").place_locked_item(
self.create_item("Saved Baby Luigi")
)
self.get_location("Touch Fuzzy Get Dizzy: Gather Coins").place_locked_item(
self.create_item("Bandit Consumables")
)
self.get_location("The Cave Of the Mystery Maze: Seed Spitting Contest").place_locked_item(
self.create_item("Bandit Watermelons")
)
self.get_location("Lakitu's Wall: Gather Coins").place_locked_item(self.create_item("Bandit Consumables"))
self.get_location("Ride Like The Wind: Gather Coins").place_locked_item(self.create_item("Bandit Consumables"))
def generate_early(self) -> None:
setup_gamevars(self)
def get_excluded_items(self) -> Set[str]:
excluded_items: Set[str] = set()
starting_gate = ["World 1 Gate", "World 2 Gate", "World 3 Gate",
"World 4 Gate", "World 5 Gate", "World 6 Gate"]
excluded_items.add(starting_gate[self.options.starting_world])
if not self.options.shuffle_midrings:
excluded_items.add("Middle Ring")
if not self.options.add_secretlens:
excluded_items.add("Secret Lens")
if not self.options.extras_enabled:
excluded_items.add("Extra Panels")
excluded_items.add("Extra 1")
excluded_items.add("Extra 2")
excluded_items.add("Extra 3")
excluded_items.add("Extra 4")
excluded_items.add("Extra 5")
excluded_items.add("Extra 6")
if self.options.split_extras:
excluded_items.add("Extra Panels")
else:
excluded_items.add("Extra 1")
excluded_items.add("Extra 2")
excluded_items.add("Extra 3")
excluded_items.add("Extra 4")
excluded_items.add("Extra 5")
excluded_items.add("Extra 6")
if self.options.split_bonus:
excluded_items.add("Bonus Panels")
else:
excluded_items.add("Bonus 1")
excluded_items.add("Bonus 2")
excluded_items.add("Bonus 3")
excluded_items.add("Bonus 4")
excluded_items.add("Bonus 5")
excluded_items.add("Bonus 6")
return excluded_items
def create_item_with_correct_settings(self, name: str) -> Item:
data = item_table[name]
item = Item(name, data.classification, data.code, self.player)
if not item.advancement:
return item
if name == "Car Morph" and self.options.stage_logic != StageLogic.option_strict:
item.classification = ItemClassification.useful
secret_lens_visibility_check = (
self.options.hidden_object_visibility >= ObjectVis.option_clouds_only
or self.options.stage_logic != StageLogic.option_strict
)
if name == "Secret Lens" and secret_lens_visibility_check:
item.classification = ItemClassification.useful
is_bonus_location = name in {"Bonus 1", "Bonus 2", "Bonus 3", "Bonus 4", "Bonus 5", "Bonus 6", "Bonus Panels"}
bonus_games_disabled = (
self.options.minigame_checks not in {MinigameChecks.option_bonus_games, MinigameChecks.option_both}
)
if is_bonus_location and bonus_games_disabled:
item.classification = ItemClassification.useful
if name in {"Bonus 1", "Bonus 3", "Bonus 4", "Bonus Panels"} and self.options.item_logic:
item.classification = ItemClassification.progression
if name == "Piece of Luigi" and self.options.goal == PlayerGoal.option_luigi_hunt:
if self.luigi_count >= self.options.luigi_pieces_required:
item.classification = ItemClassification.useful
else:
item.classification = ItemClassification.progression_skip_balancing
self.luigi_count += 1
return item
def generate_filler(self, pool: List[Item]) -> None:
if self.options.goal == PlayerGoal.option_luigi_hunt:
for _ in range(self.options.luigi_pieces_in_pool.value):
item = self.create_item_with_correct_settings("Piece of Luigi")
pool.append(item)
for _ in range(len(self.multiworld.get_unfilled_locations(self.player)) - len(pool) - 16):
item = self.create_item_with_correct_settings(self.get_filler_item_name())
pool.append(item)
def get_item_pool(self, excluded_items: Set[str]) -> List[Item]:
pool: List[Item] = []
for name, data in item_table.items():
if name not in excluded_items:
for _ in range(data.amount):
item = self.create_item_with_correct_settings(name)
pool.append(item)
return pool
def create_items(self) -> None:
self.luigi_count = 0
if self.options.minigame_checks in {MinigameChecks.option_bonus_games, MinigameChecks.option_both}:
self.multiworld.get_location("Flip Cards", self.player).place_locked_item(
self.create_item("Bonus Consumables"))
self.multiworld.get_location("Drawing Lots", self.player).place_locked_item(
self.create_item("Bonus Consumables"))
self.multiworld.get_location("Match Cards", self.player).place_locked_item(
self.create_item("Bonus Consumables"))
pool = self.get_item_pool(self.get_excluded_items())
self.generate_filler(pool)
self.multiworld.itempool += pool
def generate_output(self, output_directory: str) -> None:
rompath = "" # if variable is not declared finally clause may fail
try:
world = self.multiworld
player = self.player
rom = LocalRom(get_base_rom_path())
patch_rom(self, rom, self.player)
rompath = os.path.join(output_directory, f"{self.multiworld.get_out_file_name_base(self.player)}.sfc")
rom.write_to_file(rompath)
self.rom_name = rom.name
patch = YoshisIslandDeltaPatch(os.path.splitext(rompath)[0] + YoshisIslandDeltaPatch.patch_file_ending,
player=player, player_name=world.player_name[player], patched_path=rompath)
patch.write()
finally:
self.rom_name_available_event.set()
if os.path.exists(rompath):
os.unlink(rompath)
def modify_multidata(self, multidata: dict) -> None:
# wait for self.rom_name to be available.
self.rom_name_available_event.wait()
rom_name = getattr(self, "rom_name", None)
if rom_name:
new_name = base64.b64encode(bytes(self.rom_name)).decode()
multidata["connect_names"][new_name] = multidata["connect_names"][self.multiworld.player_name[self.player]]
def extend_hint_information(self, hint_data: typing.Dict[int, typing.Dict[int, str]]) -> None:
world_names = [f"World {i}" for i in range(1, 7)]
world_stages = [
self.world_1_stages, self.world_2_stages, self.world_3_stages,
self.world_4_stages, self.world_5_stages, self.world_6_stages
]
stage_pos_data = {}
for loc in self.multiworld.get_locations(self.player):
if loc.address is None:
continue
level_id = getattr(loc, "level_id")
for level, stages in zip(world_names, world_stages):
if level_id in stages:
stage_pos_data[loc.address] = level
break
hint_data[self.player] = stage_pos_data

View File

@ -0,0 +1,71 @@
# Yoshi's Island
## Where is the settings page?
The [player options page for this game](../player-options) contains all the options you need to configure and export a config file.
## What does randomization do to this game?
Certain interactable objects within levels will be unable to be used until the corresponding item is found. If the item is not in the player's posession, the object will flash and will not function. Objects include:
- Spring Ball
- Large Spring Ball
- ! Switch
- Dashed Platform
- Dashed Stairs
- Beanstalk
- Arrow Wheel
- Vanishing Arrow Wheel
- Ice, fire, and normal watermelons
- Super Star
- Flashing Eggs
- Giant Eggs
- Egg Launcher
- Egg Refill Plant
- Chomp Rock
- Poochy
- Transformation Morphs
- Skis
- Platform Ghost
- Middle Rings
- Buckets
- Tulips
Yoshi will start out being able to carry only one egg, and 5 capacity upgrades can be found to bring the total up to 6.
The player will start with all levels unlocked in their starting world, and can collect 'World Gates' to unlock levels from other worlds.
Extra and Bonus stages will also start out locked, and require respective items to access them. 6-8 is locked, and will be unlocked
upon reaching the number of boss clears defined by the player.
Other checks will grant the player extra lives, consumables for use in the inventory, or traps.
Additionally, the player is able to randomize the bosses found at the end of boss stages, the order of stages,
the world they start in, the starting amount of lives, route through 6-8, and the color of Yoshi for each stage.
## What is the goal of Yoshi's Island when randomized?
The player can choose one of two goals:
- Bowser: Defeat a pre-defined number of bosses, and defeat Bowser at the end of 6-8.
- Luigi Hunt: Collect a pre-defined number of 'Pieces of Luigi' within levels.
## What items and locations get shuffled?
Locations consist of 'level objectives', that being:
- Beating the stage
- Collecting 20 red coins.
- Collecting 5 flowers.
- Collecting 30 stars.
Checks will be sent immediately upon achieving that objective, regardless of if the stage is cleared or not.
Additional checks can be placed on Bandit mini-battles, or overworld minigames.
## Which items can be in another player's world?
Any shuffled item can be in other players' worlds.
## What does another world's item look like in Yoshi's Island
Items do not have an appearance in Yoshi's Island
## When the player receives an item, what happens?
When the player recieves an item, a fanfare or sound will be heard to reflect the item received. Most items, aside from Egg Capacity and level unlocks, can be checked on the menu by pressing SELECT.
If an item is in the queue and has not been received, checks will not be processed.

View File

@ -0,0 +1,123 @@
# Yoshi's Island Archipelago Randomizer Setup Guide
## Required Software
- [Archipelago](https://github.com/ArchipelagoMW/Archipelago/releases).
- Hardware or software capable of loading and playing SNES ROM files
- An emulator capable of connecting to SNI such as:
- snes9x-rr from: [snes9x rr](https://github.com/gocha/snes9x-rr/releases),
- BizHawk from: [TASVideos](https://tasvideos.org/BizHawk)
- snes9x-nwa from: [snes9x nwa](https://github.com/Skarsnik/snes9x-emunwa/releases)
NOTE: RetroArch and FXPakPro are not currently supported.
- Your legally obtained Yoshi's Island English 1.0 ROM file, probably named `Super Mario World 2 - Yoshi's Island (U).sfc`
## Installation Procedures
### Windows Setup
1. Download and install Archipelago from the link above, making sure to install the most recent version.
2. During generation/patching, you will be asked to locate your base ROM file. This is your Yoshi's Island ROM file.
3. If you are using an emulator, you should assign your Lua capable emulator as your default program for launching ROM
files.
1. Extract your emulator's folder to your Desktop, or somewhere you will remember.
2. Right-click on a ROM file and select **Open with...**
3. Check the box next to **Always use this app to open .sfc files**
4. Scroll to the bottom of the list and click the grey text **Look for another App on this PC**
5. Browse for your emulator's `.exe` file and click **Open**. This file should be located inside the folder you
extracted in step one.
## Create a Config (.yaml) File
### What is a config file and why do I need one?
See the guide on setting up a basic YAML at the Archipelago setup
guide: [Basic Multiworld Setup Guide](/tutorial/Archipelago/setup/en)
### Where do I get a config file?
The Player Options page on the website allows you to configure your personal settings and export a config file from
them.
### Verifying your config file
If you would like to validate your config file to make sure it works, you may do so on the YAML Validator page. YAML
validator page: [YAML Validation page](/mysterycheck)
## Joining a MultiWorld Game
### Obtain your patch file and create your ROM
When you join a multiworld game, you will be asked to provide your config file to whomever is hosting. Once that is done,
the host will provide you with either a link to download your patch file, or with a zip file containing everyone's patch
files. Your patch file should have a `.apyi` extension.
Put your patch file on your desktop or somewhere convenient, and double click it. This should automatically launch the
client, and will also create your ROM in the same place as your patch file.
### Connect to the client
#### With an emulator
When the client launched automatically, SNI should have also automatically launched in the background. If this is its
first time launching, you may be prompted to allow it to communicate through the Windows Firewall.
##### snes9x-rr
1. Load your ROM file if it hasn't already been loaded.
2. Click on the File menu and hover on **Lua Scripting**
3. Click on **New Lua Script Window...**
4. In the new window, click **Browse...**
5. Select the connector lua file included with your client
- Look in the Archipelago folder for `/SNI/lua/x64` or `/SNI/lua/x86` depending on if the
emulator is 64-bit or 32-bit.
6. If you see an error while loading the script that states `socket.dll missing` or similar, navigate to the folder of
the lua you are using in your file explorer and copy the `socket.dll` to the base folder of your snes9x install.
##### BizHawk
1. Ensure you have the BSNES core loaded. This is done with the main menubar, under:
- (≤ 2.8) `Config``Cores``SNES``BSNES`
- (≥ 2.9) `Config``Preferred Cores``SNES``BSNESv115+`
2. Load your ROM file if it hasn't already been loaded.
If you changed your core preference after loading the ROM, don't forget to reload it (default hotkey: Ctrl+R).
3. Drag+drop the `Connector.lua` file included with your client onto the main EmuHawk window.
- Look in the Archipelago folder for `/SNI/lua/x64` or `/SNI/lua/x86` depending on if the
emulator is 64-bit or 32-bit. Please note the most recent versions of BizHawk are 64-bit only.
- You could instead open the Lua Console manually, click `Script``Open Script`, and navigate to `Connector.lua`
with the file picker.
### Connect to the Archipelago Server
The patch file which launched your client should have automatically connected you to the AP Server. There are a few
reasons this may not happen however, including if the game is hosted on the website but was generated elsewhere. If the
client window shows "Server Status: Not Connected", simply ask the host for the address of the server, and copy/paste it
into the "Server" input field then press enter.
The client will attempt to reconnect to the new server address, and should momentarily show "Server Status: Connected".
### Play the game
When the client shows both SNES Device and Server as connected, you're ready to begin playing. Congratulations on
successfully joining a multiworld game!
## Hosting a MultiWorld game
The recommended way to host a game is to use our hosting service. The process is relatively simple:
1. Collect config files from your players.
2. Create a zip file containing your players' config files.
3. Upload that zip file to the Generate page above.
- Generate page: [WebHost Seed Generation Page](/generate)
4. Wait a moment while the seed is generated.
5. When the seed is generated, you will be redirected to a "Seed Info" page.
6. Click "Create New Room". This will take you to the server page. Provide the link to this page to your players, so
they may download their patch files from there.
7. Note that a link to a MultiWorld Tracker is at the top of the room page. The tracker shows the progress of all
players in the game. Any observers may also be given the link to this page.
8. Once all players have joined, you may begin playing.

View File

@ -0,0 +1,482 @@
from BaseClasses import CollectionState
from typing import TYPE_CHECKING
from .Options import StageLogic, BowserDoor, ObjectVis
if TYPE_CHECKING:
from . import YoshisIslandWorld
class YoshiLogic:
player: int
game_logic: str
midring_start: bool
clouds_always_visible: bool
consumable_logic: bool
luigi_pieces: int
def __init__(self, world: "YoshisIslandWorld") -> None:
self.player = world.player
self.boss_order = world.boss_order
self.luigi_pieces = world.options.luigi_pieces_required.value
if world.options.stage_logic == StageLogic.option_strict:
self.game_logic = "Easy"
elif world.options.stage_logic == StageLogic.option_loose:
self.game_logic = "Normal"
else:
self.game_logic = "Hard"
self.midring_start = not world.options.shuffle_midrings
self.consumable_logic = not world.options.item_logic
self.clouds_always_visible = world.options.hidden_object_visibility >= ObjectVis.option_clouds_only
self.bowser_door = world.options.bowser_door_mode.value
if self.bowser_door == BowserDoor.option_door_4:
self.bowser_door = BowserDoor.option_door_3
def has_midring(self, state: CollectionState) -> bool:
return self.midring_start or state.has("Middle Ring", self.player)
def reconstitute_luigi(self, state: CollectionState) -> bool:
return state.has("Piece of Luigi", self.player, self.luigi_pieces)
def bandit_bonus(self, state: CollectionState) -> bool:
return state.has("Bandit Consumables", self.player) or state.has("Bandit Watermelons", self.player)
def item_bonus(self, state: CollectionState) -> bool:
return state.has("Bonus Consumables", self.player)
def combat_item(self, state: CollectionState) -> bool:
if not self.consumable_logic:
return False
else:
if self.game_logic == "Easy":
return self.item_bonus(state)
else:
return self.bandit_bonus(state) or self.item_bonus(state)
def melon_item(self, state: CollectionState) -> bool:
if not self.consumable_logic:
return False
else:
if self.game_logic == "Easy":
return self.item_bonus(state)
else:
return state.has("Bandit Watermelons", self.player) or self.item_bonus(state)
def default_vis(self, state: CollectionState) -> bool:
if self.clouds_always_visible:
return True
else:
return False
def cansee_clouds(self, state: CollectionState) -> bool:
if self.game_logic != "Easy":
return True
else:
return self.default_vis(state) or state.has("Secret Lens", self.player) or self.combat_item(state)
def bowserdoor_1(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return state.has_all({"Egg Plant", "! Switch"}, self.player) and state.has("Egg Capacity Upgrade", self.player, 2)
elif self.game_logic == "Normal":
return state.has("Egg Plant", self.player) and state.has("Egg Capacity Upgrade", self.player, 1)
else:
return state.has("Egg Plant", self.player)
def bowserdoor_2(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return ((state.has("Egg Capacity Upgrade", self.player, 3) and state.has("Egg Plant", self.player)) or self.combat_item(state)) and state.has("Key", self.player)
elif self.game_logic == "Normal":
return ((state.has("Egg Capacity Upgrade", self.player, 2) and state.has("Egg Plant", self.player)) or self.combat_item(state)) and state.has("Key", self.player)
else:
return ((state.has("Egg Capacity Upgrade", self.player, 1) and state.has("Egg Plant", self.player)) or self.combat_item(state)) and state.has("Key", self.player)
def bowserdoor_3(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return True
elif self.game_logic == "Normal":
return True
else:
return True
def bowserdoor_4(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return True
elif self.game_logic == "Normal":
return True
else:
return True
def _68Route(self, state: CollectionState) -> bool:
if self.bowser_door == 0:
return True
elif self.bowser_door == 1:
return self.bowserdoor_1(state)
elif self.bowser_door == 2:
return self.bowserdoor_2(state)
elif self.bowser_door == 3:
return True
elif self.bowser_door == 4:
return True
elif self.bowser_door == 5:
return self.bowserdoor_1(state) and self.bowserdoor_2(state) and self.bowserdoor_3(state)
def _68CollectibleRoute(self, state: CollectionState) -> bool:
if self.bowser_door == 0:
return True
elif self.bowser_door == 1:
return self.bowserdoor_1(state)
elif self.bowser_door == 2:
return self.bowserdoor_2(state)
elif self.bowser_door == 3:
return True
elif self.bowser_door == 4:
return True
elif self.bowser_door == 5:
return self.bowserdoor_1(state)
##############################################################################
def _13Game(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return state.has("Key", self.player)
elif self.game_logic == "Normal":
return state.has("Key", self.player)
else:
return state.has("Key", self.player)
##############################################################################
def _14Clear(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return state.has_all({"Spring Ball", "Key"}, self.player)
elif self.game_logic == "Normal":
return state.has_all({"Spring Ball", "Key"}, self.player)
else:
return state.has_all({"Spring Ball", "Key"}, self.player)
def _14Boss(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return state.has("Egg Plant", self.player)
elif self.game_logic == "Normal":
return state.has("Egg Plant", self.player)
else:
return (state.has("Egg Capacity Upgrade", self.player, 5) or state.has("Egg Plant", self.player))
def _14CanFightBoss(self, state: CollectionState) -> bool:
if state.can_reach(self.boss_order[0], "Location", self.player):
return True
##############################################################################
def _17Game(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return state.has("Key", self.player)
elif self.game_logic == "Normal":
return state.has("Key", self.player)
else:
return state.has("Key", self.player)
##############################################################################
def _18Clear(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return state.has_all({"Key", "Arrow Wheel"}, self.player)
elif self.game_logic == "Normal":
return state.has_all({"Key", "Arrow Wheel"}, self.player)
else:
return state.has_all({"Key", "Arrow Wheel"}, self.player)
def _18Boss(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return True
elif self.game_logic == "Normal":
return True
else:
return True
def _18CanFightBoss(self, state: CollectionState) -> bool:
if state.can_reach(self.boss_order[1], "Location", self.player):
return True
##############################################################################
def _21Game(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return state.has_all({"Poochy", "Large Spring Ball", "Key"}, self.player)
elif self.game_logic == "Normal":
return state.has_all({"Poochy", "Large Spring Ball", "Key"}, self.player)
else:
return state.has_all({"Poochy", "Large Spring Ball", "Key"}, self.player)
##############################################################################
def _23Game(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return state.has_all({"Mole Tank Morph", "Key"}, self.player)
elif self.game_logic == "Normal":
return state.has_all({"Mole Tank Morph", "Key"}, self.player)
else:
return state.has_all({"Mole Tank Morph", "Key"}, self.player)
##############################################################################
def _24Clear(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return state.has_all({"! Switch", "Key", "Dashed Stairs"}, self.player)
elif self.game_logic == "Normal":
return state.has_all({"! Switch", "Dashed Stairs"}, self.player)
else:
return state.has("! Switch", self.player)
def _24Boss(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return True
elif self.game_logic == "Normal":
return True
else:
return True
def _24CanFightBoss(self, state: CollectionState) -> bool:
if state.can_reach(self.boss_order[2], "Location", self.player):
return True
##############################################################################
def _26Game(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return state.has_all({"Large Spring Ball", "Key"}, self.player)
elif self.game_logic == "Normal":
return state.has_all({"Large Spring Ball", "Key"}, self.player)
else:
return state.has_all({"Large Spring Ball", "Key"}, self.player)
##############################################################################
def _27Game(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return state.has("Key", self.player)
elif self.game_logic == "Normal":
return state.has("Key", self.player)
else:
return state.has("Key", self.player)
##############################################################################
def _28Clear(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return state.has_all({"Arrow Wheel", "Key"}, self.player) and (state.has("Egg Capacity Upgrade", self.player, 1))
elif self.game_logic == "Normal":
return state.has_all({"Arrow Wheel", "Key"}, self.player)
else:
return state.has_all({"Arrow Wheel", "Key"}, self.player)
def _28Boss(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return True
elif self.game_logic == "Normal":
return True
else:
return True
def _28CanFightBoss(self, state: CollectionState) -> bool:
if state.can_reach(self.boss_order[3], "Location", self.player):
return True
##############################################################################
def _32Game(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return state.has_all({"Dashed Stairs", "Spring Ball", "Key"}, self.player)
elif self.game_logic == "Normal":
return state.has_all({"Dashed Stairs", "Key"}, self.player)
else:
return state.has_all({"Dashed Stairs", "Key"}, self.player)
##############################################################################
def _34Clear(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return state.has("Dashed Platform", self.player)
elif self.game_logic == "Normal":
return (state.has("Dashed Platform", self.player) or self.has_midring(state))
else:
return True
def _34Boss(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return state.has("Giant Eggs", self.player)
elif self.game_logic == "Normal":
return True
else:
return True
def _34CanFightBoss(self, state: CollectionState) -> bool:
if state.can_reach(self.boss_order[4], "Location", self.player):
return True
##############################################################################
def _37Game(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return state.has_all({"Key", "Large Spring Ball"}, self.player)
elif self.game_logic == "Normal":
return state.has("Key", self.player)
else:
return state.has("Key", self.player)
##############################################################################
def _38Clear(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return (state.has("Egg Capacity Upgrade", self.player, 3) or self.combat_item(state))
elif self.game_logic == "Normal":
return (state.has("Egg Capacity Upgrade", self.player, 1) or self.combat_item(state))
else:
return True
def _38Boss(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return True
elif self.game_logic == "Normal":
return True
else:
return True
def _38CanFightBoss(self, state: CollectionState) -> bool:
if state.can_reach(self.boss_order[5], "Location", self.player):
return True
##############################################################################
def _42Game(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return state.has_all({"Large Spring Ball", "Key"}, self.player)
elif self.game_logic == "Normal":
return state.has_all({"Large Spring Ball", "Key"}, self.player)
else:
return state.has("Key", self.player)
##############################################################################
def _44Clear(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return state.has_all({"Dashed Stairs", "Vanishing Arrow Wheel", "Arrow Wheel", "Bucket", "Key"}, self.player) and (state.has("Egg Capacity Upgrade", self.player, 1) or self.combat_item(state))
elif self.game_logic == "Normal":
return state.has_all({"Dashed Stairs", "Vanishing Arrow Wheel", "Arrow Wheel", "Bucket", "Key"}, self.player)
else:
return state.has_all({"Dashed Stairs", "Vanishing Arrow Wheel", "Arrow Wheel", "Bucket", "Key"}, self.player)
def _44Boss(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return True
elif self.game_logic == "Normal":
return True
else:
return True
def _44CanFightBoss(self, state: CollectionState) -> bool:
if state.can_reach(self.boss_order[6], "Location", self.player):
return True
########################################################################################################
def _46Game(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return state.has_all({"Key", "Large Spring Ball"}, self.player)
elif self.game_logic == "Normal":
return state.has_all({"Key", "Large Spring Ball"}, self.player)
else:
return state.has_all({"Key", "Large Spring Ball"}, self.player)
def _47Game(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return state.has_all({"Key", "Large Spring Ball"}, self.player)
elif self.game_logic == "Normal":
return state.has_all({"Key", "Large Spring Ball"}, self.player)
else:
return state.has_all({"Key", "Large Spring Ball"}, self.player)
##############################################################################
def _48Clear(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return (state.has_all({"Dashed Stairs", "Vanishing Arrow Wheel", "Key", "Large Spring Ball"}, self.player))
elif self.game_logic == "Normal":
return (state.has_all({"Dashed Stairs", "Vanishing Arrow Wheel", "Key", "Large Spring Ball"}, self.player))
else:
return (state.has_all({"Key", "Large Spring Ball"}, self.player))
def _48Boss(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return (state.has("Egg Capacity Upgrade", self.player, 3))
elif self.game_logic == "Normal":
return (state.has("Egg Capacity Upgrade", self.player, 2))
else:
return (state.has("Egg Capacity Upgrade", self.player, 1))
def _48CanFightBoss(self, state: CollectionState) -> bool:
if state.can_reach(self.boss_order[7], "Location", self.player):
return True
######################################################################################################################
def _51Game(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return state.has("Key", self.player)
elif self.game_logic == "Normal":
return state.has("Key", self.player)
else:
return state.has("Key", self.player)
##############################################################################
def _54Clear(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return (state.has_all({"Dashed Stairs", "Platform Ghost", "Dashed Platform"}, self.player))
elif self.game_logic == "Normal":
return (state.has_all({"Dashed Stairs", "Platform Ghost", "Dashed Platform"}, self.player))
else:
return (state.has_all({"Dashed Stairs", "Platform Ghost"}, self.player))
def _54Boss(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return (state.has("Egg Capacity Upgrade", self.player, 2) and state.has("Egg Plant", self.player))
elif self.game_logic == "Normal":
return ((state.has("Egg Capacity Upgrade", self.player, 1) and state.has("Egg Plant", self.player)) or (state.has("Egg Capacity Upgrade", self.player, 5) and self.has_midring(state)))
else:
return ((state.has("Egg Plant", self.player)) or (state.has("Egg Capacity Upgrade", self.player, 3) and self.has_midring(state)))
def _54CanFightBoss(self, state: CollectionState) -> bool:
if state.can_reach(self.boss_order[8], "Location", self.player):
return True
###################################################################################################
def _58Clear(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return state.has_all({"Arrow Wheel", "Large Spring Ball"}, self.player)
elif self.game_logic == "Normal":
return state.has_all({"Arrow Wheel", "Large Spring Ball"}, self.player)
else:
return state.has_all({"Arrow Wheel", "Large Spring Ball"}, self.player)
def _58Boss(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return True
elif self.game_logic == "Normal":
return True
else:
return True
def _58CanFightBoss(self, state: CollectionState) -> bool:
if state.can_reach(self.boss_order[9], "Location", self.player):
return True
##############################################################################
def _61Game(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return state.has_all({"Dashed Platform", "Key", "Beanstalk"}, self.player)
elif self.game_logic == "Normal":
return state.has_all({"Dashed Platform", "Key", "Beanstalk"}, self.player)
else:
return state.has("Key", self.player)
##############################################################################
def _64Clear(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return state.has_all({"Spring Ball", "Large Spring Ball", "Egg Plant", "Key"}, self.player) and (state.has("Egg Capacity Upgrade", self.player, 3) or self.combat_item(state))
elif self.game_logic == "Normal":
return state.has_all({"Large Spring Ball", "Egg Plant", "Key"}, self.player) and (state.has("Egg Capacity Upgrade", self.player, 2) or self.combat_item(state))
else:
return state.has_all({"Egg Plant", "Key"}, self.player) and (state.has("Egg Capacity Upgrade", self.player, 1) or self.combat_item(state))
def _64Boss(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return state.has("Egg Plant", self.player)
elif self.game_logic == "Normal":
return state.has("Egg Plant", self.player)
else:
return True
def _64CanFightBoss(self, state: CollectionState) -> bool:
if state.can_reach(self.boss_order[10], "Location", self.player):
return True
##############################################################################
def _67Game(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return state.has("Key", self.player)
elif self.game_logic == "Normal":
return state.has("Key", self.player)
else:
return state.has("Key", self.player)
##############################################################################
def _68Clear(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return state.has_all({"Helicopter Morph", "Egg Plant", "Giant Eggs"}, self.player) and self._68Route(state)
elif self.game_logic == "Normal":
return state.has_all({"Helicopter Morph", "Egg Plant", "Giant Eggs"}, self.player) and self._68Route(state)
else:
return state.has_all({"Helicopter Morph", "Giant Eggs"}, self.player) and self._68Route(state)

View File

@ -0,0 +1,19 @@
from BaseClasses import CollectionState
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from . import YoshisIslandWorld
class BossReqs:
player: int
def __init__(self, world: "YoshisIslandWorld") -> None:
self.player = world.player
self.castle_unlock = world.options.castle_open_condition.value
self.boss_unlock = world.options.castle_clear_condition.value
def castle_access(self, state: CollectionState) -> bool:
return state.has("Boss Clear", self.player, self.castle_unlock)
def castle_clear(self, state: CollectionState) -> bool:
return state.has("Boss Clear", self.player, self.boss_unlock)

View File

@ -0,0 +1,460 @@
import struct
from typing import TYPE_CHECKING
from .Options import YoshiColors, BabySound, LevelShuffle
if TYPE_CHECKING:
from . import YoshisIslandWorld
def setup_gamevars(world: "YoshisIslandWorld") -> None:
if world.options.luigi_pieces_in_pool < world.options.luigi_pieces_required:
world.options.luigi_pieces_in_pool.value = world.random.randint(world.options.luigi_pieces_required.value, 100)
world.starting_lives = struct.pack("H", world.options.starting_lives)
world.level_colors = []
world.color_order = []
for i in range(72):
world.level_colors.append(world.random.randint(0, 7))
if world.options.yoshi_colors == YoshiColors.option_singularity:
singularity_color = world.options.yoshi_singularity_color.value
for i in range(len(world.level_colors)):
world.level_colors[i] = singularity_color
elif world.options.yoshi_colors == YoshiColors.option_random_order:
world.leader_color = world.random.randint(0, 7)
for i in range(7):
world.color_order.append(world.random.randint(0, 7))
bonus_valid = [0x00, 0x02, 0x04, 0x06, 0x08, 0x0A]
world.world_bonus = []
for i in range(12):
world.world_bonus.append(world.random.choice(bonus_valid))
safe_baby_sounds = [0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A,
0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33,
0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B,
0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x52, 0x53, 0x54, 0x55, 0x56,
0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62,
0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E,
0x73, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B,
0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2]
if world.options.baby_mario_sound == BabySound.option_random_sound_effect:
world.baby_mario_sfx = world.random.choice(safe_baby_sounds)
elif world.options.baby_mario_sound == BabySound.option_disabled:
world.baby_mario_sfx = 0x42
else:
world.baby_mario_sfx = 0x44
boss_list = ["Burt The Bashful's Boss Room", "Salvo The Slime's Boss Room",
"Bigger Boo's Boss Room", "Roger The Ghost's Boss Room",
"Prince Froggy's Boss Room", "Naval Piranha's Boss Room",
"Marching Milde's Boss Room", "Hookbill The Koopa's Boss Room",
"Sluggy The Unshaven's Boss Room", "Raphael The Raven's Boss Room",
"Tap-Tap The Red Nose's Boss Room"]
world.boss_order = []
if world.options.boss_shuffle:
world.random.shuffle(boss_list)
world.boss_order = boss_list
burt_pointers = [0x3D, 0x05, 0x63, 0x00]
slime_pointers = [0x70, 0x04, 0x78, 0x00]
boo_pointers = [0x74, 0xBB, 0x7A, 0x00]
pot_pointers = [0xCF, 0x04, 0x4D, 0x00]
frog_pointers = [0xBF, 0x12, 0x62, 0x04]
plant_pointers = [0x7F, 0x0D, 0x42, 0x00]
milde_pointers = [0x82, 0x06, 0x64, 0x00]
koop_pointers = [0x86, 0x0D, 0x78, 0x00]
slug_pointers = [0x8A, 0x09, 0x7A, 0x00]
raph_pointers = [0xC4, 0x03, 0x4B, 0x05]
tap_pointers = [0xCC, 0x49, 0x64, 0x02]
boss_data_list = [
burt_pointers,
slime_pointers,
boo_pointers,
pot_pointers,
frog_pointers,
plant_pointers,
milde_pointers,
koop_pointers,
slug_pointers,
raph_pointers,
tap_pointers
]
boss_levels = [0x03, 0x07, 0x0F, 0x13, 0x1B, 0x1F, 0x27, 0x2B, 0x33, 0x37, 0x3F]
boss_room_idlist = {
"Burt The Bashful's Boss Room": 0,
"Salvo The Slime's Boss Room": 1,
"Bigger Boo's Boss Room": 2,
"Roger The Ghost's Boss Room": 3,
"Prince Froggy's Boss Room": 4,
"Naval Piranha's Boss Room": 5,
"Marching Milde's Boss Room": 6,
"Hookbill The Koopa's Boss Room": 7,
"Sluggy The Unshaven's Boss Room": 8,
"Raphael The Raven's Boss Room": 9,
"Tap-Tap The Red Nose's Boss Room": 10,
}
boss_check_list = {
"Burt The Bashful's Boss Room": "Burt The Bashful Defeated",
"Salvo The Slime's Boss Room": "Salvo The Slime Defeated",
"Bigger Boo's Boss Room": "Bigger Boo Defeated",
"Roger The Ghost's Boss Room": "Roger The Ghost Defeated",
"Prince Froggy's Boss Room": "Prince Froggy Defeated",
"Naval Piranha's Boss Room": "Naval Piranha Defeated",
"Marching Milde's Boss Room": "Marching Milde Defeated",
"Hookbill The Koopa's Boss Room": "Hookbill The Koopa Defeated",
"Sluggy The Unshaven's Boss Room": "Sluggy The Unshaven Defeated",
"Raphael The Raven's Boss Room": "Raphael The Raven Defeated",
"Tap-Tap The Red Nose's Boss Room": "Tap-Tap The Red Nose Defeated",
}
world.boss_room_id = [boss_room_idlist[roomnum] for roomnum in world.boss_order]
world.tap_tap_room = boss_levels[world.boss_room_id.index(10)]
world.boss_ap_loc = [boss_check_list[roomnum] for roomnum in world.boss_order]
world.boss_burt_data = boss_data_list[world.boss_room_id[0]]
world.boss_slime_data = boss_data_list[world.boss_room_id[1]]
world.boss_boo_data = boss_data_list[world.boss_room_id[2]]
world.boss_pot_data = boss_data_list[world.boss_room_id[3]]
world.boss_frog_data = boss_data_list[world.boss_room_id[4]]
world.boss_plant_data = boss_data_list[world.boss_room_id[5]]
world.boss_milde_data = boss_data_list[world.boss_room_id[6]]
world.boss_koop_data = boss_data_list[world.boss_room_id[7]]
world.boss_slug_data = boss_data_list[world.boss_room_id[8]]
world.boss_raph_data = boss_data_list[world.boss_room_id[9]]
world.boss_tap_data = boss_data_list[world.boss_room_id[10]]
world.global_level_list = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13,
0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42]
level_id_list = {
0x00: "1-1",
0x01: "1-2",
0x02: "1-3",
0x03: "1-4",
0x04: "1-5",
0x05: "1-6",
0x06: "1-7",
0x07: "1-8",
0x0C: "2-1",
0x0D: "2-2",
0x0E: "2-3",
0x0F: "2-4",
0x10: "2-5",
0x11: "2-6",
0x12: "2-7",
0x13: "2-8",
0x18: "3-1",
0x19: "3-2",
0x1A: "3-3",
0x1B: "3-4",
0x1C: "3-5",
0x1D: "3-6",
0x1E: "3-7",
0x1F: "3-8",
0x24: "4-1",
0x25: "4-2",
0x26: "4-3",
0x27: "4-4",
0x28: "4-5",
0x29: "4-6",
0x2A: "4-7",
0x2B: "4-8",
0x30: "5-1",
0x31: "5-2",
0x32: "5-3",
0x33: "5-4",
0x34: "5-5",
0x35: "5-6",
0x36: "5-7",
0x37: "5-8",
0x3C: "6-1",
0x3D: "6-2",
0x3E: "6-3",
0x3F: "6-4",
0x40: "6-5",
0x41: "6-6",
0x42: "6-7"
}
level_names = {
0x00: "Make Eggs, Throw Eggs",
0x01: "Watch Out Below!",
0x02: "The Cave Of Chomp Rock",
0x03: "Burt The Bashful's Fort",
0x04: "Hop! Hop! Donut Lifts",
0x05: "Shy-Guys On Stilts",
0x06: "Touch Fuzzy Get Dizzy",
0x07: "Salvo The Slime's Castle",
0x0C: "Visit Koopa And Para-Koopa",
0x0D: "The Baseball Boys",
0x0E: "What's Gusty Taste Like?",
0x0F: "Bigger Boo's Fort",
0x10: "Watch Out For Lakitu",
0x11: "The Cave Of The Mystery Maze",
0x12: "Lakitu's Wall",
0x13: "The Potted Ghost's Castle",
0x18: "Welcome To Monkey World!",
0x19: "Jungle Rhythm...",
0x1A: "Nep-Enuts' Domain",
0x1B: "Prince Froggy's Fort",
0x1C: "Jammin' Through The Trees",
0x1D: "The Cave Of Harry Hedgehog",
0x1E: "Monkeys' Favorite Lake",
0x1F: "Naval Piranha's Castle",
0x24: "GO! GO! MARIO!!",
0x25: "The Cave Of The Lakitus",
0x26: "Don't Look Back!",
0x27: "Marching Milde's Fort",
0x28: "Chomp Rock Zone",
0x29: "Lake Shore Paradise",
0x2A: "Ride Like The Wind",
0x2B: "Hookbill The Koopa's Castle",
0x30: "BLIZZARD!!!",
0x31: "Ride The Ski Lifts",
0x32: "Danger - Icy Conditions Ahead",
0x33: "Sluggy The Unshaven's Fort",
0x34: "Goonie Rides!",
0x35: "Welcome To Cloud World",
0x36: "Shifting Platforms Ahead",
0x37: "Raphael The Raven's Castle",
0x3C: "Scary Skeleton Goonies!",
0x3D: "The Cave Of The Bandits",
0x3E: "Beware The Spinning Logs",
0x3F: "Tap-Tap The Red Nose's Fort",
0x40: "The Very Loooooong Cave",
0x41: "The Deep, Underground Maze",
0x42: "KEEP MOVING!!!!"
}
world_1_offsets = [0x01, 0x00, 0x00, 0x00, 0x00, 0x00]
world_2_offsets = [0x01, 0x01, 0x00, 0x00, 0x00, 0x00]
world_3_offsets = [0x01, 0x01, 0x01, 0x00, 0x00, 0x00]
world_4_offsets = [0x01, 0x01, 0x01, 0x01, 0x00, 0x00]
world_5_offsets = [0x01, 0x01, 0x01, 0x01, 0x01, 0x00]
easy_start_lv = [0x02, 0x04, 0x06, 0x0E, 0x10, 0x18, 0x1C, 0x28,
0x30, 0x31, 0x35, 0x36, 0x3E, 0x40, 0x42]
norm_start_lv = [0x00, 0x01, 0x02, 0x04, 0x06, 0x0E, 0x10, 0x12, 0x18, 0x1A,
0x1C, 0x1E, 0x28, 0x30, 0x31, 0x34, 0x35, 0x36, 0x3D, 0x3E, 0x40, 0x42]
hard_start_lv = [0x00, 0x01, 0x02, 0x04, 0x06, 0x0D, 0x0E, 0x10, 0x11, 0x12, 0x18, 0x1A, 0x1C,
0x1E, 0x24, 0x25, 0x26, 0x28, 0x29, 0x30, 0x31, 0x34, 0x35, 0x36, 0x3D, 0x3E,
0x40, 0x42]
diff_index = [easy_start_lv, norm_start_lv, hard_start_lv]
diff_level = diff_index[world.options.stage_logic.value]
boss_lv = [0x03, 0x07, 0x0F, 0x13, 0x1B, 0x1F, 0x27, 0x2B, 0x33, 0x37, 0x3F]
world.world_start_lv = [0, 8, 16, 24, 32, 40]
if not world.options.shuffle_midrings:
easy_start_lv.extend([0x1A, 0x24, 0x34])
norm_start_lv.extend([0x24, 0x3C])
hard_start_lv.extend([0x1D, 0x3C])
if world.options.level_shuffle != LevelShuffle.option_bosses_guranteed:
hard_start_lv.extend([0x07, 0x1B, 0x1F, 0x2B, 0x33, 0x37])
if not world.options.shuffle_midrings:
easy_start_lv.extend([0x1B])
norm_start_lv.extend([0x1B, 0x2B, 0x37])
starting_level = world.random.choice(diff_level)
starting_level_entrance = world.world_start_lv[world.options.starting_world.value]
if world.options.level_shuffle:
world.global_level_list.remove(starting_level)
world.random.shuffle(world.global_level_list)
if world.options.level_shuffle == LevelShuffle.option_bosses_guranteed:
for i in range(11):
world.global_level_list = [item for item in world.global_level_list
if item not in boss_lv]
world.random.shuffle(boss_lv)
world.global_level_list.insert(3 - world_1_offsets[world.options.starting_world.value], boss_lv[0]) # 1 if starting world is 1, 0 otherwise
world.global_level_list.insert(7 - world_1_offsets[world.options.starting_world.value], boss_lv[1])
world.global_level_list.insert(11 - world_2_offsets[world.options.starting_world.value], boss_lv[2])
world.global_level_list.insert(15 - world_2_offsets[world.options.starting_world.value], boss_lv[3])
world.global_level_list.insert(19 - world_3_offsets[world.options.starting_world.value], boss_lv[4])
world.global_level_list.insert(23 - world_3_offsets[world.options.starting_world.value], boss_lv[5])
world.global_level_list.insert(27 - world_4_offsets[world.options.starting_world.value], boss_lv[6])
world.global_level_list.insert(31 - world_4_offsets[world.options.starting_world.value], boss_lv[7])
world.global_level_list.insert(35 - world_5_offsets[world.options.starting_world.value], boss_lv[8])
world.global_level_list.insert(39 - world_5_offsets[world.options.starting_world.value], boss_lv[9])
world.global_level_list.insert(43 - 1, boss_lv[10])
world.global_level_list.insert(starting_level_entrance, starting_level)
world.level_location_list = [level_id_list[LevelID] for LevelID in world.global_level_list]
world.level_name_list = [level_names[LevelID] for LevelID in world.global_level_list]
level_panel_dict = {
0x00: [0x04, 0x04, 0x53],
0x01: [0x20, 0x04, 0x53],
0x02: [0x3C, 0x04, 0x53],
0x03: [0x58, 0x04, 0x53],
0x04: [0x74, 0x04, 0x53],
0x05: [0x90, 0x04, 0x53],
0x06: [0xAC, 0x04, 0x53],
0x07: [0xC8, 0x04, 0x53],
0x0C: [0x04, 0x24, 0x53],
0x0D: [0x20, 0x24, 0x53],
0x0E: [0x3C, 0x24, 0x53],
0x0F: [0x58, 0x24, 0x53],
0x10: [0x74, 0x24, 0x53],
0x11: [0x90, 0x24, 0x53],
0x12: [0xAC, 0x24, 0x53],
0x13: [0xC8, 0x24, 0x53],
0x18: [0x04, 0x44, 0x53],
0x19: [0x20, 0x44, 0x53],
0x1A: [0x3C, 0x44, 0x53],
0x1B: [0x58, 0x44, 0x53],
0x1C: [0x74, 0x44, 0x53],
0x1D: [0x90, 0x44, 0x53],
0x1E: [0xAC, 0x44, 0x53],
0x1F: [0xC8, 0x44, 0x53],
0x24: [0x04, 0x64, 0x53],
0x25: [0x20, 0x64, 0x53],
0x26: [0x3C, 0x64, 0x53],
0x27: [0x58, 0x64, 0x53],
0x28: [0x74, 0x64, 0x53],
0x29: [0x90, 0x64, 0x53],
0x2A: [0xAC, 0x64, 0x53],
0x2B: [0xC8, 0x64, 0x53],
0x30: [0x04, 0x04, 0x53],
0x31: [0x20, 0x04, 0x53],
0x32: [0x3C, 0x04, 0x53],
0x33: [0x58, 0x04, 0x53],
0x34: [0x74, 0x04, 0x53],
0x35: [0x90, 0x04, 0x53],
0x36: [0xAC, 0x04, 0x53],
0x37: [0xC8, 0x04, 0x53],
0x3C: [0x04, 0x24, 0x53],
0x3D: [0x20, 0x24, 0x53],
0x3E: [0x3C, 0x24, 0x53],
0x3F: [0x58, 0x24, 0x53],
0x40: [0x74, 0x24, 0x53],
0x41: [0x90, 0x24, 0x53],
0x42: [0xAC, 0x24, 0x53],
}
panel_palette_1 = [0x00, 0x03, 0x04, 0x05, 0x0C, 0x10, 0x12, 0x13, 0x19, 0x1A, 0x1B, 0x1C, 0x1D,
0x24, 0x26, 0x27, 0x29, 0x2A, 0x2B, 0x30, 0x32, 0x34,
0x35, 0x37, 0x3C, 0x3D, 0x40, 0x41] # 000C
panel_palette_2 = [0x01, 0x02, 0x06, 0x07, 0x0D, 0x0E, 0x0F, 0x11, 0x18, 0x1E, 0x1F, 0x25, 0x28,
0x31, 0x33, 0x36, 0x3E, 0x3F, 0x42] # 0010
stage_number = 0
world_number = 1
for i in range(47):
stage_number += 1
if stage_number >= 9:
world_number += 1
stage_number = 1
for _ in range(3):
setattr(world, f"Stage{world_number}{stage_number}StageGFX",
level_panel_dict[world.global_level_list[i]])
world.level_gfx_table = []
world.palette_panel_list = []
for i in range(47):
if world.global_level_list[i] >= 0x30:
world.level_gfx_table.append(0x15)
else:
world.level_gfx_table.append(0x11)
if world.global_level_list[i] in panel_palette_1:
world.palette_panel_list.extend([0x00, 0x0C])
elif world.global_level_list[i] in panel_palette_2:
world.palette_panel_list.extend([0x00, 0x10])
world.palette_panel_list[16:16] = [0x00, 0x0c, 0x00, 0x0c, 0x00, 0x18, 0x00, 0x18]
world.palette_panel_list[40:40] = [0x00, 0x0c, 0x00, 0x0c, 0x00, 0x18, 0x00, 0x18]
world.palette_panel_list[64:64] = [0x00, 0x0c, 0x00, 0x0c, 0x00, 0x18, 0x00, 0x18]
world.palette_panel_list[88:88] = [0x00, 0x0c, 0x00, 0x0c, 0x00, 0x18, 0x00, 0x18]
world.palette_panel_list[112:112] = [0x00, 0x0c, 0x00, 0x0c, 0x00, 0x18, 0x00, 0x18]
world.level_gfx_table.insert(8, 0x15)
world.level_gfx_table.insert(8, 0x15)
world.level_gfx_table.insert(8, 0x15)
world.level_gfx_table.insert(8, 0x11)
world.level_gfx_table.insert(20, 0x15)
world.level_gfx_table.insert(20, 0x15)
world.level_gfx_table.insert(20, 0x15)
world.level_gfx_table.insert(20, 0x11)
world.level_gfx_table.insert(32, 0x15)
world.level_gfx_table.insert(32, 0x15)
world.level_gfx_table.insert(32, 0x15)
world.level_gfx_table.insert(32, 0x11)
world.level_gfx_table.insert(44, 0x15)
world.level_gfx_table.insert(44, 0x15)
world.level_gfx_table.insert(44, 0x15)
world.level_gfx_table.insert(44, 0x11)
world.level_gfx_table.insert(56, 0x15)
world.level_gfx_table.insert(56, 0x15)
world.level_gfx_table.insert(56, 0x15)
world.level_gfx_table.insert(56, 0x15)
castle_door_dict = {
0: [0xB8, 0x05, 0x77, 0x00],
1: [0xB8, 0x05, 0x77, 0x00],
2: [0xC6, 0x07, 0x7A, 0x00],
3: [0xCD, 0x05, 0x5B, 0x00],
4: [0xD3, 0x00, 0x77, 0x06],
5: [0xB8, 0x05, 0x77, 0x00],
}
world.castle_door = castle_door_dict[world.options.bowser_door_mode.value]
world.world_1_stages = world.global_level_list[0:8]
world.world_2_stages = world.global_level_list[8:16]
world.world_3_stages = world.global_level_list[16:24]
world.world_4_stages = world.global_level_list[24:32]
world.world_5_stages = world.global_level_list[32:40]
world.world_6_stages = world.global_level_list[40:47]
world.world_1_stages.extend([0x08, 0x09])
world.world_2_stages.extend([0x14, 0x15])
world.world_3_stages.extend([0x20, 0x21])
world.world_4_stages.extend([0x2C, 0x2D])
world.world_5_stages.extend([0x38, 0x39])
world.world_6_stages.extend([0x43, 0x44, 0x45])
bowser_text_table = {
0: [0xDE, 0xEE, 0xDC, 0xDC, 0xE5], # Gween
1: [0xE7, 0xE0, 0xE5, 0xE2, 0xD0], # Pink
3: [0xEB, 0xDF, 0xF0, 0xD8, 0xE5], # Thyan
2: [0xF0, 0xDC, 0xEE, 0xEE, 0xE6], # Yewow
4: [0xE7, 0xEC, 0xDF, 0xE7, 0xE3], # puhpl
5: [0xD9, 0xEE, 0xE6, 0xEE, 0xE5], # Bwown
6: [0xEE, 0xDC, 0xDB, 0xD0, 0xD0], # Wed
7: [0xD9, 0xEE, 0xEC, 0xDC, 0xD0], # Bwue
}
if world.options.yoshi_colors == YoshiColors.option_random_order:
world.bowser_text = bowser_text_table[world.leader_color]
else:
world.bowser_text = bowser_text_table[world.level_colors[67]]