Files
dockipelago/worlds/mk64/Options.py
Jonathan Tinney 7971961166
Some checks failed
Analyze modified files / flake8 (push) Failing after 2m28s
Build / build-win (push) Has been cancelled
Build / build-ubuntu2204 (push) Has been cancelled
ctest / Test C++ ubuntu-latest (push) Has been cancelled
ctest / Test C++ windows-latest (push) Has been cancelled
Analyze modified files / mypy (push) Has been cancelled
Build and Publish Docker Images / Push Docker image to Docker Hub (push) Successful in 5m4s
Native Code Static Analysis / scan-build (push) Failing after 5m2s
type check / pyright (push) Successful in 1m7s
unittests / Test Python 3.11.2 ubuntu-latest (push) Failing after 16m23s
unittests / Test Python 3.12 ubuntu-latest (push) Failing after 28m19s
unittests / Test Python 3.13 ubuntu-latest (push) Failing after 14m49s
unittests / Test hosting with 3.13 on ubuntu-latest (push) Successful in 5m0s
unittests / Test Python 3.13 macos-latest (push) Has been cancelled
unittests / Test Python 3.11 windows-latest (push) Has been cancelled
unittests / Test Python 3.13 windows-latest (push) Has been cancelled
add schedule I, sonic 1/frontiers/heroes, spirit island
2026-04-02 23:46:36 -07:00

288 lines
11 KiB
Python

