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 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"
@ -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"
@ -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"
@ -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
@ -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"
@ -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"
@ -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"
@ -148,6 +170,7 @@ 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"
@ -155,9 +178,10 @@ class ExcludeSpecialZone(Toggle):
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"
@ -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"
@ -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"
@ -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"
@ -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"
@ -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"
@ -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

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
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.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 .Rules import set_rules
class SMWSettings(settings.Group):
@ -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):
"""