Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SMW: Option Groups and Presets #3345

Merged
merged 5 commits into from
May 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 88 additions & 3 deletions worlds/smw/Options.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
from dataclasses import dataclass

from Options import Choice, Range, Toggle, DeathLink, DefaultOnToggle, PerGameCommonOptions
from Options import Choice, Range, Toggle, DeathLink, DefaultOnToggle, OptionGroup, PerGameCommonOptions


class Goal(Choice):
"""
Determines the goal of the seed

Bowser: Defeat Koopalings, reach Bowser's Castle and defeat Bowser

Yoshi Egg Hunt: Find a certain number of Yoshi Eggs
"""
display_name = "Goal"
Expand All @@ -28,7 +30,9 @@ class BossesRequired(Range):
class NumberOfYoshiEggs(Range):
"""
Maximum possible number of Yoshi Eggs that will be in the item pool

If fewer available locations exist in the pool than this number, the number of available locations will be used instead.

Required Percentage of Yoshi Eggs will be calculated based off of that number.
"""
display_name = "Max Number of Yoshi Eggs"
Expand Down Expand Up @@ -64,7 +68,9 @@ class MoonChecks(Toggle):
class Hidden1UpChecks(Toggle):
"""
Whether collecting a hidden 1-Up mushroom in a level will grant a check

These checks are considered cryptic as there's no actual indicator that they're in their respective places

Enable this option at your own risk
"""
display_name = "Hidden 1-Up Checks"
Expand All @@ -80,7 +86,9 @@ class BonusBlockChecks(Toggle):
class Blocksanity(Toggle):
"""
Whether hitting a block with an item or coin inside will grant a check

Note that some blocks are excluded due to how the option and the game works!

Exclusion list:
* Blocks in Top Secret Area & Front Door/Bowser Castle
* Blocks that are unreachable unless you glitch your way in
Expand All @@ -91,10 +99,15 @@ class Blocksanity(Toggle):
class BowserCastleDoors(Choice):
"""
How the doors of Bowser's Castle behave

Vanilla: Front and Back Doors behave as vanilla

Fast: Both doors behave as the Back Door

Slow: Both doors behave as the Front Door

"Front Door" rooms depend on the `bowser_castle_rooms` option

"Back Door" only requires going through the dark hallway to Bowser
"""
display_name = "Bowser Castle Doors"
Expand All @@ -107,10 +120,15 @@ class BowserCastleDoors(Choice):
class BowserCastleRooms(Choice):
"""
How the rooms of Bowser's Castle Front Door behave

Vanilla: You can choose which rooms to enter, as in vanilla

Random Two Room: Two random rooms are chosen

Random Five Room: Five random rooms are chosen

Gauntlet: All eight rooms must be cleared

Labyrinth: Which room leads to Bowser?
"""
display_name = "Bowser Castle Rooms"
Expand All @@ -125,9 +143,13 @@ class BowserCastleRooms(Choice):
class BossShuffle(Choice):
"""
How bosses are shuffled

None: Bosses are not shuffled

Simple: Four Reznors and the seven Koopalings are shuffled around

Full: Each boss location gets a fully random boss

Singularity: One or two bosses are chosen and placed at every boss location
"""
display_name = "Boss Shuffle"
Expand All @@ -148,16 +170,18 @@ class LevelShuffle(Toggle):
class ExcludeSpecialZone(Toggle):
"""
If active, this option will prevent any progression items from being placed in Special Zone levels.

Additionally, if Level Shuffle is active, Special Zone levels will not be shuffled away from their vanilla tiles.
"""
display_name = "Exclude Special Zone"


class SwapDonutGhostHouseExits(Toggle):
"""
If enabled, this option will swap which overworld direction the two exits of the level at the Donut Ghost House
overworld tile go:
If enabled, this option will swap which overworld direction the two exits of the level at the Donut Ghost House overworld tile go:

False: Normal Exit goes up, Secret Exit goes right.

True: Normal Exit goes right, Secret Exit goes up.
"""
display_name = "Swap Donut GH Exits"
Expand Down Expand Up @@ -258,6 +282,7 @@ class Autosave(DefaultOnToggle):
class EarlyClimb(Toggle):
"""
Force Climb to appear early in the seed as a local item.

This is particularly useful to prevent BK when Level Shuffle is disabled
"""
display_name = "Early Climb"
Expand All @@ -277,9 +302,13 @@ class OverworldSpeed(Choice):
class MusicShuffle(Choice):
"""
Music shuffle type

None: No Music is shuffled

Consistent: Each music track is consistently shuffled throughout the game

Full: Each individual level has a random music track

Singularity: The entire game uses one song for overworld and one song for levels
"""
display_name = "Music Shuffle"
Expand All @@ -293,9 +322,13 @@ class MusicShuffle(Choice):
class SFXShuffle(Choice):
"""
Shuffles almost every instance of sound effect playback

Archipelago elements that play sound effects aren't randomized

None: No SFX are shuffled

Full: Each individual SFX call has a random SFX

Singularity: The entire game uses one SFX for every SFX call
"""
display_name = "Sound Effect Shuffle"
Expand Down Expand Up @@ -324,8 +357,11 @@ class MarioPalette(Choice):
class LevelPaletteShuffle(Choice):
"""
Whether to shuffle level palettes

Off: Do not shuffle palettes

On Legacy: Uses only the palette sets from the original game

