Mario & Luigi: Superstar Saga: Implement New Game (#2754)
* Commit for PR * Commit for PR * Update worlds/mlss/Client.py Co-authored-by: Silvris <58583688+Silvris@users.noreply.github.com> * Update worlds/mlss/__init__.py Co-authored-by: Silvris <58583688+Silvris@users.noreply.github.com> * Update worlds/mlss/__init__.py Co-authored-by: Silvris <58583688+Silvris@users.noreply.github.com> * Update worlds/mlss/docs/setup_en.md Co-authored-by: Silvris <58583688+Silvris@users.noreply.github.com> * Remove deprecated import. Updated settings and romfile syntax * Updated Options to new system. Changed all references from MultiWorld to World * Changed switch statements to if else * Update en_Mario & Luigi Superstar Saga.md * Updated client.py * Update Client.py * Update worlds/mlss/docs/en_Mario & Luigi Superstar Saga.md Co-authored-by: Nicholas Saylor <79181893+nicholassaylor@users.noreply.github.com> * Updated logic, Updated patch implementation, Removed unused imports, Cleaned up Code * Update __init__.py * Changed reference from world to mlssworld * Update worlds/mlss/docs/en_Mario & Luigi Superstar Saga.md Co-authored-by: Nicholas Saylor <79181893+nicholassaylor@users.noreply.github.com> * Update worlds/mlss/docs/en_Mario & Luigi Superstar Saga.md Co-authored-by: Nicholas Saylor <79181893+nicholassaylor@users.noreply.github.com> * Update worlds/mlss/docs/en_Mario & Luigi Superstar Saga.md Co-authored-by: Nicholas Saylor <79181893+nicholassaylor@users.noreply.github.com> * Update worlds/mlss/docs/en_Mario & Luigi Superstar Saga.md Co-authored-by: Nicholas Saylor <79181893+nicholassaylor@users.noreply.github.com> * Update worlds/mlss/docs/en_Mario & Luigi Superstar Saga.md Co-authored-by: Nicholas Saylor <79181893+nicholassaylor@users.noreply.github.com> * Update worlds/mlss/docs/en_Mario & Luigi Superstar Saga.md Co-authored-by: Nicholas Saylor <79181893+nicholassaylor@users.noreply.github.com> * Fix merge conflict + update prep * v1.2 * Leftover print commands * Update basepatch.bsdiff * Update basepatch.bsdiff * v1.3 * Update Rom.py * Change tracker locations to serverside, no longer locations. Various code cleanup and logic changes. * Event removal continuation. * Partial Implementation of APPP (Incomplete)) * v1.4 Implemented APPP * Docs Updated * Update Rom.py * Update setup_en.md * Update Rom.py * Update Rules.py * Fix for APPP being broken on webhost * Update Rom.py * Update Rom.py * Location name fixes + pants color fixes * Update Rules.py * Fix for ultra hammer cutscene * Fixed compat. issues with python ver. 3.8 * Updated hidden block yaml option * pre-v1.5 * Update Client.py * Update basepatch.bsdiff * v1.5 * Update XP multiplier to have a minimum of 0 * Update 'Beanfruit' to 'Bean Fruit' * v1.6 * Update Rom.py * Update basepatch.bsdiff * Initial review refactor * Revert state logic changes. Continuation of refactor. * Fixed failed generations. Finished refactor. * Reworked colors. Removed all .txt files * Actually removed the .txt files this time * Update Rom.py * Update README.md Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> * Update worlds/mlss/Options.py Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> * Update worlds/mlss/Client.py Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> * Update worlds/mlss/docs/en_Mario & Luigi Superstar Saga.md Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> * Update worlds/mlss/__init__.py Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> * Update worlds/mlss/docs/en_Mario & Luigi Superstar Saga.md Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> * Update worlds/mlss/Data.py Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> * Review refactor. * Update README.md Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> * Update worlds/mlss/Rules.py Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> * Add coin blocks to LocationName * Refactor. * Update Items.py * Delete mlss.apworld * Small asm bugfix * Update basepatch.bsdiff * Client sends less messages to server * Update basepatch.bsdiff --------- Co-authored-by: Silvris <58583688+Silvris@users.noreply.github.com> Co-authored-by: Nicholas Saylor <79181893+nicholassaylor@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:
parent
2aa3ef372d
commit
5935093615
|
@ -65,6 +65,7 @@ Currently, the following games are supported:
|
||||||
* Castlevania 64
|
* Castlevania 64
|
||||||
* A Short Hike
|
* A Short Hike
|
||||||
* Yoshi's Island
|
* Yoshi's Island
|
||||||
|
* Mario & Luigi: Superstar Saga
|
||||||
|
|
||||||
For setup and instructions check out our [tutorials page](https://archipelago.gg/tutorial/).
|
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
|
Downloads can be found at [Releases](https://github.com/ArchipelagoMW/Archipelago/releases), including compiled
|
||||||
|
|
|
@ -92,6 +92,9 @@
|
||||||
/worlds/lufia2ac/ @el-u
|
/worlds/lufia2ac/ @el-u
|
||||||
/worlds/lufia2ac/docs/ @wordfcuk @el-u
|
/worlds/lufia2ac/docs/ @wordfcuk @el-u
|
||||||
|
|
||||||
|
# Mario & Luigi: Superstar Saga
|
||||||
|
/worlds/mlss/ @jamesbrq
|
||||||
|
|
||||||
# Meritous
|
# Meritous
|
||||||
/worlds/meritous/ @FelicitusNeko
|
/worlds/meritous/ @FelicitusNeko
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,297 @@
|
||||||
|
from typing import TYPE_CHECKING, Optional, Set, List, Dict
|
||||||
|
import struct
|
||||||
|
|
||||||
|
from NetUtils import ClientStatus
|
||||||
|
from .Locations import roomCount, nonBlock, beanstones, roomException, shop, badge, pants, eReward
|
||||||
|
from .Items import items_by_id
|
||||||
|
|
||||||
|
import asyncio
|
||||||
|
|
||||||
|
import worlds._bizhawk as bizhawk
|
||||||
|
from worlds._bizhawk.client import BizHawkClient
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from worlds._bizhawk.context import BizHawkClientContext
|
||||||
|
|
||||||
|
ROOM_ARRAY_POINTER = 0x51FA00
|
||||||
|
|
||||||
|
|
||||||
|
class MLSSClient(BizHawkClient):
|
||||||
|
game = "Mario & Luigi Superstar Saga"
|
||||||
|
system = "GBA"
|
||||||
|
patch_suffix = ".apmlss"
|
||||||
|
local_checked_locations: Set[int]
|
||||||
|
goal_flag: int
|
||||||
|
rom_slot_name: Optional[str]
|
||||||
|
eUsed: List[int]
|
||||||
|
room: int
|
||||||
|
local_events: List[int]
|
||||||
|
player_name: Optional[str]
|
||||||
|
checked_flags: Dict[int, list] = {}
|
||||||
|
|
||||||
|
def __init__(self) -> None:
|
||||||
|
super().__init__()
|
||||||
|
self.local_checked_locations = set()
|
||||||
|
self.local_set_events = {}
|
||||||
|
self.local_found_key_items = {}
|
||||||
|
self.rom_slot_name = None
|
||||||
|
self.seed_verify = False
|
||||||
|
self.eUsed = []
|
||||||
|
self.room = 0
|
||||||
|
self.local_events = []
|
||||||
|
|
||||||
|
async def validate_rom(self, ctx: "BizHawkClientContext") -> bool:
|
||||||
|
from CommonClient import logger
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Check ROM name/patch version
|
||||||
|
rom_name_bytes = await bizhawk.read(ctx.bizhawk_ctx, [(0xA0, 14, "ROM")])
|
||||||
|
rom_name = bytes([byte for byte in rom_name_bytes[0] if byte != 0]).decode("UTF-8")
|
||||||
|
if not rom_name.startswith("MARIO&LUIGIU"):
|
||||||
|
return False
|
||||||
|
if rom_name == "MARIO&LUIGIUA8":
|
||||||
|
logger.info(
|
||||||
|
"ERROR: You appear to be running an unpatched version of Mario & Luigi Superstar Saga. "
|
||||||
|
"You need to generate a patch file and use it to create a patched ROM."
|
||||||
|
)
|
||||||
|
return False
|
||||||
|
if rom_name != "MARIO&LUIGIUAP":
|
||||||
|
logger.info(
|
||||||
|
"ERROR: The patch file used to create this ROM is not compatible with "
|
||||||
|
"this client. Double check your client version against the version being "
|
||||||
|
"used by the generator."
|
||||||
|
)
|
||||||
|
return False
|
||||||
|
except UnicodeDecodeError:
|
||||||
|
return False
|
||||||
|
except bizhawk.RequestFailedError:
|
||||||
|
return False # Should verify on the next pass
|
||||||
|
|
||||||
|
ctx.game = self.game
|
||||||
|
ctx.items_handling = 0b101
|
||||||
|
ctx.want_slot_data = True
|
||||||
|
ctx.watcher_timeout = 0.125
|
||||||
|
self.rom_slot_name = rom_name
|
||||||
|
self.seed_verify = False
|
||||||
|
name_bytes = (await bizhawk.read(ctx.bizhawk_ctx, [(0xDF0000, 16, "ROM")]))[0]
|
||||||
|
name = bytes([byte for byte in name_bytes if byte != 0]).decode("UTF-8")
|
||||||
|
self.player_name = name
|
||||||
|
|
||||||
|
for i in range(59):
|
||||||
|
self.checked_flags[i] = []
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
async def set_auth(self, ctx: "BizHawkClientContext") -> None:
|
||||||
|
ctx.auth = self.player_name
|
||||||
|
|
||||||
|
def on_package(self, ctx, cmd, args) -> None:
|
||||||
|
if cmd == "RoomInfo":
|
||||||
|
ctx.seed_name = args["seed_name"]
|
||||||
|
|
||||||
|
async def game_watcher(self, ctx: "BizHawkClientContext") -> None:
|
||||||
|
from CommonClient import logger
|
||||||
|
|
||||||
|
try:
|
||||||
|
if ctx.seed_name is None:
|
||||||
|
return
|
||||||
|
if not self.seed_verify:
|
||||||
|
seed = await bizhawk.read(ctx.bizhawk_ctx, [(0xDF00A0, len(ctx.seed_name), "ROM")])
|
||||||
|
seed = seed[0].decode("UTF-8")
|
||||||
|
if seed != ctx.seed_name:
|
||||||
|
logger.info(
|
||||||
|
"ERROR: The ROM you loaded is for a different game of AP. "
|
||||||
|
"Please make sure the host has sent you the correct patch file,"
|
||||||
|
"and that you have opened the correct ROM."
|
||||||
|
)
|
||||||
|
raise bizhawk.ConnectorError("Loaded ROM is for Incorrect lobby.")
|
||||||
|
self.seed_verify = True
|
||||||
|
|
||||||
|
read_state = await bizhawk.read(
|
||||||
|
ctx.bizhawk_ctx,
|
||||||
|
[
|
||||||
|
(0x4564, 59, "EWRAM"),
|
||||||
|
(0x2330, 2, "IWRAM"),
|
||||||
|
(0x3FE0, 1, "IWRAM"),
|
||||||
|
(0x304A, 1, "EWRAM"),
|
||||||
|
(0x304B, 1, "EWRAM"),
|
||||||
|
(0x304C, 4, "EWRAM"),
|
||||||
|
(0x3060, 6, "EWRAM"),
|
||||||
|
(0x4808, 2, "EWRAM"),
|
||||||
|
(0x4407, 1, "EWRAM"),
|
||||||
|
(0x2339, 1, "IWRAM"),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
flags = read_state[0]
|
||||||
|
current_room = int.from_bytes(read_state[1], "little")
|
||||||
|
shop_init = read_state[2][0]
|
||||||
|
shop_scroll = read_state[3][0] & 0x1F
|
||||||
|
is_buy = read_state[4][0] != 0
|
||||||
|
shop_address = (struct.unpack("<I", read_state[5])[0]) & 0xFFFFFF
|
||||||
|
logo = bytes([byte for byte in read_state[6] if byte < 0x70]).decode("UTF-8")
|
||||||
|
received_index = (read_state[7][0] << 8) + read_state[7][1]
|
||||||
|
cackletta = read_state[8][0] & 0x40
|
||||||
|
shopping = read_state[9][0] & 0xF
|
||||||
|
|
||||||
|
if logo != "MLSSAP":
|
||||||
|
return
|
||||||
|
|
||||||
|
locs_to_send = set()
|
||||||
|
|
||||||
|
# Checking shop purchases
|
||||||
|
if is_buy:
|
||||||
|
await bizhawk.write(ctx.bizhawk_ctx, [(0x304A, [0x0, 0x0], "EWRAM")])
|
||||||
|
if shop_address != 0x3C0618 and shop_address != 0x3C0684:
|
||||||
|
location = shop[shop_address][shop_scroll]
|
||||||
|
else:
|
||||||
|
if shop_init & 0x1 != 0:
|
||||||
|
location = badge[shop_address][shop_scroll]
|
||||||
|
else:
|
||||||
|
location = pants[shop_address][shop_scroll]
|
||||||
|
if location in ctx.server_locations:
|
||||||
|
locs_to_send.add(location)
|
||||||
|
|
||||||
|
# Loop for receiving items. Item is written as an ID into 0x3057.
|
||||||
|
# ASM reads the ID in a loop and give the player the item before resetting the RAM address to 0x0.
|
||||||
|
# If RAM address isn't 0x0 yet break out and try again later to give the rest of the items
|
||||||
|
for i in range(len(ctx.items_received) - received_index):
|
||||||
|
item_data = items_by_id[ctx.items_received[received_index + i].item]
|
||||||
|
b = await bizhawk.guarded_read(ctx.bizhawk_ctx, [(0x3057, 1, "EWRAM")], [(0x3057, [0x0], "EWRAM")])
|
||||||
|
if b is None:
|
||||||
|
break
|
||||||
|
await bizhawk.write(
|
||||||
|
ctx.bizhawk_ctx,
|
||||||
|
[
|
||||||
|
(0x3057, [id_to_RAM(item_data.itemID)], "EWRAM"),
|
||||||
|
(0x4808, [(received_index + i + 1) // 0x100, (received_index + i + 1) % 0x100], "EWRAM"),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
await asyncio.sleep(0.1)
|
||||||
|
|
||||||
|
# Early return and location send if you are currently in a shop,
|
||||||
|
# since other flags aren't going to change
|
||||||
|
if shopping & 0x3 == 0x3:
|
||||||
|
if locs_to_send != self.local_checked_locations:
|
||||||
|
self.local_checked_locations = locs_to_send
|
||||||
|
|
||||||
|
if locs_to_send is not None:
|
||||||
|
await ctx.send_msgs([{"cmd": "LocationChecks", "locations": list(locs_to_send)}])
|
||||||
|
return
|
||||||
|
|
||||||
|
# Checking flags that aren't digspots or blocks
|
||||||
|
for item in nonBlock:
|
||||||
|
address, mask, location = item
|
||||||
|
if location in self.local_checked_locations:
|
||||||
|
continue
|
||||||
|
flag_bytes = await bizhawk.read(ctx.bizhawk_ctx, [(address, 1, "EWRAM"), (0x3060, 6, "EWRAM")])
|
||||||
|
flag_byte = flag_bytes[0][0]
|
||||||
|
backup_logo = bytes([byte for byte in flag_bytes[1] if byte < 0x70]).decode("UTF-8")
|
||||||
|
if backup_logo != "MLSSAP":
|
||||||
|
return
|
||||||
|
if flag_byte & mask != 0:
|
||||||
|
if location >= 0xDA0000 and location not in self.local_events:
|
||||||
|
self.local_events += [location]
|
||||||
|
await ctx.send_msgs(
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"cmd": "Set",
|
||||||
|
"key": f"mlss_flag_{ctx.team}_{ctx.slot}",
|
||||||
|
"default": 0,
|
||||||
|
"want_reply": False,
|
||||||
|
"operations": [{"operation": "or", "value": 1 << (location - 0xDA0000)}],
|
||||||
|
}
|
||||||
|
]
|
||||||
|
)
|
||||||
|
continue
|
||||||
|
if location in roomException:
|
||||||
|
if current_room not in roomException[location]:
|
||||||
|
exception = True
|
||||||
|
else:
|
||||||
|
exception = False
|
||||||
|
else:
|
||||||
|
exception = True
|
||||||
|
|
||||||
|
if location in eReward:
|
||||||
|
if location not in self.eUsed:
|
||||||
|
self.eUsed += [location]
|
||||||
|
location = eReward[len(self.eUsed) - 1]
|
||||||
|
else:
|
||||||
|
continue
|
||||||
|
if (location in ctx.server_locations) and exception:
|
||||||
|
locs_to_send.add(location)
|
||||||
|
|
||||||
|
# Check for set location flags.
|
||||||
|
for byte_i, byte in enumerate(bytearray(flags)):
|
||||||
|
for j in range(8):
|
||||||
|
if j in self.checked_flags[byte_i]:
|
||||||
|
continue
|
||||||
|
and_value = 1 << j
|
||||||
|
if byte & and_value != 0:
|
||||||
|
flag_id = byte_i * 8 + (j + 1)
|
||||||
|
room, item = find_key(roomCount, flag_id)
|
||||||
|
pointer_arr = await bizhawk.read(
|
||||||
|
ctx.bizhawk_ctx, [(ROOM_ARRAY_POINTER + ((room - 1) * 4), 4, "ROM")]
|
||||||
|
)
|
||||||
|
pointer = struct.unpack("<I", pointer_arr[0])[0]
|
||||||
|
pointer = pointer & 0xFFFFFF
|
||||||
|
offset = await bizhawk.read(ctx.bizhawk_ctx, [(pointer, 1, "ROM")])
|
||||||
|
offset = offset[0][0]
|
||||||
|
if offset != 0:
|
||||||
|
offset = 2
|
||||||
|
pointer += (item * 8) + 1 + offset
|
||||||
|
for key, value in beanstones.items():
|
||||||
|
if pointer == value:
|
||||||
|
pointer = key
|
||||||
|
break
|
||||||
|
if pointer in ctx.server_locations:
|
||||||
|
self.checked_flags[byte_i] += [j]
|
||||||
|
locs_to_send.add(pointer)
|
||||||
|
|
||||||
|
if not ctx.finished_game and cackletta != 0 and current_room == 0x1C7:
|
||||||
|
await ctx.send_msgs([{"cmd": "StatusUpdate", "status": ClientStatus.CLIENT_GOAL}])
|
||||||
|
|
||||||
|
if self.room != current_room:
|
||||||
|
self.room = current_room
|
||||||
|
await ctx.send_msgs(
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"cmd": "Set",
|
||||||
|
"key": f"mlss_room_{ctx.team}_{ctx.slot}",
|
||||||
|
"default": 0,
|
||||||
|
"want_reply": False,
|
||||||
|
"operations": [{"operation": "replace", "value": current_room}],
|
||||||
|
}
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
# Send locations if there are any to send.
|
||||||
|
if locs_to_send != self.local_checked_locations:
|
||||||
|
self.local_checked_locations = locs_to_send
|
||||||
|
|
||||||
|
if locs_to_send is not None:
|
||||||
|
await ctx.send_msgs([{"cmd": "LocationChecks", "locations": list(locs_to_send)}])
|
||||||
|
|
||||||
|
except bizhawk.RequestFailedError:
|
||||||
|
# Exit handler and return to main loop to reconnect.
|
||||||
|
pass
|
||||||
|
except bizhawk.ConnectorError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def find_key(dictionary, target):
|
||||||
|
leftover = target
|
||||||
|
|
||||||
|
for key, value in dictionary.items():
|
||||||
|
if leftover > value:
|
||||||
|
leftover -= value
|
||||||
|
else:
|
||||||
|
return key, leftover
|
||||||
|
|
||||||
|
|
||||||
|
def id_to_RAM(id_: int):
|
||||||
|
code = id_
|
||||||
|
if 0x1C <= code <= 0x1F:
|
||||||
|
code += 0xE
|
||||||
|
if 0x20 <= code <= 0x26:
|
||||||
|
code -= 0x4
|
||||||
|
return code
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,190 @@
|
||||||
|
import typing
|
||||||
|
|
||||||
|
from BaseClasses import Item, ItemClassification
|
||||||
|
|
||||||
|
|
||||||
|
class ItemData(typing.NamedTuple):
|
||||||
|
code: int
|
||||||
|
itemName: str
|
||||||
|
classification: ItemClassification
|
||||||
|
itemID: int
|
||||||
|
|
||||||
|
|
||||||
|
class MLSSItem(Item):
|
||||||
|
game: str = "Mario & Luigi Superstar Saga"
|
||||||
|
|
||||||
|
|
||||||
|
itemList: typing.List[ItemData] = [
|
||||||
|
ItemData(77771000, "5 Coins", ItemClassification.filler, 0x4),
|
||||||
|
ItemData(77771001, "Mushroom", ItemClassification.filler, 0xA),
|
||||||
|
ItemData(77771002, "Super Mushroom", ItemClassification.filler, 0xB),
|
||||||
|
ItemData(77771003, "Ultra Mushroom", ItemClassification.filler, 0xC),
|
||||||
|
ItemData(77771004, "Max Mushroom", ItemClassification.filler, 0xD),
|
||||||
|
ItemData(77771005, "Nuts", ItemClassification.filler, 0xE),
|
||||||
|
ItemData(77771006, "Super Nuts", ItemClassification.filler, 0xF),
|
||||||
|
ItemData(77771007, "Ultra Nuts", ItemClassification.useful, 0x10),
|
||||||
|
ItemData(77771008, "Max Nuts", ItemClassification.useful, 0x11),
|
||||||
|
ItemData(77771009, "Syrup", ItemClassification.filler, 0x12),
|
||||||
|
ItemData(77771010, "Super Syrup", ItemClassification.filler, 0x13),
|
||||||
|
ItemData(77771011, "Ultra Syrup", ItemClassification.useful, 0x14),
|
||||||
|
ItemData(77771012, "Max Syrup", ItemClassification.useful, 0x15),
|
||||||
|
ItemData(77771013, "1-UP Mushroom", ItemClassification.useful, 0x16),
|
||||||
|
ItemData(77771014, "1-UP Super", ItemClassification.useful, 0x17),
|
||||||
|
ItemData(77771015, "Golden Mushroom", ItemClassification.useful, 0x18),
|
||||||
|
ItemData(77771016, "Refreshing Herb", ItemClassification.filler, 0x19),
|
||||||
|
ItemData(77771017, "Red Pepper", ItemClassification.useful, 0x1A),
|
||||||
|
ItemData(77771018, "Green Pepper", ItemClassification.useful, 0x1B),
|
||||||
|
ItemData(77771019, "Hoo Bean", ItemClassification.filler, 0x1D),
|
||||||
|
ItemData(77771020, "Chuckle Bean", ItemClassification.filler, 0x1E),
|
||||||
|
ItemData(77771021, "Woohoo Blend", ItemClassification.useful, 0x20),
|
||||||
|
ItemData(77771022, "Hoohoo Blend", ItemClassification.useful, 0x21),
|
||||||
|
ItemData(77771023, "Chuckle Blend", ItemClassification.useful, 0x22),
|
||||||
|
ItemData(77771024, "Teehee Blend", ItemClassification.useful, 0x23),
|
||||||
|
ItemData(77771025, "Hoolumbian", ItemClassification.useful, 0x24),
|
||||||
|
ItemData(77771026, "Chuckoccino", ItemClassification.useful, 0x25),
|
||||||
|
ItemData(77771027, "Teeheespresso", ItemClassification.useful, 0x26),
|
||||||
|
ItemData(77771028, "Peasley's Rose", ItemClassification.progression, 0x31),
|
||||||
|
ItemData(77771029, "Beanbean Brooch", ItemClassification.progression, 0x32),
|
||||||
|
ItemData(77771030, "Red Goblet", ItemClassification.progression, 0x33),
|
||||||
|
ItemData(77771031, "Green Goblet", ItemClassification.progression, 0x34),
|
||||||
|
ItemData(77771032, "Red Chuckola Fruit", ItemClassification.progression, 0x35),
|
||||||
|
ItemData(77771033, "White Chuckola Fruit", ItemClassification.progression, 0x36),
|
||||||
|
ItemData(77771034, "Purple Chuckola Fruit", ItemClassification.progression, 0x37),
|
||||||
|
ItemData(77771035, "Hammers", ItemClassification.progression, 0x38),
|
||||||
|
ItemData(77771036, "Firebrand", ItemClassification.progression, 0x39),
|
||||||
|
ItemData(77771037, "Thunderhand", ItemClassification.progression, 0x3A),
|
||||||
|
ItemData(77771038, "Membership Card", ItemClassification.progression, 0x40),
|
||||||
|
ItemData(77771039, "Winkle Card", ItemClassification.progression, 0x41),
|
||||||
|
ItemData(77771040, "Peach's Extra Dress", ItemClassification.progression, 0x42),
|
||||||
|
ItemData(77771041, "Fake Beanstar", ItemClassification.progression, 0x43),
|
||||||
|
ItemData(77771042, "Red Pearl Bean", ItemClassification.progression, 0x45),
|
||||||
|
ItemData(77771043, "Green Pearl Bean", ItemClassification.progression, 0x46),
|
||||||
|
ItemData(77771044, "Bean Fruit 1", ItemClassification.progression_skip_balancing, 0x47),
|
||||||
|
ItemData(77771045, "Bean Fruit 2", ItemClassification.progression_skip_balancing, 0x50),
|
||||||
|
ItemData(77771046, "Bean Fruit 3", ItemClassification.progression_skip_balancing, 0x51),
|
||||||
|
ItemData(77771047, "Bean Fruit 4", ItemClassification.progression_skip_balancing, 0x52),
|
||||||
|
ItemData(77771048, "Bean Fruit 5", ItemClassification.progression_skip_balancing, 0x53),
|
||||||
|
ItemData(77771049, "Bean Fruit 6", ItemClassification.progression_skip_balancing, 0x54),
|
||||||
|
ItemData(77771050, "Bean Fruit 7", ItemClassification.progression_skip_balancing, 0x55),
|
||||||
|
ItemData(77771051, "Blue Neon Egg", ItemClassification.progression, 0x56),
|
||||||
|
ItemData(77771052, "Red Neon Egg", ItemClassification.progression, 0x57),
|
||||||
|
ItemData(77771053, "Green Neon Egg", ItemClassification.progression, 0x60),
|
||||||
|
ItemData(77771054, "Yellow Neon Egg", ItemClassification.progression, 0x61),
|
||||||
|
ItemData(77771055, "Purple Neon Egg", ItemClassification.progression, 0x62),
|
||||||
|
ItemData(77771056, "Orange Neon Egg", ItemClassification.progression, 0x63),
|
||||||
|
ItemData(77771057, "Azure Neon Egg", ItemClassification.progression, 0x64),
|
||||||
|
ItemData(77771058, "Beanstar Piece 1", ItemClassification.progression, 0x65),
|
||||||
|
ItemData(77771059, "Beanstar Piece 2", ItemClassification.progression, 0x66),
|
||||||
|
ItemData(77771060, "Beanstar Piece 3", ItemClassification.progression, 0x67),
|
||||||
|
ItemData(77771061, "Beanstar Piece 4", ItemClassification.progression, 0x70),
|
||||||
|
ItemData(77771062, "Spangle", ItemClassification.progression, 0x72),
|
||||||
|
ItemData(77771063, "Beanlet 1", ItemClassification.filler, 0x73),
|
||||||
|
ItemData(77771064, "Beanlet 2", ItemClassification.filler, 0x74),
|
||||||
|
ItemData(77771065, "Beanlet 3", ItemClassification.filler, 0x75),
|
||||||
|
ItemData(77771066, "Beanlet 4", ItemClassification.filler, 0x76),
|
||||||
|
ItemData(77771067, "Beanlet 5", ItemClassification.filler, 0x77),
|
||||||
|
ItemData(77771068, "Beanstone 1", ItemClassification.filler, 0x80),
|
||||||
|
ItemData(77771069, "Beanstone 2", ItemClassification.filler, 0x81),
|
||||||
|
ItemData(77771070, "Beanstone 3", ItemClassification.filler, 0x82),
|
||||||
|
ItemData(77771071, "Beanstone 4", ItemClassification.filler, 0x83),
|
||||||
|
ItemData(77771072, "Beanstone 5", ItemClassification.filler, 0x84),
|
||||||
|
ItemData(77771073, "Beanstone 6", ItemClassification.filler, 0x85),
|
||||||
|
ItemData(77771074, "Beanstone 7", ItemClassification.filler, 0x86),
|
||||||
|
ItemData(77771075, "Beanstone 8", ItemClassification.filler, 0x87),
|
||||||
|
ItemData(77771076, "Beanstone 9", ItemClassification.filler, 0x90),
|
||||||
|
ItemData(77771077, "Beanstone 10", ItemClassification.filler, 0x91),
|
||||||
|
ItemData(77771078, "Secret Scroll 1", ItemClassification.useful, 0x92),
|
||||||
|
ItemData(77771079, "Secret Scroll 2", ItemClassification.useful, 0x93),
|
||||||
|
ItemData(77771080, "Castle Badge", ItemClassification.useful, 0x9F),
|
||||||
|
ItemData(77771081, "Pea Badge", ItemClassification.useful, 0xA0),
|
||||||
|
ItemData(77771082, "Bean B. Badge", ItemClassification.useful, 0xA1),
|
||||||
|
ItemData(77771083, "Counter Badge", ItemClassification.useful, 0xA2),
|
||||||
|
ItemData(77771084, "Charity Badge", ItemClassification.useful, 0xA3),
|
||||||
|
ItemData(77771085, "Bros. Badge", ItemClassification.useful, 0xA4),
|
||||||
|
ItemData(77771086, "Miracle Badge", ItemClassification.useful, 0xA5),
|
||||||
|
ItemData(77771087, "Ohoracle Badge", ItemClassification.useful, 0xA6),
|
||||||
|
ItemData(77771088, "Mush Badge", ItemClassification.useful, 0xA7),
|
||||||
|
ItemData(77771089, "Mari-Lui Badge", ItemClassification.useful, 0xA8),
|
||||||
|
ItemData(77771090, "Muscle Badge", ItemClassification.useful, 0xA9),
|
||||||
|
ItemData(77771091, "Spiny Badge AA", ItemClassification.useful, 0xAA),
|
||||||
|
ItemData(77771092, "Mush Badge A", ItemClassification.useful, 0xAB),
|
||||||
|
ItemData(77771093, "Grab Badge", ItemClassification.useful, 0xAC),
|
||||||
|
ItemData(77771094, "Mush Badge AA", ItemClassification.useful, 0xAD),
|
||||||
|
ItemData(77771095, "Power Badge", ItemClassification.useful, 0xAE),
|
||||||
|
ItemData(77771096, "Wonder Badge", ItemClassification.useful, 0xAF),
|
||||||
|
ItemData(77771097, "Beauty Badge", ItemClassification.useful, 0xB0),
|
||||||
|
ItemData(77771098, "Salvage Badge", ItemClassification.useful, 0xB1),
|
||||||
|
ItemData(77771099, "Oh-Pah Badge", ItemClassification.useful, 0xB2),
|
||||||
|
ItemData(77771100, "Brilliant Badge", ItemClassification.useful, 0xB3),
|
||||||
|
ItemData(77771101, "Sarge Badge", ItemClassification.useful, 0xB4),
|
||||||
|
ItemData(77771102, "General Badge", ItemClassification.useful, 0xB5),
|
||||||
|
ItemData(77771103, "Tank Badge", ItemClassification.useful, 0xB6),
|
||||||
|
ItemData(77771104, "Bros. Rock", ItemClassification.useful, 0xBD),
|
||||||
|
ItemData(77771105, "Soulful Bros.", ItemClassification.useful, 0xC0),
|
||||||
|
ItemData(77771106, "High-End Badge", ItemClassification.useful, 0xC1),
|
||||||
|
ItemData(77771107, "Bean Pants", ItemClassification.useful, 0xCC),
|
||||||
|
ItemData(77771108, "Bean Trousers", ItemClassification.useful, 0xCD),
|
||||||
|
ItemData(77771109, "Blue Jeans", ItemClassification.useful, 0xCE),
|
||||||
|
ItemData(77771110, "Parasol Pants", ItemClassification.useful, 0xCF),
|
||||||
|
ItemData(77771111, "Hard Pants", ItemClassification.useful, 0xD0),
|
||||||
|
ItemData(77771112, "Heart Jeans", ItemClassification.useful, 0xD1),
|
||||||
|
ItemData(77771113, "Plaid Trousers", ItemClassification.useful, 0xD2),
|
||||||
|
ItemData(77771114, "#1 Trousers", ItemClassification.useful, 0xD3),
|
||||||
|
ItemData(77771115, "Safety Slacks", ItemClassification.useful, 0xD4),
|
||||||
|
ItemData(77771116, "Shroom Pants", ItemClassification.useful, 0xD5),
|
||||||
|
ItemData(77771117, "Shroom Bells", ItemClassification.useful, 0xD6),
|
||||||
|
ItemData(77771118, "Shroom Slacks", ItemClassification.useful, 0xD7),
|
||||||
|
ItemData(77771119, "Peachy Jeans", ItemClassification.useful, 0xD8),
|
||||||
|
ItemData(77771120, "Mushwin Pants", ItemClassification.useful, 0xD9),
|
||||||
|
ItemData(77771121, "Mushluck Pants", ItemClassification.useful, 0xDA),
|
||||||
|
ItemData(77771122, "Scandal Jeans", ItemClassification.useful, 0xDB),
|
||||||
|
ItemData(77771123, "Street Jeans", ItemClassification.useful, 0xDC),
|
||||||
|
ItemData(77771124, "Tropic Slacks", ItemClassification.useful, 0xDD),
|
||||||
|
ItemData(77771125, "Hermetic Pants", ItemClassification.useful, 0xDE),
|
||||||
|
ItemData(77771126, "Beanstar Pants", ItemClassification.useful, 0xDF),
|
||||||
|
ItemData(77771127, "Peasley Slacks", ItemClassification.useful, 0xE0),
|
||||||
|
ItemData(77771128, "Queen B. Jeans", ItemClassification.useful, 0xE1),
|
||||||
|
ItemData(77771129, "B. Brand Jeans", ItemClassification.useful, 0xE2),
|
||||||
|
ItemData(77771130, "Heart Slacks", ItemClassification.useful, 0xE3),
|
||||||
|
ItemData(77771131, "Casual Slacks", ItemClassification.useful, 0xE4),
|
||||||
|
ItemData(77771132, "Casual Coral", ItemClassification.useful, 0xEB),
|
||||||
|
ItemData(77771133, "Harhall's Pants", ItemClassification.useful, 0xF1),
|
||||||
|
ItemData(77771134, "Wool Trousers", ItemClassification.useful, 0xF3),
|
||||||
|
ItemData(77771135, "Iron Pants", ItemClassification.useful, 0xF7),
|
||||||
|
ItemData(77771136, "Greed Wallet", ItemClassification.useful, 0xF8),
|
||||||
|
ItemData(77771137, "Bonus Ring", ItemClassification.useful, 0xF9),
|
||||||
|
ItemData(77771138, "Excite Spring", ItemClassification.useful, 0xFA),
|
||||||
|
ItemData(77771139, "Great Force", ItemClassification.useful, 0xFB),
|
||||||
|
ItemData(77771140, "Power Grip", ItemClassification.useful, 0xFC),
|
||||||
|
ItemData(77771141, "Cobalt Necktie", ItemClassification.useful, 0xFD),
|
||||||
|
ItemData(77771142, "Game Boy Horror SP", ItemClassification.useful, 0xFE),
|
||||||
|
ItemData(77771143, "Woo Bean", ItemClassification.skip_balancing, 0x1C),
|
||||||
|
ItemData(77771144, "Hee Bean", ItemClassification.skip_balancing, 0x1F),
|
||||||
|
]
|
||||||
|
|
||||||
|
item_frequencies: typing.Dict[str, int] = {
|
||||||
|
"5 Coins": 40,
|
||||||
|
"Mushroom": 55,
|
||||||
|
"Super Mushroom": 15,
|
||||||
|
"Ultra Mushroom": 12,
|
||||||
|
"Nuts": 10,
|
||||||
|
"Super Nuts": 5,
|
||||||
|
"Ultra Nuts": 5,
|
||||||
|
"Max Nuts": 2,
|
||||||
|
"Syrup": 28,
|
||||||
|
"Super Syrup": 10,
|
||||||
|
"Ultra Syrup": 10,
|
||||||
|
"Max Syrup": 2,
|
||||||
|
"1-Up Mushroom": 15,
|
||||||
|
"1-Up Super": 5,
|
||||||
|
"Golden Mushroom": 3,
|
||||||
|
"Refreshing Herb": 9,
|
||||||
|
"Red Pepper": 2,
|
||||||
|
"Green Pepper": 2,
|
||||||
|
"Hoo Bean": 100,
|
||||||
|
"Chuckle Bean": 200,
|
||||||
|
"Hammers": 3,
|
||||||
|
}
|
||||||
|
|
||||||
|
item_table: typing.Dict[str, ItemData] = {item.itemName: item for item in itemList}
|
||||||
|
items_by_id: typing.Dict[int, ItemData] = {item.code: item for item in itemList}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,559 @@
|
||||||
|
class LocationName:
|
||||||
|
StardustFields1Block1 = "Stardust Fields Room 1 Block 1"
|
||||||
|
StardustFields1Block2 = "Stardust Fields Room 1 Block 2"
|
||||||
|
StardustFields2Block = "Stardust Fields Room 2 Block"
|
||||||
|
StardustFields3Block = "Stardust Fields Room 3 Block"
|
||||||
|
StardustFields4Block1 = "Stardust Fields Room 4 Block 1"
|
||||||
|
StardustFields4Block2 = "Stardust Fields Room 4 Block 2"
|
||||||
|
StardustFields4Block3 = "Stardust Fields Room 4 Block 3"
|
||||||
|
StardustFields5Block = "Stardust Fields Room 5 Block"
|
||||||
|
HoohooVillageHammerHouseBlock = "Hoohoo Village Hammer House Block"
|
||||||
|
BeanbeanCastleTownLeftSideHouseBlock1 = "Beanbean Castle Town Left Side House Block 1"
|
||||||
|
BeanbeanCastleTownLeftSideHouseBlock2 = "Beanbean Castle Town Left Side House Block 2"
|
||||||
|
BeanbeanCastleTownLeftSideHouseBlock3 = "Beanbean Castle Town Left Side House Block 3"
|
||||||
|
BeanbeanCastleTownLeftSideHouseBlock4 = "Beanbean Castle Town Left Side House Block 4"
|
||||||
|
BeanbeanCastleTownRightSideHouseBlock1 = "Beanbean Castle Town Right Side House Block 1"
|
||||||
|
BeanbeanCastleTownRightSideHouseBlock2 = "Beanbean Castle Town Right Side House Block 2"
|
||||||
|
BeanbeanCastleTownRightSideHouseBlock3 = "Beanbean Castle Town Right Side House Block 3"
|
||||||
|
BeanbeanCastleTownRightSideHouseBlock4 = "Beanbean Castle Town Right Side House Block 4"
|
||||||
|
BeanbeanCastleTownMiniMarioBlock1 = "Beanbean Castle Town Mini Mario Block 1"
|
||||||
|
BeanbeanCastleTownMiniMarioBlock2 = "Beanbean Castle Town Mini Mario Block 2"
|
||||||
|
BeanbeanCastleTownMiniMarioBlock3 = "Beanbean Castle Town Mini Mario Block 3"
|
||||||
|
BeanbeanCastleTownMiniMarioBlock4 = "Beanbean Castle Town Mini Mario Block 4"
|
||||||
|
BeanbeanCastleTownMiniMarioBlock5 = "Beanbean Castle Town Mini Mario Block 5"
|
||||||
|
HoohooMountainSummitDigspot = "Hoohoo Mountain Summit Digspot"
|
||||||
|
HoohooMountainBelowSummitDigspot = "Hoohoo Mountain Below Summit Digspot"
|
||||||
|
HoohooMountainBelowSummitBlock1 = "Hoohoo Mountain Below Summit Block 1"
|
||||||
|
HoohooMountainBelowSummitBlock2 = "Hoohoo Mountain Below Summit Block 2"
|
||||||
|
HoohooMountainBelowSummitBlock3 = "Hoohoo Mountain Below Summit Block 3"
|
||||||
|
HoohooMountainAfterHoohoorosBlock1 = "Hoohoo Mountain After Hoohooros Block 1"
|
||||||
|
HoohooMountainAfterHoohoorosDigspot = "Hoohoo Mountain After Hoohooros Digspot"
|
||||||
|
HoohooMountainAfterHoohoorosBlock2 = "Hoohoo Mountain After Hoohooros Block 2"
|
||||||
|
HoohooMountainHoohoorosRoomBlock1 = "Hoohoo Mountain Hoohooros Room Block 1"
|
||||||
|
HoohooMountainHoohoorosRoomBlock2 = "Hoohoo Mountain Hoohooros Room Block 2"
|
||||||
|
HoohooMountainHoohoorosRoomDigspot1 = "Hoohoo Mountain Hoohooros Room Digspot 1"
|
||||||
|
HoohooMountainHoohoorosRoomDigspot2 = "Hoohoo Mountain Hoohooros Room Digspot 2"
|
||||||
|
HoohooMountainBeforeHoohoorosBlock = "Hoohoo Mountain Before Hoohooros Block"
|
||||||
|
HoohooMountainBeforeHoohoorosDigspot = "Hoohoo Mountain Before Hoohooros Digspot"
|
||||||
|
HoohooMountainFountainRoomBlock1 = "Hoohoo Mountain Fountain Room Block 1"
|
||||||
|
HoohooMountainFountainRoomBlock2 = "Hoohoo Mountain Fountain Room Block 2"
|
||||||
|
HoohooMountainRoom2Digspot1 = "Hoohoo Mountain Room 2 Digspot 1"
|
||||||
|
HoohooMountainRoom2Digspot2 = "Hoohoo Mountain Room 2 Digspot 2"
|
||||||
|
HoohooMountainRoom1Block1 = "Hoohoo Mountain Room 1 Block 1"
|
||||||
|
HoohooMountainRoom1Block2 = "Hoohoo Mountain Room 1 Block 2"
|
||||||
|
HoohooMountainRoom1Block3 = "Hoohoo Mountain Room 1 Block 3"
|
||||||
|
HoohooMountainBaseRoom1Block = "Hoohoo Mountain Base Room 1 Block"
|
||||||
|
HoohooMountainBaseRoom1Digspot = "Hoohoo Mountain Base Room 1 Digspot"
|
||||||
|
HoohooVillageRightSideBlock = "Hoohoo Village Right Side Block"
|
||||||
|
HoohooVillageRightSideDigspot = "Hoohoo Village Right Side Digspot"
|
||||||
|
HoohooVillageBridgeRoomBlock1 = "Hoohoo Village Bridge Room Block 1"
|
||||||
|
HoohooVillageBridgeRoomBlock2 = "Hoohoo Village Bridge Room Block 2"
|
||||||
|
HoohooVillageBridgeRoomBlock3 = "Hoohoo Village Bridge Room Block 3"
|
||||||
|
HoohooMountainBaseBridgeRoomBlock1 = "Hoohoo Mountain Base Bridge Room Block 1"
|
||||||
|
HoohooMountainBaseBridgeRoomBlock2 = "Hoohoo Mountain Base Bridge Room Block 2"
|
||||||
|
HoohooMountainBaseBridgeRoomBlock3 = "Hoohoo Mountain Base Bridge Room Block 3"
|
||||||
|
HoohooMountainBaseBridgeRoomBlock4 = "Hoohoo Mountain Base Bridge Room Block 4"
|
||||||
|
HoohooMountainBaseBridgeRoomDigspot = "Hoohoo Mountain Base Bridge Room Digspot"
|
||||||
|
HoohooMountainBaseBoostatueRoomBlock1 = "Hoohoo Mountain Base Boostatue Room Block 1"
|
||||||
|
HoohooMountainBaseBoostatueRoomBlock2 = "Hoohoo Mountain Base Boostatue Room Block 2"
|
||||||
|
HoohooMountainBaseBoostatueRoomDigspot1 = "Hoohoo Mountain Base Boostatue Room Digspot 1"
|
||||||
|
HoohooMountainBaseBoostatueRoomDigspot2 = "Hoohoo Mountain Base Boostatue Room Digspot 2"
|
||||||
|
HoohooMountainBaseBoostatueRoomDigspot3 = "Hoohoo Mountain Base Boostatue Room Digspot 3"
|
||||||
|
BeanbeanOutskirtsBooStatueMole = "Beanbean Outskirts Boo Statue Mole"
|
||||||
|
HoohooMountainBaseGrassyAreaBlock1 = "Hoohoo Mountain Base Grassy Area Block 1"
|
||||||
|
HoohooMountainBaseGrassyAreaBlock2 = "Hoohoo Mountain Base Grassy Area Block 2"
|
||||||
|
HoohooMountainBaseGuffawhaRuinsEntranceDigspot = "Hoohoo Mountain Base Guffawha Ruins Entrance Digspot"
|
||||||
|
HoohooMountainBaseTeeheeValleyEntranceDigspot = "Hoohoo Mountain Base Teehee Valley Entrance Digspot"
|
||||||
|
HoohooMountainBaseTeeheeValleyEntranceBlock = "Hoohoo Mountain Base Teehee Valley Entrance Block"
|
||||||
|
HoohooMountainBaseAfterMinecartMinigameBlock1 = "Hoohoo Mountain Base After Minecart Minigame Block 1"
|
||||||
|
HoohooMountainBaseAfterMinecartMinigameBlock2 = "Hoohoo Mountain Base After Minecart Minigame Block 2"
|
||||||
|
HoohooMountainBasePastUltraHammerRocksBlock1 = "Hoohoo Mountain Base Past Ultra Hammer Rocks Block 1"
|
||||||
|
HoohooMountainBasePastUltraHammerRocksBlock2 = "Hoohoo Mountain Base Past Ultra Hammer Rocks Block 2"
|
||||||
|
HoohooMountainBasePastUltraHammerRocksBlock3 = "Hoohoo Mountain Base Past Ultra Hammer Rocks Block 3"
|
||||||
|
CaveConnectingStardustFieldsAndHoohooVillageBlock1 = "Cave Connecting Stardust Fields and Hoohoo Village Block 1"
|
||||||
|
CaveConnectingStardustFieldsAndHoohooVillageBlock2 = "Cave Connecting Stardust Fields and Hoohoo Village Block 2"
|
||||||
|
HoohooVillageSouthCaveBlock = "Hoohoo Village South Cave Block"
|
||||||
|
HoohooVillageSuperHammerCaveDigspot = "Hoohoo Village Super Hammer Cave Digspot"
|
||||||
|
HoohooVillageSuperHammerCaveBlock = "Hoohoo Village Super Hammer Cave Block"
|
||||||
|
HoohooVillageNorthCaveRoom1Block = "Hoohoo Village North Cave Room 1 Block"
|
||||||
|
HoohooVillageNorthCaveRoom2Block = "Hoohoo Village North Cave Room 2 Block"
|
||||||
|
HoohooVillageNorthCaveRoom2Digspot = "Hoohoo Village North Cave Room 2 Digspot"
|
||||||
|
HoohooMountainBaseMinecartCaveDigspot = "Hoohoo Mountain Base Minecart Cave Digspot"
|
||||||
|
BeanbeanOutskirtsFarmRoomDigspot1 = "Beanbean Outskirts Farm Room Digspot 1"
|
||||||
|
BeanbeanOutskirtsFarmRoomDigspot2 = "Beanbean Outskirts Farm Room Digspot 2"
|
||||||
|
BeanbeanOutskirtsFarmRoomDigspot3 = "Beanbean Outskirts Farm Room Digspot 3"
|
||||||
|
BeanbeanOutskirtsNWBlock = "Beanbean Outskirts NW Block"
|
||||||
|
BeanbeanOutskirtsNWDigspot = "Beanbean Outskirts NW Digspot"
|
||||||
|
BeanbeanOutskirtsWDigspot1 = "Beanbean Outskirts W Digspot 1"
|
||||||
|
BeanbeanOutskirtsWDigspot2 = "Beanbean Outskirts W"
|
||||||
|
BeanbeanOutskirtsNRoom1Digspot = "Beanbean Outskirts N Room 1 Digspot"
|
||||||
|
BeanbeanOutskirtsNRoom2Digspot = "Beanbean Outskirts N Room 2 Digspot"
|
||||||
|
BeanbeanOutskirtsSRoom1Digspot1 = "Beanbean Outskirts S Room 1 Digspot 1"
|
||||||
|
BeanbeanOutskirtsSRoom1Block = "Beanbean Outskirts S Room 1 Block"
|
||||||
|
BeanbeanOutskirtsSRoom1Digspot2 = "Beanbean Outskirts S Room 1 Digspot 2"
|
||||||
|
BeanbeanOutskirtsSRoom2Block1 = "Beanbean Outskirts S Room 2 Block 1"
|
||||||
|
BeanbeanOutskirtsSRoom2Digspot1 = "Beanbean Outskirts S Room 2 Digspot 1"
|
||||||
|
BeanbeanOutskirtsSRoom2Digspot2 = "Beanbean Outskirts S Room 2 Digspot 2"
|
||||||
|
BeanbeanOutskirtsSRoom2Block2 = "Beanbean Outskirts S Room 2 Block 2"
|
||||||
|
BeanbeanOutskirtsSRoom2Digspot3 = "Beanbean Outskirts S Room 2 Digspot 3"
|
||||||
|
BeanbeanOutskirtsNEDigspot1 = "Beanbean Outskirts NE Digspot 1"
|
||||||
|
BeanbeanOutskirtsNEDigspot2 = "Beanbean Outskirts NE Digspot 2"
|
||||||
|
BeanbeanOutskirtsEDigspot1 = "Beanbean Outskirts E Digspot 1"
|
||||||
|
BeanbeanOutskirtsEDigspot2 = "Beanbean Outskirts E Digspot 2"
|
||||||
|
BeanbeanOutskirtsEDigspot3 = "Beanbean Outskirts E Digspot 3"
|
||||||
|
BeanbeanOutskirtsSEDigspot1 = "Beanbean Outskirts SE Digspot 1"
|
||||||
|
BeanbeanOutskirtsSEDigspot2 = "Beanbean Outskirts SE Digspot 2"
|
||||||
|
BeanbeanOutskirtsSEDigspot3 = "Beanbean Outskirts SE Digspot 3"
|
||||||
|
BeanbeanOutskirtsNorthBeachDigspot1 = "Beanbean Outskirts North Beach Digspot 1"
|
||||||
|
BeanbeanOutskirtsNorthBeachDigspot2 = "Beanbean Outskirts North Beach Digspot 2"
|
||||||
|
BeanbeanOutskirtsNorthBeachDigspot3 = "Beanbean Outskirts North Beach Digspot 3"
|
||||||
|
BeanbeanOutskirtsSouthBeachDigspot = "Beanbean Outskirts South Beach Digspot"
|
||||||
|
BeanbeanOutskirtsSurfBeachDigspot1 = "Beanbean Outskirts Surf Beach Digspot 1"
|
||||||
|
BeanbeanOutskirtsSurfBeachBlock = "Beanbean Outskirts Surf Beach Block"
|
||||||
|
BeanbeanOutskirtsSurfBeachDigspot2 = "Beanbean Outskirts Surf Beach Digspot 2"
|
||||||
|
BeanbeanOutskirtsSurfBeachDigspot3 = "Beanbean Outskirts Surf Beach Digspot 3"
|
||||||
|
ChateauRoom1Digspot = "Chateau Room 1 Digspot"
|
||||||
|
ChateauPoppleFightRoomBlock1 = "Chateau Popple Fight Room Block 1"
|
||||||
|
ChateauPoppleFightRoomBlock2 = "Chateau Popple Fight Room Block 2"
|
||||||
|
ChateauPoppleFightRoomDigspot = "Chateau Popple Fight Room Digspot"
|
||||||
|
ChateauBarrelRoomDigspot = "Chateau Barrel Room Digspot"
|
||||||
|
ChateauGobletRoomDigspot = "Chateau Goblet Room Digspot"
|
||||||
|
ChucklehuckWoodsCaveRoom1Block1 = "Chucklehuck Woods Cave Room 1 Block 1"
|
||||||
|
ChucklehuckWoodsCaveRoom1Block2 = "Chucklehuck Woods Cave Room 1 Block 2"
|
||||||
|
ChucklehuckWoodsCaveRoom2Block = "Chucklehuck Woods Cave Room 2 Block"
|
||||||
|
ChucklehuckWoodsCaveRoom3Block = "Chucklehuck Woods Cave Room 3 Block"
|
||||||
|
ChucklehuckWoodsRoom2Block = "Chucklehuck Woods Room 2 Block"
|
||||||
|
ChucklehuckWoodsRoom2Digspot = "Chucklehuck Woods Room 2 Digspot"
|
||||||
|
ChucklehuckWoodsPipeRoomBlock1 = "Chucklehuck Woods Pipe Room Block 1"
|
||||||
|
ChucklehuckWoodsPipeRoomBlock2 = "Chucklehuck Woods Pipe Room Block 2"
|
||||||
|
ChucklehuckWoodsPipeRoomDigspot1 = "Chucklehuck Woods Pipe Room Digspot 1"
|
||||||
|
ChucklehuckWoodsPipeRoomDigspot2 = "Chucklehuck Woods Pipe Room Digspot 2"
|
||||||
|
ChucklehuckWoodsRoom4Block1 = "Chucklehuck Woods Room 4 Block 1"
|
||||||
|
ChucklehuckWoodsRoom4Block2 = "Chucklehuck Woods Room 4 Block 2"
|
||||||
|
ChucklehuckWoodsRoom4Block3 = "Chucklehuck Woods Room 4 Block 3"
|
||||||
|
ChucklehuckWoodsRoom7Block1 = "Chucklehuck Woods Room 7 Block 1"
|
||||||
|
ChucklehuckWoodsRoom7Block2 = "Chucklehuck Woods Room 7 Block 2"
|
||||||
|
ChucklehuckWoodsRoom7Digspot1 = "Chucklehuck Woods Room 7 Digspot 1"
|
||||||
|
ChucklehuckWoodsRoom7Digspot2 = "Chucklehuck Woods Room 7 Digspot 2"
|
||||||
|
ChucklehuckWoodsRoom8Digspot = "Chucklehuck Woods Room 8 Digspot"
|
||||||
|
ChucklehuckWoodsEastOfChucklerootDigspot = "Chucklehuck Woods East of Chuckleroot Digspot"
|
||||||
|
ChucklehuckWoodsNortheastOfChucklerootDigspot1 = "Chucklehuck Woods Northeast of Chuckleroot Digspot 1"
|
||||||
|
ChucklehuckWoodsNortheastOfChucklerootDigspot2 = "Chucklehuck Woods Northeast of Chuckleroot Digspot 2"
|
||||||
|
ChucklehuckWoodsNortheastOfChucklerootDigspot3 = "Chucklehuck Woods Northeast of Chuckleroot Digspot 3"
|
||||||
|
ChucklehuckWoodsNortheastOfChucklerootDigspot4 = "Chucklehuck Woods Northeast of Chuckleroot Digspot 4"
|
||||||
|
ChucklehuckWoodsWhiteFruitRoomDigspot1 = "Chucklehuck Woods White Fruit Room Digspot 1"
|
||||||
|
ChucklehuckWoodsWhiteFruitRoomDigspot2 = "Chucklehuck Woods White Fruit Room Digspot 2"
|
||||||
|
ChucklehuckWoodsWhiteFruitRoomDigspot3 = "Chucklehuck Woods White Fruit Room Digspot 3"
|
||||||
|
ChucklehuckWoodsWestOfChucklerootBlock = "Chucklehuck Woods West of Chuckleroot Block"
|
||||||
|
ChucklehuckWoodsSouthwestOfChucklerootBlock = "Chucklehuck Woods Southwest of Chuckleroot Block"
|
||||||
|
ChucklehuckWoodsWigglerRoomDigspot1 = "Chucklehuck Woods Wiggler Room Digspot 1"
|
||||||
|
ChucklehuckWoodsWigglerRoomDigspot2 = "Chucklehuck Woods Wiggler Room Digspot 2"
|
||||||
|
ChucklehuckWoodsAfterChucklerootBlock1 = "Chucklehuck Woods After Chuckleroot Block 1"
|
||||||
|
ChucklehuckWoodsAfterChucklerootBlock2 = "Chucklehuck Woods After Chuckleroot Block 2"
|
||||||
|
ChucklehuckWoodsAfterChucklerootBlock3 = "Chucklehuck Woods After Chuckleroot Block 3"
|
||||||
|
ChucklehuckWoodsAfterChucklerootBlock4 = "Chucklehuck Woods After Chuckleroot Block 4"
|
||||||
|
ChucklehuckWoodsAfterChucklerootBlock5 = "Chucklehuck Woods After Chuckleroot Block 5"
|
||||||
|
ChucklehuckWoodsAfterChucklerootBlock6 = "Chucklehuck Woods After Chuckleroot Block 6"
|
||||||
|
WinkleAreaBeanstarRoomBlock = "Winkle Area Beanstar Room Block"
|
||||||
|
WinkleAreaDigspot = "Winkle Area Digspot"
|
||||||
|
WinkleAreaOutsideColosseumBlock = "Winkle Area Outside Colosseum Block"
|
||||||
|
ChucklehuckWoodsKoopaRoomBlock1 = "Chucklehuck Woods Koopa Room Block 1"
|
||||||
|
ChucklehuckWoodsKoopaRoomBlock2 = "Chucklehuck Woods Koopa Room Block 2"
|
||||||
|
ChucklehuckWoodsKoopaRoomDigspot = "Chucklehuck Woods Koopa Room Digspot"
|
||||||
|
ChucklehuckWoodsWinkleCaveBlock1 = "Chucklehuck Woods Winkle Cave Block 1"
|
||||||
|
ChucklehuckWoodsWinkleCaveBlock2 = "Chucklehuck Woods Winkle Cave Block 2"
|
||||||
|
OhoOasisWestDigspot = "Oho Oasis West Digspot"
|
||||||
|
OhoOasisFirePalaceBlock = "Oho Oasis Fire Palace Block"
|
||||||
|
SewersRoom3Block1 = "Sewers Room 3 Block 1"
|
||||||
|
SewersRoom3Block2 = "Sewers Room 3 Block 2"
|
||||||
|
SewersRoom3Block3 = "Sewers Room 3 Block 3"
|
||||||
|
SewersRoom5Block1 = "Sewers Room 5 Block 1"
|
||||||
|
SewersRoom5Block2 = "Sewers Room 5 Block 2"
|
||||||
|
SewersPrisonRoomBlock1 = "Sewers Prison Room Block 1"
|
||||||
|
SewersPrisonRoomBlock2 = "Sewers Prison Room Block 2"
|
||||||
|
SewersPrisonRoomBlock3 = "Sewers Prison Room Block 3"
|
||||||
|
SewersPrisonRoomBlock4 = "Sewers Prison Room Block 4"
|
||||||
|
OhoOceanFirePuzzleRoomDigspot = "Oho Ocean Fire Puzzle Room Digspot"
|
||||||
|
OhoOceanSouthRoom1Block = "Oho Ocean South Room 1 Block"
|
||||||
|
OhoOceanSouthRoom2Digspot = "Oho Ocean South Room 2 Digspot"
|
||||||
|
OhoOceanSpikeRoomDigspot1 = "Oho Ocean Spike Room Digspot 1"
|
||||||
|
OhoOceanSpikeRoomDigspot2 = "Oho Ocean Spike Room Digspot 2"
|
||||||
|
OceanNorthWhirlpoolBlock1 = "Oho Ocean North Whirlpool Block 1"
|
||||||
|
OceanNorthWhirlpoolBlock2 = "Oho Ocean North Whirlpool Block 2"
|
||||||
|
OceanNorthWhirlpoolBlock3 = "Oho Ocean North Whirlpool Block 3"
|
||||||
|
OceanNorthWhirlpoolBlock4 = "Oho Ocean North Whirlpool Block 4"
|
||||||
|
OceanNorthWhirlpoolDigspot1 = "Oho Ocean North Whirlpool Digspot 1"
|
||||||
|
OceanNorthWhirlpoolDigspot2 = "Oho Ocean North Whirlpool Digspot 2"
|
||||||
|
OceanSouthWhirlpoolDigspot1 = "Oho Ocean South Whirlpool Digspot 1"
|
||||||
|
OceanSouthWhirlpoolDigspot2 = "Oho Ocean South Whirlpool Digspot 2"
|
||||||
|
OceanSouthWhirlpoolDigspot3 = "Oho Ocean South Whirlpool Digspot 3"
|
||||||
|
OceanSouthWhirlpoolDigspot4 = "Oho Ocean South Whirlpool Digspot 4"
|
||||||
|
OceanSouthWhirlpoolDigspot5 = "Oho Ocean South Whirlpool Digspot 5"
|
||||||
|
OceanSouthWhirlpoolDigspot6 = "Oho Ocean South Whirlpool Digspot 6"
|
||||||
|
OceanSouthWhirlpoolRoom2Digspot = "Oho Ocean South Whirlpool Room 2 Digspot"
|
||||||
|
WoohooHooniversityStarRoomBlock1 = "Woohoo Hooniversity Star Room Block 1"
|
||||||
|
WoohooHooniversityStarRoomBlock2 = "Woohoo Hooniversity Star Room Block 2"
|
||||||
|
WoohooHooniversityStarRoomBlock3 = "Woohoo Hooniversity Star Room Block 3"
|
||||||
|
WoohooHooniversitySunDoorBlock1 = "Woohoo Hooniversity Sun Door Block 1"
|
||||||
|
WoohooHooniversitySunDoorBlock2 = "Woohoo Hooniversity Sun Door Block 2"
|
||||||
|
WoohooHooniversitySouthOfStarRoomBlock = "Woohoo Hooniversity South Of Star Room Block"
|
||||||
|
WoohooHooniversityWestOfStarRoomDigspot1 = "Woohoo Hooniversity West Of Star Room Digspot 1"
|
||||||
|
WoohooHooniversityWestOfStarRoomDigspot2 = "Woohoo Hooniversity West Of Star Room Digspot 2"
|
||||||
|
WoohooHooniversityBarrelPuzzleEntranceDigspot1 = "Woohoo Hooniversity Barrel Puzzle Entrance Digspot 1"
|
||||||
|
WoohooHooniversityBarrelPuzzleEntranceBlock1 = "Woohoo Hooniversity Barrel Puzzle Entrance Block 1"
|
||||||
|
WoohooHooniversityBarrelPuzzleEntranceBlock2 = "Woohoo Hooniversity Barrel Puzzle Entrance Block 2"
|
||||||
|
WoohooHooniversityBarrelPuzzleEntranceBlock3 = "Woohoo Hooniversity Barrel Puzzle Entrance Block 3"
|
||||||
|
WoohooHooniversityBarrelPuzzleEntranceBlock4 = "Woohoo Hooniversity Barrel Puzzle Entrance Block 4"
|
||||||
|
WoohooHooniversityBarrelPuzzleEntranceDigspot2 = "Woohoo Hooniversity Barrel Puzzle Entrance Digspot 2"
|
||||||
|
ChucklehuckWoodsRoom1Digspot = "Chucklehuck Woods Room 1 Digspot"
|
||||||
|
WoohooHooniversityWestOfStarRoom2Digspot = "Woohoo Hooniversity West of Star Room 2 Digspot"
|
||||||
|
WoohooHooniversityWestOfStarRoom3Digspot = "Woohoo Hooniversity West of Star Room 3 Digspot"
|
||||||
|
WoohooHooniversityWestOfStarRoom4Block1 = "Woohoo Hooniversity West of Star Room 4 Block 1"
|
||||||
|
WoohooHooniversityWestOfStarRoom4Block2 = "Woohoo Hooniversity West of Star Room 4 Block 2"
|
||||||
|
WoohooHooniversityWestOfStarRoom4Block3 = "Woohoo Hooniversity West of Star Room 4 Block 3"
|
||||||
|
WoohooHooniversityWestOfStarRoom4Digspot1 = "Woohoo Hooniversity West of Star Room 4 Digspot 1"
|
||||||
|
WoohooHooniversityWestOfStarRoom4Digspot2 = "Woohoo Hooniversity West of Star Room 4 Digspot 2"
|
||||||
|
WoohooHooniversityWestOfStarRoom5Digspot = "Woohoo Hooniversity West of Star Room 5 Digspot"
|
||||||
|
WoohooHooniversityEntranceToMiniMarioRoomDigspot1 = "Woohoo Hooniversity Entrance to Mini Mario Room Digspot 1"
|
||||||
|
WoohooHooniversityEntranceToMiniMarioRoomDigspot2 = "Woohoo Hooniversity Entrance to Mini Mario Room Digspot 2"
|
||||||
|
WoohooHooniversityEntranceToMiniMarioRoom2Digspot = "Woohoo Hooniversity Entrance to Mini Mario Room 2 Digspot"
|
||||||
|
WoohooHooniversityMiniMarioPuzzleBlock = "Woohoo Hooniversity Mini Mario Puzzle Block"
|
||||||
|
WoohooHooniversityMiniMarioPuzzleDigspot = "Woohoo Hooniversity Mini Mario Puzzle Digspot"
|
||||||
|
WoohooHooniversityMiniMarioPuzzleSecretAreaBlock1 = "Woohoo Hooniversity Mini Mario Puzzle Secret Area Block 1"
|
||||||
|
WoohooHooniversityMiniMarioPuzzleSecretAreaBlock2 = "Woohoo Hooniversity Mini Mario Puzzle Secret Area Block 2"
|
||||||
|
WoohooHooniversityMiniMarioPuzzleSecretAreaBlock3 = "Woohoo Hooniversity Mini Mario Puzzle Secret Area Block 3"
|
||||||
|
WoohooHooniversityMiniMarioPuzzleSecretAreaBlock4 = "Woohoo Hooniversity Mini Mario Puzzle Secret Area Block 4"
|
||||||
|
WoohooHooniversityPastSunDoorBlock1 = "Woohoo Hooniversity Past Sun Door Block 1"
|
||||||
|
WoohooHooniversityPastSunDoorBlock2 = "Woohoo Hooniversity Past Sun Door Block 2"
|
||||||
|
WoohooHooniversityPastSunDoorBlock3 = "Woohoo Hooniversity Past Sun Door Block 3"
|
||||||
|
WoohooHooniversityPastCacklettaRoom1Block = "Woohoo Hooniversity Past Cackletta Room 1 Block"
|
||||||
|
WoohooHooniversityPastCacklettaRoom2Block1 = "Woohoo Hooniversity Past Cackletta Room 2 Block 1"
|
||||||
|
WoohooHooniversityPastCacklettaRoom2Block2 = "Woohoo Hooniversity Past Cackletta Room 2 Block 2"
|
||||||
|
WoohooHooniversityPastCacklettaRoom2Digspot = "Woohoo Hooniversity Past Cackletta Room 2 Digspot"
|
||||||
|
AirportEntranceDigspot = "Airport Entrance Digspot"
|
||||||
|
AirportLobbyDigspot = "Airport Lobby Digspot"
|
||||||
|
AirportLeftsideDigspot1 = "Airport Leftside Digspot 1"
|
||||||
|
AirportLeftsideDigspot2 = "Airport Leftside Digspot 2"
|
||||||
|
AirportLeftsideDigspot3 = "Airport Leftside Digspot 3"
|
||||||
|
AirportLeftsideDigspot4 = "Airport Leftside Digspot 4"
|
||||||
|
AirportLeftsideDigspot5 = "Airport Leftside Digspot 5"
|
||||||
|
AirportCenterDigspot1 = "Airport Center Digspot 1"
|
||||||
|
AirportCenterDigspot2 = "Airport Center Digspot 2"
|
||||||
|
AirportCenterDigspot3 = "Airport Center Digspot 3"
|
||||||
|
AirportCenterDigspot4 = "Airport Center Digspot 4"
|
||||||
|
AirportCenterDigspot5 = "Airport Center Digspot 5"
|
||||||
|
AirportRightsideDigspot1 = "Airport Rightside Digspot 1"
|
||||||
|
AirportRightsideDigspot2 = "Airport Rightside Digspot 2"
|
||||||
|
AirportRightsideDigspot3 = "Airport Rightside Digspot 3"
|
||||||
|
AirportRightsideDigspot4 = "Airport Rightside Digspot 4"
|
||||||
|
AirportRightsideDigspot5 = "Airport Rightside Digspot 5"
|
||||||
|
GwarharLagoonPipeRoomDigspot = "Gwarhar Lagoon Pipe Room Digspot"
|
||||||
|
GwarharLagoonMassageParlorEntranceDigspot = "Gwarhar Lagoon Massage Parlor Entrance Digspot"
|
||||||
|
GwarharLagoonPastHermieDigspot = "Gwarhar Lagoon Past Hermie Digspot"
|
||||||
|
GwarharLagoonEntranceToWestUnderwaterAreaDigspot = "Gwarhar Lagoon Entrance to West Underwater Area Digspot"
|
||||||
|
GwarharLagoonFireDashPuzzleRoom1Digspot1 = "Gwarhar Lagoon Fire Dash Puzzle Room 1 Digspot 1"
|
||||||
|
GwarharLagoonFireDashPuzzleRoom1Digspot2 = "Gwarhar Lagoon Fire Dash Puzzle Room 1 Digspot 2"
|
||||||
|
GwarharLagoonFireDashPuzzleRoom2Digspot = "Gwarhar Lagoon Fire Dash Puzzle Room 2 Digspot"
|
||||||
|
GwarharLagoonFireDashPuzzleRoom3Digspot1 = "Gwarhar Lagoon Fire Dash Puzzle Room 3 Digspot 1"
|
||||||
|
GwarharLagoonFireDashPuzzleRoom3Digspot2 = "Gwarhar Lagoon Fire Dash Puzzle Room 3 Digspot 2"
|
||||||
|
GwarharLagoonEastOfStoneBridgeBlock = "Gwarhar Lagoon East of Stone Bridge Block"
|
||||||
|
GwarharLagoonNorthOfSpangleRoomDigspot = "Gwarhar Lagoon North of Spangle Room Digspot"
|
||||||
|
GwarharLagoonWestOfSpangleRoomDigspot = "Gwarhar Lagoon West of Spangle Room Digspot"
|
||||||
|
GwarharLagoonSpangleRoomBlock = "Gwarhar Lagoon Spangle Room Block"
|
||||||
|
GwarharLagoonFirstUnderwaterAreaRoom1Block = "Gwarhar Lagoon First Underwater Area Room 1 Block"
|
||||||
|
GwarharLagoonFirstUnderwaterAreaRoom2Block1 = "Gwarhar Lagoon First Underwater Area Room 2 Block 1"
|
||||||
|
GwarharLagoonFirstUnderwaterAreaRoom2Block2 = "Gwarhar Lagoon First Underwater Area Room 2 Block 2"
|
||||||
|
GwarharLagoonSecondUnderwaterAreaRoom4Digspot = "Gwarhar Lagoon Second Underwater Area Room 4 Digspot"
|
||||||
|
GwarharLagoonSecondUnderwaterAreaRoom2Digspot1 = "Gwarhar Lagoon Second Underwater Area Room 2 Digspot 1"
|
||||||
|
GwarharLagoonSecondUnderwaterAreaRoom2Digspot2 = "Gwarhar Lagoon Second Underwater Area Room 2 Digspot 2"
|
||||||
|
GwarharLagoonSecondUnderwaterAreaRoom3Block1 = "Gwarhar Lagoon Second Underwater Area Room 3 Block 1"
|
||||||
|
GwarharLagoonSecondUnderwaterAreaRoom3Block2 = "Gwarhar Lagoon Second Underwater Area Room 3 Block 2"
|
||||||
|
GwarharLagoonSecondUnderwaterAreaRoom3Block3 = "Gwarhar Lagoon Second Underwater Area Room 3 Block 3"
|
||||||
|
GwarharLagoonSecondUnderwaterAreaRoom1Digspot = "Gwarhar Lagoon Second Underwater Area Room 1 Digspot"
|
||||||
|
WoohooHooniversityBasementRoom1Digspot = "Woohoo Hooniversity Basement Room 1 Digspot"
|
||||||
|
WoohooHooniversityBasementRoom2Digspot = "Woohoo Hooniversity Basement Room 2 Digspot"
|
||||||
|
WoohooHooniversityBasementRoom3Block = "Woohoo Hooniversity Basement Room 3 Block"
|
||||||
|
WoohooHooniversityBasementRoom4Block = "Woohoo Hooniversity Basement Room 4 Block"
|
||||||
|
WoohooHooniversityPoppleRoomDigspot1 = "Woohoo Hooniversity Popple Room Digspot 1"
|
||||||
|
WoohooHooniversityPoppleRoomDigspot2 = "Woohoo Hooniversity Popple Room Digspot 2"
|
||||||
|
TeeheeValleyBeforePoppleDigspot1 = "Teehee Valley Before Popple Digspot 1"
|
||||||
|
TeeheeValleyBeforePoppleDigspot2 = "Teehee Valley Before Popple Digspot 2"
|
||||||
|
TeeheeValleyBeforePoppleDigspot3 = "Teehee Valley Before Popple Digspot 3"
|
||||||
|
TeeheeValleyBeforePoppleDigspot4 = "Teehee Valley Before Popple Digspot 4"
|
||||||
|
TeeheeValleyRoom1Digspot1 = "Teehee Valley Room 1 Digspot 1"
|
||||||
|
TeeheeValleyRoom1Digspot2 = "Teehee Valley Room 1 Digspot 2"
|
||||||
|
TeeheeValleyRoom1Digspot3 = "Teehee Valley Room 1 Digspot 3"
|
||||||
|
TeeheeValleyEastRoomDigspot1 = "Teehee Valley East Room Digspot 1"
|
||||||
|
TeeheeValleyEastRoomDigspot2 = "Teehee Valley East Room Digspot 2"
|
||||||
|
TeeheeValleyEastRoomDigspot3 = "Teehee Valley East Room Digspot 3"
|
||||||
|
TeeheeValleySoloMarioRoomDigspot1 = "Teehee Valley Solo Mario Room Digspot 1"
|
||||||
|
TeeheeValleySoloMarioRoomDigspot2 = "Teehee Valley Solo Mario Room Digspot 2"
|
||||||
|
TeeheeValleySoloMarioRoomDigspot3 = "Teehee Valley Solo Mario Room Digspot 3"
|
||||||
|
TeeheeValleySoloMarioRoomDigspot4 = "Teehee Valley Solo Mario Room Digspot 4"
|
||||||
|
TeeheeValleyPastUltraHammersBlock1 = "Teehee Valley Past Ultra Hammer Rock Block 1"
|
||||||
|
TeeheeValleyPastUltraHammersBlock2 = "Teehee Valley Past Ultra Hammer Rock Block 2"
|
||||||
|
TeeheeValleyPastUltraHammersDigspot1 = "Teehee Valley Past Ultra Hammer Rock Digspot 1"
|
||||||
|
TeeheeValleyPastUltraHammersDigspot2 = "Teehee Valley Past Ultra Hammer Rock Digspot 2 (Post-Birdo)"
|
||||||
|
TeeheeValleyPastUltraHammersDigspot3 = "Teehee Valley Past Ultra Hammer Rock Digspot 3"
|
||||||
|
TeeheeValleyEntranceToHoohooMountainDigspot = "Teehee Valley Entrance To Hoohoo Mountain Digspot"
|
||||||
|
TeeheeValleySoloLuigiMazeRoom2Digspot1 = "Teehee Valley Solo Luigi Maze Room 2 Digspot 1"
|
||||||
|
TeeheeValleySoloLuigiMazeRoom2Digspot2 = "Teehee Valley Solo Luigi Maze Room 2 Digspot 2"
|
||||||
|
TeeheeValleySoloLuigiMazeRoom1Block = "Teehee Valley Solo Luigi Maze Room 1 Block"
|
||||||
|
TeeheeValleyBeforeTrunkleDigspot = "Teehee Valley Before Trunkle Digspot"
|
||||||
|
TeeheeValleyTrunkleRoomDigspot = "Teehee Valley Trunkle Room Digspot"
|
||||||
|
SSChuckolaStorageRoomBlock1 = "S.S. Chuckola Storage Room Block 1"
|
||||||
|
SSChuckolaStorageRoomBlock2 = "S.S. Chuckola Storage Room Block 2"
|
||||||
|
LittleFungitownEmbassyRoomBlock = "Little Fungitown Embassy Room Block"
|
||||||
|
LittleFungitownEntranceRoomBlock = "Little Fungitown Entrance Room Block"
|
||||||
|
JokesEndPipeDigspot = "Joke's End Pipe Digspot"
|
||||||
|
JokesEndStaircaseDigspot = "Joke's End Staircase Digspot"
|
||||||
|
JokesEndWestOfFirstBoilerRoomBlock1 = "Joke's End West Of First Boiler Room Block 1"
|
||||||
|
JokesEndWestOfFirstBoilerRoomBlock2 = "Joke's End West Of First Boiler Room Block 2"
|
||||||
|
JokesEndFirstBoilerRoomDigspot1 = "Joke's End First Boiler Room Digspot 1"
|
||||||
|
JokesEndFirstBoilerRoomDigspot2 = "Joke's End First Boiler Room Digspot 2"
|
||||||
|
JokesEndFurnaceRoom1Block1 = "Joke's End Furnace Room 1 Block 1"
|
||||||
|
JokesEndFurnaceRoom1Block2 = "Joke's End Furnace Room 1 Block 2"
|
||||||
|
JokesEndFurnaceRoom1Block3 = "Joke's End Furnace Room 1 Block 3"
|
||||||
|
JokesEndNortheastOfBoilerRoom1Block = "Joke's End Northeast Of Boiler Room 1 Block"
|
||||||
|
JokesEndNortheastOfBoilerRoom3Digspot = "Joke's End Northeast Of Boiler Room 3 Digspot"
|
||||||
|
JokesEndNortheastOfBoilerRoom2Block1 = "Joke's End Northeast Of Boiler Room 2 Block"
|
||||||
|
JokesEndNortheastOfBoilerRoom2Block2 = "Joke's End Northeast Of Boiler Room 2 Digspot"
|
||||||
|
JokesEndSecondFloorWestRoomBlock1 = "Joke's End Second Floor West Room Block 1"
|
||||||
|
JokesEndSecondFloorWestRoomBlock2 = "Joke's End Second Floor West Room Block 2"
|
||||||
|
JokesEndSecondFloorWestRoomBlock3 = "Joke's End Second Floor West Room Block 3"
|
||||||
|
JokesEndSecondFloorWestRoomBlock4 = "Joke's End Second Floor West Room Block 4"
|
||||||
|
JokesEndSecondFloorEastRoomDigspot = "Joke's End Second Floor East Room Digspot"
|
||||||
|
JokesEndFinalSplitUpRoomDigspot = "Joke's End Final Split Up Room Digspot"
|
||||||
|
JokesEndSouthOfBridgeRoomBlock = "Joke's End South Of Bridge Room Block"
|
||||||
|
JokesEndSoloLuigiRoom1Block = "Joke's End Solo Luigi Room 1 Block"
|
||||||
|
JokesEndSoloLuigiRoom1Digspot = "Joke's End Solo Luigi Room 1 Digspot"
|
||||||
|
JokesEndSoloMarioFinalRoomBlock1 = "Joke's End Solo Mario Final Room Block 1"
|
||||||
|
JokesEndSoloMarioFinalRoomBlock2 = "Joke's End Solo Mario Final Room Block 2"
|
||||||
|
JokesEndSoloMarioFinalRoomBlock3 = "Joke's End Solo Mario Final Room Block 3"
|
||||||
|
JokesEndSoloLuigiRoom2Digspot = "Joke's End Solo Luigi Room 2 Digspot"
|
||||||
|
JokesEndSoloMarioRoom1Digspot = "Joke's End Solo Mario Room 1 Digspot"
|
||||||
|
JokesEndSoloMarioRoom2Block1 = "Joke's End Solo Mario Room 2 Block 1"
|
||||||
|
JokesEndSoloMarioRoom2Block2 = "Joke's End Solo Mario Room 2 Block 2"
|
||||||
|
JokesEndSoloMarioRoom2Block3 = "Joke's End Solo Mario Room 2 Block 3"
|
||||||
|
JokesEndSecondBoilerRoomDigspot1 = "Joke's End Second Boiler Room Digspot 1"
|
||||||
|
JokesEndSecondBoilerRoomDigspot2 = "Joke's End Second Boiler Room Digspot 2"
|
||||||
|
JokesEndNorthOfSecondBoilerRoomBlock1 = "Joke's End North Of Second Boiler Room Block 1"
|
||||||
|
JokesEndNorthOfSecondBoilerRoomBlock2 = "Joke's End North Of Second Boiler Room Block 2"
|
||||||
|
WinkleAreaColloseumDigspot = "Winkle Area Colloseum Digspot"
|
||||||
|
HoohooMountainFountainRoom2Block = "Hoohoo Mountain Fountain Room 2 Block"
|
||||||
|
HoohooMountainFountainRoom2Digspot = "Hoohoo Mountain Fountain Room 2 Digspot"
|
||||||
|
HoohooMountainPastHoohoorosConnectorRoomDigspot1 = "Hoohoo Mountain Past Hoohooros Connector Room Digspot 1"
|
||||||
|
HoohooMountainPastHoohoorosConnectorRoomBlock = "Hoohoo Mountain Past Hoohooros Connector Room Block"
|
||||||
|
HoohooMountainPastHoohoorosConnectorRoomDigspot2 = "Hoohoo Mountain Past Hoohooros Connector Room Digspot 2"
|
||||||
|
JokesEndBeforeJojoraRoomBlock1 = "Joke's End Before Jojora Room Block 1"
|
||||||
|
JokesEndBeforeJojoraRoomBlock2 = "Joke's End Before Jojora Room Block 2"
|
||||||
|
JokesEndBeforeJojoraRoomDigspot = "Joke's End Before Jojora Room Digspot"
|
||||||
|
JokesEndJojoraRoomDigspot = "Joke's End Jojora Room Digspot"
|
||||||
|
BeanbeanOutskirtsBeforeHarhallDigspot1 = "Beanbean Outskirts Before Harhall Digspot 1"
|
||||||
|
BeanbeanOutskirtsBeforeHarhallDigspot2 = "Beanbean Outskirts Before Harhall Digspot 2"
|
||||||
|
BeanbeanOutskirtsBroochGuardsRoomDigspot1 = "Beanbean Outskirts Brooch Guards Room Digspot 1"
|
||||||
|
BeanbeanOutskirtsBroochGuardsRoomDigspot2 = "Beanbean Outskirts Brooch Guards Room Digspot 2"
|
||||||
|
BeanbeanOutskirtsChateauEntranceDigspot1 = "Beanbean Outskirts Chateau Entrance Digspot 1"
|
||||||
|
BeanbeanOutskirtsChateauEntranceDigspot2 = "Beanbean Outskirts Chateau Entrance Digspot 2"
|
||||||
|
BeanbeanOutskirtsSouthOfHooniversityGuardsDigspot1 = "Beanbean Outskirts South of Hooniversity Guards Digspot 1"
|
||||||
|
BeanbeanOutskirtsSouthOfHooniversityGuardsDigspot2 = "Beanbean Outskirts South of Hooniversity Guards Digspot 2"
|
||||||
|
BeanbeanOutskirtsSouthOfHooniversityGuardsDigspot3 = "Beanbean Outskirts South of Hooniversity Guards Digspot 3"
|
||||||
|
OutsideWoohooHooniversityBlock = "Outside Woohoo Hooniversity Block"
|
||||||
|
BeanbeanOutskirtsEntranceToHoohooMountainBaseDigspot1 = (
|
||||||
|
"Beanbean Outskirts Entrance to Hoohoo Mountain Base Digspot 1"
|
||||||
|
)
|
||||||
|
BeanbeanOutskirtsEntranceToHoohooMountainBaseDigspot2 = (
|
||||||
|
"Beanbean Outskirts Entrance to Hoohoo Mountain Base Digspot 2"
|
||||||
|
)
|
||||||
|
WoohooHooniversitySoloMarioBarrelAreaBlock1 = "Woohoo Hooniversity Solo Mario Barrel Area Block 1"
|
||||||
|
WoohooHooniversitySoloMarioBarrelAreaBlock2 = "Woohoo Hooniversity Solo Mario Barrel Area Block 2"
|
||||||
|
WoohooHooniversitySoloMarioBarrelAreaBlock3 = "Woohoo Hooniversity Solo Mario Barrel Area Block 3"
|
||||||
|
BeanbeanOutskirtsPipe2RoomDigspot = "Beanbean Outskirts Pipe 2 Room Digspot"
|
||||||
|
BeanbeanOutskirtsPipe4RoomDigspot = "Beanbean Outskirts Pipe 4 Room Digspot"
|
||||||
|
BeanbeanCastleTownBeanletReward = "Beanbean Castle Town Beanlet Reward"
|
||||||
|
HoohooVillageMoleBehindTurtle = "Hoohoo Village Mole Behind Turtle"
|
||||||
|
HoohooMountainBaseMoleNearTeeheeValley = "Hoohoo Mountain Base Mole Near Teehee Valley"
|
||||||
|
BeanbeanOutskirtsSoloLuigiCaveMole = "Beanbean Outskirts Solo Luigi Cave Mole"
|
||||||
|
BeanbeanOutskirtsFarmRoomMoleReward1 = "Beanbean Outskirts Farm Room Mole Reward 1"
|
||||||
|
BeanbeanOutskirtsFarmRoomMoleReward2 = "Beanbean Outskirts Farm Room Mole Reward 2"
|
||||||
|
JokesEndMoleReward1 = "Joke's End Mole Reward 1"
|
||||||
|
JokesEndMoleReward2 = "Joke's End Mole Reward 2"
|
||||||
|
NorthOceanWhirlpoolMole = "North Ocean Whirlpool Mole"
|
||||||
|
BeanbeanOutskirtsNESoloMarioMole1 = "Beanbean Outskirts NE Solo Mario Mole 1"
|
||||||
|
HoohooVillageHammers = "Hoohoo Village Hammers"
|
||||||
|
BeanbeanOutskirtsSuperHammerUpgrade = "Beanbean Outskirts Super Hammer Upgrade"
|
||||||
|
BeanbeanOutskirtsUltraHammerUpgrade = "Beanbean Outskirts Ultra Hammer Upgrade"
|
||||||
|
OhoOasisFirebrand = "Oho Oasis Firebrand"
|
||||||
|
OhoOasisThunderhand = "Oho Oasis Thunderhand"
|
||||||
|
ChucklehuckWoodsRedChuckolaFruit = "Chucklehuck Woods Red Chuckola Fruit"
|
||||||
|
ChucklehuckWoodsWhiteChuckolaFruit = "Chucklehuck Woods White Chuckola Fruit"
|
||||||
|
ChucklehuckWoodsPurpleChuckolaFruit = "Chucklehuck Woods Purple Chuckola Fruit"
|
||||||
|
SSChuckolaMembershipCard = "S.S. Chuckola Membership Card"
|
||||||
|
WinkleAreaWinkleCard = "Winkle Area Winkle Card"
|
||||||
|
BeanbeanCastlePeachsExtraDress = "Beanbean Castle Peach's Extra Dress"
|
||||||
|
BeanbeanCastleFakeBeastar = "Beanbean Castle Fake Beanstar"
|
||||||
|
BeanbeanCastleTownBeanlet1 = "Beanbean Castle Town Beanlet 1"
|
||||||
|
BeanbeanCastleTownBeanlet2 = "Beanbean Castle Town Beanlet 2"
|
||||||
|
BeanbeanCastleTownBeanlet3 = "Beanbean Castle Town Beanlet 3"
|
||||||
|
BeanbeanCastleTownBeanlet4 = "Beanbean Castle Town Beanlet 4"
|
||||||
|
BeanbeanCastleTownBeanlet5 = "Beanbean Castle Town Beanlet 5"
|
||||||
|
BeanbeanCastleTownBeanstone1 = "Beanbean Castle Town Beanstone 1"
|
||||||
|
BeanbeanCastleTownBeanstone2 = "Beanbean Castle Town Beanstone 2"
|
||||||
|
BeanbeanCastleTownBeanstone3 = "Beanbean Castle Town Beanstone 3"
|
||||||
|
BeanbeanCastleTownBeanstone4 = "Beanbean Castle Town Beanstone 4"
|
||||||
|
BeanbeanCastleTownBeanstone5 = "Beanbean Castle Town Beanstone 5"
|
||||||
|
BeanbeanCastleTownBeanstone6 = "Beanbean Castle Town Beanstone 6"
|
||||||
|
BeanbeanCastleTownBeanstone7 = "Beanbean Castle Town Beanstone 7"
|
||||||
|
BeanbeanCastleTownBeanstone8 = "Beanbean Castle Town Beanstone 8"
|
||||||
|
BeanbeanCastleTownBeanstone9 = "Beanbean Castle Town Beanstone 9"
|
||||||
|
BeanbeanCastleTownBeanstone10 = "Beanbean Castle Town Beanstone 10"
|
||||||
|
YoshiTheaterBlueYoshi = "Yoshi Theater Blue Yoshi"
|
||||||
|
YoshiTheaterRedYoshi = "Yoshi Theater Red Yoshi"
|
||||||
|
YoshiTheaterGreenYoshi = "Yoshi Theater Green Yoshi"
|
||||||
|
YoshiTheaterYellowYoshi = "Yoshi Theater Yellow Yoshi"
|
||||||
|
YoshiTheaterPurpleYoshi = "Yoshi Theater Purple Yoshi"
|
||||||
|
YoshiTheaterOrangeYoshi = "Yoshi Theater Orange Yoshi"
|
||||||
|
YoshiTheaterAzureYoshi = "Yoshi Theater Azure Yoshi"
|
||||||
|
BeanbeanCastleBeanbeanBrooch = "Beanbean Castle Beanbean Brooch"
|
||||||
|
BeanbeanOutskirtsSecretScroll1 = "Beanbean Outskirts Secret Scroll 1"
|
||||||
|
BeanbeanOutskirtsSecretScroll2 = "Beanbean Outskirts Secret Scroll 2"
|
||||||
|
BeanbeanOutskirtsBeanFruit1 = "Beanbean Outskirts Bean Fruit 1"
|
||||||
|
BeanbeanOutskirtsBeanFruit2 = "Beanbean Outskirts Bean Fruit 2"
|
||||||
|
BeanbeanOutskirtsBeanFruit3 = "Beanbean Outskirts Bean Fruit 3"
|
||||||
|
BeanbeanOutskirtsBeanFruit4 = "Beanbean Outskirts Bean Fruit 4"
|
||||||
|
BeanbeanOutskirtsBeanFruit5 = "Beanbean Outskirts Bean Fruit 5"
|
||||||
|
BeanbeanOutskirtsBeanFruit6 = "Beanbean Outskirts Bean Fruit 6"
|
||||||
|
BeanbeanOutskirtsBeanFruit7 = "Beanbean Outskirts Bean Fruit 7"
|
||||||
|
HoohooMountainPeasleysRose = "Hoohoo Mountain Peasley's Rose"
|
||||||
|
ChateauGreenGoblet = "Chateau Green Goblet"
|
||||||
|
ChateauRedGoblet = "Chateau Red Goblet"
|
||||||
|
GwarharLagoonRedPearlBean = "Gwarhar Lagoon Red Pearl Bean"
|
||||||
|
GwarharLagoonGreenPearlBean = "Gwarhar Lagoon Green Pearl Bean"
|
||||||
|
GwarharLagoonSpangle = "Gwarhar Lagoon Spangle"
|
||||||
|
BeanstarPieceWinkleArea = "Beanstar Piece Winkle Area"
|
||||||
|
BeanstarPieceHarhall = "Beanstar Piece Harhall"
|
||||||
|
BeanstarPieceYoshiTheater = "Beanstar Piece Yoshi Theater"
|
||||||
|
BeanstarPieceHermie = "Beanstar Piece Hermie"
|
||||||
|
ShopStartingFlag1 = "Shop Starting Flag 1"
|
||||||
|
ShopStartingFlag2 = "Shop Starting Flag 2"
|
||||||
|
ShopStartingFlag3 = "Shop Starting Flag 3"
|
||||||
|
ShopChuckolatorFlag = "Shop Chuckolator Flag"
|
||||||
|
ShopMomPiranhaFlag1 = "Shop Mom Piranha Flag 1"
|
||||||
|
ShopMomPiranhaFlag2 = "Shop Mom Piranha Flag 2"
|
||||||
|
ShopMomPiranhaFlag3 = "Shop Mom Piranha Flag 3"
|
||||||
|
ShopMomPiranhaFlag4 = "Shop Mom Piranha Flag 4"
|
||||||
|
ShopPeachKidnappedFlag1 = "Shop Enter Fungitown Flag 1"
|
||||||
|
ShopPeachKidnappedFlag2 = "Shop Enter Fungitown Flag 2"
|
||||||
|
FungitownShopStartingFlag1 = "Fungitown Shop Starting Flag 1"
|
||||||
|
FungitownShopStartingFlag2 = "Fungitown Shop Starting Flag 2"
|
||||||
|
FungitownShopStartingFlag3 = "Fungitown Shop Starting Flag 3"
|
||||||
|
FungitownShopStartingFlag4 = "Fungitown Shop Starting Flag 4"
|
||||||
|
FungitownShopStartingFlag5 = "Fungitown Shop Starting Flag 5"
|
||||||
|
FungitownShopStartingFlag6 = "Fungitown Shop Starting Flag 6"
|
||||||
|
FungitownShopStartingFlag7 = "Fungitown Shop Starting Flag 7"
|
||||||
|
FungitownShopStartingFlag8 = "Fungitown Shop Starting Flag 8"
|
||||||
|
ShopBeanstarCompleteFlag1 = "Shop Beanstar Complete Flag 1"
|
||||||
|
ShopBeanstarCompleteFlag2 = "Shop Beanstar Complete Flag 2"
|
||||||
|
ShopBeanstarCompleteFlag3 = "Shop Beanstar Complete Flag 3"
|
||||||
|
FungitownShopBeanstarCompleteFlag = "Fungitown Shop Beanstar Complete Flag"
|
||||||
|
ShopBirdoFlag = "Shop Birdo Flag"
|
||||||
|
FungitownShopBirdoFlag = "Fungitown Shop Birdo Flag"
|
||||||
|
CoffeeShopBrewReward1 = "Coffee Shop Brew Reward 1"
|
||||||
|
CoffeeShopBrewReward2 = "Coffee Shop Brew Reward 2"
|
||||||
|
CoffeeShopBrewReward3 = "Coffee Shop Brew Reward 3"
|
||||||
|
CoffeeShopBrewReward4 = "Coffee Shop Brew Reward 4"
|
||||||
|
CoffeeShopBrewReward5 = "Coffee Shop Brew Reward 5"
|
||||||
|
CoffeeShopBrewReward6 = "Coffee Shop Brew Reward 6"
|
||||||
|
CoffeeShopBrewReward7 = "Coffee Shop Brew Reward 7"
|
||||||
|
CoffeeShopWoohooBlend = "Coffee Shop Woohoo Blend"
|
||||||
|
CoffeeShopHoohooBlend = "Coffee Shop Hoohoo Blend"
|
||||||
|
CoffeeShopChuckleBlend = "Coffee Shop Chuckle Blend"
|
||||||
|
CoffeeShopTeeheeBlend = "Coffee Shop Teehee Blend"
|
||||||
|
CoffeeShopHoolumbian = "Coffee Shop Hoolumbian"
|
||||||
|
CoffeeShopChuckoccino = "Coffee Shop Chuckoccino"
|
||||||
|
CoffeeShopTeeheespresso = "Coffee Shop Teeheespresso"
|
||||||
|
PantsShopStartingFlag1 = "Pants Shop Starting Flag 1"
|
||||||
|
PantsShopStartingFlag2 = "Pants Shop Starting Flag 2"
|
||||||
|
PantsShopStartingFlag3 = "Pants Shop Starting Flag 3"
|
||||||
|
PantsShopChuckolatorFlag1 = "Pants Shop Chuckolator Flag 1"
|
||||||
|
PantsShopChuckolatorFlag2 = "Pants Shop Chuckolator Flag 2"
|
||||||
|
PantsShopChuckolatorFlag3 = "Pants Shop Chuckolator Flag 3"
|
||||||
|
PantsShopMomPiranhaFlag1 = "Pants Shop Mom Piranha Flag 1"
|
||||||
|
PantsShopMomPiranhaFlag2 = "Pants Shop Mom Piranha Flag 2"
|
||||||
|
PantsShopMomPiranhaFlag3 = "Pants Shop Mom Piranha Flag 3"
|
||||||
|
PantsShopPeachKidnappedFlag1 = "Pants Shop Enter Fungitown Flag 1"
|
||||||
|
PantsShopPeachKidnappedFlag2 = "Pants Shop Enter Fungitown Flag 2"
|
||||||
|
PantsShopPeachKidnappedFlag3 = "Pants Shop Enter Fungitown Flag 3"
|
||||||
|
PantsShopBeanstarCompleteFlag1 = "Pants Shop Beanstar Complete Flag 1"
|
||||||
|
PantsShopBeanstarCompleteFlag2 = "Pants Shop Beanstar Complete Flag 2"
|
||||||
|
PantsShopBeanstarCompleteFlag3 = "Pants Shop Beanstar Complete Flag 3"
|
||||||
|
PantsShopBirdoFlag1 = "Pants Shop Birdo Flag 1"
|
||||||
|
PantsShopBirdoFlag2 = "Pants Shop Birdo Flag 2"
|
||||||
|
PantsShopBirdoFlag3 = "Pants Shop Birdo Flag 3"
|
||||||
|
FungitownPantsShopStartingFlag1 = "Fungitown Pants Shop Starting Flag 1"
|
||||||
|
FungitownPantsShopStartingFlag2 = "Fungitown Pants Shop Starting Flag 2"
|
||||||
|
FungitownPantsShopStartingFlag3 = "Fungitown Pants Shop Starting Flag 3"
|
||||||
|
FungitownPantsShopBeanstarCompleteFlag1 = "Fungitown Pants Shop Beanstar Complete Flag 1"
|
||||||
|
FungitownPantsShopBeanstarCompleteFlag2 = "Fungitown Pants Shop Beanstar Complete Flag 2"
|
||||||
|
FungitownPantsShopBirdoFlag1 = "Fungitown Pants Shop Birdo Flag 1"
|
||||||
|
FungitownPantsShopBirdoFlag2 = "Fungitown Pants Shop Birdo Flag 2"
|
||||||
|
BeanbeanOutskirtsNESoloMarioMole2 = "Beanbean Outskirts NE Solo Mario Mole 2"
|
||||||
|
GwarharLagoonSpangleReward = "Gwarhar Lagoon Spangle Reward"
|
||||||
|
BowsersCastleEntranceBlock1 = "Bowser's Castle Entrance Block 1"
|
||||||
|
BowsersCastleEntranceBlock2 = "Bowser's Castle Entrance Block 2"
|
||||||
|
BowsersCastleEntranceDigspot = "Bowser's Castle Entrance Digspot"
|
||||||
|
BowsersCastleIggyMortonHallwayBlock1 = "Bowser's Castle Iggy & Morton Hallway Block 1"
|
||||||
|
BowsersCastleIggyMortonHallwayBlock2 = "Bowser's Castle Iggy & Morton Hallway Block 2"
|
||||||
|
BowsersCastleIggyMortonHallwayDigspot = "Bowser's Castle Iggy & Morton Hallway Digspot"
|
||||||
|
BowsersCastleAfterMortonBlock = "Bowser's Castle After Morton Block"
|
||||||
|
BowsersCastleLudwigRoyHallwayBlock1 = "Bowser's Castle Ludwig & Roy Hallway Block 1"
|
||||||
|
BowsersCastleLudwigRoyHallwayBlock2 = "Bowser's Castle Ludwig & Roy Hallway Block 2"
|
||||||
|
BowsersCastleRoyCorridorBlock1 = "Bowser's Castle Roy Corridor Block 1"
|
||||||
|
BowsersCastleRoyCorridorBlock2 = "Bowser's Castle Roy Corridor Block 2"
|
||||||
|
BowsersCastleWendyLarryHallwayDigspot = "Bowser's Castle Wendy & Larry Hallway Digspot"
|
||||||
|
BowsersCastleBeforeFawfulFightBlock1 = "Bowser's Castle Before Fawful Fight Block 1"
|
||||||
|
BowsersCastleBeforeFawfulFightBlock2 = "Bowser's Castle Before Fawful Fight Block 2"
|
||||||
|
BowsersCastleGreatDoorBlock1 = "Bowser's Castle Great Door Block 1"
|
||||||
|
BowsersCastleGreatDoorBlock2 = "Bowser's Castle Great Door Block 2"
|
||||||
|
BowsersCastleMortonRoom1Digspot = "Bowser's Castle Morton Room 1 Digspot"
|
||||||
|
BowsersCastleLemmyRoom1Block = "Bowser's Castle Lemmy Room 1 Block"
|
||||||
|
BowsersCastleLemmyRoom1Digspot = "Bowser's Castle Lemmy Room 1 Digspot"
|
||||||
|
BowsersCastleLudwigRoom1Block = "Bowser's Castle Ludwig Room 1 Block"
|
||||||
|
BowsersCastleMiniMarioSidescrollerBlock1 = "Bowser's Castle Mini Mario Sidescroller Block 1"
|
||||||
|
BowsersCastleMiniMarioSidescrollerBlock2 = "Bowser's Castle Mini Mario Sidescroller Block 2"
|
||||||
|
BowsersCastleMiniMarioMazeBlock1 = "Bowser's Castle Mini Mario Maze Block 1"
|
||||||
|
BowsersCastleMiniMarioMazeBlock2 = "Bowser's Castle Mini Mario Maze Block 2"
|
||||||
|
BowsersCastleBeforeWendyFightBlock1 = "Bowser's Castle Before Wendy Fight Block 1"
|
||||||
|
BowsersCastleBeforeWendyFightBlock2 = "Bowser's Castle Before Wendy Fight Block 2"
|
||||||
|
BowsersCastleLarryRoomBlock = "Bowser's Castle Larry Room Block"
|
||||||
|
BowsersCastleLemmyRoomMole = "Bowser's Castle Lemmy Room Mole"
|
||||||
|
SurfMinigame = "Surf Minigame"
|
||||||
|
BeanbeanOutskirtsThunderHandMole = "Beanbean Outskirts Thunderhand Mole"
|
||||||
|
BadgeShopMomPiranhaFlag1 = "Badge Shop Mom Piranha Flag 1"
|
||||||
|
BadgeShopMomPiranhaFlag2 = "Badge Shop Mom Piranha Flag 2"
|
||||||
|
BadgeShopMomPiranhaFlag3 = "Badge Shop Mom Piranha Flag 3"
|
||||||
|
HarhallsPants = "Harhall's Pants"
|
||||||
|
HoohooMountainBaseBooStatueCaveCoinBlock1 = "Hoohoo Mountain Base Boo Statue Cave Coin Block 1"
|
||||||
|
HoohooMountainBaseBooStatueCaveCoinBlock2 = "Hoohoo Mountain Base Boo Statue Cave Coin Block 2"
|
||||||
|
HoohooMountainBaseBooStatueCaveCoinBlock3 = "Hoohoo Mountain Base Boo Statue Cave Coin Block 3"
|
||||||
|
BeanbeanOutskirtsNWCoinBlock = "Beanbean Outskirts NW Coin Block"
|
||||||
|
BeanbeanOutskirtsSRoom1CoinBlock = "Beanbean Outskirts S Room 1 Coin Block"
|
||||||
|
BeanbeanOutskirtsSRoom2CoinBlock = "Beanbean Outskirts S Room 2 Coin Block"
|
||||||
|
ChateauPoppleRoomCoinBlock1 = "Chateau Popple Room Coin Block 1"
|
||||||
|
ChateauPoppleRoomCoinBlock2 = "Chateau Popple Room Coin Block 2"
|
||||||
|
ChucklehuckWoodsCaveRoom1CoinBlock = "Chucklehuck Woods Cave Room 1 Coin Block"
|
||||||
|
ChucklehuckWoodsCaveRoom2CoinBlock = "Chucklehuck Woods Cave Room 2 Coin Block"
|
||||||
|
ChucklehuckWoodsCaveRoom3CoinBlock = "Chucklehuck Woods Cave Room 3 Coin Block"
|
||||||
|
ChucklehuckWoodsPipe5RoomCoinBlock = "Chucklehuck Woods Pipe 5 Room Coin Block"
|
||||||
|
ChucklehuckWoodsRoom7CoinBlock = "Chucklehuck Woods Room 7 Coin Block"
|
||||||
|
ChucklehuckWoodsAfterChucklerootCoinBlock = "Chucklehuck Woods After Chuckleroot Coin Block"
|
||||||
|
ChucklehuckWoodsKoopaRoomCoinBlock = "Chucklehuck Woods Koopa Room Coin Block"
|
||||||
|
ChucklehuckWoodsWinkleAreaCaveCoinBlock = "Chucklehuck Woods Winkle Area Cave Coin Block"
|
||||||
|
SewersPrisonRoomCoinBlock = "Sewers Prison Room Coin Block"
|
||||||
|
TeeheeValleyPastUltraHammerRocksCoinBlock = "Teehee Valley Past Ultra Hammer Rocks Coin Block"
|
||||||
|
SSChuckolaStorageRoomCoinBlock1 = "S.S. Chuckola Storage Room Coin Block 1"
|
||||||
|
SSChuckolaStorageRoomCoinBlock2 = "S.S. Chuckola Storage Room Coin Block 2"
|
||||||
|
GwarharLagoonFirstUnderwaterAreaRoom2CoinBlock = "Gwarhar Lagoon First Underwater Area Room 2 Coin Block"
|
||||||
|
JokesEndSecondFloorWestRoomCoinBlock = "Joke's End Second Floor West Room Coin Block"
|
||||||
|
JokesEndNorthofBridgeRoomCoinBlock = "Joke's End North of Bridge Room Coin Block"
|
||||||
|
|
|
@ -0,0 +1,299 @@
|
||||||
|
from Options import Choice, Toggle, StartInventoryPool, PerGameCommonOptions, Range
|
||||||
|
from dataclasses import dataclass
|
||||||
|
|
||||||
|
|
||||||
|
class BowsersCastleSkip(Toggle):
|
||||||
|
"""
|
||||||
|
Skip straight from the entrance hall to Bowletta in Bowser's Castle.
|
||||||
|
All Bowser's Castle locations will be removed from the location pool.
|
||||||
|
"""
|
||||||
|
|
||||||
|
display_name = "Bowser's Castle Skip"
|
||||||
|
|
||||||
|
|
||||||
|
class ExtraPipes(Toggle):
|
||||||
|
"""
|
||||||
|
Gives the player access to pipes 1, 3, 4, and 6 from the start.
|
||||||
|
"""
|
||||||
|
|
||||||
|
display_name = "Start With Extra Pipes"
|
||||||
|
|
||||||
|
|
||||||
|
class SkipMinecart(Toggle):
|
||||||
|
"""
|
||||||
|
Skip the minecart minigame that leads you through Hoohoo Mountain Base.
|
||||||
|
This will remove the 1 location in the minecart cave from the location pool.
|
||||||
|
"""
|
||||||
|
|
||||||
|
display_name = "Skip Minecart Minigame"
|
||||||
|
|
||||||
|
|
||||||
|
class DisableSurf(Toggle):
|
||||||
|
"""
|
||||||
|
Remove the surf minigame location from the location pool.
|
||||||
|
"""
|
||||||
|
|
||||||
|
display_name = "Disable Surf Minigame"
|
||||||
|
|
||||||
|
|
||||||
|
class MusicOptions(Choice):
|
||||||
|
"""
|
||||||
|
Choose if you want to randomize or disable music.
|
||||||
|
default: Music will be untouched.
|
||||||
|
randomize: Music will be randomized.
|
||||||
|
disable: All music will be disabled. No music will play throughout the entire game.
|
||||||
|
"""
|
||||||
|
|
||||||
|
display_name = "Music Options"
|
||||||
|
option_default = 0
|
||||||
|
option_randomize = 1
|
||||||
|
option_disable = 2
|
||||||
|
default = 0
|
||||||
|
|
||||||
|
|
||||||
|
class RandomSounds(Toggle):
|
||||||
|
"""
|
||||||
|
Randomizes every sound in the game, minus a select few that can softlock the game.
|
||||||
|
"""
|
||||||
|
|
||||||
|
display_name = "Randomize Sounds"
|
||||||
|
|
||||||
|
|
||||||
|
class MarioColor(Choice):
|
||||||
|
"""
|
||||||
|
This changes the color of Mario's hat, as well as some key colors that are red including UI etc.
|
||||||
|
"""
|
||||||
|
|
||||||
|
display_name = "Mario's Color"
|
||||||
|
option_red = 0
|
||||||
|
option_green = 1
|
||||||
|
option_blue = 2
|
||||||
|
option_cyan = 3
|
||||||
|
option_yellow = 4
|
||||||
|
option_orange = 5
|
||||||
|
option_purple = 6
|
||||||
|
option_pink = 7
|
||||||
|
option_black = 8
|
||||||
|
option_white = 9
|
||||||
|
option_silhouette = 10
|
||||||
|
option_chaos = 11
|
||||||
|
option_true_chaos = 12
|
||||||
|
default = 0
|
||||||
|
|
||||||
|
|
||||||
|
class LuigiColor(Choice):
|
||||||
|
"""
|
||||||
|
This changes the color of Luigi's hat, as well as some key colors that are green including UI etc.
|
||||||
|
"""
|
||||||
|
|
||||||
|
display_name = "Luigi's Color"
|
||||||
|
option_red = 0
|
||||||
|
option_green = 1
|
||||||
|
option_blue = 2
|
||||||
|
option_cyan = 3
|
||||||
|
option_yellow = 4
|
||||||
|
option_orange = 5
|
||||||
|
option_purple = 6
|
||||||
|
option_pink = 7
|
||||||
|
option_black = 8
|
||||||
|
option_white = 9
|
||||||
|
option_silhouette = 10
|
||||||
|
option_chaos = 11
|
||||||
|
option_true_chaos = 12
|
||||||
|
default = 1
|
||||||
|
|
||||||
|
|
||||||
|
class MarioPants(Choice):
|
||||||
|
"""
|
||||||
|
This changes the color of Mario's trousers.
|
||||||
|
"""
|
||||||
|
|
||||||
|
display_name = "Mario's Pants Color"
|
||||||
|
option_vanilla = 0
|
||||||
|
option_red = 1
|
||||||
|
option_green = 2
|
||||||
|
option_blue = 3
|
||||||
|
option_cyan = 4
|
||||||
|
option_yellow = 5
|
||||||
|
option_orange = 6
|
||||||
|
option_purple = 7
|
||||||
|
option_pink = 8
|
||||||
|
option_black = 9
|
||||||
|
option_white = 10
|
||||||
|
option_chaos = 11
|
||||||
|
default = 0
|
||||||
|
|
||||||
|
|
||||||
|
class LuigiPants(Choice):
|
||||||
|
"""
|
||||||
|
This changes the color of Luigi's trousers.
|
||||||
|
"""
|
||||||
|
|
||||||
|
display_name = "Luigi's Pants Color"
|
||||||
|
option_vanilla = 0
|
||||||
|
option_red = 1
|
||||||
|
option_green = 2
|
||||||
|
option_blue = 3
|
||||||
|
option_cyan = 4
|
||||||
|
option_yellow = 5
|
||||||
|
option_orange = 6
|
||||||
|
option_purple = 7
|
||||||
|
option_pink = 8
|
||||||
|
option_black = 9
|
||||||
|
option_white = 10
|
||||||
|
option_chaos = 11
|
||||||
|
default = 0
|
||||||
|
|
||||||
|
|
||||||
|
class RandomizeEnemies(Choice):
|
||||||
|
"""
|
||||||
|
Randomize all normal enemy encounters in the game.
|
||||||
|
If Bowser's castle skip is enabled, then enemies from Bowser's Castle will not be included.
|
||||||
|
Disabled: Enemies will not be randomized.
|
||||||
|
Vanilla Groups: Vanilla enemy groups will be shuffled with each other. Custom enemy groups will not be made.
|
||||||
|
Custom Groups: Custom enemy groups will be made and shuffled. Some enemy groups will only be semi-random,
|
||||||
|
including groups with flying enemies or pestnuts in them.
|
||||||
|
"""
|
||||||
|
|
||||||
|
display_name = "Randomize Enemies"
|
||||||
|
option_disabled = 0
|
||||||
|
option_vanilla_groups = 1
|
||||||
|
option_custom_groups = 2
|
||||||
|
default = 0
|
||||||
|
|
||||||
|
|
||||||
|
class RandomizeBosses(Choice):
|
||||||
|
"""
|
||||||
|
Randomize all boss encounters in the game.
|
||||||
|
If Bowser's castle skip is enabled then bosses from Bowser's Castle will not be included.
|
||||||
|
Some bosses are not randomized due to flags, and story (such as the final boss).
|
||||||
|
Boss Only: Bosses will only be swapped with another boss.
|
||||||
|
Boss Normal: Bosses can be swapped with normal enemy encounters.
|
||||||
|
"""
|
||||||
|
|
||||||
|
display_name = "Randomize Bosses"
|
||||||
|
option_disabled = 0
|
||||||
|
option_boss_only = 1
|
||||||
|
option_boss_normal = 2
|
||||||
|
default = 0
|
||||||
|
|
||||||
|
|
||||||
|
class ScaleStats(Toggle):
|
||||||
|
"""
|
||||||
|
This scales enemy HP, POW, DEF, and XP to vanilla values.
|
||||||
|
This setting is intended for use with the Enemy Randomizer and is Recommended to turn on.
|
||||||
|
If you are not using the Enemy Randomizer the effects will be minimal.
|
||||||
|
"""
|
||||||
|
|
||||||
|
display_name = "Scale Enemy Stats"
|
||||||
|
|
||||||
|
|
||||||
|
class XPMultiplier(Range):
|
||||||
|
"""
|
||||||
|
This will multiply any XP you receive in battle by the chosen multiplier.
|
||||||
|
"""
|
||||||
|
|
||||||
|
display_name = "XP Multiplier"
|
||||||
|
range_start = 0
|
||||||
|
range_end = 4
|
||||||
|
default = 1
|
||||||
|
|
||||||
|
|
||||||
|
class TattleHp(Toggle):
|
||||||
|
"""
|
||||||
|
This will display the enemies' current and max health while in battle.
|
||||||
|
"""
|
||||||
|
|
||||||
|
display_name = "Tattle HP"
|
||||||
|
|
||||||
|
|
||||||
|
class RandomizeBackgrounds(Toggle):
|
||||||
|
"""
|
||||||
|
This randomizes the background image in battles.
|
||||||
|
"""
|
||||||
|
|
||||||
|
display_name = "Randomize Battle Backgrounds"
|
||||||
|
|
||||||
|
|
||||||
|
class HiddenVisible(Choice):
|
||||||
|
"""
|
||||||
|
This makes any hidden blocks in the game into regular item blocks and vice versa.
|
||||||
|
Disabled: Hidden blocks will remain invisible.
|
||||||
|
Hidden Visible: Hidden blocks will turn visible to the player.
|
||||||
|
Blocks Invisible: All item blocks will turn invisible. Hidden blocks will also remain invisible.
|
||||||
|
"""
|
||||||
|
|
||||||
|
display_name = "Item Block Visibility"
|
||||||
|
option_disabled = 0
|
||||||
|
option_hidden_visible = 1
|
||||||
|
option_blocks_invisible = 2
|
||||||
|
default = 0
|
||||||
|
|
||||||
|
|
||||||
|
class Coins(Toggle):
|
||||||
|
"""
|
||||||
|
Add all coin blocks in the game to the location pool.
|
||||||
|
"""
|
||||||
|
|
||||||
|
display_name = "Coin Blocks"
|
||||||
|
|
||||||
|
|
||||||
|
class HarhallsPants(Toggle):
|
||||||
|
"""
|
||||||
|
This will remove the Harhall's Pants check from the pool.
|
||||||
|
"""
|
||||||
|
|
||||||
|
display_name = "Remove Harhall's Pants"
|
||||||
|
|
||||||
|
|
||||||
|
class DifficultLogic(Toggle):
|
||||||
|
"""
|
||||||
|
This adjusts the logic to be more difficult in a few areas,
|
||||||
|
allowing for the logic to account for players getting to certain areas in unintended ways.
|
||||||
|
Enable at your own risk, this is not an option made for beginners.
|
||||||
|
"""
|
||||||
|
|
||||||
|
display_name = "Difficult Logic"
|
||||||
|
|
||||||
|
|
||||||
|
class ChuckleBeans(Choice):
|
||||||
|
"""
|
||||||
|
Choose how you want chuckle bean digspots to be randomized.
|
||||||
|
An amount of chuckle beans will be removed from the item pool,
|
||||||
|
equal to the amount of locations removed by the setting that you choose.
|
||||||
|
None: No chuckle bean digspots will be added into the location pool.
|
||||||
|
Only Visible: Only chuckle bean digspots clearly marked with an X will be added into the location pool.
|
||||||
|
All: All chuckle bean digspots will be added into the location pool.
|
||||||
|
"""
|
||||||
|
|
||||||
|
display_name = "Chuckle Beans"
|
||||||
|
option_none = 0
|
||||||
|
option_only_visible = 1
|
||||||
|
option_all = 2
|
||||||
|
default = 2
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class MLSSOptions(PerGameCommonOptions):
|
||||||
|
start_inventory_from_pool: StartInventoryPool
|
||||||
|
coins: Coins
|
||||||
|
difficult_logic: DifficultLogic
|
||||||
|
castle_skip: BowsersCastleSkip
|
||||||
|
extra_pipes: ExtraPipes
|
||||||
|
skip_minecart: SkipMinecart
|
||||||
|
disable_surf: DisableSurf
|
||||||
|
harhalls_pants: HarhallsPants
|
||||||
|
block_visibility: HiddenVisible
|
||||||
|
chuckle_beans: ChuckleBeans
|
||||||
|
music_options: MusicOptions
|
||||||
|
randomize_sounds: RandomSounds
|
||||||
|
randomize_enemies: RandomizeEnemies
|
||||||
|
randomize_bosses: RandomizeBosses
|
||||||
|
randomize_backgrounds: RandomizeBackgrounds
|
||||||
|
scale_stats: ScaleStats
|
||||||
|
xp_multiplier: XPMultiplier
|
||||||
|
tattle_hp: TattleHp
|
||||||
|
mario_color: MarioColor
|
||||||
|
luigi_color: LuigiColor
|
||||||
|
mario_pants: MarioPants
|
||||||
|
luigi_pants: LuigiPants
|
|
@ -0,0 +1,323 @@
|
||||||
|
import typing
|
||||||
|
|
||||||
|
from BaseClasses import Region, Entrance
|
||||||
|
from .Locations import (
|
||||||
|
MLSSLocation,
|
||||||
|
mainArea,
|
||||||
|
chucklehuck,
|
||||||
|
castleTown,
|
||||||
|
startingFlag,
|
||||||
|
chuckolatorFlag,
|
||||||
|
piranhaFlag,
|
||||||
|
kidnappedFlag,
|
||||||
|
beanstarFlag,
|
||||||
|
birdoFlag,
|
||||||
|
surfable,
|
||||||
|
hooniversity,
|
||||||
|
gwarharEntrance,
|
||||||
|
gwarharMain,
|
||||||
|
fungitown,
|
||||||
|
fungitownBeanstar,
|
||||||
|
fungitownBirdo,
|
||||||
|
teeheeValley,
|
||||||
|
winkle,
|
||||||
|
sewers,
|
||||||
|
airport,
|
||||||
|
bowsers,
|
||||||
|
bowsersMini,
|
||||||
|
jokesEntrance,
|
||||||
|
jokesMain,
|
||||||
|
theater,
|
||||||
|
booStatue,
|
||||||
|
oasis,
|
||||||
|
postJokes,
|
||||||
|
baseUltraRocks,
|
||||||
|
coins,
|
||||||
|
)
|
||||||
|
from . import StateLogic
|
||||||
|
|
||||||
|
if typing.TYPE_CHECKING:
|
||||||
|
from . import MLSSWorld
|
||||||
|
|
||||||
|
|
||||||
|
def create_regions(world: "MLSSWorld", excluded: typing.List[str]):
|
||||||
|
menu_region = Region("Menu", world.player, world.multiworld)
|
||||||
|
world.multiworld.regions.append(menu_region)
|
||||||
|
|
||||||
|
create_region(world, "Main Area", mainArea, excluded)
|
||||||
|
create_region(world, "Chucklehuck Woods", chucklehuck, excluded)
|
||||||
|
create_region(world, "Beanbean Castle Town", castleTown, excluded)
|
||||||
|
create_region(world, "Shop Starting Flag", startingFlag, excluded)
|
||||||
|
create_region(world, "Shop Chuckolator Flag", chuckolatorFlag, excluded)
|
||||||
|
create_region(world, "Shop Mom Piranha Flag", piranhaFlag, excluded)
|
||||||
|
create_region(world, "Shop Enter Fungitown Flag", kidnappedFlag, excluded)
|
||||||
|
create_region(world, "Shop Beanstar Complete Flag", beanstarFlag, excluded)
|
||||||
|
create_region(world, "Shop Birdo Flag", birdoFlag, excluded)
|
||||||
|
create_region(world, "Surfable", surfable, excluded)
|
||||||
|
create_region(world, "Hooniversity", hooniversity, excluded)
|
||||||
|
create_region(world, "GwarharEntrance", gwarharEntrance, excluded)
|
||||||
|
create_region(world, "GwarharMain", gwarharMain, excluded)
|
||||||
|
create_region(world, "TeeheeValley", teeheeValley, excluded)
|
||||||
|
create_region(world, "Winkle", winkle, excluded)
|
||||||
|
create_region(world, "Sewers", sewers, excluded)
|
||||||
|
create_region(world, "Airport", airport, excluded)
|
||||||
|
create_region(world, "JokesEntrance", jokesEntrance, excluded)
|
||||||
|
create_region(world, "JokesMain", jokesMain, excluded)
|
||||||
|
create_region(world, "PostJokes", postJokes, excluded)
|
||||||
|
create_region(world, "Theater", theater, excluded)
|
||||||
|
create_region(world, "Fungitown", fungitown, excluded)
|
||||||
|
create_region(world, "Fungitown Shop Beanstar Complete Flag", fungitownBeanstar, excluded)
|
||||||
|
create_region(world, "Fungitown Shop Birdo Flag", fungitownBirdo, excluded)
|
||||||
|
create_region(world, "BooStatue", booStatue, excluded)
|
||||||
|
create_region(world, "Oasis", oasis, excluded)
|
||||||
|
create_region(world, "BaseUltraRocks", baseUltraRocks, excluded)
|
||||||
|
|
||||||
|
if world.options.coins:
|
||||||
|
create_region(world, "Coins", coins, excluded)
|
||||||
|
|
||||||
|
if not world.options.castle_skip:
|
||||||
|
create_region(world, "Bowser's Castle", bowsers, excluded)
|
||||||
|
create_region(world, "Bowser's Castle Mini", bowsersMini, excluded)
|
||||||
|
|
||||||
|
|
||||||
|
def connect_regions(world: "MLSSWorld"):
|
||||||
|
names: typing.Dict[str, int] = {}
|
||||||
|
|
||||||
|
connect(world, names, "Menu", "Main Area")
|
||||||
|
if world.options.coins:
|
||||||
|
connect(world, names, "Main Area", "Coins")
|
||||||
|
connect(world, names, "Main Area", "BaseUltraRocks", lambda state: StateLogic.ultra(state, world.player))
|
||||||
|
connect(world, names, "Main Area", "Chucklehuck Woods", lambda state: StateLogic.brooch(state, world.player))
|
||||||
|
connect(world, names, "Main Area", "BooStatue", lambda state: StateLogic.canCrash(state, world.player))
|
||||||
|
connect(
|
||||||
|
world,
|
||||||
|
names,
|
||||||
|
"Main Area",
|
||||||
|
"Hooniversity",
|
||||||
|
lambda state: StateLogic.canDig(state, world.player) and StateLogic.canMini(state, world.player),
|
||||||
|
)
|
||||||
|
connect(world, names, "Hooniversity", "Oasis")
|
||||||
|
connect(
|
||||||
|
world,
|
||||||
|
names,
|
||||||
|
"Main Area",
|
||||||
|
"TeeheeValley",
|
||||||
|
lambda state: StateLogic.super(state, world.player) or StateLogic.canDash(state, world.player),
|
||||||
|
)
|
||||||
|
connect(
|
||||||
|
world,
|
||||||
|
names,
|
||||||
|
"TeeheeValley",
|
||||||
|
"GwarharEntrance",
|
||||||
|
lambda state: StateLogic.membership(state, world.player) and StateLogic.fire(state, world.player),
|
||||||
|
)
|
||||||
|
connect(
|
||||||
|
world,
|
||||||
|
names,
|
||||||
|
"TeeheeValley",
|
||||||
|
"Oasis",
|
||||||
|
lambda state: StateLogic.membership(state, world.player) and StateLogic.fire(state, world.player),
|
||||||
|
)
|
||||||
|
connect(
|
||||||
|
world,
|
||||||
|
names,
|
||||||
|
"TeeheeValley",
|
||||||
|
"Fungitown",
|
||||||
|
lambda state: StateLogic.thunder(state, world.player)
|
||||||
|
and StateLogic.castleTown(state, world.player)
|
||||||
|
and StateLogic.rose(state, world.player),
|
||||||
|
)
|
||||||
|
connection = connect(
|
||||||
|
world,
|
||||||
|
names,
|
||||||
|
"Fungitown",
|
||||||
|
"Fungitown Shop Beanstar Complete Flag",
|
||||||
|
lambda state: StateLogic.pieces(state, world.player) or StateLogic.fungitown_birdo_shop(state, world.player),
|
||||||
|
True,
|
||||||
|
)
|
||||||
|
world.multiworld.register_indirect_condition(world.get_region("Fungitown Shop Birdo Flag"), connection)
|
||||||
|
connect(world, names, "Main Area", "Shop Starting Flag")
|
||||||
|
connection = connect(
|
||||||
|
world,
|
||||||
|
names,
|
||||||
|
"Shop Starting Flag",
|
||||||
|
"Shop Chuckolator Flag",
|
||||||
|
lambda state: (
|
||||||
|
StateLogic.brooch(state, world.player)
|
||||||
|
and StateLogic.fruits(state, world.player)
|
||||||
|
and (
|
||||||
|
StateLogic.thunder(state, world.player)
|
||||||
|
or StateLogic.fire(state, world.player)
|
||||||
|
or StateLogic.hammers(state, world.player)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
or (
|
||||||
|
StateLogic.piranha_shop(state, world.player)
|
||||||
|
or StateLogic.fungitown_shop(state, world.player)
|
||||||
|
or StateLogic.star_shop(state, world.player)
|
||||||
|
or StateLogic.birdo_shop(state, world.player)
|
||||||
|
),
|
||||||
|
True,
|
||||||
|
)
|
||||||
|
world.multiworld.register_indirect_condition(world.get_region("Shop Mom Piranha Flag"), connection)
|
||||||
|
world.multiworld.register_indirect_condition(world.get_region("Shop Enter Fungitown Flag"), connection)
|
||||||
|
world.multiworld.register_indirect_condition(world.get_region("Shop Beanstar Complete Flag"), connection)
|
||||||
|
world.multiworld.register_indirect_condition(world.get_region("Shop Birdo Flag"), connection)
|
||||||
|
connection = connect(
|
||||||
|
world,
|
||||||
|
names,
|
||||||
|
"Shop Starting Flag",
|
||||||
|
"Shop Mom Piranha Flag",
|
||||||
|
lambda state: StateLogic.thunder(state, world.player)
|
||||||
|
or (
|
||||||
|
StateLogic.fungitown_shop(state, world.player)
|
||||||
|
or StateLogic.star_shop(state, world.player)
|
||||||
|
or StateLogic.birdo_shop(state, world.player)
|
||||||
|
),
|
||||||
|
True,
|
||||||
|
)
|
||||||
|
world.multiworld.register_indirect_condition(world.get_region("Shop Enter Fungitown Flag"), connection)
|
||||||
|
world.multiworld.register_indirect_condition(world.get_region("Shop Beanstar Complete Flag"), connection)
|
||||||
|
world.multiworld.register_indirect_condition(world.get_region("Shop Birdo Flag"), connection)
|
||||||
|
connection = connect(
|
||||||
|
world,
|
||||||
|
names,
|
||||||
|
"Shop Starting Flag",
|
||||||
|
"Shop Enter Fungitown Flag",
|
||||||
|
lambda state: StateLogic.fungitown(state, world.player)
|
||||||
|
or (StateLogic.star_shop(state, world.player) or StateLogic.birdo_shop(state, world.player)),
|
||||||
|
True,
|
||||||
|
)
|
||||||
|
world.multiworld.register_indirect_condition(world.get_region("Shop Beanstar Complete Flag"), connection)
|
||||||
|
world.multiworld.register_indirect_condition(world.get_region("Shop Birdo Flag"), connection)
|
||||||
|
connection = connect(
|
||||||
|
world,
|
||||||
|
names,
|
||||||
|
"Shop Starting Flag",
|
||||||
|
"Shop Beanstar Complete Flag",
|
||||||
|
lambda state: (
|
||||||
|
StateLogic.castleTown(state, world.player)
|
||||||
|
and StateLogic.pieces(state, world.player)
|
||||||
|
and StateLogic.rose(state, world.player)
|
||||||
|
)
|
||||||
|
or StateLogic.birdo_shop(state, world.player),
|
||||||
|
True,
|
||||||
|
)
|
||||||
|
world.multiworld.register_indirect_condition(world.get_region("Shop Birdo Flag"), connection)
|
||||||
|
connect(world, names, "Main Area", "Sewers", lambda state: StateLogic.rose(state, world.player))
|
||||||
|
connect(world, names, "Main Area", "Airport", lambda state: StateLogic.thunder(state, world.player))
|
||||||
|
connect(world, names, "Main Area", "Theater", lambda state: StateLogic.canDash(state, world.player))
|
||||||
|
connect(world, names, "Main Area", "Surfable", lambda state: StateLogic.surfable(state, world.player))
|
||||||
|
connect(world, names, "Surfable", "GwarharEntrance")
|
||||||
|
connect(world, names, "Surfable", "Oasis")
|
||||||
|
connect(world, names, "Surfable", "JokesEntrance", lambda state: StateLogic.fire(state, world.player))
|
||||||
|
connect(world, names, "JokesMain", "PostJokes", lambda state: StateLogic.postJokes(state, world.player))
|
||||||
|
if not world.options.castle_skip:
|
||||||
|
connect(world, names, "PostJokes", "Bowser's Castle")
|
||||||
|
connect(
|
||||||
|
world,
|
||||||
|
names,
|
||||||
|
"Bowser's Castle",
|
||||||
|
"Bowser's Castle Mini",
|
||||||
|
lambda state: StateLogic.canMini(state, world.player) and StateLogic.thunder(state, world.player),
|
||||||
|
)
|
||||||
|
connect(world, names, "Chucklehuck Woods", "Winkle", lambda state: StateLogic.canDash(state, world.player))
|
||||||
|
connect(
|
||||||
|
world,
|
||||||
|
names,
|
||||||
|
"Chucklehuck Woods",
|
||||||
|
"Beanbean Castle Town",
|
||||||
|
lambda state: StateLogic.fruits(state, world.player)
|
||||||
|
and (
|
||||||
|
StateLogic.hammers(state, world.player)
|
||||||
|
or StateLogic.fire(state, world.player)
|
||||||
|
or StateLogic.thunder(state, world.player)
|
||||||
|
),
|
||||||
|
)
|
||||||
|
if world.options.difficult_logic:
|
||||||
|
connect(world, names, "GwarharEntrance", "GwarharMain", lambda state: StateLogic.canDash(state, world.player))
|
||||||
|
connect(world, names, "JokesEntrance", "JokesMain", lambda state: StateLogic.canDig(state, world.player))
|
||||||
|
connect(
|
||||||
|
world,
|
||||||
|
names,
|
||||||
|
"Shop Starting Flag",
|
||||||
|
"Shop Birdo Flag",
|
||||||
|
lambda state: StateLogic.postJokes(state, world.player),
|
||||||
|
)
|
||||||
|
connect(
|
||||||
|
world,
|
||||||
|
names,
|
||||||
|
"Fungitown",
|
||||||
|
"Fungitown Shop Birdo Flag",
|
||||||
|
lambda state: StateLogic.postJokes(state, world.player),
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
connect(
|
||||||
|
world,
|
||||||
|
names,
|
||||||
|
"GwarharEntrance",
|
||||||
|
"GwarharMain",
|
||||||
|
lambda state: StateLogic.canDash(state, world.player) and StateLogic.canCrash(state, world.player),
|
||||||
|
)
|
||||||
|
connect(
|
||||||
|
world,
|
||||||
|
names,
|
||||||
|
"JokesEntrance",
|
||||||
|
"JokesMain",
|
||||||
|
lambda state: StateLogic.canCrash(state, world.player) and StateLogic.canDig(state, world.player),
|
||||||
|
)
|
||||||
|
connect(
|
||||||
|
world,
|
||||||
|
names,
|
||||||
|
"Shop Starting Flag",
|
||||||
|
"Shop Birdo Flag",
|
||||||
|
lambda state: StateLogic.canCrash(state, world.player) and StateLogic.postJokes(state, world.player),
|
||||||
|
)
|
||||||
|
connect(
|
||||||
|
world,
|
||||||
|
names,
|
||||||
|
"Fungitown",
|
||||||
|
"Fungitown Shop Birdo Flag",
|
||||||
|
lambda state: StateLogic.canCrash(state, world.player) and StateLogic.postJokes(state, world.player),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def create_region(world: "MLSSWorld", name, locations, excluded):
|
||||||
|
ret = Region(name, world.player, world.multiworld)
|
||||||
|
for location in locations:
|
||||||
|
loc = MLSSLocation(world.player, location.name, location.id, ret)
|
||||||
|
if location.name in excluded:
|
||||||
|
continue
|
||||||
|
ret.locations.append(loc)
|
||||||
|
world.multiworld.regions.append(ret)
|
||||||
|
|
||||||
|
|
||||||
|
def connect(
|
||||||
|
world: "MLSSWorld",
|
||||||
|
used_names: typing.Dict[str, int],
|
||||||
|
source: str,
|
||||||
|
target: str,
|
||||||
|
rule: typing.Optional[typing.Callable] = None,
|
||||||
|
reach: typing.Optional[bool] = False,
|
||||||
|
) -> Entrance | None:
|
||||||
|
source_region = world.multiworld.get_region(source, world.player)
|
||||||
|
target_region = world.multiworld.get_region(target, world.player)
|
||||||
|
|
||||||
|
if target not in used_names:
|
||||||
|
used_names[target] = 1
|
||||||
|
name = target
|
||||||
|
else:
|
||||||
|
used_names[target] += 1
|
||||||
|
name = target + (" " * used_names[target])
|
||||||
|
|
||||||
|
connection = Entrance(world.player, name, source_region)
|
||||||
|
|
||||||
|
if rule:
|
||||||
|
connection.access_rule = rule
|
||||||
|
|
||||||
|
source_region.exits.append(connection)
|
||||||
|
connection.connect(target_region)
|
||||||
|
if reach:
|
||||||
|
return connection
|
||||||
|
else:
|
||||||
|
return None
|
|
@ -0,0 +1,437 @@
|
||||||
|
import io
|
||||||
|
import json
|
||||||
|
import random
|
||||||
|
|
||||||
|
from . import Data
|
||||||
|
from typing import TYPE_CHECKING, Optional
|
||||||
|
from BaseClasses import Item, Location
|
||||||
|
from settings import get_settings
|
||||||
|
from worlds.Files import APProcedurePatch, APTokenMixin, APTokenTypes, APPatchExtension
|
||||||
|
from .Items import item_table
|
||||||
|
from .Locations import shop, badge, pants, location_table, hidden, all_locations
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from . import MLSSWorld
|
||||||
|
|
||||||
|
colors = [
|
||||||
|
Data.redHat,
|
||||||
|
Data.greenHat,
|
||||||
|
Data.blueHat,
|
||||||
|
Data.azureHat,
|
||||||
|
Data.yellowHat,
|
||||||
|
Data.orangeHat,
|
||||||
|
Data.purpleHat,
|
||||||
|
Data.pinkHat,
|
||||||
|
Data.blackHat,
|
||||||
|
Data.whiteHat,
|
||||||
|
Data.silhouetteHat,
|
||||||
|
Data.chaosHat,
|
||||||
|
Data.truechaosHat
|
||||||
|
]
|
||||||
|
|
||||||
|
cpants = [
|
||||||
|
Data.vanilla,
|
||||||
|
Data.redPants,
|
||||||
|
Data.greenPants,
|
||||||
|
Data.bluePants,
|
||||||
|
Data.azurePants,
|
||||||
|
Data.yellowPants,
|
||||||
|
Data.orangePants,
|
||||||
|
Data.purplePants,
|
||||||
|
Data.pinkPants,
|
||||||
|
Data.blackPants,
|
||||||
|
Data.whitePants,
|
||||||
|
Data.chaosPants
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def get_base_rom_as_bytes() -> bytes:
|
||||||
|
with open(get_settings().mlss_options.rom_file, "rb") as infile:
|
||||||
|
base_rom_bytes = bytes(infile.read())
|
||||||
|
return base_rom_bytes
|
||||||
|
|
||||||
|
|
||||||
|
class MLSSPatchExtension(APPatchExtension):
|
||||||
|
game = "Mario & Luigi Superstar Saga"
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def randomize_music(caller: APProcedurePatch, rom: bytes):
|
||||||
|
options = json.loads(caller.get_file("options.json").decode("UTF-8"))
|
||||||
|
if options["music_options"] != 1:
|
||||||
|
return rom
|
||||||
|
stream = io.BytesIO(rom)
|
||||||
|
random.seed(options["seed"] + options["player"])
|
||||||
|
|
||||||
|
songs = []
|
||||||
|
stream.seek(0x21CB74)
|
||||||
|
for _ in range(50):
|
||||||
|
if stream.tell() == 0x21CBD8:
|
||||||
|
stream.seek(4, 1)
|
||||||
|
continue
|
||||||
|
temp = stream.read(4)
|
||||||
|
songs.append(temp)
|
||||||
|
|
||||||
|
random.shuffle(songs)
|
||||||
|
stream.seek(0x21CB74)
|
||||||
|
for _ in range(50):
|
||||||
|
if stream.tell() == 0x21CBD8:
|
||||||
|
stream.seek(4, 1)
|
||||||
|
continue
|
||||||
|
stream.write(songs.pop())
|
||||||
|
|
||||||
|
return stream.getvalue()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def hidden_visible(caller: APProcedurePatch, rom: bytes):
|
||||||
|
options = json.loads(caller.get_file("options.json").decode("UTF-8"))
|
||||||
|
if options["block_visibility"] == 0:
|
||||||
|
return rom
|
||||||
|
stream = io.BytesIO(rom)
|
||||||
|
|
||||||
|
for location in all_locations:
|
||||||
|
stream.seek(location.id - 6)
|
||||||
|
b = stream.read(1)
|
||||||
|
if b[0] == 0x10 and options["block_visibility"] == 1:
|
||||||
|
stream.seek(location.id - 6)
|
||||||
|
stream.write(bytes([0x0]))
|
||||||
|
if b[0] == 0x0 and options["block_visibility"] == 2:
|
||||||
|
stream.seek(location.id - 6)
|
||||||
|
stream.write(bytes([0x10]))
|
||||||
|
|
||||||
|
return stream.getvalue()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def randomize_sounds(caller: APProcedurePatch, rom: bytes):
|
||||||
|
options = json.loads(caller.get_file("options.json").decode("UTF-8"))
|
||||||
|
if options["randomize_sounds"] != 1:
|
||||||
|
return rom
|
||||||
|
stream = io.BytesIO(rom)
|
||||||
|
random.seed(options["seed"] + options["player"])
|
||||||
|
fresh_pointers = Data.sounds
|
||||||
|
pointers = Data.sounds
|
||||||
|
|
||||||
|
random.shuffle(pointers)
|
||||||
|
stream.seek(0x21CC44, 0)
|
||||||
|
for i in range(354):
|
||||||
|
current_position = stream.tell()
|
||||||
|
value = int.from_bytes(stream.read(3), "little")
|
||||||
|
if value in fresh_pointers:
|
||||||
|
stream.seek(current_position)
|
||||||
|
stream.write(pointers.pop().to_bytes(3, "little"))
|
||||||
|
stream.seek(1, 1)
|
||||||
|
|
||||||
|
return stream.getvalue()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def enemy_randomize(caller: APProcedurePatch, rom: bytes):
|
||||||
|
options = json.loads(caller.get_file("options.json").decode("UTF-8"))
|
||||||
|
if options["randomize_bosses"] == 0 and options["randomize_enemies"] == 0:
|
||||||
|
return rom
|
||||||
|
|
||||||
|
enemies = [pos for pos in Data.enemies if pos not in Data.bowsers] if options["castle_skip"] else Data.enemies
|
||||||
|
bosses = [pos for pos in Data.bosses if pos not in Data.bowsers] if options["castle_skip"] else Data.bosses
|
||||||
|
stream = io.BytesIO(rom)
|
||||||
|
random.seed(options["seed"] + options["player"])
|
||||||
|
|
||||||
|
if options["randomize_bosses"] == 1 or (options["randomize_bosses"] == 2) and options["randomize_enemies"] == 0:
|
||||||
|
raw = []
|
||||||
|
for pos in bosses:
|
||||||
|
stream.seek(pos + 1)
|
||||||
|
raw += [stream.read(0x1F)]
|
||||||
|
random.shuffle(raw)
|
||||||
|
for pos in bosses:
|
||||||
|
stream.seek(pos + 1)
|
||||||
|
stream.write(raw.pop())
|
||||||
|
|
||||||
|
if options["randomize_enemies"] == 1:
|
||||||
|
raw = []
|
||||||
|
for pos in enemies:
|
||||||
|
stream.seek(pos + 1)
|
||||||
|
raw += [stream.read(0x1F)]
|
||||||
|
if options["randomize_bosses"] == 2:
|
||||||
|
for pos in bosses:
|
||||||
|
stream.seek(pos + 1)
|
||||||
|
raw += [stream.read(0x1F)]
|
||||||
|
random.shuffle(raw)
|
||||||
|
for pos in enemies:
|
||||||
|
stream.seek(pos + 1)
|
||||||
|
stream.write(raw.pop())
|
||||||
|
if options["randomize_bosses"] == 2:
|
||||||
|
for pos in bosses:
|
||||||
|
stream.seek(pos + 1)
|
||||||
|
stream.write(raw.pop())
|
||||||
|
return stream.getvalue()
|
||||||
|
|
||||||
|
enemies_raw = []
|
||||||
|
groups = []
|
||||||
|
|
||||||
|
if options["randomize_enemies"] == 0:
|
||||||
|
return stream.getvalue()
|
||||||
|
|
||||||
|
if options["randomize_bosses"] == 2:
|
||||||
|
for pos in bosses:
|
||||||
|
stream.seek(pos + 1)
|
||||||
|
groups += [stream.read(0x1F)]
|
||||||
|
|
||||||
|
for pos in enemies:
|
||||||
|
stream.seek(pos + 8)
|
||||||
|
for _ in range(6):
|
||||||
|
enemy = int.from_bytes(stream.read(1))
|
||||||
|
if enemy > 0:
|
||||||
|
stream.seek(1, 1)
|
||||||
|
flag = int.from_bytes(stream.read(1))
|
||||||
|
if flag == 0x7:
|
||||||
|
break
|
||||||
|
if flag in [0x0, 0x2, 0x4]:
|
||||||
|
if enemy not in Data.pestnut and enemy not in Data.flying:
|
||||||
|
enemies_raw += [enemy]
|
||||||
|
stream.seek(1, 1)
|
||||||
|
else:
|
||||||
|
stream.seek(3, 1)
|
||||||
|
|
||||||
|
random.shuffle(enemies_raw)
|
||||||
|
chomp = False
|
||||||
|
for pos in enemies:
|
||||||
|
stream.seek(pos + 8)
|
||||||
|
|
||||||
|
for _ in range(6):
|
||||||
|
enemy = int.from_bytes(stream.read(1))
|
||||||
|
if enemy > 0 and enemy not in Data.flying and enemy not in Data.pestnut:
|
||||||
|
if enemy == 0x52:
|
||||||
|
chomp = True
|
||||||
|
stream.seek(1, 1)
|
||||||
|
flag = int.from_bytes(stream.read(1))
|
||||||
|
if flag not in [0x0, 0x2, 0x4]:
|
||||||
|
stream.seek(1, 1)
|
||||||
|
continue
|
||||||
|
stream.seek(-3, 1)
|
||||||
|
stream.write(bytes([enemies_raw.pop()]))
|
||||||
|
stream.seek(1, 1)
|
||||||
|
stream.write(bytes([0x6]))
|
||||||
|
stream.seek(1, 1)
|
||||||
|
else:
|
||||||
|
stream.seek(3, 1)
|
||||||
|
|
||||||
|
stream.seek(pos + 1)
|
||||||
|
raw = stream.read(0x1F)
|
||||||
|
if chomp:
|
||||||
|
raw = raw[0:3] + bytes([0x67, 0xAB, 0x28, 0x08]) + raw[7:]
|
||||||
|
else:
|
||||||
|
raw = raw[0:3] + bytes([0xEE, 0x2C, 0x28, 0x08]) + raw[7:]
|
||||||
|
groups += [raw]
|
||||||
|
chomp = False
|
||||||
|
|
||||||
|
random.shuffle(groups)
|
||||||
|
arr = enemies
|
||||||
|
if options["randomize_bosses"] == 2:
|
||||||
|
arr += bosses
|
||||||
|
|
||||||
|
for pos in arr:
|
||||||
|
stream.seek(pos + 1)
|
||||||
|
stream.write(groups.pop())
|
||||||
|
|
||||||
|
return stream.getvalue()
|
||||||
|
|
||||||
|
|
||||||
|
class MLSSProcedurePatch(APProcedurePatch, APTokenMixin):
|
||||||
|
game = "Mario & Luigi Superstar Saga"
|
||||||
|
hash = "4b1a5897d89d9e74ec7f630eefdfd435"
|
||||||
|
patch_file_ending = ".apmlss"
|
||||||
|
result_file_ending = ".gba"
|
||||||
|
|
||||||
|
procedure = [
|
||||||
|
("apply_bsdiff4", ["base_patch.bsdiff4"]),
|
||||||
|
("apply_tokens", ["token_data.bin"]),
|
||||||
|
("enemy_randomize", []),
|
||||||
|
("hidden_visible", []),
|
||||||
|
("randomize_sounds", []),
|
||||||
|
("randomize_music", []),
|
||||||
|
]
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_source_data(cls) -> bytes:
|
||||||
|
return get_base_rom_as_bytes()
|
||||||
|
|
||||||
|
|
||||||
|
def write_tokens(world: "MLSSWorld", patch: MLSSProcedurePatch) -> None:
|
||||||
|
options_dict = {
|
||||||
|
"randomize_enemies": world.options.randomize_enemies.value,
|
||||||
|
"randomize_bosses": world.options.randomize_bosses.value,
|
||||||
|
"castle_skip": world.options.castle_skip.value,
|
||||||
|
"randomize_sounds": world.options.randomize_sounds.value,
|
||||||
|
"music_options": world.options.music_options.value,
|
||||||
|
"block_visibility": world.options.block_visibility.value,
|
||||||
|
"seed": world.multiworld.seed,
|
||||||
|
"player": world.player,
|
||||||
|
}
|
||||||
|
patch.write_file("options.json", json.dumps(options_dict).encode("UTF-8"))
|
||||||
|
|
||||||
|
# Bake player name into ROM
|
||||||
|
patch.write_token(APTokenTypes.WRITE, 0xDF0000, world.multiworld.player_name[world.player].encode("UTF-8"))
|
||||||
|
|
||||||
|
# Bake seed name into ROM
|
||||||
|
patch.write_token(APTokenTypes.WRITE, 0xDF00A0, world.multiworld.seed_name.encode("UTF-8"))
|
||||||
|
|
||||||
|
# Bake patch into header
|
||||||
|
patch.write_token(APTokenTypes.WRITE, 0xAD, "P".encode("UTF-8"))
|
||||||
|
|
||||||
|
# Intro Skip
|
||||||
|
patch.write_token(
|
||||||
|
APTokenTypes.WRITE,
|
||||||
|
0x244D08,
|
||||||
|
bytes([0x88, 0x0, 0x19, 0x91, 0x1, 0x20, 0x58, 0x1, 0xF, 0xA0, 0x3, 0x15, 0x27, 0x8]),
|
||||||
|
)
|
||||||
|
|
||||||
|
# Patch S.S Chuckola Loading Zones
|
||||||
|
patch.write_token(APTokenTypes.WRITE, 0x25FD4E, bytes([0x48, 0x30, 0x80, 0x60, 0x50, 0x2, 0xF]))
|
||||||
|
|
||||||
|
patch.write_token(APTokenTypes.WRITE, 0x25FD83, bytes([0x48, 0x30, 0x80, 0x60, 0xC0, 0x2, 0xF]))
|
||||||
|
|
||||||
|
patch.write_token(APTokenTypes.WRITE, 0x25FDB8, bytes([0x48, 0x30, 0x05, 0x80, 0xE4, 0x0, 0xF]))
|
||||||
|
|
||||||
|
patch.write_token(APTokenTypes.WRITE, 0x25FDED, bytes([0x48, 0x30, 0x06, 0x80, 0xE4, 0x0, 0xF]))
|
||||||
|
|
||||||
|
patch.write_token(APTokenTypes.WRITE, 0x25FE22, bytes([0x48, 0x30, 0x07, 0x80, 0xE4, 0x0, 0xF]))
|
||||||
|
|
||||||
|
patch.write_token(APTokenTypes.WRITE, 0x25FE57, bytes([0x48, 0x30, 0x08, 0x80, 0xE4, 0x0, 0xF]))
|
||||||
|
|
||||||
|
if world.options.extra_pipes:
|
||||||
|
patch.write_token(APTokenTypes.WRITE, 0xD00001, bytes([0x1]))
|
||||||
|
|
||||||
|
if world.options.castle_skip:
|
||||||
|
patch.write_token(APTokenTypes.WRITE, 0x3AEAB0, bytes([0xC1, 0x67, 0x0, 0x6, 0x1C, 0x08, 0x3]))
|
||||||
|
patch.write_token(APTokenTypes.WRITE, 0x3AEC18, bytes([0x89, 0x65, 0x0, 0xE, 0xA, 0x08, 0x1]))
|
||||||
|
|
||||||
|
if world.options.skip_minecart:
|
||||||
|
patch.write_token(APTokenTypes.WRITE, 0x3AC728, bytes([0x89, 0x13, 0x0, 0x10, 0xF, 0x08, 0x1]))
|
||||||
|
patch.write_token(APTokenTypes.WRITE, 0x3AC56C, bytes([0x49, 0x16, 0x0, 0x8, 0x8, 0x08, 0x1]))
|
||||||
|
|
||||||
|
if world.options.scale_stats:
|
||||||
|
patch.write_token(APTokenTypes.WRITE, 0xD00002, bytes([0x1]))
|
||||||
|
|
||||||
|
if world.options.xp_multiplier:
|
||||||
|
patch.write_token(APTokenTypes.WRITE, 0xD00003, bytes([world.options.xp_multiplier.value]))
|
||||||
|
|
||||||
|
if world.options.tattle_hp:
|
||||||
|
patch.write_token(APTokenTypes.WRITE, 0xD00000, bytes([0x1]))
|
||||||
|
|
||||||
|
if world.options.music_options == 2:
|
||||||
|
patch.write_token(APTokenTypes.WRITE, 0x19B118, bytes([0x0, 0x25]))
|
||||||
|
|
||||||
|
if world.options.randomize_backgrounds:
|
||||||
|
all_enemies = Data.enemies + Data.bosses
|
||||||
|
for address in all_enemies:
|
||||||
|
patch.write_token(APTokenTypes.WRITE, address + 3, bytes([world.random.randint(0x0, 0x26)]))
|
||||||
|
|
||||||
|
for location_name in location_table.keys():
|
||||||
|
if (
|
||||||
|
(world.options.skip_minecart and "Minecart" in location_name and "After" not in location_name)
|
||||||
|
or (world.options.castle_skip and "Bowser" in location_name)
|
||||||
|
or (world.options.disable_surf and "Surf Minigame" in location_name)
|
||||||
|
or (world.options.harhalls_pants and "Harhall's" in location_name)
|
||||||
|
):
|
||||||
|
continue
|
||||||
|
if (world.options.chuckle_beans == 0 and "Digspot" in location_name) or (
|
||||||
|
world.options.chuckle_beans == 1 and location_table[location_name] in hidden
|
||||||
|
):
|
||||||
|
continue
|
||||||
|
if not world.options.coins and "Coin" in location_name:
|
||||||
|
continue
|
||||||
|
location = world.multiworld.get_location(location_name, world.player)
|
||||||
|
item = location.item
|
||||||
|
address = [address for address in all_locations if address.name == location.name]
|
||||||
|
item_inject(world, patch, location.address, address[0].itemType, item)
|
||||||
|
if "Shop" in location_name and "Coffee" not in location_name and item.player != world.player:
|
||||||
|
desc_inject(world, patch, location, item)
|
||||||
|
|
||||||
|
swap_colors(world, patch, world.options.mario_pants.value, 0, True)
|
||||||
|
swap_colors(world, patch, world.options.luigi_pants.value, 1, True)
|
||||||
|
swap_colors(world, patch, world.options.mario_color.value, 0)
|
||||||
|
swap_colors(world, patch, world.options.luigi_color.value, 1)
|
||||||
|
|
||||||
|
patch.write_file("token_data.bin", patch.get_token_binary())
|
||||||
|
|
||||||
|
|
||||||
|
def swap_colors(world: "MLSSWorld", patch: MLSSProcedurePatch, color: int, bro: int,
|
||||||
|
pants_option: Optional[bool] = False):
|
||||||
|
if not pants_option and color == bro:
|
||||||
|
return
|
||||||
|
chaos = False
|
||||||
|
if not pants_option and color == 11 or color == 12:
|
||||||
|
chaos = True
|
||||||
|
if pants_option and color == 11:
|
||||||
|
chaos = True
|
||||||
|
for c in [c for c in (cpants[color] if pants_option else colors[color])
|
||||||
|
if (c[3] == bro if not chaos else c[1] == bro)]:
|
||||||
|
if chaos:
|
||||||
|
patch.write_token(APTokenTypes.WRITE, c[0],
|
||||||
|
bytes([world.random.randint(0, 255), world.random.randint(0, 127)]))
|
||||||
|
else:
|
||||||
|
patch.write_token(APTokenTypes.WRITE, c[0], bytes([c[1], c[2]]))
|
||||||
|
|
||||||
|
|
||||||
|
def item_inject(world: "MLSSWorld", patch: MLSSProcedurePatch, location: int, item_type: int, item: Item):
|
||||||
|
if item.player == world.player:
|
||||||
|
code = item_table[item.name].itemID
|
||||||
|
else:
|
||||||
|
code = 0x3F
|
||||||
|
if item_type == 0:
|
||||||
|
patch.write_token(APTokenTypes.WRITE, location, bytes([code]))
|
||||||
|
elif item_type == 1:
|
||||||
|
if code == 0x1D or code == 0x1E:
|
||||||
|
code += 0xE
|
||||||
|
if 0x20 <= code <= 0x26:
|
||||||
|
code -= 0x4
|
||||||
|
insert = int(code)
|
||||||
|
insert2 = insert % 0x10
|
||||||
|
insert2 *= 0x10
|
||||||
|
insert //= 0x10
|
||||||
|
insert += 0x20
|
||||||
|
patch.write_token(APTokenTypes.WRITE, location, bytes([insert, insert2]))
|
||||||
|
elif item_type == 2:
|
||||||
|
if code == 0x1D or code == 0x1E:
|
||||||
|
code += 0xE
|
||||||
|
if 0x20 <= code <= 0x26:
|
||||||
|
code -= 0x4
|
||||||
|
patch.write_token(APTokenTypes.WRITE, location, bytes([code]))
|
||||||
|
elif item_type == 3:
|
||||||
|
if code == 0x1D or code == 0x1E:
|
||||||
|
code += 0xE
|
||||||
|
if code < 0x1D:
|
||||||
|
code -= 0xA
|
||||||
|
if 0x20 <= code <= 0x26:
|
||||||
|
code -= 0xE
|
||||||
|
patch.write_token(APTokenTypes.WRITE, location, bytes([code]))
|
||||||
|
else:
|
||||||
|
patch.write_token(APTokenTypes.WRITE, location, bytes([0x18]))
|
||||||
|
|
||||||
|
|
||||||
|
def desc_inject(world: "MLSSWorld", patch: MLSSProcedurePatch, location: Location, item: Item):
|
||||||
|
index = -1
|
||||||
|
for key, value in shop.items():
|
||||||
|
if location.address in value:
|
||||||
|
if key == 0x3C05F0:
|
||||||
|
index = value.index(location.address)
|
||||||
|
else:
|
||||||
|
index = value.index(location.address) + 14
|
||||||
|
|
||||||
|
for key, value in badge.items():
|
||||||
|
if index != -1:
|
||||||
|
break
|
||||||
|
if location.address in value:
|
||||||
|
if key == 0x3C0618:
|
||||||
|
index = value.index(location.address) + 24
|
||||||
|
else:
|
||||||
|
index = value.index(location.address) + 41
|
||||||
|
|
||||||
|
for key, value in pants.items():
|
||||||
|
if index != -1:
|
||||||
|
break
|
||||||
|
if location.address in value:
|
||||||
|
if key == 0x3C0618:
|
||||||
|
index = value.index(location.address) + 48
|
||||||
|
else:
|
||||||
|
index = value.index(location.address) + 66
|
||||||
|
|
||||||
|
dstring = f"{world.multiworld.player_name[item.player]}: {item.name}"
|
||||||
|
patch.write_token(APTokenTypes.WRITE, 0xD11000 + (index * 0x40), dstring.encode("UTF8"))
|
|
@ -0,0 +1,571 @@
|
||||||
|
import typing
|
||||||
|
|
||||||
|
from worlds.generic.Rules import add_rule, forbid_item
|
||||||
|
from .Names.LocationName import LocationName
|
||||||
|
from .Locations import all_locations, hidden
|
||||||
|
from . import StateLogic
|
||||||
|
|
||||||
|
if typing.TYPE_CHECKING:
|
||||||
|
from . import MLSSWorld
|
||||||
|
|
||||||
|
|
||||||
|
def set_rules(world: "MLSSWorld", excluded):
|
||||||
|
for location in all_locations:
|
||||||
|
if "Digspot" in location.name:
|
||||||
|
if (world.options.skip_minecart and "Minecart" in location.name) or (
|
||||||
|
world.options.castle_skip and "Bowser" in location.name
|
||||||
|
):
|
||||||
|
continue
|
||||||
|
if world.options.chuckle_beans == 0 or world.options.chuckle_beans == 1 and location.id in hidden:
|
||||||
|
continue
|
||||||
|
add_rule(
|
||||||
|
world.get_location(location.name),
|
||||||
|
lambda state: StateLogic.canDig(state, world.player),
|
||||||
|
)
|
||||||
|
if "Beanstone" in location.name:
|
||||||
|
add_rule(
|
||||||
|
world.get_location(location.name),
|
||||||
|
lambda state: StateLogic.canDig(state, world.player),
|
||||||
|
)
|
||||||
|
if "Shop" in location.name and "Coffee" not in location.name and location.name not in excluded:
|
||||||
|
forbid_item(world.get_location(location.name), "Hammers", world.player)
|
||||||
|
if "Badge" in location.name or "Pants" in location.name:
|
||||||
|
add_rule(
|
||||||
|
world.get_location(location.name),
|
||||||
|
lambda state: StateLogic.brooch(state, world.player) or StateLogic.rose(state, world.player),
|
||||||
|
)
|
||||||
|
if location.itemType != 0 and location.name not in excluded:
|
||||||
|
if "Bowser" in location.name and world.options.castle_skip:
|
||||||
|
continue
|
||||||
|
forbid_item(world.get_location(location.name), "5 Coins", world.player)
|
||||||
|
|
||||||
|
if world.options.chuckle_beans == 2:
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.HoohooVillageSuperHammerCaveDigspot),
|
||||||
|
lambda state: StateLogic.canCrash(state, world.player) or StateLogic.super(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.BeanbeanOutskirtsFarmRoomDigspot2),
|
||||||
|
lambda state: StateLogic.thunder(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.BeanbeanOutskirtsFarmRoomDigspot3),
|
||||||
|
lambda state: StateLogic.thunder(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.ChucklehuckWoodsWhiteFruitRoomDigspot3),
|
||||||
|
lambda state: StateLogic.canMini(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.JokesEndJojoraRoomDigspot),
|
||||||
|
lambda state: StateLogic.canDash(state, world.player),
|
||||||
|
)
|
||||||
|
|
||||||
|
if world.options.chuckle_beans != 0:
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.HoohooMountainBaseBoostatueRoomDigspot2),
|
||||||
|
lambda state: StateLogic.canCrash(state, world.player) or StateLogic.super(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.BeanbeanOutskirtsFarmRoomDigspot1),
|
||||||
|
lambda state: StateLogic.thunder(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.ChucklehuckWoodsWhiteFruitRoomDigspot2),
|
||||||
|
lambda state: StateLogic.canMini(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.TeeheeValleyPastUltraHammersDigspot1),
|
||||||
|
lambda state: StateLogic.ultra(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.TeeheeValleyPastUltraHammersDigspot3),
|
||||||
|
lambda state: StateLogic.ultra(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.BeanbeanOutskirtsNorthBeachDigspot3),
|
||||||
|
lambda state: StateLogic.canDash(state, world.player) or StateLogic.super(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.BeanbeanOutskirtsEDigspot2),
|
||||||
|
lambda state: StateLogic.thunder(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.BeanbeanOutskirtsNEDigspot1),
|
||||||
|
lambda state: StateLogic.thunder(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.BeanbeanOutskirtsSRoom1Digspot2),
|
||||||
|
lambda state: StateLogic.ultra(state, world.player) and StateLogic.thunder(state, world.player),
|
||||||
|
)
|
||||||
|
|
||||||
|
forbid_item(
|
||||||
|
world.get_location(LocationName.SSChuckolaMembershipCard), "Nuts", world.player
|
||||||
|
) # Bandaid Fix
|
||||||
|
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.HoohooVillageHammerHouseBlock),
|
||||||
|
lambda state: StateLogic.hammers(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.HoohooMountainBaseBoostatueRoomBlock2),
|
||||||
|
lambda state: StateLogic.canCrash(state, world.player) or StateLogic.super(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.BeanbeanOutskirtsBooStatueMole),
|
||||||
|
lambda state: StateLogic.canMini(state, world.player) and StateLogic.canDig(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.HoohooVillageSuperHammerCaveBlock),
|
||||||
|
lambda state: StateLogic.canCrash(state, world.player) or StateLogic.super(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.BeanbeanOutskirtsFarmRoomMoleReward1),
|
||||||
|
lambda state: StateLogic.thunder(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.BeanbeanOutskirtsFarmRoomMoleReward2),
|
||||||
|
lambda state: StateLogic.thunder(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.BeanbeanOutskirtsThunderHandMole),
|
||||||
|
lambda state: StateLogic.thunder(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.BeanbeanOutskirtsNWBlock),
|
||||||
|
lambda state: StateLogic.super(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.BeanbeanOutskirtsBeanFruit1),
|
||||||
|
lambda state: StateLogic.canDig(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.BeanbeanOutskirtsBeanFruit2),
|
||||||
|
lambda state: StateLogic.canDig(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.BeanbeanOutskirtsBeanFruit3),
|
||||||
|
lambda state: StateLogic.canDig(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.BeanbeanOutskirtsBeanFruit4),
|
||||||
|
lambda state: StateLogic.super(state, world.player) and StateLogic.canDig(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.BeanbeanOutskirtsBeanFruit5),
|
||||||
|
lambda state: StateLogic.super(state, world.player) and StateLogic.canDig(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.BeanbeanOutskirtsBeanFruit6),
|
||||||
|
lambda state: StateLogic.canDig(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.BeanbeanOutskirtsBeanFruit7),
|
||||||
|
lambda state: StateLogic.teehee(state, world.player) and StateLogic.canDig(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.BeanbeanOutskirtsSRoom1Block),
|
||||||
|
lambda state: StateLogic.ultra(state, world.player) and StateLogic.thunder(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.BeanbeanOutskirtsSRoom2Block1),
|
||||||
|
lambda state: StateLogic.canDig(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.WoohooHooniversityMiniMarioPuzzleSecretAreaBlock1),
|
||||||
|
lambda state: StateLogic.canMini(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.WoohooHooniversityMiniMarioPuzzleSecretAreaBlock2),
|
||||||
|
lambda state: StateLogic.canMini(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.WoohooHooniversityMiniMarioPuzzleSecretAreaBlock3),
|
||||||
|
lambda state: StateLogic.canMini(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.WoohooHooniversityMiniMarioPuzzleSecretAreaBlock4),
|
||||||
|
lambda state: StateLogic.canMini(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.WoohooHooniversityMiniMarioPuzzleBlock),
|
||||||
|
lambda state: StateLogic.canMini(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.BeanbeanOutskirtsSecretScroll1),
|
||||||
|
lambda state: StateLogic.thunder(state, world.player) and StateLogic.super(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.BeanbeanOutskirtsSecretScroll2),
|
||||||
|
lambda state: StateLogic.thunder(state, world.player) and StateLogic.ultra(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.HoohooVillageMoleBehindTurtle),
|
||||||
|
lambda state: StateLogic.canDash(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.BeanbeanOutskirtsNESoloMarioMole1),
|
||||||
|
lambda state: StateLogic.canMini(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.BeanbeanOutskirtsNESoloMarioMole2),
|
||||||
|
lambda state: StateLogic.canMini(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.BeanbeanOutskirtsSuperHammerUpgrade),
|
||||||
|
lambda state: StateLogic.thunder(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.BeanbeanOutskirtsUltraHammerUpgrade),
|
||||||
|
lambda state: StateLogic.thunder(state, world.player)
|
||||||
|
and StateLogic.pieces(state, world.player)
|
||||||
|
and StateLogic.castleTown(state, world.player)
|
||||||
|
and StateLogic.rose(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.BeanbeanOutskirtsSoloLuigiCaveMole),
|
||||||
|
lambda state: StateLogic.canDig(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.ChucklehuckWoodsRedChuckolaFruit),
|
||||||
|
lambda state: StateLogic.canMini(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.ChucklehuckWoodsWhiteChuckolaFruit),
|
||||||
|
lambda state: StateLogic.canDig(state, world.player) and StateLogic.canMini(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.ChucklehuckWoodsAfterChucklerootBlock1),
|
||||||
|
lambda state: StateLogic.fruits(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.ChucklehuckWoodsAfterChucklerootBlock2),
|
||||||
|
lambda state: StateLogic.fruits(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.ChucklehuckWoodsAfterChucklerootBlock3),
|
||||||
|
lambda state: StateLogic.fruits(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.ChucklehuckWoodsAfterChucklerootBlock4),
|
||||||
|
lambda state: StateLogic.fruits(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.ChucklehuckWoodsAfterChucklerootBlock5),
|
||||||
|
lambda state: StateLogic.fruits(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.ChucklehuckWoodsAfterChucklerootBlock6),
|
||||||
|
lambda state: StateLogic.fruits(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.ChucklehuckWoodsRoom7Block1),
|
||||||
|
lambda state: StateLogic.hammers(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.ChucklehuckWoodsRoom7Block2),
|
||||||
|
lambda state: StateLogic.hammers(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.ChucklehuckWoodsRoom4Block1),
|
||||||
|
lambda state: StateLogic.canMini(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.ChucklehuckWoodsRoom4Block2),
|
||||||
|
lambda state: StateLogic.canMini(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.ChucklehuckWoodsRoom4Block3),
|
||||||
|
lambda state: StateLogic.canMini(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.ChucklehuckWoodsPipeRoomBlock1),
|
||||||
|
lambda state: StateLogic.hammers(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.ChucklehuckWoodsPipeRoomBlock2),
|
||||||
|
lambda state: StateLogic.hammers(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.BeanbeanCastleTownMiniMarioBlock1),
|
||||||
|
lambda state: StateLogic.canMini(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.BeanbeanCastleTownMiniMarioBlock2),
|
||||||
|
lambda state: StateLogic.canMini(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.BeanbeanCastleTownMiniMarioBlock3),
|
||||||
|
lambda state: StateLogic.canMini(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.BeanbeanCastleTownMiniMarioBlock4),
|
||||||
|
lambda state: StateLogic.canMini(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.BeanbeanCastleTownMiniMarioBlock5),
|
||||||
|
lambda state: StateLogic.canMini(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.BeanbeanCastleFakeBeastar),
|
||||||
|
lambda state: StateLogic.pieces(state, world.player) and StateLogic.rose(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.BeanbeanCastlePeachsExtraDress),
|
||||||
|
lambda state: StateLogic.pieces(state, world.player) and StateLogic.rose(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.SewersRoom5Block1),
|
||||||
|
lambda state: StateLogic.hammers(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.SewersRoom5Block2),
|
||||||
|
lambda state: StateLogic.hammers(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.GwarharLagoonFirstUnderwaterAreaRoom1Block),
|
||||||
|
lambda state: StateLogic.canDash(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.GwarharLagoonFirstUnderwaterAreaRoom2Block1),
|
||||||
|
lambda state: StateLogic.canDash(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.GwarharLagoonFirstUnderwaterAreaRoom2Block2),
|
||||||
|
lambda state: StateLogic.canDash(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.GwarharLagoonRedPearlBean),
|
||||||
|
lambda state: StateLogic.fire(state, world.player) and StateLogic.thunder(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.GwarharLagoonGreenPearlBean),
|
||||||
|
lambda state: StateLogic.fire(state, world.player) and StateLogic.thunder(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.TeeheeValleyPastUltraHammersBlock1),
|
||||||
|
lambda state: StateLogic.ultra(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.TeeheeValleyPastUltraHammersBlock2),
|
||||||
|
lambda state: StateLogic.ultra(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.TeeheeValleySoloLuigiMazeRoom1Block),
|
||||||
|
lambda state: StateLogic.ultra(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.OhoOasisFirebrand),
|
||||||
|
lambda state: StateLogic.canMini(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.OhoOasisThunderhand),
|
||||||
|
lambda state: StateLogic.canDig(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.BeanstarPieceYoshiTheater),
|
||||||
|
lambda state: StateLogic.neon(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.YoshiTheaterAzureYoshi),
|
||||||
|
lambda state: StateLogic.beanFruit(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.YoshiTheaterBlueYoshi),
|
||||||
|
lambda state: StateLogic.beanFruit(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.YoshiTheaterGreenYoshi),
|
||||||
|
lambda state: StateLogic.beanFruit(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.YoshiTheaterOrangeYoshi),
|
||||||
|
lambda state: StateLogic.beanFruit(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.YoshiTheaterPurpleYoshi),
|
||||||
|
lambda state: StateLogic.beanFruit(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.YoshiTheaterRedYoshi),
|
||||||
|
lambda state: StateLogic.beanFruit(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.YoshiTheaterYellowYoshi),
|
||||||
|
lambda state: StateLogic.beanFruit(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.WinkleAreaBeanstarRoomBlock),
|
||||||
|
lambda state: StateLogic.winkle(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.BeanstarPieceWinkleArea),
|
||||||
|
lambda state: StateLogic.winkle(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.GwarharLagoonSpangleReward),
|
||||||
|
lambda state: StateLogic.spangle(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.PantsShopMomPiranhaFlag1),
|
||||||
|
lambda state: StateLogic.brooch(state, world.player) or StateLogic.rose(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.PantsShopMomPiranhaFlag2),
|
||||||
|
lambda state: StateLogic.brooch(state, world.player) or StateLogic.rose(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.PantsShopMomPiranhaFlag3),
|
||||||
|
lambda state: StateLogic.brooch(state, world.player) or StateLogic.rose(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.BadgeShopMomPiranhaFlag1),
|
||||||
|
lambda state: StateLogic.brooch(state, world.player) or StateLogic.rose(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.BadgeShopMomPiranhaFlag2),
|
||||||
|
lambda state: StateLogic.brooch(state, world.player) or StateLogic.rose(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.BadgeShopMomPiranhaFlag3),
|
||||||
|
lambda state: StateLogic.brooch(state, world.player) or StateLogic.rose(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.ChateauGreenGoblet),
|
||||||
|
lambda state: StateLogic.brooch(state, world.player) and StateLogic.canDig(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.ChateauRedGoblet),
|
||||||
|
lambda state: StateLogic.brooch(state, world.player) and StateLogic.canMini(state, world.player),
|
||||||
|
)
|
||||||
|
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.GwarharLagoonSpangle),
|
||||||
|
lambda state: StateLogic.ultra(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.GwarharLagoonSpangleRoomBlock),
|
||||||
|
lambda state: StateLogic.ultra(state, world.player),
|
||||||
|
)
|
||||||
|
if world.options.difficult_logic:
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.GwarharLagoonSpangleReward),
|
||||||
|
lambda state: StateLogic.canCrash(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.BeanstarPieceHermie),
|
||||||
|
lambda state: StateLogic.canCrash(state, world.player),
|
||||||
|
)
|
||||||
|
if world.options.chuckle_beans != 0:
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.GwarharLagoonPastHermieDigspot),
|
||||||
|
lambda state: StateLogic.canCrash(state, world.player),
|
||||||
|
)
|
||||||
|
|
||||||
|
if world.options.coins:
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.HoohooMountainBaseBooStatueCaveCoinBlock1),
|
||||||
|
lambda state: StateLogic.canCrash(state, world.player) or StateLogic.super(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.HoohooMountainBaseBooStatueCaveCoinBlock2),
|
||||||
|
lambda state: StateLogic.canCrash(state, world.player) or StateLogic.super(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.HoohooMountainBaseBooStatueCaveCoinBlock3),
|
||||||
|
lambda state: StateLogic.canCrash(state, world.player) or StateLogic.super(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.BeanbeanOutskirtsNWCoinBlock),
|
||||||
|
lambda state: StateLogic.super(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.BeanbeanOutskirtsSRoom1CoinBlock),
|
||||||
|
lambda state: StateLogic.ultra(state, world.player) and StateLogic.thunder(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.BeanbeanOutskirtsSRoom2CoinBlock),
|
||||||
|
lambda state: StateLogic.canCrash(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.ChateauPoppleRoomCoinBlock1),
|
||||||
|
lambda state: StateLogic.brooch(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.ChateauPoppleRoomCoinBlock2),
|
||||||
|
lambda state: StateLogic.brooch(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.ChucklehuckWoodsCaveRoom1CoinBlock),
|
||||||
|
lambda state: StateLogic.brooch(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.ChucklehuckWoodsCaveRoom2CoinBlock),
|
||||||
|
lambda state: StateLogic.brooch(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.ChucklehuckWoodsCaveRoom3CoinBlock),
|
||||||
|
lambda state: StateLogic.brooch(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.ChucklehuckWoodsPipe5RoomCoinBlock),
|
||||||
|
lambda state: StateLogic.brooch(state, world.player) and StateLogic.hammers(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.ChucklehuckWoodsRoom7CoinBlock),
|
||||||
|
lambda state: StateLogic.brooch(state, world.player) and StateLogic.hammers(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.ChucklehuckWoodsAfterChucklerootCoinBlock),
|
||||||
|
lambda state: StateLogic.brooch(state, world.player) and StateLogic.fruits(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.ChucklehuckWoodsKoopaRoomCoinBlock),
|
||||||
|
lambda state: StateLogic.brooch(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.ChucklehuckWoodsWinkleAreaCaveCoinBlock),
|
||||||
|
lambda state: StateLogic.brooch(state, world.player) and StateLogic.canDash(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.SewersPrisonRoomCoinBlock),
|
||||||
|
lambda state: StateLogic.rose(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.TeeheeValleyPastUltraHammerRocksCoinBlock),
|
||||||
|
lambda state: StateLogic.ultra(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.SSChuckolaStorageRoomCoinBlock1),
|
||||||
|
lambda state: StateLogic.super(state, world.player) or StateLogic.canDash(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.SSChuckolaStorageRoomCoinBlock2),
|
||||||
|
lambda state: StateLogic.super(state, world.player) or StateLogic.canDash(state, world.player),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.GwarharLagoonFirstUnderwaterAreaRoom2CoinBlock),
|
||||||
|
lambda state: StateLogic.canDash(state, world.player)
|
||||||
|
and (StateLogic.membership(state, world.player) or StateLogic.surfable(state, world.player)),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.JokesEndSecondFloorWestRoomCoinBlock),
|
||||||
|
lambda state: StateLogic.ultra(state, world.player)
|
||||||
|
and StateLogic.fire(state, world.player)
|
||||||
|
and (
|
||||||
|
StateLogic.membership(state, world.player)
|
||||||
|
or (StateLogic.canDig(state, world.player) and StateLogic.canMini(state, world.player))
|
||||||
|
),
|
||||||
|
)
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.JokesEndNorthofBridgeRoomCoinBlock),
|
||||||
|
lambda state: StateLogic.ultra(state, world.player)
|
||||||
|
and StateLogic.fire(state, world.player)
|
||||||
|
and StateLogic.canDig(state, world.player)
|
||||||
|
and (StateLogic.membership(state, world.player) or StateLogic.canMini(state, world.player)),
|
||||||
|
)
|
||||||
|
if not world.options.difficult_logic:
|
||||||
|
add_rule(
|
||||||
|
world.get_location(LocationName.JokesEndNorthofBridgeRoomCoinBlock),
|
||||||
|
lambda state: StateLogic.canCrash(state, world.player),
|
||||||
|
)
|
|
@ -0,0 +1,155 @@
|
||||||
|
def canDig(state, player):
|
||||||
|
return state.has("Green Goblet", player) and state.has("Hammers", player)
|
||||||
|
|
||||||
|
|
||||||
|
def canMini(state, player):
|
||||||
|
return state.has("Red Goblet", player) and state.has("Hammers", player)
|
||||||
|
|
||||||
|
|
||||||
|
def canDash(state, player):
|
||||||
|
return state.has("Red Pearl Bean", player) and state.has("Firebrand", player)
|
||||||
|
|
||||||
|
|
||||||
|
def canCrash(state, player):
|
||||||
|
return state.has("Green Pearl Bean", player) and state.has("Thunderhand", player)
|
||||||
|
|
||||||
|
|
||||||
|
def hammers(state, player):
|
||||||
|
return state.has("Hammers", player)
|
||||||
|
|
||||||
|
|
||||||
|
def super(state, player):
|
||||||
|
return state.has("Hammers", player, 2)
|
||||||
|
|
||||||
|
|
||||||
|
def ultra(state, player):
|
||||||
|
return state.has("Hammers", player, 3)
|
||||||
|
|
||||||
|
|
||||||
|
def fruits(state, player):
|
||||||
|
return (
|
||||||
|
state.has("Red Chuckola Fruit", player)
|
||||||
|
and state.has("Purple Chuckola Fruit", player)
|
||||||
|
and state.has("White Chuckola Fruit", player)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def pieces(state, player):
|
||||||
|
return (
|
||||||
|
state.has("Beanstar Piece 1", player)
|
||||||
|
and state.has("Beanstar Piece 2", player)
|
||||||
|
and state.has("Beanstar Piece 3", player)
|
||||||
|
and state.has("Beanstar Piece 4", player)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def neon(state, player):
|
||||||
|
return (
|
||||||
|
state.has("Blue Neon Egg", player)
|
||||||
|
and state.has("Red Neon Egg", player)
|
||||||
|
and state.has("Green Neon Egg", player)
|
||||||
|
and state.has("Yellow Neon Egg", player)
|
||||||
|
and state.has("Purple Neon Egg", player)
|
||||||
|
and state.has("Orange Neon Egg", player)
|
||||||
|
and state.has("Azure Neon Egg", player)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def spangle(state, player):
|
||||||
|
return state.has("Spangle", player)
|
||||||
|
|
||||||
|
|
||||||
|
def rose(state, player):
|
||||||
|
return state.has("Peasley's Rose", player)
|
||||||
|
|
||||||
|
|
||||||
|
def brooch(state, player):
|
||||||
|
return state.has("Beanbean Brooch", player)
|
||||||
|
|
||||||
|
|
||||||
|
def thunder(state, player):
|
||||||
|
return state.has("Thunderhand", player)
|
||||||
|
|
||||||
|
|
||||||
|
def fire(state, player):
|
||||||
|
return state.has("Firebrand", player)
|
||||||
|
|
||||||
|
|
||||||
|
def dressBeanstar(state, player):
|
||||||
|
return state.has("Peach's Extra Dress", player) and state.has("Fake Beanstar", player)
|
||||||
|
|
||||||
|
|
||||||
|
def membership(state, player):
|
||||||
|
return state.has("Membership Card", player)
|
||||||
|
|
||||||
|
|
||||||
|
def winkle(state, player):
|
||||||
|
return state.has("Winkle Card", player)
|
||||||
|
|
||||||
|
|
||||||
|
def beanFruit(state, player):
|
||||||
|
return (
|
||||||
|
state.has("Bean Fruit 1", player)
|
||||||
|
and state.has("Bean Fruit 2", player)
|
||||||
|
and state.has("Bean Fruit 3", player)
|
||||||
|
and state.has("Bean Fruit 4", player)
|
||||||
|
and state.has("Bean Fruit 5", player)
|
||||||
|
and state.has("Bean Fruit 6", player)
|
||||||
|
and state.has("Bean Fruit 7", player)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def surfable(state, player):
|
||||||
|
return ultra(state, player) and (
|
||||||
|
(canDig(state, player) and canMini(state, player)) or (membership(state, player) and fire(state, player))
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def postJokes(state, player):
|
||||||
|
return (
|
||||||
|
surfable(state, player)
|
||||||
|
and canDig(state, player)
|
||||||
|
and dressBeanstar(state, player)
|
||||||
|
and pieces(state, player)
|
||||||
|
and fruits(state, player)
|
||||||
|
and brooch(state, player)
|
||||||
|
and rose(state, player)
|
||||||
|
and canDash(state, player)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def teehee(state, player):
|
||||||
|
return super(state, player) or canDash(state, player)
|
||||||
|
|
||||||
|
|
||||||
|
def castleTown(state, player):
|
||||||
|
return fruits(state, player) and brooch(state, player)
|
||||||
|
|
||||||
|
|
||||||
|
def fungitown(state, player):
|
||||||
|
return (
|
||||||
|
castleTown(state, player)
|
||||||
|
and thunder(state, player)
|
||||||
|
and rose(state, player)
|
||||||
|
and (super(state, player) or canDash(state, player))
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def piranha_shop(state, player):
|
||||||
|
return state.can_reach("Shop Mom Piranha Flag", "Region", player)
|
||||||
|
|
||||||
|
|
||||||
|
def fungitown_shop(state, player):
|
||||||
|
return state.can_reach("Shop Enter Fungitown Flag", "Region", player)
|
||||||
|
|
||||||
|
|
||||||
|
def star_shop(state, player):
|
||||||
|
return state.can_reach("Shop Beanstar Complete Flag", "Region", player)
|
||||||
|
|
||||||
|
|
||||||
|
def birdo_shop(state, player):
|
||||||
|
return state.can_reach("Shop Birdo Flag", "Region", player)
|
||||||
|
|
||||||
|
|
||||||
|
def fungitown_birdo_shop(state, player):
|
||||||
|
return state.can_reach("Fungitown Shop Birdo Flag", "Region", player)
|
|
@ -0,0 +1,183 @@
|
||||||
|
import os
|
||||||
|
import pkgutil
|
||||||
|
import typing
|
||||||
|
import settings
|
||||||
|
from BaseClasses import Tutorial, ItemClassification
|
||||||
|
from worlds.AutoWorld import WebWorld, World
|
||||||
|
from typing import List, Dict, Any
|
||||||
|
from .Locations import all_locations, location_table, bowsers, bowsersMini, hidden, coins
|
||||||
|
from .Options import MLSSOptions
|
||||||
|
from .Items import MLSSItem, itemList, item_frequencies, item_table
|
||||||
|
from .Names.LocationName import LocationName
|
||||||
|
from .Client import MLSSClient
|
||||||
|
from .Regions import create_regions, connect_regions
|
||||||
|
from .Rom import MLSSProcedurePatch, write_tokens
|
||||||
|
from .Rules import set_rules
|
||||||
|
|
||||||
|
|
||||||
|
class MLSSWebWorld(WebWorld):
|
||||||
|
theme = "partyTime"
|
||||||
|
bug_report_page = "https://github.com/jamesbrq/ArchipelagoMLSS/issues"
|
||||||
|
tutorials = [
|
||||||
|
Tutorial(
|
||||||
|
tutorial_name="Setup Guide",
|
||||||
|
description="A guide to setting up Mario & Luigi: Superstar Saga for Archipelago.",
|
||||||
|
language="English",
|
||||||
|
file_name="setup_en.md",
|
||||||
|
link="setup/en",
|
||||||
|
authors=["jamesbrq"],
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class MLSSSettings(settings.Group):
|
||||||
|
class RomFile(settings.UserFilePath):
|
||||||
|
"""File name of the MLSS US rom"""
|
||||||
|
|
||||||
|
copy_to = "Mario & Luigi - Superstar Saga (U).gba"
|
||||||
|
description = "MLSS ROM File"
|
||||||
|
md5s = ["4b1a5897d89d9e74ec7f630eefdfd435"]
|
||||||
|
|
||||||
|
rom_file: RomFile = RomFile(RomFile.copy_to)
|
||||||
|
rom_start: bool = True
|
||||||
|
|
||||||
|
|
||||||
|
class MLSSWorld(World):
|
||||||
|
"""
|
||||||
|
Adventure with Mario and Luigi together in the Beanbean Kingdom
|
||||||
|
to stop the evil Cackletta and retrieve the Beanstar.
|
||||||
|
"""
|
||||||
|
|
||||||
|
game = "Mario & Luigi Superstar Saga"
|
||||||
|
web = MLSSWebWorld()
|
||||||
|
options_dataclass = MLSSOptions
|
||||||
|
options: MLSSOptions
|
||||||
|
settings: typing.ClassVar[MLSSSettings]
|
||||||
|
item_name_to_id = {name: data.code for name, data in item_table.items()}
|
||||||
|
location_name_to_id = {loc_data.name: loc_data.id for loc_data in all_locations}
|
||||||
|
required_client_version = (0, 4, 5)
|
||||||
|
|
||||||
|
disabled_locations: List[str]
|
||||||
|
|
||||||
|
def generate_early(self) -> None:
|
||||||
|
self.disabled_locations = []
|
||||||
|
if self.options.chuckle_beans == 0:
|
||||||
|
self.disabled_locations += [location.name for location in all_locations if "Digspot" in location.name]
|
||||||
|
if self.options.castle_skip:
|
||||||
|
self.disabled_locations += [location.name for location in all_locations if "Bowser" in location.name]
|
||||||
|
if self.options.chuckle_beans == 1:
|
||||||
|
self.disabled_locations = [location.name for location in all_locations if location.id in hidden]
|
||||||
|
if self.options.skip_minecart:
|
||||||
|
self.disabled_locations += [LocationName.HoohooMountainBaseMinecartCaveDigspot]
|
||||||
|
if self.options.disable_surf:
|
||||||
|
self.disabled_locations += [LocationName.SurfMinigame]
|
||||||
|
if self.options.harhalls_pants:
|
||||||
|
self.disabled_locations += [LocationName.HarhallsPants]
|
||||||
|
if not self.options.coins:
|
||||||
|
self.disabled_locations += [location.name for location in all_locations if location in coins]
|
||||||
|
|
||||||
|
def create_regions(self) -> None:
|
||||||
|
create_regions(self, self.disabled_locations)
|
||||||
|
connect_regions(self)
|
||||||
|
|
||||||
|
item = self.create_item("Mushroom")
|
||||||
|
self.get_location(LocationName.ShopStartingFlag1).place_locked_item(item)
|
||||||
|
item = self.create_item("Syrup")
|
||||||
|
self.get_location(LocationName.ShopStartingFlag2).place_locked_item(item)
|
||||||
|
item = self.create_item("1-UP Mushroom")
|
||||||
|
self.get_location(LocationName.ShopStartingFlag3).place_locked_item(item)
|
||||||
|
item = self.create_item("Hoo Bean")
|
||||||
|
self.get_location(LocationName.PantsShopStartingFlag1).place_locked_item(item)
|
||||||
|
item = self.create_item("Chuckle Bean")
|
||||||
|
self.get_location(LocationName.PantsShopStartingFlag2).place_locked_item(item)
|
||||||
|
|
||||||
|
def fill_slot_data(self) -> Dict[str, Any]:
|
||||||
|
return {
|
||||||
|
"CastleSkip": self.options.castle_skip.value,
|
||||||
|
"SkipMinecart": self.options.skip_minecart.value,
|
||||||
|
"DisableSurf": self.options.disable_surf.value,
|
||||||
|
"HarhallsPants": self.options.harhalls_pants.value,
|
||||||
|
"ChuckleBeans": self.options.chuckle_beans.value,
|
||||||
|
"DifficultLogic": self.options.difficult_logic.value,
|
||||||
|
"Coins": self.options.coins.value,
|
||||||
|
}
|
||||||
|
|
||||||
|
def create_items(self) -> None:
|
||||||
|
# First add in all progression and useful items
|
||||||
|
required_items = []
|
||||||
|
precollected = [item for item in itemList if item in self.multiworld.precollected_items]
|
||||||
|
for item in itemList:
|
||||||
|
if item.classification != ItemClassification.filler and item.classification != ItemClassification.skip_balancing:
|
||||||
|
freq = item_frequencies.get(item.itemName, 1)
|
||||||
|
if item in precollected:
|
||||||
|
freq = max(freq - precollected.count(item), 0)
|
||||||
|
if self.options.harhalls_pants and "Harhall's" in item.itemName:
|
||||||
|
continue
|
||||||
|
required_items += [item.itemName for _ in range(freq)]
|
||||||
|
|
||||||
|
for itemName in required_items:
|
||||||
|
self.multiworld.itempool.append(self.create_item(itemName))
|
||||||
|
|
||||||
|
# Then, create our list of filler items
|
||||||
|
filler_items = []
|
||||||
|
for item in itemList:
|
||||||
|
if item.classification != ItemClassification.filler:
|
||||||
|
continue
|
||||||
|
if item.itemName == "5 Coins" and not self.options.coins:
|
||||||
|
continue
|
||||||
|
freq = item_frequencies.get(item.itemName, 1)
|
||||||
|
if self.options.chuckle_beans == 0:
|
||||||
|
if item.itemName == "Chuckle Bean":
|
||||||
|
continue
|
||||||
|
if self.options.chuckle_beans == 1:
|
||||||
|
if item.itemName == "Chuckle Bean":
|
||||||
|
freq -= 59
|
||||||
|
filler_items += [item.itemName for _ in range(freq)]
|
||||||
|
|
||||||
|
# And finally take as many fillers as we need to have the same amount of items and locations.
|
||||||
|
remaining = len(all_locations) - len(required_items) - 5
|
||||||
|
if self.options.castle_skip:
|
||||||
|
remaining -= len(bowsers) + len(bowsersMini) - (5 if self.options.chuckle_beans == 0 else 0)
|
||||||
|
if self.options.skip_minecart and self.options.chuckle_beans == 2:
|
||||||
|
remaining -= 1
|
||||||
|
if self.options.disable_surf:
|
||||||
|
remaining -= 1
|
||||||
|
if self.options.harhalls_pants:
|
||||||
|
remaining -= 1
|
||||||
|
if self.options.chuckle_beans == 0:
|
||||||
|
remaining -= 192
|
||||||
|
if self.options.chuckle_beans == 1:
|
||||||
|
remaining -= 59
|
||||||
|
if not self.options.coins:
|
||||||
|
remaining -= len(coins)
|
||||||
|
|
||||||
|
self.multiworld.itempool += [
|
||||||
|
self.create_item(filler_item_name) for filler_item_name in self.random.sample(filler_items, remaining)
|
||||||
|
]
|
||||||
|
|
||||||
|
def set_rules(self) -> None:
|
||||||
|
set_rules(self, self.disabled_locations)
|
||||||
|
if self.options.castle_skip:
|
||||||
|
self.multiworld.completion_condition[self.player] = lambda state: state.can_reach(
|
||||||
|
"PostJokes", "Region", self.player
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
self.multiworld.completion_condition[self.player] = lambda state: state.can_reach(
|
||||||
|
"Bowser's Castle Mini", "Region", self.player
|
||||||
|
)
|
||||||
|
|
||||||
|
def create_item(self, name: str) -> MLSSItem:
|
||||||
|
item = item_table[name]
|
||||||
|
return MLSSItem(item.itemName, item.classification, item.code, self.player)
|
||||||
|
|
||||||
|
def get_filler_item_name(self) -> str:
|
||||||
|
return self.random.choice(list(filter(lambda item: item.classification == ItemClassification.filler, itemList)))
|
||||||
|
|
||||||
|
def generate_output(self, output_directory: str) -> None:
|
||||||
|
patch = MLSSProcedurePatch(player=self.player, player_name=self.multiworld.player_name[self.player])
|
||||||
|
patch.write_file("base_patch.bsdiff4", pkgutil.get_data(__name__, "data/basepatch.bsdiff"))
|
||||||
|
write_tokens(self, patch)
|
||||||
|
rom_path = os.path.join(
|
||||||
|
output_directory, f"{self.multiworld.get_out_file_name_base(self.player)}" f"{patch.patch_file_ending}"
|
||||||
|
)
|
||||||
|
patch.write(rom_path)
|
Binary file not shown.
|
@ -0,0 +1,66 @@
|
||||||
|
# Mario & Luigi: Superstar Saga
|
||||||
|
|
||||||
|
## Where is the options 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?
|
||||||
|
|
||||||
|
Items which the player would normally acquire throughout the game have been moved around. Logic remains, so the game is
|
||||||
|
always able to be completed, but because of the item shuffle, the player may need to access certain areas before they
|
||||||
|
would in the vanilla game.
|
||||||
|
|
||||||
|
The game has been changed to an open-world style as opposed to the linear style the vanilla game has.
|
||||||
|
|
||||||
|
Other Features such as Turbo through textboxes (Hold L/R+A) and Pipe Warping from any room (Hold L+R+SELECT) have been added for convenience.
|
||||||
|
|
||||||
|
Enemies and Bosses can be randomized, and their stats can be scaled to feel more like the vanilla game's stats.
|
||||||
|
|
||||||
|
Other aspects of the game can be randomized as well such as music, sounds, battle backgrounds, Mario and Luigi's Colors, and more.
|
||||||
|
|
||||||
|
## What is the goal of Mario & Luigi: Superstar Saga when randomized?
|
||||||
|
|
||||||
|
Defeat Cackletta's Soul in Bowser's Castle. This requires you to collect all 4 Beanstar Pieces, restore the Beanstar, and bring Peach's Extra Dress and the Fake Beanstar to Fawful at the end of Jokes End.
|
||||||
|
|
||||||
|
In total, this requires:
|
||||||
|
- 4 Beanstar Pieces
|
||||||
|
- Peach's Extra Dress
|
||||||
|
- Fake Beanstar
|
||||||
|
- Ultra Hammers
|
||||||
|
- Fire Hand
|
||||||
|
- Thunder Hand
|
||||||
|
- Red Pearl Bean
|
||||||
|
- Green Pearl Bean
|
||||||
|
- Green Goblet
|
||||||
|
- Peasley's Rose
|
||||||
|
- Beanbean Brooch
|
||||||
|
- All 3 Chuckola Fruits
|
||||||
|
- Membership Card OR Red Goblet
|
||||||
|
|
||||||
|
## What items and locations can get shuffled?
|
||||||
|
|
||||||
|
Locations in which items can be found:
|
||||||
|
- All Item Blocks and Coin Blocks
|
||||||
|
- All Chuckle Bean Digspots
|
||||||
|
- All Shop items
|
||||||
|
- All Pants and Badge shop items
|
||||||
|
- All Espresso brews and rewards
|
||||||
|
- All Minigame Rewards
|
||||||
|
- All Event based items
|
||||||
|
|
||||||
|
Items that can be shuffled:
|
||||||
|
- All consumable items (Mushrooms, Nuts, Syrups etc.)
|
||||||
|
- All Hoo Beans and Chuckle Beans
|
||||||
|
- All Badges and Pants
|
||||||
|
- All key items (Beanfruits, Beanbean Brooch, Hammers etc.)
|
||||||
|
- All Extra Gears (Great Force, Gameboy Horror SP etc.)
|
||||||
|
|
||||||
|
## What does another world's item look like in Mario & Luigi: Superstar Saga?
|
||||||
|
|
||||||
|
Items will show up as a Golden Mushroom from boxes and Digspots and "AP Item" in all textboxes.
|
||||||
|
Items in a shop from another player's world will display the player name and item name in addition to being displayed as an AP Item.
|
||||||
|
|
||||||
|
## When the player receives an item, what happens?
|
||||||
|
|
||||||
|
Items will be placed directly into the players inventory after a few seconds. Sometimes for certain events and cutscenes to be properly triggered right after you received an item, you may have to leave and re-enter the room to properly load everything required for the respective event or cutscene.
|
|
@ -0,0 +1,53 @@
|
||||||
|
# Setup Guide for Mario & Luigi: Superstar Saga Archipelago
|
||||||
|
|
||||||
|
## Important
|
||||||
|
|
||||||
|
As we are using Bizhawk, this guide is only applicable to Windows and Linux systems.
|
||||||
|
|
||||||
|
## Required Software
|
||||||
|
|
||||||
|
- Bizhawk: [Bizhawk Releases from TASVideos](https://tasvideos.org/BizHawk/ReleaseHistory)
|
||||||
|
- Version 2.9.1 is recommended.
|
||||||
|
- Detailed installation instructions for Bizhawk can be found at the above link.
|
||||||
|
- Windows users must run the prerequisite installer first, which can also be found at the above link.
|
||||||
|
- The built-in Bizhawk client, which can be installed [here](https://github.com/ArchipelagoMW/Archipelago/releases)
|
||||||
|
- A US copy of Mario & Luigi: Superstar Saga
|
||||||
|
|
||||||
|
## Optional Software
|
||||||
|
|
||||||
|
- [Poptracker](https://github.com/black-sliver/PopTracker/releases)
|
||||||
|
- [MLSS Autotracker](https://github.com/seto10987/MLSS-PopTracker/releases)
|
||||||
|
|
||||||
|
## Configuring your YAML file
|
||||||
|
|
||||||
|
### What is a YAML file and why do I need one?
|
||||||
|
|
||||||
|
Your YAML file contains a set of configuration options which provide the generator with information about how it should
|
||||||
|
generate your game. Each player of a multiworld will provide their own YAML file. This setup allows each player to enjoy
|
||||||
|
an experience customized for their taste, and different players in the same multiworld can all have different options.
|
||||||
|
|
||||||
|
### Where do I get a YAML file?
|
||||||
|
|
||||||
|
You can customize your options by visiting the
|
||||||
|
[Mario & Luigi Superstar Saga Options Page](/games/Mario%20&%20Luigi%20Superstar%20Saga/player-options)
|
||||||
|
|
||||||
|
## Joining a MultiWorld Game
|
||||||
|
|
||||||
|
### Obtain your GBA patch file
|
||||||
|
|
||||||
|
When you join a multiworld game, you will be asked to provide your YAML file to whoever is hosting. Once that is done,
|
||||||
|
the host will provide you with either a link to download your data file, or with a zip file containing everyone's data
|
||||||
|
files. Your data file should have a `.apmlss` extension.
|
||||||
|
|
||||||
|
Double-click on your `.apmlss` file to start your client and start the ROM patch process. Once the process is finished, the client and the emulator will be started automatically (if you associated the extension
|
||||||
|
to the emulator as recommended).
|
||||||
|
|
||||||
|
### Connect to the Multiserver
|
||||||
|
|
||||||
|
Once both the client and the emulator are started, you must connect them. Within the emulator click on the "Tools"
|
||||||
|
menu and select "Lua Console". Click the folder button or press Ctrl+O to open a Lua script.
|
||||||
|
|
||||||
|
Navigate to your Archipelago install folder and open `data/lua/connector_bizhawk_generic.lua`.
|
||||||
|
|
||||||
|
To connect the client to the multiserver simply put `<address>:<port>` on the textfield on top and press enter (if the
|
||||||
|
server uses password, type in the bottom textfield `/connect <address>:<port> [password]`)
|
Loading…
Reference in New Issue