from typing import TYPE_CHECKING
from dataclasses import dataclass
from . import Locations
from Options import Choice, DefaultOnToggle, Toggle, Range, OptionList, StartInventoryPool, PerGameCommonOptions
if TYPE_CHECKING:
from . import MK64World
class TwoPlayer(Toggle):
"""(NOT YET SUPPORTED)
Start with two characters unlocked and shuffle a separate Player 2 set of item powers into the item pool.
This is the intended way to do local multiplayer, but you can still access the 2-player grand prix mode
with this off, and the 1-player grand prix mode with it on."""
display_name = "Two Player Couch Co-op"
class GameMode(Choice):
"""Determines how to advance through the game. Cups is closest to the vanilla game.
Cups: Courses are raced in sets of four, place 4th or better to advance each race. Unlock each cup progressively.
The Cups victory condition is beating the Special Cup on 150cc.
Courses (NOT YET SUPPORTED): Each course is run individually. Unlock the final courses progressively to reach the
final race. The Courses victory condition is winning 1st place on the last course."""
display_name = "Game Mode"
option_cups = 0
option_courses = 1
default = 0
class LogicDifficulty(Choice):
"""Scales the logic threshhold where skill is involved. Specifically, how many good items are available before you
are expected to be able to qualify and win on tough courses.
Basic: Makes sure you have plenty of good items early. For easier play, or skipping 50 cc.
(Basic is more likely to fail generation. To raise chances try increasing shuffle_item_box_clusters and
minimum_filler_items. Future versions will be less fragile to generation failure.)
Advanced: Balanced runs for a competent karter.
Expert: Low logic, high randomness, high skill. Few good items may be available early in the run.
No Logic: If fences are enabled, THE RUN MAY BE NEAR IMPOSSIBLE!"""
display_name = "Logic Difficulty"
option_basic = 6
option_advanced = 3
option_expert = 0
option_no_logic = -100
default = 6
class LockedCourses(Range):
"""(NOT YET SUPPORTED)
In Courses Game Mode, how many final courses are locked until Progressive Course Unlock items are found."""
display_name = "Locked Courses"
range_start = 0
range_end = 15
default = 4
class CourseOrder(Choice):
"""The order for the courses to be arranged in."""
display_name = "Course Order"
option_vanilla = 0
option_shuffle = 1
option_short_to_long = 2
option_long_to_short = 3
option_alphabetical = 4
default = 1
class FinalCoursePool(OptionList):
"""When Course Order is set to shuffle, the final course will be chosen from the Final Course Pool.
Leaving this blank will allow any course to come last.
For Rainbow Road to come last use: ["Rainbow Road"].
For Bowser's Castle to come last use: ["Bowser's Castle"].
For any course longer than 1000 meters to come last use: ["Rainbow Road", "Wario Stadium", "Toad's Turnpike"]."""
display_name = "Final Course Pool"
valid_keys = frozenset({course_name.casefold() for course_name in Locations.course_locations.keys()})
valid_keys_casefold = True
class MirrorCourseChance(Range):
"""(NOT YET SUPPORTED) Percent chance for a course to be mirrored."""
display_name = "Mirror Course Chance"
range_start = 0
range_end = 100
default = 0
class TwoLapCourses(Choice):
"""Reduce the number of laps in a race from 3 to 2 on long courses."""
display_name = "Two Lap Courses"
option_off = 0
option_rainbow_road = 1
option_wario_stadium = 2
option_rainbow_road_and_wario_stadium = 3
default = 0
class HazardLocations(DefaultOnToggle):
"""Whether to include hazards which can be destroyed or defeated by the star power as location checks."""
display_name = "Add Hazard Locations"
class SecretLocations(DefaultOnToggle):
"""Whether to add 10 location checks as item pickups in noteworthy locations on certain courses."""
display_name = "Add Course Secret Locations"
class ShuffleDriftAbilities(Choice):
"""Optionally shuffle into the item pool the ability to drift and the ability to use mini-turbos as progressive
unlocks per kart. "Plentiful" shuffles a 3rd progressive unlock into the pool. "Free Drift" means karts start
with the ability to drift. "Free mini-turbo" means both abilities will be obtained together."""
display_name = "Shuffle Drift Abilities"
option_off = 0
option_on = 1
option_plentiful = 2
option_free_drift = 3
option_free_mini_turbo = 4
alias_vanilla = 0
alias_shuffle = 0
alias_false = 0
alias_on = 1
alias_yes = 1
alias_true = 1
default = 1
class TractionTires(DefaultOnToggle):
"""Optionally shuffle into the item pool the ability to have traction on off-road and winter surface types,
per kart. "Off" means karts always have traction, as in the vanilla game."""
display_name = "Add Traction Tires"
class StartingItems(DefaultOnToggle):
"""Optionally shuffle into the item pool a random item power to start each race with, per kart. For example
Mario may be able to start each race with a blue shell. Which item is random per kart."""
display_name = "Add Starting Items"
class ShuffleRailings(DefaultOnToggle):
"""Whether to shuffle most track railings into the item pool."""
display_name = "Shuffle Railings"
class Fences(DefaultOnToggle):
"""Adds colored fences to every course to add variety to the player's racing lines, and blocks about 20% of
item boxes. Also adds Yellow/Red/Green/Blue Switch items to the item pool which disable that color of fences.
Fences only affect player karts; shells and CPU karts path through them."""
display_name = "Fences Block Paths"
class FeatherItem(DefaultOnToggle):
"""Adds the feather item as seen in Super Mario Kart and the early demos of Mario Kart 64. It can be used to vault
fences. Having access to the feather puts locations blocked by fences in logic."""
display_name = "Feather Item"
class ShuffleItemBoxRespawning(Toggle):
"""Causes item boxes to not respawn mid-race, and shuffles one "item box respawning" item into the item pool."""
display_name = "Shuffle Item Box Respawning"
class ConsistentItemBoxes(Choice):
"""Make each item box always give the same item. "On" will always show which item will be given instead of a
question mark (?) inside the item boxes. "Identify" will only show which item will be given after triggering the
item roulette once."""
display_name = "Consistent Item Boxes"
option_off = 0
option_on = 1
option_identify = 2
default = 0
class ShuffleSpecialItemBoxes(DefaultOnToggle):
"""Whether to shuffle the special item boxes which always give blue shells into the item pool. One is attached to
the hot air balloon on Luigi Raceway, and the other is on the big rock on Koopa Troopa Beach."""
display_name = "Shuffle Special Item Boxes"
class ShuffleItemBoxClusters(Range):
"""How many item box clusters to shuffle into the item pool. At least one item spot from each shuffled cluster will
be used as a location check.
(More shuffled clusters helps generation succeed. Future versions will be less fragile to generation failure.)"""
display_name = "Shuffle Item Box Clusters"
range_start = 0
range_end = 72
default = 36
class FillerTrapPercentage(Range):
"""What percentage of filler items will be traps."""
display_name = "Filler Trap Percentage"
range_start = 0
range_end = 100
default = 20
class MinimumFillerItems(Range):
"""Force more filler items than needed to match the number of locations.
(More filler items helps generation succeed. Future versions will be less fragile to generation failure.)"""
display_name = "Minimum Filler Items"
range_start = 0
range_end = 40
default = 30
class FixResultsMusic(DefaultOnToggle):
"""Fixes the race win results screen music so the first section repeats 2 times, not 64 times.
The official soundtrack uses this AABB form."""
display_name = "Fix Winning Results Music"
class SoundMode(Choice): # TODO: Add support for this
"""(NOT YET SUPPORTED)
Sets the sound mode in the game's option menu ahead of time."""
display_name = "Sound Mode"
option_stereo = 0
option_headphones = 1
option_mono = 2
default = 0
# Options as they will appear in YAML settings
@dataclass
class MK64Options(PerGameCommonOptions):
start_inventory_from_pool: StartInventoryPool
two_player: TwoPlayer
game_mode: GameMode
locked_courses: LockedCourses
course_order: CourseOrder
logic_difficulty: LogicDifficulty
final_course_pool: FinalCoursePool
mirror_course_chance: MirrorCourseChance
two_lap_courses: TwoLapCourses
hazard_locations: HazardLocations
secret_locations: SecretLocations
shuffle_drift_abilities: ShuffleDriftAbilities
add_traction_tires: TractionTires
add_starting_items: StartingItems
shuffle_railings: ShuffleRailings
fences: Fences
feather_item: FeatherItem
shuffle_item_box_respawning: ShuffleItemBoxRespawning
consistent_item_boxes: ConsistentItemBoxes
shuffle_special_item_boxes: ShuffleSpecialItemBoxes
shuffle_item_box_clusters: ShuffleItemBoxClusters
filler_trap_percentage: FillerTrapPercentage
minimum_filler_items: MinimumFillerItems
fix_results_music: FixResultsMusic
sound_mode: SoundMode
# Used for shorthand/faster access to relevant options during world generation
class Opt:
def __init__(self, world: "MK64World"):
# Relevant Options
self.two_player = world.options.two_player.value
self.mode = world.options.game_mode.value
self.course_order = world.options.course_order.value
self.locked_courses = world.options.locked_courses.value
self.logic = world.options.logic_difficulty.value
self.final_pool = world.options.final_course_pool.value
self.mirror_chance = world.options.mirror_course_chance.value
self.two_lap_courses = world.options.two_lap_courses.value
self.hazards = world.options.hazard_locations.value
self.secrets = world.options.secret_locations.value
self.drift = world.options.shuffle_drift_abilities.value
self.traction = world.options.add_traction_tires.value
self.starting_items = world.options.add_starting_items.value
self.railings = world.options.shuffle_railings.value
self.fences = world.options.fences.value
self.feather = world.options.feather_item.value
self.box_respawning = world.options.shuffle_item_box_respawning.value
self.consistent = world.options.consistent_item_boxes.value
self.special_boxes = world.options.shuffle_special_item_boxes.value
self.clusters = world.options.shuffle_item_box_clusters.value
self.trap_percentage = world.options.filler_trap_percentage.value
self.min_filler = world.options.minimum_filler_items.value
self.fix_music = world.options.fix_results_music.value