On Curated: Uses custom, hand-crafted palette sets
"""
display_name = "Level Palette Shuffle"
Expand All @@ -338,8 +374,11 @@ class LevelPaletteShuffle(Choice):
class OverworldPaletteShuffle(Choice):
"""
Whether to shuffle overworld palettes

Off: Do not shuffle palettes

On Legacy: Uses only the palette sets from the original game

On Curated: Uses custom, hand-crafted palette sets
"""
display_name = "Overworld Palette Shuffle"
Expand All @@ -359,6 +398,52 @@ class StartingLifeCount(Range):
default = 5


smw_option_groups = [
OptionGroup("Goal Options", [
Goal,
BossesRequired,
NumberOfYoshiEggs,
PercentageOfYoshiEggs,
]),
OptionGroup("Sanity Options", [
DragonCoinChecks,
MoonChecks,
Hidden1UpChecks,
BonusBlockChecks,
Blocksanity,
]),
OptionGroup("Level Shuffling", [
LevelShuffle,
ExcludeSpecialZone,
BowserCastleDoors,
BowserCastleRooms,
BossShuffle,
SwapDonutGhostHouseExits,
]),
OptionGroup("Junk and Traps", [
JunkFillPercentage,
TrapFillPercentage,
IceTrapWeight,
StunTrapWeight,
LiteratureTrapWeight,
TimerTrapWeight,
ReverseTrapWeight,
ThwimpTrapWeight,
]),
OptionGroup("Aesthetics", [
DisplayReceivedItemPopups,
Autosave,
OverworldSpeed,
MusicShuffle,
SFXShuffle,
MarioPalette,
LevelPaletteShuffle,
OverworldPaletteShuffle,
StartingLifeCount,
]),
]


@dataclass
class SMWOptions(PerGameCommonOptions):
death_link: DeathLink
Expand Down
57 changes: 57 additions & 0 deletions worlds/smw/Presets.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
from typing import Dict, Any

all_random = {
"goal": "random",
"bosses_required": "random",
"max_yoshi_egg_cap": "random",
"percentage_of_yoshi_eggs": "random",
"dragon_coin_checks": "random",
"moon_checks": "random",
"hidden_1up_checks": "random",
"bonus_block_checks": "random",
"blocksanity": "random",
"bowser_castle_doors": "random",
"bowser_castle_rooms": "random",
"level_shuffle": "random",
"exclude_special_zone": "random",
"boss_shuffle": "random",
"swap_donut_gh_exits": "random",
"display_received_item_popups": "random",
"junk_fill_percentage": "random",
"trap_fill_percentage": "random",
"ice_trap_weight": "random",
"stun_trap_weight": "random",
"literature_trap_weight": "random",
"timer_trap_weight": "random",
"reverse_trap_weight": "random",
"thwimp_trap_weight": "random",
"autosave": "random",
"early_climb": "random",
"overworld_speed": "random",
"music_shuffle": "random",
"sfx_shuffle": "random",
"mario_palette": "random",
"level_palette_shuffle": "random",
"overworld_palette_shuffle": "random",
"starting_life_count": "random",
}

allsanity = {
"dragon_coin_checks": True,
"moon_checks": True,
"hidden_1up_checks": True,
"bonus_block_checks": True,
"blocksanity": True,
"level_shuffle": True,
"boss_shuffle": "full",
"music_shuffle": "full",
"sfx_shuffle": "full",
"mario_palette": "random",
"level_palette_shuffle": "on_curated",
"overworld_palette_shuffle": "on_curated",
}

smw_options_presets: Dict[str, Dict[str, Any]] = {
"All Random": all_random,
"Allsanity": allsanity,
}
21 changes: 13 additions & 8 deletions worlds/smw/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,19 @@
import threading

from BaseClasses import Item, MultiWorld, Tutorial, ItemClassification
from worlds.AutoWorld import WebWorld, World
from worlds.generic.Rules import add_rule, exclusion_rules

from .Client import SMWSNIClient
from .Items import SMWItem, ItemData, item_table, junk_table
from .Locations import SMWLocation, all_locations, setup_locations, special_zone_level_names, special_zone_dragon_coin_names, special_zone_hidden_1up_names, special_zone_blocksanity_names
from .Options import SMWOptions
from .Regions import create_regions, connect_regions
from .Levels import full_level_list, generate_level_list, location_id_to_level_id
from .Rules import set_rules
from worlds.generic.Rules import add_rule, exclusion_rules
from .Locations import SMWLocation, all_locations, setup_locations, special_zone_level_names, special_zone_dragon_coin_names, special_zone_hidden_1up_names, special_zone_blocksanity_names
from .Names import ItemName, LocationName
from .Client import SMWSNIClient
from worlds.AutoWorld import WebWorld, World
from .Options import SMWOptions, smw_option_groups
from .Presets import smw_options_presets
from .Regions import create_regions, connect_regions
from .Rom import LocalRom, patch_rom, get_base_rom_path, SMWDeltaPatch
from .Rules import set_rules


class SMWSettings(settings.Group):
Expand All @@ -40,9 +42,12 @@ class SMWWeb(WebWorld):
"setup/en",
["PoryGone"]
)

tutorials = [setup_en]

option_groups = smw_option_groups
options_presets = smw_options_presets


class SMWWorld(World):
"""
Expand Down
Loading