479 lines
16 KiB
Python
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,
|
|
])
|
|
]
|