Archipelago/worlds/dark_souls_3/Options.py

479 lines
16 KiB
Python

from dataclasses import dataclass
import json
from typing import Any, Dict
from Options import Choice, DeathLink, DefaultOnToggle, ExcludeLocations, NamedRange, OptionDict, \
OptionGroup, PerGameCommonOptions, Range, Removed, Toggle
## Game Options
class EarlySmallLothricBanner(Choice):
"""Force Small Lothric Banner into an early sphere in your world or across all worlds."""
display_name = "Early Small Lothric Banner"
option_off = 0
option_early_global = 1
option_early_local = 2
default = option_off
class LateBasinOfVowsOption(Choice):
"""Guarantee that you don't need to enter Lothric Castle until later in the run.
- **Off:** You may have to enter Lothric Castle and the areas beyond it immediately after High
Wall of Lothric.
- **After Small Lothric Banner:** You may have to enter Lothric Castle after Catacombs of
Carthus.
- **After Small Doll:** You won't have to enter Lothric Castle until after Irithyll of the
Boreal Valley.
"""
display_name = "Late Basin of Vows"
option_off = 0
alias_false = 0
option_after_small_lothric_banner = 1
alias_true = 1
option_after_small_doll = 2
class LateDLCOption(Choice):
"""Guarantee that you don't need to enter the DLC until later in the run.
- **Off:** You may have to enter the DLC after Catacombs of Carthus.
- **After Small Doll:** You may have to enter the DLC after Irithyll of the Boreal Valley.
- **After Basin:** You won't have to enter the DLC until after Lothric Castle.
"""
display_name = "Late DLC"
option_off = 0
alias_false = 0
option_after_small_doll = 1
alias_true = 1
option_after_basin = 2
class EnableDLCOption(Toggle):
"""Include DLC locations, items, and enemies in the randomized pools.
To use this option, you must own both the "Ashes of Ariandel" and the "Ringed City" DLCs.
"""
display_name = "Enable DLC"
class EnableNGPOption(Toggle):
"""Include items and locations exclusive to NG+ cycles."""
display_name = "Enable NG+"
## Equipment
class RandomizeStartingLoadout(DefaultOnToggle):
"""Randomizes the equipment characters begin with."""
display_name = "Randomize Starting Loadout"
class RequireOneHandedStartingWeapons(DefaultOnToggle):
"""Require starting equipment to be usable one-handed."""
display_name = "Require One-Handed Starting Weapons"
class AutoEquipOption(Toggle):
"""Automatically equips any received armor or left/right weapons."""
display_name = "Auto-Equip"
class LockEquipOption(Toggle):
"""Lock the equipment slots so you cannot change your armor or your left/right weapons.
Works great with the Auto-equip option.
"""
display_name = "Lock Equipment Slots"
class NoEquipLoadOption(Toggle):
"""Disable the equip load constraint from the game."""
display_name = "No Equip Load"
class NoWeaponRequirementsOption(Toggle):
"""Disable the weapon requirements by removing any movement or damage penalties, permitting you
to use any weapon early.
"""
display_name = "No Weapon Requirements"
class NoSpellRequirementsOption(Toggle):
"""Disable the spell requirements permitting you to use any spell."""
display_name = "No Spell Requirements"
## Weapons
class RandomizeInfusionOption(Toggle):
"""Enable this option to infuse a percentage of the pool of weapons and shields."""
display_name = "Randomize Infusion"
class RandomizeInfusionPercentageOption(NamedRange):
"""The percentage of weapons/shields in the pool to be infused if Randomize Infusion is toggled.
"""
display_name = "Percentage of Infused Weapons"
range_start = 0
range_end = 100
default = 33
# 3/155 weapons are infused in the base game, or about 2%
special_range_names = {"similar to base game": 2}
class RandomizeWeaponLevelOption(Choice):
"""Enable this option to upgrade a percentage of the pool of weapons to a random value between
the minimum and maximum levels defined.
- **All:** All weapons are eligible, both basic and epic
- **Basic:** Only weapons that can be upgraded to +10
- **Epic:** Only weapons that can be upgraded to +5
"""
display_name = "Randomize Weapon Level"
option_none = 0
option_all = 1
option_basic = 2
option_epic = 3
class RandomizeWeaponLevelPercentageOption(Range):
"""The percentage of weapons in the pool to be upgraded if randomize weapons level is toggled."""
display_name = "Percentage of Randomized Weapons"
range_start = 0
range_end = 100
default = 33
class MinLevelsIn5WeaponPoolOption(Range):
"""The minimum upgraded value of a weapon in the pool of weapons that can only reach +5."""
display_name = "Minimum Level of +5 Weapons"
range_start = 0
range_end = 5
default = 1
class MaxLevelsIn5WeaponPoolOption(Range):
"""The maximum upgraded value of a weapon in the pool of weapons that can only reach +5."""
display_name = "Maximum Level of +5 Weapons"
range_start = 0
range_end = 5
default = 5
class MinLevelsIn10WeaponPoolOption(Range):
"""The minimum upgraded value of a weapon in the pool of weapons that can reach +10."""
display_name = "Minimum Level of +10 Weapons"
range_start = 0
range_end = 10
default = 1
class MaxLevelsIn10WeaponPoolOption(Range):
"""The maximum upgraded value of a weapon in the pool of weapons that can reach +10."""
display_name = "Maximum Level of +10 Weapons"
range_start = 0
range_end = 10
default = 10
## Item Smoothing
class SmoothSoulItemsOption(DefaultOnToggle):
"""Distribute soul items in a similar order as the base game.
By default, soul items will be distributed totally randomly. If this is set, less valuable soul
items will generally appear in earlier spheres and more valuable ones will generally appear
later.
"""
display_name = "Smooth Soul Items"
class SmoothUpgradeItemsOption(DefaultOnToggle):
"""Distribute upgrade items in a similar order as the base game.
By default, upgrade items will be distributed totally randomly. If this is set, lower-level
upgrade items will generally appear in earlier spheres and higher-level ones will generally
appear later.
"""
display_name = "Smooth Upgrade Items"
class SmoothUpgradedWeaponsOption(DefaultOnToggle):
"""Distribute upgraded weapons in a similar order as the base game.
By default, upgraded weapons will be distributed totally randomly. If this is set, lower-level
weapons will generally appear in earlier spheres and higher-level ones will generally appear
later.
"""
display_name = "Smooth Upgraded Weapons"
### Enemies
class RandomizeEnemiesOption(DefaultOnToggle):
"""Randomize enemy and boss placements."""
display_name = "Randomize Enemies"
class SimpleEarlyBossesOption(DefaultOnToggle):
"""Avoid replacing Iudex Gundyr and Vordt with late bosses.
This excludes all bosses after Dancer of the Boreal Valley from these two boss fights. Disable
it for a chance at a much harder early game.
This is ignored unless enemies are randomized.
"""
display_name = "Simple Early Bosses"
class ScaleEnemiesOption(DefaultOnToggle):
"""Scale randomized enemy stats to match the areas in which they appear.
Disabling this will tend to make the early game much more difficult and the late game much
easier.
This is ignored unless enemies are randomized.
"""
display_name = "Scale Enemies"
class RandomizeMimicsWithEnemiesOption(Toggle):
"""Mix Mimics into the main enemy pool.
If this is enabled, Mimics will be replaced by normal enemies who drop the Mimic rewards on
death, and Mimics will be placed randomly in place of normal enemies. It's recommended to enable
Impatient Mimics as well if you enable this.
This is ignored unless enemies are randomized.
"""
display_name = "Randomize Mimics With Enemies"
class RandomizeSmallCrystalLizardsWithEnemiesOption(Toggle):
"""Mix small Crystal Lizards into the main enemy pool.
If this is enabled, Crystal Lizards will be replaced by normal enemies who drop the Crystal
Lizard rewards on death, and Crystal Lizards will be placed randomly in place of normal enemies.
This is ignored unless enemies are randomized.
"""
display_name = "Randomize Small Crystal Lizards With Enemies"
class ReduceHarmlessEnemiesOption(Toggle):
"""Reduce the frequency that "harmless" enemies appear.
Enable this to add a bit of extra challenge. This severely limits the number of enemies that are
slow to aggro, slow to attack, and do very little damage that appear in the enemy pool.
This is ignored unless enemies are randomized.
"""
display_name = "Reduce Harmless Enemies"
class AllChestsAreMimicsOption(Toggle):
"""Replace all chests with mimics that drop the same items.
If "Randomize Mimics With Enemies" is set, these chests will instead be replaced with random
enemies that drop the same items.
This is ignored unless enemies are randomized.
"""
display_name = "All Chests Are Mimics"
class ImpatientMimicsOption(Toggle):
"""Mimics attack as soon as you get close instead of waiting for you to open them.
This is ignored unless enemies are randomized.
"""
display_name = "Impatient Mimics"
class RandomEnemyPresetOption(OptionDict):
"""The YAML preset for the static enemy randomizer.
See the static randomizer documentation in `randomizer\\presets\\README.txt` for details.
Include this as nested YAML. For example:
.. code-block:: YAML
random_enemy_preset:
RemoveSource: Ancient Wyvern; Darkeater Midir
DontRandomize: Iudex Gundyr
"""
display_name = "Random Enemy Preset"
supports_weighting = False
default = {}
valid_keys = ["Description", "RecommendFullRandomization", "RecommendNoEnemyProgression",
"OopsAll", "Boss", "Miniboss", "Basic", "BuffBasicEnemiesAsBosses",
"DontRandomize", "RemoveSource", "Enemies"]
@classmethod
def get_option_name(cls, value: Dict[str, Any]) -> str:
return json.dumps(value)
## Item & Location
class DS3ExcludeLocations(ExcludeLocations):
"""Prevent these locations from having an important item."""
default = frozenset({"Hidden", "Small Crystal Lizards", "Upgrade", "Small Souls", "Miscellaneous"})
class ExcludedLocationBehaviorOption(Choice):
"""How to choose items for excluded locations in DS3.
- **Allow Useful:** Excluded locations can't have progression items, but they can have useful
items.
- **Forbid Useful:** Neither progression items nor useful items can be placed in excluded
locations.
- **Do Not Randomize:** Excluded locations always contain the same item as in vanilla Dark Souls
III.
A "progression item" is anything that's required to unlock another location in some game. A
"useful item" is something each game defines individually, usually items that are quite
desirable but not strictly necessary.
"""
display_name = "Excluded Locations Behavior"
option_allow_useful = 1
option_forbid_useful = 2
option_do_not_randomize = 3
default = 2
class MissableLocationBehaviorOption(Choice):
"""Which items can be placed in locations that can be permanently missed.
- **Allow Useful:** Missable locations can't have progression items, but they can have useful
items.
- **Forbid Useful:** Neither progression items nor useful items can be placed in missable
locations.
- **Do Not Randomize:** Missable locations always contain the same item as in vanilla Dark Souls
III.
A "progression item" is anything that's required to unlock another location in some game. A
"useful item" is something each game defines individually, usually items that are quite
desirable but not strictly necessary.
"""
display_name = "Missable Locations Behavior"
option_allow_useful = 1
option_forbid_useful = 2
option_do_not_randomize = 3
default = 2
@dataclass
class DarkSouls3Options(PerGameCommonOptions):
# Game Options
early_banner: EarlySmallLothricBanner
late_basin_of_vows: LateBasinOfVowsOption
late_dlc: LateDLCOption
death_link: DeathLink
enable_dlc: EnableDLCOption
enable_ngp: EnableNGPOption
# Equipment
random_starting_loadout: RandomizeStartingLoadout
require_one_handed_starting_weapons: RequireOneHandedStartingWeapons
auto_equip: AutoEquipOption
lock_equip: LockEquipOption
no_equip_load: NoEquipLoadOption
no_weapon_requirements: NoWeaponRequirementsOption
no_spell_requirements: NoSpellRequirementsOption
# Weapons
randomize_infusion: RandomizeInfusionOption
randomize_infusion_percentage: RandomizeInfusionPercentageOption
randomize_weapon_level: RandomizeWeaponLevelOption
randomize_weapon_level_percentage: RandomizeWeaponLevelPercentageOption
min_levels_in_5: MinLevelsIn5WeaponPoolOption
max_levels_in_5: MaxLevelsIn5WeaponPoolOption
min_levels_in_10: MinLevelsIn10WeaponPoolOption
max_levels_in_10: MaxLevelsIn10WeaponPoolOption
# Item Smoothing
smooth_soul_items: SmoothSoulItemsOption
smooth_upgrade_items: SmoothUpgradeItemsOption
smooth_upgraded_weapons: SmoothUpgradedWeaponsOption
# Enemies
randomize_enemies: RandomizeEnemiesOption
simple_early_bosses: SimpleEarlyBossesOption
scale_enemies: ScaleEnemiesOption
randomize_mimics_with_enemies: RandomizeMimicsWithEnemiesOption
randomize_small_crystal_lizards_with_enemies: RandomizeSmallCrystalLizardsWithEnemiesOption
reduce_harmless_enemies: ReduceHarmlessEnemiesOption
all_chests_are_mimics: AllChestsAreMimicsOption
impatient_mimics: ImpatientMimicsOption
random_enemy_preset: RandomEnemyPresetOption
# Item & Location
exclude_locations: DS3ExcludeLocations
excluded_location_behavior: ExcludedLocationBehaviorOption
missable_location_behavior: MissableLocationBehaviorOption
# Removed
pool_type: Removed
enable_weapon_locations: Removed
enable_shield_locations: Removed
enable_armor_locations: Removed
enable_ring_locations: Removed
enable_spell_locations: Removed
enable_key_locations: Removed
enable_boss_locations: Removed
enable_npc_locations: Removed
enable_misc_locations: Removed
enable_health_upgrade_locations: Removed
enable_progressive_locations: Removed
guaranteed_items: Removed
excluded_locations: Removed
missable_locations: Removed
option_groups = [
OptionGroup("Equipment", [
RandomizeStartingLoadout,
RequireOneHandedStartingWeapons,
AutoEquipOption,
LockEquipOption,
NoEquipLoadOption,
NoWeaponRequirementsOption,
NoSpellRequirementsOption,
]),
OptionGroup("Weapons", [
RandomizeInfusionOption,
RandomizeInfusionPercentageOption,
RandomizeWeaponLevelOption,
RandomizeWeaponLevelPercentageOption,
MinLevelsIn5WeaponPoolOption,
MaxLevelsIn5WeaponPoolOption,
MinLevelsIn10WeaponPoolOption,
MaxLevelsIn10WeaponPoolOption,
]),
OptionGroup("Item Smoothing", [
SmoothSoulItemsOption,
SmoothUpgradeItemsOption,
SmoothUpgradedWeaponsOption,
]),
OptionGroup("Enemies", [
RandomizeEnemiesOption,
SimpleEarlyBossesOption,
ScaleEnemiesOption,
RandomizeMimicsWithEnemiesOption,
RandomizeSmallCrystalLizardsWithEnemiesOption,
ReduceHarmlessEnemiesOption,
AllChestsAreMimicsOption,
ImpatientMimicsOption,
RandomEnemyPresetOption,
]),
OptionGroup("Item & Location Options", [
DS3ExcludeLocations,
ExcludedLocationBehaviorOption,
MissableLocationBehaviorOption,
])
]