Files
dockipelago/worlds/k64/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

247 lines
6.6 KiB
Python

import random
from dataclasses import dataclass
from Options import DeathLinkMixin, Choice, Toggle, OptionDict, OptionSet, Range, PlandoBosses, DefaultOnToggle, \
PerGameCommonOptions, Visibility, StartInventoryPool, PlandoConnections
from .names import LocationName
class K64PlandoConnections(PlandoConnections):
display_name = "Plando Connections"
entrances = [f"{level} {i}"
for idx, level in LocationName.level_names.items()
for i in range(LocationName.level_max[idx])]
exits = entrances
class GoalSpeed(Choice):
"""
Normal: the goal is unlocked after defeating the 6 bosses
Fast: the goal is unlocked after acquiring the target number of Crystal Shards
"""
display_name = "Goal Speed"
option_normal = 0
option_fast = 1
class SplitPowerCombos(Toggle):
"""
If enabled, Power Combos are added to the pool as separate items, and must be unlocked separate from
its base abilities.
"""
display_name = "Split Power Combos"
class MaxCrystalShards(Range):
"""
Maximum number of crystal shards to include in the pool of items.
"""
display_name = "Max Crystal Shards"
range_start = 5 # set to 5 so strict bosses does not degrade
range_end = 72 # 72 default locations, let's not push our luck
default = 30
class CrystalShardsRequired(Range):
"""
Percentage of crystal shards required to unlock the boss of Ripple Star, and grant access to Zero-Two.
"""
display_name = "Required Crystal Shards"
range_start = 1
range_end = 100
default = 50
class LevelShuffle(Choice):
"""
None: No stage shuffling.
Same World: shuffles stages around their world.
Shuffled: shuffles stages across all worlds.
"""
display_name = "Stage Shuffle"
option_none = 0
option_same_world = 1
option_shuffled = 2
default = 0
class BossShuffle(PlandoBosses):
"""
None: Bosses will remain in their vanilla locations
Shuffled: Bosses will be shuffled amongst each other
Full: Bosses will be randomized
Singularity: All (non-Zero-Two) bosses will be replaced with a single boss
Supports plando placement.
"""
bosses = frozenset(LocationName.boss_names.keys())
locations = frozenset(LocationName.level_names_inverse.keys())
duplicate_bosses = True
@classmethod
def can_place_boss(cls, boss: str, location: str) -> bool:
# Kirby has no logic about requiring bosses in specific locations (since we load in their stage)
return True
display_name = "Boss Shuffle"
option_none = 0
option_shuffled = 1
option_full = 2
option_singularity = 3
class BossRequirementRandom(Toggle):
"""
If enabled, unlocking a boss will require a random amount of Crystal Shards, up to a certain amount per level.
"""
display_name = "Randomize Boss Unlock Requirement"
class Consumables(OptionSet):
"""
Which type of pickups should become checks.
Options are 1-Ups, Food, and Stars.
All of Adeleine's gifts are considered food.
The large stars that replace Crystals are not considered checks.
"""
display_name = "Consumables"
valid_keys = {"1-Ups", "Food", "Stars"}
default = frozenset({})
class FillerPercentage(Range):
"""
Percentage of non-required Crystal Shards to be converted to filler items (1-Ups, Maxim Tomatoes, Invincibility Candy).
"""
display_name = "Filler Percentage"
range_start = 0
range_end = 100
default = 50
class KirbyFlavorPreset(Choice):
"""
The color of Kirby, from a list of presets.
"""
display_name = "Kirby Flavor"
option_default = 0
option_bubblegum = 1
option_cherry = 2
option_blueberry = 3
option_lemon = 4
option_kiwi = 5
option_grape = 6
option_chocolate = 7
option_marshmallow = 8
option_licorice = 9
option_watermelon = 10
option_orange = 11
option_lime = 12
option_kusamochi = 16
option_citrus = 23
option_wafer = 24
option_ice = 25
option_cream = 26
option_snowcone = 31
option_cotton_candy = 48
option_chocomint = 49
option_cheeseburger = 50
option_rose = 27
option_daisy = 28
option_lavender = 29
option_lilac = 13
option_blue_poppy = 32
option_fuschia = 47
option_canary = 22
option_carbon = 17
option_snow = 18
option_ivory = 21
option_chalk = 44
option_sapphire = 19
option_emerald = 20
option_gameboy = 45
option_nostalgic = 15
option_halloween = 43
option_bright = 30
option_ocean = 42
option_miku = 14
option_rin = 51
option_len = 52
option_luka = 53
option_meiko = 54
option_kaito = 55
option_mirror = 46
option_dedede = 33
option_waddle_dee = 34
option_susie = 35
option_mogeko = 36
option_link = 37
option_callie = 38
option_marie = 39
option_pearl = 40
option_marina = 41
option_custom = -1
default = 0
@classmethod
def get_option_name(cls, value: int) -> str:
if value in (cls.option_meiko, cls.option_kaito):
return cls.name_lookup[value].upper()
return super().get_option_name(value)
@classmethod
def from_text(cls, text: str) -> Choice:
text = text.lower()
if text == "random":
choice_list = list(cls.name_lookup)
choice_list.remove(-1)
return cls(random.choice(choice_list))
return super().from_text(text)
class KirbyFlavor(OptionDict):
"""
A custom color for Kirby. To use a custom color, set the preset to Custom and then define a dict of keys from "1" to
"17", with their values being an HTML hex color.
"""
default = {
"1": "#080000",
"2": "#F64A5A",
"3": "#6A4152",
"4": "#F6F6F6",
"5": "#F7A5B5",
"6": "#E66A62",
"7": "#00085A",
"8": "#EE8BA4",
"9": "#733141",
"10": "#D5D5D5",
"11": "#312029",
"12": "#8B949C",
"13": "#0000D5",
"14": "#8B626A",
"15": "#BD838B",
"16": "#FF6946",
"17": "#FF2600",
}
visibility = Visibility.complex_ui | Visibility.template
@dataclass
class K64Options(PerGameCommonOptions, DeathLinkMixin):
start_inventory_from_pool: StartInventoryPool
plando_connections: PlandoConnections
goal_speed: GoalSpeed
split_power_combos: SplitPowerCombos
stage_shuffle: LevelShuffle
# boss_shuffle: BossShuffle
boss_requirement_random: BossRequirementRandom
max_crystals: MaxCrystalShards
required_crystals: CrystalShardsRequired
consumables: Consumables
filler_percentage: FillerPercentage
kirby_flavor_preset: KirbyFlavorPreset
kirby_flavor: KirbyFlavor