SMW: Option Groups and Presets (#3345)

* SMW: Add Option Groups and Presets

* Fix Boss Shuffle Preset

* Tooltip formatting
This commit is contained in:
PoryGone 2024-05-21 18:09:05 -04:00 committed by GitHub
parent 9441cc31b7
commit 62e68ba1cc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 160 additions and 13 deletions

View File

@ -1,12 +1,14 @@
from dataclasses import dataclass 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): class Goal(Choice):
""" """
Determines the goal of the seed Determines the goal of the seed
Bowser: Defeat Koopalings, reach Bowser's Castle and defeat Bowser Bowser: Defeat Koopalings, reach Bowser's Castle and defeat Bowser
Yoshi Egg Hunt: Find a certain number of Yoshi Eggs Yoshi Egg Hunt: Find a certain number of Yoshi Eggs
""" """
display_name = "Goal" display_name = "Goal"
@ -28,7 +30,9 @@ class BossesRequired(Range):
class NumberOfYoshiEggs(Range): class NumberOfYoshiEggs(Range):
""" """
Maximum possible number of Yoshi Eggs that will be in the item pool 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. 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. Required Percentage of Yoshi Eggs will be calculated based off of that number.
""" """
display_name = "Max Number of Yoshi Eggs" display_name = "Max Number of Yoshi Eggs"
@ -64,7 +68,9 @@ class MoonChecks(Toggle):
class Hidden1UpChecks(Toggle): class Hidden1UpChecks(Toggle):
""" """
Whether collecting a hidden 1-Up mushroom in a level will grant a check 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 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 Enable this option at your own risk
""" """
display_name = "Hidden 1-Up Checks" display_name = "Hidden 1-Up Checks"
@ -80,7 +86,9 @@ class BonusBlockChecks(Toggle):
class Blocksanity(Toggle): class Blocksanity(Toggle):
""" """
Whether hitting a block with an item or coin inside will grant a check 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! Note that some blocks are excluded due to how the option and the game works!
Exclusion list: Exclusion list:
* Blocks in Top Secret Area & Front Door/Bowser Castle * Blocks in Top Secret Area & Front Door/Bowser Castle
* Blocks that are unreachable unless you glitch your way in * Blocks that are unreachable unless you glitch your way in
@ -91,10 +99,15 @@ class Blocksanity(Toggle):
class BowserCastleDoors(Choice): class BowserCastleDoors(Choice):
""" """
How the doors of Bowser's Castle behave How the doors of Bowser's Castle behave
Vanilla: Front and Back Doors behave as vanilla Vanilla: Front and Back Doors behave as vanilla
Fast: Both doors behave as the Back Door Fast: Both doors behave as the Back Door
Slow: Both doors behave as the Front Door Slow: Both doors behave as the Front Door
"Front Door" rooms depend on the `bowser_castle_rooms` option "Front Door" rooms depend on the `bowser_castle_rooms` option
"Back Door" only requires going through the dark hallway to Bowser "Back Door" only requires going through the dark hallway to Bowser
""" """
display_name = "Bowser Castle Doors" display_name = "Bowser Castle Doors"
@ -107,10 +120,15 @@ class BowserCastleDoors(Choice):
class BowserCastleRooms(Choice): class BowserCastleRooms(Choice):
""" """
How the rooms of Bowser's Castle Front Door behave How the rooms of Bowser's Castle Front Door behave
Vanilla: You can choose which rooms to enter, as in vanilla Vanilla: You can choose which rooms to enter, as in vanilla
Random Two Room: Two random rooms are chosen Random Two Room: Two random rooms are chosen
Random Five Room: Five random rooms are chosen Random Five Room: Five random rooms are chosen
Gauntlet: All eight rooms must be cleared Gauntlet: All eight rooms must be cleared
Labyrinth: Which room leads to Bowser? Labyrinth: Which room leads to Bowser?
""" """
display_name = "Bowser Castle Rooms" display_name = "Bowser Castle Rooms"
@ -125,9 +143,13 @@ class BowserCastleRooms(Choice):
class BossShuffle(Choice): class BossShuffle(Choice):
""" """
How bosses are shuffled How bosses are shuffled
None: Bosses are not shuffled None: Bosses are not shuffled
Simple: Four Reznors and the seven Koopalings are shuffled around Simple: Four Reznors and the seven Koopalings are shuffled around
Full: Each boss location gets a fully random boss Full: Each boss location gets a fully random boss
Singularity: One or two bosses are chosen and placed at every boss location Singularity: One or two bosses are chosen and placed at every boss location
""" """
display_name = "Boss Shuffle" display_name = "Boss Shuffle"
@ -148,6 +170,7 @@ class LevelShuffle(Toggle):
class ExcludeSpecialZone(Toggle): class ExcludeSpecialZone(Toggle):
""" """
If active, this option will prevent any progression items from being placed in Special Zone levels. 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. Additionally, if Level Shuffle is active, Special Zone levels will not be shuffled away from their vanilla tiles.
""" """
display_name = "Exclude Special Zone" display_name = "Exclude Special Zone"
@ -155,9 +178,10 @@ class ExcludeSpecialZone(Toggle):
class SwapDonutGhostHouseExits(Toggle): class SwapDonutGhostHouseExits(Toggle):
""" """
If enabled, this option will swap which overworld direction the two exits of the level at the Donut Ghost House If enabled, this option will swap which overworld direction the two exits of the level at the Donut Ghost House overworld tile go:
overworld tile go:
False: Normal Exit goes up, Secret Exit goes right. False: Normal Exit goes up, Secret Exit goes right.
True: Normal Exit goes right, Secret Exit goes up. True: Normal Exit goes right, Secret Exit goes up.
""" """
display_name = "Swap Donut GH Exits" display_name = "Swap Donut GH Exits"
@ -258,6 +282,7 @@ class Autosave(DefaultOnToggle):
class EarlyClimb(Toggle): class EarlyClimb(Toggle):
""" """
Force Climb to appear early in the seed as a local item. Force Climb to appear early in the seed as a local item.
This is particularly useful to prevent BK when Level Shuffle is disabled This is particularly useful to prevent BK when Level Shuffle is disabled
""" """
display_name = "Early Climb" display_name = "Early Climb"
@ -277,9 +302,13 @@ class OverworldSpeed(Choice):
class MusicShuffle(Choice): class MusicShuffle(Choice):
""" """
Music shuffle type Music shuffle type
None: No Music is shuffled None: No Music is shuffled
Consistent: Each music track is consistently shuffled throughout the game Consistent: Each music track is consistently shuffled throughout the game
Full: Each individual level has a random music track Full: Each individual level has a random music track
Singularity: The entire game uses one song for overworld and one song for levels Singularity: The entire game uses one song for overworld and one song for levels
""" """
display_name = "Music Shuffle" display_name = "Music Shuffle"
@ -293,9 +322,13 @@ class MusicShuffle(Choice):
class SFXShuffle(Choice): class SFXShuffle(Choice):
""" """
Shuffles almost every instance of sound effect playback Shuffles almost every instance of sound effect playback
Archipelago elements that play sound effects aren't randomized Archipelago elements that play sound effects aren't randomized
None: No SFX are shuffled None: No SFX are shuffled
Full: Each individual SFX call has a random SFX Full: Each individual SFX call has a random SFX
Singularity: The entire game uses one SFX for every SFX call Singularity: The entire game uses one SFX for every SFX call
""" """
display_name = "Sound Effect Shuffle" display_name = "Sound Effect Shuffle"
@ -324,8 +357,11 @@ class MarioPalette(Choice):
class LevelPaletteShuffle(Choice): class LevelPaletteShuffle(Choice):
""" """
Whether to shuffle level palettes Whether to shuffle level palettes
Off: Do not shuffle palettes Off: Do not shuffle palettes
On Legacy: Uses only the palette sets from the original game On Legacy: Uses only the palette sets from the original game
On Curated: Uses custom, hand-crafted palette sets On Curated: Uses custom, hand-crafted palette sets
""" """
display_name = "Level Palette Shuffle" display_name = "Level Palette Shuffle"
@ -338,8 +374,11 @@ class LevelPaletteShuffle(Choice):
class OverworldPaletteShuffle(Choice): class OverworldPaletteShuffle(Choice):
""" """
Whether to shuffle overworld palettes Whether to shuffle overworld palettes
Off: Do not shuffle palettes Off: Do not shuffle palettes
On Legacy: Uses only the palette sets from the original game On Legacy: Uses only the palette sets from the original game
On Curated: Uses custom, hand-crafted palette sets On Curated: Uses custom, hand-crafted palette sets
""" """
display_name = "Overworld Palette Shuffle" display_name = "Overworld Palette Shuffle"
@ -359,6 +398,52 @@ class StartingLifeCount(Range):
default = 5 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 @dataclass
class SMWOptions(PerGameCommonOptions): class SMWOptions(PerGameCommonOptions):
death_link: DeathLink death_link: DeathLink

57
worlds/smw/Presets.py Normal file
View File

@ -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,
}

View File

@ -6,17 +6,19 @@ import settings
import threading import threading
from BaseClasses import Item, MultiWorld, Tutorial, ItemClassification from BaseClasses import Item, MultiWorld, Tutorial, ItemClassification
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 .Names import ItemName, LocationName
from .Client import SMWSNIClient
from worlds.AutoWorld import WebWorld, World 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 .Levels import full_level_list, generate_level_list, location_id_to_level_id
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 .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 .Rom import LocalRom, patch_rom, get_base_rom_path, SMWDeltaPatch
from .Rules import set_rules
class SMWSettings(settings.Group): class SMWSettings(settings.Group):
@ -43,6 +45,9 @@ class SMWWeb(WebWorld):
tutorials = [setup_en] tutorials = [setup_en]
option_groups = smw_option_groups
options_presets = smw_options_presets
class SMWWorld(World): class SMWWorld(World):
""" """