CV64: Add option groups (#3360)

* Add the option groups.

* Get rid of all mid-sentence line breaks.
This commit is contained in:
LiquidCat64 2024-05-22 18:16:13 -06:00 committed by GitHub
parent a43e294786
commit 56d01f3913
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 203 additions and 103 deletions

View File

@ -8,7 +8,7 @@ from BaseClasses import Item, Region, Tutorial, ItemClassification
from .items import CV64Item, filler_item_names, get_item_info, get_item_names_to_ids, get_item_counts
from .locations import CV64Location, get_location_info, verify_locations, get_location_names_to_ids, base_id
from .entrances import verify_entrances, get_warp_entrances
from .options import CV64Options, CharacterStages, DraculasCondition, SubWeaponShuffle
from .options import CV64Options, cv64_option_groups, CharacterStages, DraculasCondition, SubWeaponShuffle
from .stages import get_locations_from_stage, get_normal_stage_exits, vanilla_stage_order, \
shuffle_stages, generate_warps, get_region_names
from .regions import get_region_info
@ -45,6 +45,8 @@ class CV64Web(WebWorld):
["Liquid Cat"]
)]
option_groups = cv64_option_groups
class CV64World(World):
"""

View File

@ -1,10 +1,11 @@
from dataclasses import dataclass
from Options import Choice, DefaultOnToggle, Range, Toggle, PerGameCommonOptions, StartInventoryPool
from Options import OptionGroup, Choice, DefaultOnToggle, Range, Toggle, PerGameCommonOptions, StartInventoryPool
class CharacterStages(Choice):
"""Whether to include Reinhardt-only stages, Carrie-only stages, or both with or without branching paths at the end
of Villa and Castle Center."""
"""
Whether to include Reinhardt-only stages, Carrie-only stages, or both with or without branching paths at the end of Villa and Castle Center.
"""
display_name = "Character Stages"
option_both = 0
option_branchless_both = 1
@ -14,14 +15,18 @@ class CharacterStages(Choice):
class StageShuffle(Toggle):
"""Shuffles which stages appear in which stage slots. Villa and Castle Center will never appear in any character
stage slots if Character Stages is set to Both; they can only be somewhere on the main path.
Castle Keep will always be at the end of the line."""
"""
Shuffles which stages appear in which stage slots.
Villa and Castle Center will never appear in any character stage slots if Character Stages is set to Both; they can only be somewhere on the main path.
Castle Keep will always be at the end of the line.
"""
display_name = "Stage Shuffle"
class StartingStage(Choice):
"""Which stage to start at if Stage Shuffle is turned on."""
"""
Which stage to start at if Stage Shuffle is turned on.
"""
display_name = "Starting Stage"
option_forest_of_silence = 0
option_castle_wall = 1
@ -39,8 +44,9 @@ class StartingStage(Choice):
class WarpOrder(Choice):
"""Arranges the warps in the warp menu in whichever stage order chosen,
thereby changing the order they are unlocked in."""
"""
Arranges the warps in the warp menu in whichever stage order chosen, thereby changing the order they are unlocked in.
"""
display_name = "Warp Order"
option_seed_stage_order = 0
option_vanilla_stage_order = 1
@ -49,7 +55,9 @@ class WarpOrder(Choice):
class SubWeaponShuffle(Choice):
"""Shuffles all sub-weapons in the game within each other in their own pool or in the main item pool."""
"""
Shuffles all sub-weapons in the game within each other in their own pool or in the main item pool.
"""
display_name = "Sub-weapon Shuffle"
option_off = 0
option_own_pool = 1
@ -58,8 +66,10 @@ class SubWeaponShuffle(Choice):
class SpareKeys(Choice):
"""Puts an additional copy of every non-Special key item in the pool for every key item that there is.
Chance gives each key item a 50% chance of having a duplicate instead of guaranteeing one for all of them."""
"""
Puts an additional copy of every non-Special key item in the pool for every key item that there is.
Chance gives each key item a 50% chance of having a duplicate instead of guaranteeing one for all of them.
"""
display_name = "Spare Keys"
option_off = 0
option_on = 1
@ -68,14 +78,17 @@ class SpareKeys(Choice):
class HardItemPool(Toggle):
"""Replaces some items in the item pool with less valuable ones, to make the item pool sort of resemble Hard Mode
in the PAL version."""
"""
Replaces some items in the item pool with less valuable ones, to make the item pool sort of resemble Hard Mode in the PAL version.
"""
display_name = "Hard Item Pool"
class Special1sPerWarp(Range):
"""Sets how many Special1 jewels are needed per warp menu option unlock.
This will decrease until the number x 7 is less than or equal to the Total Specail1s if it isn't already."""
"""
Sets how many Special1 jewels are needed per warp menu option unlock.
This will decrease until the number x 7 is less than or equal to the Total Specail1s if it isn't already.
"""
range_start = 1
range_end = 10
default = 1
@ -83,7 +96,9 @@ class Special1sPerWarp(Range):
class TotalSpecial1s(Range):
"""Sets how many Speical1 jewels are in the pool in total."""
"""
Sets how many Speical1 jewels are in the pool in total.
"""
range_start = 7
range_end = 70
default = 7
@ -91,11 +106,13 @@ class TotalSpecial1s(Range):
class DraculasCondition(Choice):
"""Sets the requirement for unlocking and opening the door to Dracula's chamber.
"""
Sets the requirement for unlocking and opening the door to Dracula's chamber.
None: No requirement. Door is unlocked from the start.
Crystal: Activate the big crystal in Castle Center's basement. Neither boss afterwards has to be defeated.
Bosses: Kill a specified number of bosses with health bars and claim their Trophies.
Specials: Find a specified number of Special2 jewels shuffled in the main item pool."""
Specials: Find a specified number of Special2 jewels shuffled in the main item pool.
"""
display_name = "Dracula's Condition"
option_none = 0
option_crystal = 1
@ -105,7 +122,9 @@ class DraculasCondition(Choice):
class PercentSpecial2sRequired(Range):
"""Percentage of Special2s required to enter Dracula's chamber when Dracula's Condition is Special2s."""
"""
Percentage of Special2s required to enter Dracula's chamber when Dracula's Condition is Special2s.
"""
range_start = 1
range_end = 100
default = 80
@ -113,7 +132,9 @@ class PercentSpecial2sRequired(Range):
class TotalSpecial2s(Range):
"""How many Speical2 jewels are in the pool in total when Dracula's Condition is Special2s."""
"""
How many Speical2 jewels are in the pool in total when Dracula's Condition is Special2s.
"""
range_start = 1
range_end = 70
default = 25
@ -121,58 +142,70 @@ class TotalSpecial2s(Range):
class BossesRequired(Range):
"""How many bosses need to be defeated to enter Dracula's chamber when Dracula's Condition is set to Bosses.
This will automatically adjust if there are fewer available bosses than the chosen number."""
"""
How many bosses need to be defeated to enter Dracula's chamber when Dracula's Condition is set to Bosses.
This will automatically adjust if there are fewer available bosses than the chosen number.
"""
range_start = 1
range_end = 16
default = 14
default = 12
display_name = "Bosses Required"
class CarrieLogic(Toggle):
"""Adds the 2 checks inside Underground Waterway's crawlspace to the pool.
"""
Adds the 2 checks inside Underground Waterway's crawlspace to the pool.
If you (and everyone else if racing the same seed) are planning to only ever play Reinhardt, don't enable this.
Can be combined with Hard Logic to include Carrie-only tricks."""
Can be combined with Hard Logic to include Carrie-only tricks.
"""
display_name = "Carrie Logic"
class HardLogic(Toggle):
"""Properly considers sequence break tricks in logic (i.e. maze skip). Can be combined with Carrie Logic to include
Carrie-only tricks.
See the Game Page for a full list of tricks and glitches that may be logically required."""
"""
Properly considers sequence break tricks in logic (i.e. maze skip). Can be combined with Carrie Logic to include Carrie-only tricks.
See the Game Page for a full list of tricks and glitches that may be logically required.
"""
display_name = "Hard Logic"
class MultiHitBreakables(Toggle):
"""Adds the items that drop from the objects that break in three hits to the pool. There are 18 of these throughout
the game, adding up to 79 or 80 checks (depending on sub-weapons
being shuffled anywhere or not) in total with all stages.
The game will be modified to
remember exactly which of their items you've picked up instead of simply whether they were broken or not."""
"""
Adds the items that drop from the objects that break in three hits to the pool.
There are 18 of these throughout the game, adding up to 79 or 80 checks (depending on sub-weapons being shuffled anywhere or not) in total with all stages.
The game will be modified to remember exactly which of their items you've picked up instead of simply whether they were broken or not.
"""
display_name = "Multi-hit Breakables"
class EmptyBreakables(Toggle):
"""Adds 9 check locations in the form of breakables that normally have nothing (all empty Forest coffins, etc.)
and some additional Red Jewels and/or moneybags into the item pool to compensate."""
"""
Adds 9 check locations in the form of breakables that normally have nothing (all empty Forest coffins, etc.) and some additional Red Jewels and/or moneybags into the item pool to compensate.
"""
display_name = "Empty Breakables"
class LizardLockerItems(Toggle):
"""Adds the 6 items inside Castle Center 2F's Lizard-man generators to the pool.
Picking up all of these can be a very tedious luck-based process, so they are off by default."""
"""
Adds the 6 items inside Castle Center 2F's Lizard-man generators to the pool.
Picking up all of these can be a very tedious luck-based process, so they are off by default.
"""
display_name = "Lizard Locker Items"
class Shopsanity(Toggle):
"""Adds 7 one-time purchases from Renon's shop into the location pool. After buying an item from a slot, it will
revert to whatever it is in the vanilla game."""
"""
Adds 7 one-time purchases from Renon's shop into the location pool.
After buying an item from a slot, it will revert to whatever it is in the vanilla game.
"""
display_name = "Shopsanity"
class ShopPrices(Choice):
"""Randomizes the amount of gold each item costs in Renon's shop.
Use the below options to control how much or little an item can cost."""
"""
Randomizes the amount of gold each item costs in Renon's shop.
Use the Minimum and Maximum Gold Price options to control how much or how little an item can cost.
"""
display_name = "Shop Prices"
option_vanilla = 0
option_randomized = 1
@ -180,7 +213,9 @@ class ShopPrices(Choice):
class MinimumGoldPrice(Range):
"""The lowest amount of gold an item can cost in Renon's shop, divided by 100."""
"""
The lowest amount of gold an item can cost in Renon's shop, divided by 100.
"""
display_name = "Minimum Gold Price"
range_start = 1
range_end = 50
@ -188,7 +223,9 @@ class MinimumGoldPrice(Range):
class MaximumGoldPrice(Range):
"""The highest amount of gold an item can cost in Renon's shop, divided by 100."""
"""
The highest amount of gold an item can cost in Renon's shop, divided by 100.
"""
display_name = "Maximum Gold Price"
range_start = 1
range_end = 50
@ -196,8 +233,9 @@ class MaximumGoldPrice(Range):
class PostBehemothBoss(Choice):
"""Sets which boss is fought in the vampire triplets' room in Castle Center by which characters after defeating
Behemoth."""
"""
Sets which boss is fought in the vampire triplets' room in Castle Center by which characters after defeating Behemoth.
"""
display_name = "Post-Behemoth Boss"
option_vanilla = 0
option_inverted = 1
@ -207,7 +245,9 @@ class PostBehemothBoss(Choice):
class RoomOfClocksBoss(Choice):
"""Sets which boss is fought at Room of Clocks by which characters."""
"""
Sets which boss is fought at Room of Clocks by which characters.
"""
display_name = "Room of Clocks Boss"
option_vanilla = 0
option_inverted = 1
@ -217,7 +257,9 @@ class RoomOfClocksBoss(Choice):
class RenonFightCondition(Choice):
"""Sets the condition on which the Renon fight will trigger."""
"""
Sets the condition on which the Renon fight will trigger.
"""
display_name = "Renon Fight Condition"
option_never = 0
option_spend_30k = 1
@ -226,7 +268,9 @@ class RenonFightCondition(Choice):
class VincentFightCondition(Choice):
"""Sets the condition on which the vampire Vincent fight will trigger."""
"""
Sets the condition on which the vampire Vincent fight will trigger.
"""
display_name = "Vincent Fight Condition"
option_never = 0
option_wait_16_days = 1
@ -235,7 +279,9 @@ class VincentFightCondition(Choice):
class BadEndingCondition(Choice):
"""Sets the condition on which the currently-controlled character's Bad Ending will trigger."""
"""
Sets the condition on which the currently-controlled character's Bad Ending will trigger.
"""
display_name = "Bad Ending Condition"
option_never = 0
option_kill_vincent = 1
@ -244,24 +290,32 @@ class BadEndingCondition(Choice):
class IncreaseItemLimit(DefaultOnToggle):
"""Increases the holding limit of usable items from 10 to 99 of each item."""
"""
Increases the holding limit of usable items from 10 to 99 of each item.
"""
display_name = "Increase Item Limit"
class NerfHealingItems(Toggle):
"""Decreases the amount of health healed by Roast Chickens to 25%, Roast Beefs to 50%, and Healing Kits to 80%."""
"""
Decreases the amount of health healed by Roast Chickens to 25%, Roast Beefs to 50%, and Healing Kits to 80%.
"""
display_name = "Nerf Healing Items"
class LoadingZoneHeals(DefaultOnToggle):
"""Whether end-of-level loading zones restore health and cure status aliments or not.
Recommended off for those looking for more of a survival horror experience!"""
"""
Whether end-of-level loading zones restore health and cure status aliments or not.
Recommended off for those looking for more of a survival horror experience!
"""
display_name = "Loading Zone Heals"
class InvisibleItems(Choice):
"""Sets which items are visible in their locations and which are invisible until picked up.
'Chance' gives each item a 50/50 chance of being visible or invisible."""
"""
Sets which items are visible in their locations and which are invisible until picked up.
'Chance' gives each item a 50/50 chance of being visible or invisible.
"""
display_name = "Invisible Items"
option_vanilla = 0
option_reveal_all = 1
@ -271,21 +325,25 @@ class InvisibleItems(Choice):
class DropPreviousSubWeapon(Toggle):
"""When receiving a sub-weapon, the one you had before will drop behind you, so it can be taken back if desired."""
"""
When receiving a sub-weapon, the one you had before will drop behind you, so it can be taken back if desired.
"""
display_name = "Drop Previous Sub-weapon"
class PermanentPowerUps(Toggle):
"""Replaces PowerUps with PermaUps, which upgrade your B weapon level permanently and will stay even after
dying and/or continuing.
To compensate, only two will be in the pool overall, and they will not drop from any enemy or projectile."""
"""
Replaces PowerUps with PermaUps, which upgrade your B weapon level permanently and will stay even after dying and/or continuing.
To compensate, only two will be in the pool overall, and they will not drop from any enemy or projectile.
"""
display_name = "Permanent PowerUps"
class IceTrapPercentage(Range):
"""Replaces a percentage of junk items with Ice Traps.
These will be visibly disguised as other items, and receiving one will freeze you
as if you were hit by Camilla's ice cloud attack."""
"""
Replaces a percentage of junk items with Ice Traps.
These will be visibly disguised as other items, and receiving one will freeze you as if you were hit by Camilla's ice cloud attack.
"""
display_name = "Ice Trap Percentage"
range_start = 0
range_end = 100
@ -293,7 +351,9 @@ class IceTrapPercentage(Range):
class IceTrapAppearance(Choice):
"""What items Ice Traps can possibly be disguised as."""
"""
What items Ice Traps can possibly be disguised as.
"""
display_name = "Ice Trap Appearance"
option_major_only = 0
option_junk_only = 1
@ -302,31 +362,34 @@ class IceTrapAppearance(Choice):
class DisableTimeRestrictions(Toggle):
"""Disables the restriction on every event and door that requires the current time
to be within a specific range, so they can be triggered at any time.
"""
Disables the restriction on every event and door that requires the current time to be within a specific range, so they can be triggered at any time.
This includes all sun/moon doors and, in the Villa, the meeting with Rosa and the fountain pillar.
The Villa coffin is not affected by this."""
The Villa coffin is not affected by this.
"""
display_name = "Disable Time Requirements"
class SkipGondolas(Toggle):
"""Makes jumping on and activating a gondola in Tunnel instantly teleport you
to the other station, thereby skipping the entire three-minute ride.
The item normally at the gondola transfer point is moved to instead be
near the red gondola at its station."""
"""
Makes jumping on and activating a gondola in Tunnel instantly teleport you to the other station, thereby skipping the entire three-minute ride.
The item normally at the gondola transfer point is moved to instead be near the red gondola at its station.
"""
display_name = "Skip Gondolas"
class SkipWaterwayBlocks(Toggle):
"""Opens the door to the third switch in Underground Waterway from the start so that the jumping across floating
brick platforms won't have to be done. Shopping at the Contract on the other side of them may still be logically
required if Shopsanity is on."""
"""
Opens the door to the third switch in Underground Waterway from the start so that the jumping across floating brick platforms won't have to be done.
Shopping at the Contract on the other side of them may still be logically required if Shopsanity is on.
"""
display_name = "Skip Waterway Blocks"
class Countdown(Choice):
"""Displays, near the HUD clock and below the health bar, the number of unobtained progression-marked items
or the total check locations remaining in the stage you are currently in."""
"""
Displays, near the HUD clock and below the health bar, the number of unobtained progression-marked items or the total check locations remaining in the stage you are currently in.
"""
display_name = "Countdown"
option_none = 0
option_majors = 1
@ -335,19 +398,21 @@ class Countdown(Choice):
class BigToss(Toggle):
"""Makes every non-immobilizing damage source launch you as if you got hit by Behemoth's charge.
"""
Makes every non-immobilizing damage source launch you as if you got hit by Behemoth's charge.
Press A while tossed to cancel the launch momentum and avoid being thrown off ledges.
Hold Z to have all incoming damage be treated as it normally would.
Any tricks that might be possible with it are NOT considered in logic by any options."""
Any tricks that might be possible with it are not in logic.
"""
display_name = "Big Toss"
class PantherDash(Choice):
"""Hold C-right at any time to sprint way faster. Any tricks that might be
possible with it are NOT considered in logic by any options and any boss
fights with boss health meters, if started, are expected to be finished
before leaving their arenas if Dracula's Condition is bosses. Jumpless will
prevent jumping while moving at the increased speed to ensure logic cannot be broken with it."""
"""
Hold C-right at any time to sprint way faster.
Any tricks that are possible with it are not in logic and any boss fights with boss health meters, if started, are expected to be finished before leaving their arenas if Dracula's Condition is bosses.
Jumpless will prevent jumping while moving at the increased speed to make logic harder to break with it.
"""
display_name = "Panther Dash"
option_off = 0
option_on = 1
@ -356,19 +421,25 @@ class PantherDash(Choice):
class IncreaseShimmySpeed(Toggle):
"""Increases the speed at which characters shimmy left and right while hanging on ledges."""
"""
Increases the speed at which characters shimmy left and right while hanging on ledges.
"""
display_name = "Increase Shimmy Speed"
class FallGuard(Toggle):
"""Removes fall damage from landing too hard. Note that falling for too long will still result in instant death."""
"""
Removes fall damage from landing too hard. Note that falling for too long will still result in instant death.
"""
display_name = "Fall Guard"
class BackgroundMusic(Choice):
"""Randomizes or disables the music heard throughout the game.
"""
Randomizes or disables the music heard throughout the game.
Randomized music is split into two pools: songs that loop and songs that don't.
The "lead-in" versions of some songs will be paired accordingly."""
The "lead-in" versions of some songs will be paired accordingly.
"""
display_name = "Background Music"
option_normal = 0
option_disabled = 1
@ -377,8 +448,10 @@ class BackgroundMusic(Choice):
class MapLighting(Choice):
"""Randomizes the lighting color RGB values on every map during every time of day to be literally anything.
The colors and/or shading of the following things are affected: fog, maps, player, enemies, and some objects."""
"""
Randomizes the lighting color RGB values on every map during every time of day to be literally anything.
The colors and/or shading of the following things are affected: fog, maps, player, enemies, and some objects.
"""
display_name = "Map Lighting"
option_normal = 0
option_randomized = 1
@ -386,12 +459,16 @@ class MapLighting(Choice):
class CinematicExperience(Toggle):
"""Enables an unused film reel effect on every cutscene in the game. Purely cosmetic."""
"""
Enables an unused film reel effect on every cutscene in the game. Purely cosmetic.
"""
display_name = "Cinematic Experience"
class WindowColorR(Range):
"""The red value for the background color of the text windows during gameplay."""
"""
The red value for the background color of the text windows during gameplay.
"""
display_name = "Window Color R"
range_start = 0
range_end = 15
@ -399,7 +476,9 @@ class WindowColorR(Range):
class WindowColorG(Range):
"""The green value for the background color of the text windows during gameplay."""
"""
The green value for the background color of the text windows during gameplay.
"""
display_name = "Window Color G"
range_start = 0
range_end = 15
@ -407,7 +486,9 @@ class WindowColorG(Range):
class WindowColorB(Range):
"""The blue value for the background color of the text windows during gameplay."""
"""
The blue value for the background color of the text windows during gameplay.
"""
display_name = "Window Color B"
range_start = 0
range_end = 15
@ -415,7 +496,9 @@ class WindowColorB(Range):
class WindowColorA(Range):
"""The alpha value for the background color of the text windows during gameplay."""
"""
The alpha value for the background color of the text windows during gameplay.
"""
display_name = "Window Color A"
range_start = 0
range_end = 15
@ -423,9 +506,10 @@ class WindowColorA(Range):
class DeathLink(Choice):
"""When you die, everyone dies. Of course the reverse is true too.
Explosive: Makes received DeathLinks kill you via the Magical Nitro explosion
instead of the normal death animation."""
"""
When you die, everyone dies. Of course the reverse is true too.
Explosive: Makes received DeathLinks kill you via the Magical Nitro explosion instead of the normal death animation.
"""
display_name = "DeathLink"
option_off = 0
alias_no = 0
@ -437,6 +521,7 @@ class DeathLink(Choice):
@dataclass
class CV64Options(PerGameCommonOptions):
start_inventory_from_pool: StartInventoryPool
character_stages: CharacterStages
stage_shuffle: StageShuffle
starting_stage: StartingStage
@ -479,13 +564,26 @@ class CV64Options(PerGameCommonOptions):
big_toss: BigToss
panther_dash: PantherDash
increase_shimmy_speed: IncreaseShimmySpeed
background_music: BackgroundMusic
map_lighting: MapLighting
fall_guard: FallGuard
cinematic_experience: CinematicExperience
window_color_r: WindowColorR
window_color_g: WindowColorG
window_color_b: WindowColorB
window_color_a: WindowColorA
background_music: BackgroundMusic
map_lighting: MapLighting
fall_guard: FallGuard
cinematic_experience: CinematicExperience
death_link: DeathLink
start_inventory_from_pool: StartInventoryPool
cv64_option_groups = [
OptionGroup("gameplay tweaks", [
HardItemPool, ShopPrices, MinimumGoldPrice, MaximumGoldPrice, PostBehemothBoss, RoomOfClocksBoss,
RenonFightCondition, VincentFightCondition, BadEndingCondition, IncreaseItemLimit, NerfHealingItems,
LoadingZoneHeals, InvisibleItems, DropPreviousSubWeapon, PermanentPowerUps, IceTrapPercentage,
IceTrapAppearance, DisableTimeRestrictions, SkipGondolas, SkipWaterwayBlocks, Countdown, BigToss, PantherDash,
IncreaseShimmySpeed, FallGuard, DeathLink
]),
OptionGroup("cosmetics", [
WindowColorR, WindowColorG, WindowColorB, WindowColorA, BackgroundMusic, MapLighting, CinematicExperience
])
]