forked from mirror/Archipelago
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
247 lines
6.6 KiB
Python
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
|