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
437 lines
12 KiB
Python
437 lines
12 KiB
Python
from dataclasses import dataclass
|
|
from Options import (
|
|
FreeText,
|
|
NumericOption,
|
|
Toggle,
|
|
DefaultOnToggle,
|
|
Choice,
|
|
TextChoice,
|
|
Range,
|
|
NamedRange,
|
|
OptionList,
|
|
PerGameCommonOptions,
|
|
OptionSet,
|
|
OptionCounter,
|
|
StartInventoryPool, OptionGroup, Visibility,
|
|
DeathLinkMixin,
|
|
)
|
|
|
|
class Goal(Choice):
|
|
"""
|
|
sleigh_ride: Sleigh parts are placed in their local areas that you must
|
|
physically collect them to goal.
|
|
sleigh_ride_with_parts: Sleigh parts are randomized in the pool that you
|
|
must find all the required parts and the Sleigh Room Key to goal.
|
|
missions_completed: You must complete a certain number of missions to
|
|
goal.
|
|
squashing_all_gifts: You must squash every gift in the entire game to goal.
|
|
supadows_completed: You are required to win every supadow minigame to
|
|
goal and obtain access to their minigames to do so.
|
|
slaughter: You must kill every Who, every animal, and every robot to goal.
|
|
"""
|
|
|
|
display_name = "Goal"
|
|
option_sleigh_ride = 0
|
|
option_sleigh_ride_with_parts = 1
|
|
option_missions_completed = 2
|
|
option_squashing_all_gifts = 3
|
|
option_supadows_completed = 4
|
|
option_slaughter = 5
|
|
default = 0
|
|
visibility = Visibility.none
|
|
|
|
|
|
class MissionsCompleted(Range):
|
|
"""
|
|
If your goal is missions_completed, set how many missions you want to
|
|
complete to goal. If your goal is missions_completed_with_gifts, this option
|
|
will be ignored.
|
|
"""
|
|
|
|
display_name = "Mission Goal Count"
|
|
range_start = 3
|
|
range_end = 22
|
|
default = 12
|
|
visibility = Visibility.none
|
|
|
|
# We will make a list of every mission in the game, excluding squashing gifts.
|
|
# Randomly pick whatever range is chosen via missions_completed to include
|
|
# in the location pool. If they include squashing all gifts, include those in the
|
|
# list.
|
|
class MissionCompletedIncludeGiftSquash(Toggle):
|
|
"""
|
|
If your goal is missions_completed, include the squashing all gift missions.
|
|
Otherwise, if your goal is not missions_completed, this will do nothing.
|
|
"""
|
|
display_name = "Include Gift Squashing in Missions Completed Goal"
|
|
visibility = Visibility.none
|
|
|
|
|
|
class StartingArea(Choice):
|
|
"""
|
|
Here, you can select which area you'll start the game with.
|
|
Whichever one you pick is the region you'll have access to at the start of the Multiworld.
|
|
If "progressive_vacuums" is enabled, this is not considered and will always start in Whoville.
|
|
"""
|
|
|
|
option_whoville = 0
|
|
option_who_forest = 1
|
|
option_who_dump = 2
|
|
option_who_lake = 3
|
|
default = 0
|
|
display_name = "Starting Area"
|
|
|
|
|
|
class ProgressiveVacuums(Toggle): # DefaultOnToggle
|
|
"""
|
|
Determines whether you get access to main areas progressively.
|
|
If enabled, you will receive Whoville, Who Forest, Who Dump, and Who Lake in that order.
|
|
"""
|
|
|
|
display_name = "Progressive Vacuum Tubes"
|
|
|
|
|
|
class Missionsanity(Choice):
|
|
"""
|
|
How mission checks are randomized in the pool.
|
|
- none: Does not add mission checks
|
|
- completion: Only completing the mission gives you a check
|
|
- individual: Individual tasks for one mission, such as individual snowmen
|
|
squashed, are checks.
|
|
- both: Both individual tasks and mission completion are randomized.
|
|
"""
|
|
|
|
display_name = "Mission Locations"
|
|
option_none = 0
|
|
option_completion = 1
|
|
option_individual = 2
|
|
option_both = 3
|
|
default = 1
|
|
|
|
class AdvancedLogic(Toggle):
|
|
|
|
"""
|
|
Enables logic to allow skips, damage boosts, glitches, game restarts,
|
|
excessive egg usage, and various other unintentional ways that beginners
|
|
wouldn't grasp on their first playthrough if this is enabled to be considered
|
|
logical.
|
|
"""
|
|
|
|
display_name = "Advanced Logic"
|
|
visibility = Visibility.none
|
|
|
|
class ExcludeEnvironments(OptionSet):
|
|
"""
|
|
Allows entire environments to be entirely removed to ensure you are not
|
|
logically required to enter the environment along with any and all checks
|
|
that are in that environment too.
|
|
|
|
Valid keys: "Post Office", "Clock Tower", "City Hall", "Ski Resort",
|
|
"Civic Center", "Minefield", "Power Plant", "Generator Building",
|
|
"Scout's Hut", "North Shore", "Mayor's Villa", "Submarine World"
|
|
"""
|
|
|
|
display_name = "Exclude Environments"
|
|
valid_keys = {
|
|
"Post Office",
|
|
"Clock Tower",
|
|
"City Hall",
|
|
"Ski Resort",
|
|
"Civic Center",
|
|
"Minefield",
|
|
"Power Plant",
|
|
"Generator Building",
|
|
"Scout's Hut",
|
|
"North Shore",
|
|
"Mayor's Villa",
|
|
"Submarine World",
|
|
}
|
|
|
|
|
|
class ProgressiveGadgets(Toggle): # DefaultOnToggle
|
|
"""
|
|
Determines whether you get access to a gadget as the individual blueprint count.
|
|
"""
|
|
|
|
display_name = "Progressive Gadgets"
|
|
visibility = Visibility.none
|
|
|
|
|
|
class Supadow(Toggle):
|
|
"""
|
|
Enables completing minigames through the Supadows in Mount Crumpit as checks.
|
|
"""
|
|
|
|
display_name = "Supadow Minigames"
|
|
visibility = Visibility.none
|
|
|
|
|
|
class Gifts(Toggle):
|
|
"""
|
|
Determines if individual gifts are checks
|
|
NOTE: This currently only disables the missions relating to squashing all
|
|
gifts for an entire region.
|
|
"""
|
|
|
|
display_name = "Giftsanity"
|
|
|
|
|
|
class Killsanity(OptionSet):
|
|
"""
|
|
Determines whether you consider killing/destroying certain enemies
|
|
throughout the games are checks.
|
|
|
|
"Whos" are considereed as people such as guards, children, and other
|
|
humanoid related figures.
|
|
"Animals" are considered as non-human species such as Summer beasts,
|
|
porcupines, moose, and mosquitoes.
|
|
"Robots" are considered mechanical beings that electrocute the player,
|
|
specifically the robots you find in Who Dump.
|
|
"""
|
|
|
|
display_name = "Killsanity"
|
|
valid_keys = {"Whos", "Animals", "Robots"}
|
|
visibility = Visibility.none
|
|
|
|
|
|
class Gadgetrando(DefaultOnToggle):
|
|
"""
|
|
Determines whether the Grinch's gadgets will be randomized or not.
|
|
"""
|
|
|
|
display_name = "Randomize Gadgets"
|
|
|
|
|
|
class Gadgetrandolist(OptionSet):
|
|
"""
|
|
If "gadget_rando" is enabled, gadgets that you add to the dictionary will
|
|
be randomized.
|
|
"""
|
|
|
|
display_name = "Gadgets Randomized"
|
|
default = [
|
|
"Binoculars",
|
|
"Rotten Egg Launcher",
|
|
"Rocket Spring",
|
|
"Slime Shooter",
|
|
"Octopus Climbing Device",
|
|
"Marine Mobile",
|
|
"Grinch Copter",
|
|
]
|
|
|
|
|
|
class ExcludeGC(Toggle):
|
|
"""
|
|
Tired of getting Grinch Copter? This option ensures Grinch Copter is
|
|
entirely taken out from the multiworld.
|
|
Note that locations that hard require Grinch Copter will also be removed.
|
|
"""
|
|
|
|
display_name = "Remove Grinch Copter"
|
|
|
|
|
|
class Moverando(Toggle):
|
|
"""
|
|
Determines whether the Grinch's moves will be randomized or not.
|
|
NOTE: Tutorial section would be logical linearly and vacuum tubes would still
|
|
be logical. To access them, you can use certain controller combinations to
|
|
warp to their respective areas in Mount Crumpit at any time.
|
|
To warp to the computer room, press and hold start, L1, and R1 at the same time.
|
|
To warp to the top, press and hold start, L2, and R2 at the same time.
|
|
"""
|
|
|
|
display_name = "Randomize Moves"
|
|
|
|
|
|
class Moverandolist(OptionSet):
|
|
"""
|
|
If "move_rando" is enabled, the Grinch's moves that you add to the dictionary will be randomized.
|
|
"""
|
|
|
|
display_name = "Moves Randomized"
|
|
default = [
|
|
"Pancake",
|
|
"Bad Breath",
|
|
"Seize",
|
|
"Max",
|
|
"Sneak",
|
|
]
|
|
|
|
|
|
class UnlimitedEggs(Toggle):
|
|
"""
|
|
Determine if you run out of rotten eggs when you utilize your gadgets.
|
|
NOTE: Attempting to enable this with ringlink will force generation to stop
|
|
until either option is disabled.
|
|
"""
|
|
|
|
display_name = "Unlimited Rotten Eggs"
|
|
|
|
|
|
class RingLinkOption(Toggle):
|
|
"""
|
|
Whenever this is toggled, your ammo is linked with other ringlink-compatible
|
|
games that also have this enabled.
|
|
NOTE: Attempting to enable this with unlimited_eggs will force generation
|
|
to stop until either option is enabled.
|
|
"""
|
|
|
|
display_name = "Ring Link"
|
|
|
|
|
|
class TrapLinkOption(Toggle):
|
|
"""
|
|
If a trap is sent from Grinch, traps that are compatible with other games
|
|
are triggered as well.
|
|
"""
|
|
|
|
display_name = "Trap Link"
|
|
visibility = Visibility.none
|
|
|
|
|
|
class FillerWeight(OptionCounter):
|
|
"""
|
|
Determines which filler is added to the pool.
|
|
"""
|
|
|
|
display_name = "Filler Weights"
|
|
# min = 0
|
|
# max = 100
|
|
default = {
|
|
"5 Rotten Eggs": 50,
|
|
"10 Rotten Eggs": 25,
|
|
"20 Rotten Eggs": 25,
|
|
}
|
|
|
|
|
|
class TrapPercentage(Range):
|
|
"""
|
|
Determines how much filler is replaced with traps.
|
|
"""
|
|
|
|
display_name = "Trap Percentage"
|
|
range_start = 0
|
|
range_end = 100
|
|
default = 10
|
|
|
|
|
|
class TrapWeight(OptionCounter):
|
|
"""
|
|
Determines which traps are replaced with filler in the pool.
|
|
"""
|
|
|
|
display_name = "Trap Weights"
|
|
# min = 0
|
|
# max = 100
|
|
default = {
|
|
"Dump it to Crumpit": 33,
|
|
"Who sent me back?": 33,
|
|
"Depletion Trap": 34,
|
|
}
|
|
|
|
class MiscLocations(Toggle):
|
|
"""
|
|
Adds locations that aren't specifically categorized and are either random
|
|
events or just unnecessarily added locations that don't mean anything.
|
|
"""
|
|
|
|
display_name = "Miscellaneous Locations"
|
|
|
|
|
|
class DamageRate(Range):
|
|
"""
|
|
How much damage can the Grinch tolerate before death
|
|
0 = Invincible
|
|
1 = Base game damage rate
|
|
78 = Instant death without any Hearts of Stone
|
|
88 = Instant death with one Heart of Stone
|
|
99 = Instant death with two Hearts of Stone
|
|
110 = Instant death with three Hearts of Stone
|
|
120 = Instant death
|
|
"""
|
|
|
|
display_name = "Damage Rate"
|
|
range_start = 0
|
|
range_end = 120
|
|
default = 1
|
|
visibility = Visibility.none
|
|
|
|
|
|
class MusicRando(Toggle):
|
|
"""
|
|
Randomizes all music in the game
|
|
"""
|
|
display_name = "Music Rando"
|
|
|
|
|
|
@dataclass
|
|
class GrinchOptions(DeathLinkMixin, PerGameCommonOptions):
|
|
progressive_vacuums: ProgressiveVacuums
|
|
starting_area: StartingArea
|
|
missionsanity: Missionsanity
|
|
exclude_environments: ExcludeEnvironments
|
|
giftsanity: Gifts
|
|
supadow_minigames: Supadow
|
|
killsanity: Killsanity
|
|
progressive_gadgets: ProgressiveGadgets
|
|
gadget_rando: Gadgetrando
|
|
gadgets_to_randomize: Gadgetrandolist
|
|
exclude_gc: ExcludeGC
|
|
move_rando: Moverando
|
|
moves_to_randomize: Moverandolist
|
|
unlimited_eggs: UnlimitedEggs
|
|
filler_weight: FillerWeight
|
|
trap_percentage: TrapPercentage
|
|
trap_weight: TrapWeight
|
|
ring_link: RingLinkOption
|
|
trap_link: TrapLinkOption
|
|
advanced_logic: AdvancedLogic
|
|
start_inventory_from_pool: StartInventoryPool
|
|
misc_checks: MiscLocations
|
|
damage_rate: DamageRate
|
|
goal: Goal
|
|
missions_completed: MissionsCompleted
|
|
include_gift_squash: MissionCompletedIncludeGiftSquash
|
|
music_rando: MusicRando
|
|
|
|
|
|
grinch_option_groups: list[OptionGroup] = [
|
|
# OptionGroup("Goal", [
|
|
# Goal,
|
|
# MissionsCompleted,
|
|
# MissionCompletedIncludeGiftSquash,
|
|
# ]),
|
|
OptionGroup("Item Pool", [
|
|
ProgressiveVacuums,
|
|
StartingArea,
|
|
ProgressiveGadgets,
|
|
Gadgetrando,
|
|
Gadgetrandolist,
|
|
ExcludeGC,
|
|
Moverando,
|
|
Moverandolist
|
|
]),
|
|
OptionGroup("Location Settings", [
|
|
Missionsanity,
|
|
ExcludeEnvironments,
|
|
Gifts,
|
|
Supadow,
|
|
Killsanity,
|
|
MiscLocations,
|
|
]),
|
|
# OptionGroup("Logic Settings", [
|
|
# AdvancedLogic,
|
|
# ]),
|
|
OptionGroup("In-Game Tweaks", [
|
|
UnlimitedEggs,
|
|
DamageRate,
|
|
MusicRando,
|
|
]),
|
|
OptionGroup("Filler/Trap Settings", [
|
|
FillerWeight,
|
|
TrapPercentage,
|
|
TrapWeight,
|
|
RingLinkOption,
|
|
TrapLinkOption,
|
|
]),
|
|
] |