Skip to content

Commit

Permalink
DS3: Version 3.0.0 (#3128)
Browse files Browse the repository at this point in the history
* Update worlds/dark_souls_3/Locations.py

Co-authored-by: Scipio Wright <scipiowright@gmail.com>

* Fix Covetous Silver Serpent Ring location

* Update location groups

This should cover pretty much all of the seriously hidden items. It
also splits out miniboss drops, mimic drops, and hostile NPC drops.

* Remove the "Guarded by Keys" group

On reflection, I don't think this is actually that useful. It'll also
get a lot muddier once we can randomize shops and ashes become
pseudo-"keys".

* Restore Knight Slayer's Ring classification

* Support infusions/upgrades in the new DS3 mod system

* Support random starting loadouts

* Make an item's NPC status orthogonal to its category

* Track location groups with flags

* Track Archipelago/Offline mismatches on the server

Also fix a few incorrect item names.

* Add additional locations that are now randomizable

* Don't put soul and multiple items in shops

* Add an option to enable whether NG+ items/locations are included

* Clean up useful item categorization

There are so many weapons in the game now, it doesn't make sense to
treat them all as useful

* Add more variety to filler items

* Iron out a few bugs and incompatibilities

* Fix more silly bugs

* Get tests passing

* Update options to cover new item types

Also recategorize some items.

* Verify the default values of `Option`s.

Since `Option.verify()` can handle normalization of option names, this allows options  to define defaults which rely on that normalization. For example, it allows a world to exclude certain locations by default.

This also makes it easier to catch errors if a world author accidentally sets an invalid default.

* Make a few more improvements and fixes

* Randomize Path of the Dragon

* Mark items that unlock checks as useful

These items all unlock missable checks, but they're still good to ahve in the game for variety's sake.

* Guarantee more NPC quests are completable

* Fix a syntax error

* Fix rule definition

* Support enemy randomization

* Support online Yhorm randomization

* Remove a completed TODO

* Fix tests

* Fix force_unique

* Add an option to smooth out upgrade item progression

* Add helpers for setting location/entrance rules

* Support smoother soul item progression

* Fill extra smoothing items into conditional locations as well as other worlds

* Add health item smoothing

* Handle infusions at item generation time

* Handle item upgrades at genreation time

* Fix Grave Warden's Ashes

* Don't overwrite old rules

* Randomize items based on spheres instead of DS3 locations

* Add a smoothing option for weapon upgrades

* Add rules for crow trades

* Small fixes

* Fix a few more bugs

* Fix more bugs

* Try to prevent Path of the Dragon from going somewhere it doesn't work

* Add the ability to provide enemy presets

* Various fixes and features

* Bug fixes

* Better Coiled Sword placement

* Structure DarkSouls3Location more like DarkSouls3Item

* Add events to make DS3's spheres more even

* Restructure locations to work like items do now

* Add rules for more missable locations

* Don't add two Storm Rulers

* Place Hawk Ring in Farron Keep

* Mark the Grass Crest Shield as useful

* Mark new progression items

* Fix a bug

* Support newer better Path of the Dragon code

* Don't lock the player out of Coiled Sword

* Don't create events for missable locations

* Don't throw strings

* Don't smooth event items

* Properly categorize Butcher Knife

* Be more careful about placing Yhorm in low-randomization scenarios

* Don't try to smooth DLC items with DLC disabled

* Fix another Yhorm bug

* Fix upgrade/infusion logic

* Remove the PoolType option

This distinction is no longer meaningful now that every location in
the game of each type is randomized

* Categorize HWL: Red Eye Orb as an NPC location

* Don't place Storm Ruler on CA: Coiled Sword

* Define flatten() locally to make this APWorld capable

* Fix some more Leonhard weirdness

* Fix unique item randomization

* Don't double Twin Dragon Greatshield

* Remove debugging print

* Don't add double Storm Ruler

Also remove now-redundant item sorting by category in create_items.

* Don't add double Storm Ruler

Also remove now-redundant item sorting by category in create_items.

* Add a missing dlc_enabled check

* Use nicer options syntax

* Bump data_version

* Mention where Yhorm is in which world

* Better handle excluded events

* Add a newline to Yhorm location

* Better way of handling excluded unradomized progression locations

* Fix a squidge of nondeterminism

* Only smooth items from this world

* Don't smooth progression weapons

* Remove a location that doesn't actually exist in-game

* Classify Power Within as useful

* Clarify location names

* Fix location requirements

* Clean up randomization options

* Properly name Coiled Sword location

* Add an option for configuring how missable items are handled

* Fix some bugs from location name updates

* Fix location guide link

* Fix a couple locations that were busted offline

* Update detailed location descriptions

* Fix some bugs when generating for a multiworld

* Inject Large Leather Shield

* Fix a few location issues

* Don't allow progression_skip_balancing for unnecessary locs

* Update some location info

* Don't uniquify the wrong items

* Fix some more location issues

* More location fixes

* Use hyphens instead of parens for location descriptions

* Update and fix more locations

* Fix Soul of Cinder boss name

* Fix some logic issues

* Add item groups and document item/location groups

* Fix the display name for "Impatient Mimics"

* Properly handle Transposing Kiln and Pyromancer's Flame

* Testing

* Some fixes to NPC quests, late basin, and transposing kiln

* Improve a couple location names

* Split out and improve missable NPC item logic

* Don't allow crow trades to have foreign items

* Fix a variable capture bug

* Make sure early items are accessible early even with early Castle

* Mark ID giant slave drops as missable

* Make sure late basin means that early items aren't behind it

* Make is_location_available explicitly private

* Add an _add_item_rule utility that checks availability

* Clear excluded items if excluded_locations == "unnecessary"

* Don't allow upgrades/infusions in crow trades

* Fix the documentation for deprecated options

* Create events for all excluded locations

This allows `can_reach` logic to work even if the locations are
randomized.

* Fix up Patches' and Siegward's logic based on some manual testing

* Factor out more sub-methods for setting location rules

* Oops, left these in

* Fixing name

* Left that in too

* Changing to NamedRange to support special_range_names

* Alphabetizing

* Don't call _is_location_available on foreign locations

* Add missing Leonhard items

* Changing late basin to have a post-small-doll option

* Update basin option, add logic for some of Leonhard Hawkwood and Orbeck

* Simplifying an option, fixing a copy-paste error

* Removing trailing whitespace

* Changing lost items to go into start inventory

* Revert Basin changes

* Oops

* Update Options.py

* Reverting small doll changes

* Farron Keep boss requirement logic

* Add Scroll for late_dlc

* Fixing excluded unnecessary locations

* Adding Priestess Ring as being after UG boss

* Removing missable from Corvian Titanite Slab

* Adding KFF Yhorm boss locks

* Screams about Creighton

* Elite Knight Set isn't permanently missable

* Adding Kiln requirement to KFF

* fixing valid_keys and item groups

* Fixing an option-checker

* Throwing unplaceable Storm Ruler into start inventory

* Update locations

* Refactor item injection

* Update setup doc

* Small fixes

* Fix another location name

* Fix injection calculation

* Inject guaranteed items along with progression items

* Mark boss souls as required for access to regions

This allows us to set quest requirements for boss souls and have them
automatically propagated to regions, means we need less machinery for
Yhorm bosses, and allows us to get rid of a few region-transition
events.

* Make sure Sirris's quest can be completed before Pontiff

* Removing unused list

* Changing dict to list

* Removing unused test

* Update __init__.py

* self.multiworld.random -> self.random (#9)

* Fix some miscellaneous location issues

* Rewrite the DS3 intro page/FAQ

* Removing modifying the itempool after fill (#7)

Co-authored-by: Natalie Weizenbaum <nweiz@google.com>

* Small fixes to the setup guide (#10)

Small fixes, adding an example for connecting

* Expanded Late Basin of Vows and Late DLC (#6)

* Add proper requirements for CD: Black Eye Orb

* Fix Aldrich's name

* Document the differences with the 2.x.x branch

* Don't crash if there are more items than locations in smoothing

* Apply suggestions from code review

Co-authored-by: Nicholas Saylor <79181893+nicholassaylor@users.noreply.github.com>

* Code review

* Fix _replace_with_filler

* Don't use the shared flatten function in SM

* Track local items separately rather than iterating the multiworld

* Various formatting/docs changes suggested by PyCharm (#12)

* Drop deprecated options

* Rename "offline randomizer" to "static randomizer" which is clearer

* Move `enable_*_locations` under removed options.

* Avoid excluded locations for locally-filled items

* Adding Removed options to error (#14)

* Changes for WebHost options display and the options overhaul

* unpack iterators in item list (#13)

* Allow worlds to add options to prebuilt groups

Previously, this crashed because `typing.NamedTuple` fields such as
`group.name` aren't assignable. Now it will only fail for group names
that are actually incorrectly cased, and will fail with a better error
message.

* Style changes, rename exclude behavior options, remove guaranteed items option

* Spacing/Formatting (#18)

* Various Fixes (#19)

* Universally Track Yhorm (#20)

* Account for excluded and missable

* These are behaviors now

* This is singular, apparently

* Oops

* Fleshing out the priority process

* Missable Titanite Lizards and excluded locations (#22)

* Small style/efficiency changes

* Final passthrough fixes (#24)

* Use rich option formatting

* Make the behavior option values actual behaviors (#25)

* Use !=

* Remove unused flatten utility

* Some changes from review (#28)

* Fixing determinism and making smooth faster (#29)

* Style change

* PyCharm and Mypy fixes (#26)

Co-authored-by: Scipio Wright <scipiowright@gmail.com>

* Change yhorm default (#30)

* Add indirect condition (#27)

* Update worlds/dark_souls_3/docs/locations_en.md

Co-authored-by: Nicholas Saylor <79181893+nicholassaylor@users.noreply.github.com>

* Ship all item IDs to the client

This avoids issues where items might get skipped if, for instance,
they're only in the starting inventory.

* Make sure to send AP IDs for infused/upgraded weapons

* Make `RandomEnemyPresetOption` compatible with #3280 (#31)

* Fix cast

* More typing and small fixes (#32)

---------

Co-authored-by: Scipio Wright <scipiowright@gmail.com>
Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com>
Co-authored-by: Exempt-Medic <ExemptMedic@Gmail.com>
Co-authored-by: Nicholas Saylor <79181893+nicholassaylor@users.noreply.github.com>
Co-authored-by: Doug Hoskisson <beauxq@users.noreply.github.com>
Co-authored-by: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com>
  • Loading branch information
7 people authored Aug 9, 2024
1 parent 6803c37 commit 5efb3fd
Show file tree
Hide file tree
Showing 12 changed files with 9,354 additions and 2,388 deletions.
264 changes: 264 additions & 0 deletions worlds/dark_souls_3/Bosses.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,264 @@
# In almost all cases, we leave boss and enemy randomization up to the static randomizer. But for
# Yhorm specifically we need to know where he ends up in order to ensure that the Storm Ruler is
# available before his fight.

from dataclasses import dataclass, field
from typing import Set


@dataclass
class DS3BossInfo:
"""The set of locations a given boss location blocks access to."""

name: str
"""The boss's name."""

id: int
"""The game's ID for this particular boss."""

dlc: bool = False
"""This boss appears in one of the game's DLCs."""

before_storm_ruler: bool = False
"""Whether this location appears before it's possible to get Storm Ruler in vanilla.
This is used to determine whether it's safe to place Yhorm here if weapons
aren't randomized.
"""

locations: Set[str] = field(default_factory=set)
"""Additional individual locations that can't be accessed until the boss is dead."""


# Note: the static randomizer splits up some bosses into separate fights for separate phases, each
# of which can be individually replaced by Yhorm.
all_bosses = [
DS3BossInfo("Iudex Gundyr", 4000800, before_storm_ruler = True, locations = {
"CA: Coiled Sword - boss drop"
}),
DS3BossInfo("Vordt of the Boreal Valley", 3000800, before_storm_ruler = True, locations = {
"HWL: Soul of Boreal Valley Vordt"
}),
DS3BossInfo("Curse-rotted Greatwood", 3100800, locations = {
"US: Soul of the Rotted Greatwood",
"US: Transposing Kiln - boss drop",
"US: Wargod Wooden Shield - Pit of Hollows",
"FS: Hawkwood's Shield - gravestone after Hawkwood leaves",
"FS: Sunset Shield - by grave after killing Hodrick w/Sirris",
"US: Sunset Helm - Pit of Hollows after killing Hodrick w/Sirris",
"US: Sunset Armor - pit of hollows after killing Hodrick w/Sirris",
"US: Sunset Gauntlets - pit of hollows after killing Hodrick w/Sirris",
"US: Sunset Leggings - pit of hollows after killing Hodrick w/Sirris",
"FS: Sunless Talisman - Sirris, kill GA boss",
"FS: Sunless Veil - shop, Sirris quest, kill GA boss",
"FS: Sunless Armor - shop, Sirris quest, kill GA boss",
"FS: Sunless Gauntlets - shop, Sirris quest, kill GA boss",
"FS: Sunless Leggings - shop, Sirris quest, kill GA boss",
}),
DS3BossInfo("Crystal Sage", 3300850, locations = {
"RS: Soul of a Crystal Sage",
"FS: Sage's Big Hat - shop after killing RS boss",
"FS: Hawkwood's Shield - gravestone after Hawkwood leaves",
}),
DS3BossInfo("Deacons of the Deep", 3500800, locations = {
"CD: Soul of the Deacons of the Deep",
"CD: Small Doll - boss drop",
"FS: Hawkwood's Shield - gravestone after Hawkwood leaves",
}),
DS3BossInfo("Abyss Watchers", 3300801, before_storm_ruler = True, locations = {
"FK: Soul of the Blood of the Wolf",
"FK: Cinders of a Lord - Abyss Watcher",
"FS: Undead Legion Helm - shop after killing FK boss",
"FS: Undead Legion Armor - shop after killing FK boss",
"FS: Undead Legion Gauntlet - shop after killing FK boss",
"FS: Undead Legion Leggings - shop after killing FK boss",
"FS: Farron Ring - Hawkwood",
"FS: Hawkwood's Shield - gravestone after Hawkwood leaves",
}),
DS3BossInfo("High Lord Wolnir", 3800800, before_storm_ruler = True, locations = {
"CC: Soul of High Lord Wolnir",
"FS: Wolnir's Crown - shop after killing CC boss",
"CC: Homeward Bone - Irithyll bridge",
"CC: Pontiff's Right Eye - Irithyll bridge, miniboss drop",
}),
DS3BossInfo("Pontiff Sulyvahn", 3700850, locations = {
"IBV: Soul of Pontiff Sulyvahn",
}),
DS3BossInfo("Old Demon King", 3800830, locations = {
"SL: Soul of the Old Demon King",
}),
DS3BossInfo("Aldrich, Devourer of Gods", 3700800, locations = {
"AL: Soul of Aldrich",
"AL: Cinders of a Lord - Aldrich",
"FS: Smough's Helm - shop after killing AL boss",
"FS: Smough's Armor - shop after killing AL boss",
"FS: Smough's Gauntlets - shop after killing AL boss",
"FS: Smough's Leggings - shop after killing AL boss",
"AL: Sun Princess Ring - dark cathedral, after boss",
"FS: Leonhard's Garb - shop after killing Leonhard",
"FS: Leonhard's Gauntlets - shop after killing Leonhard",
"FS: Leonhard's Trousers - shop after killing Leonhard",
}),
DS3BossInfo("Dancer of the Boreal Valley", 3000899, locations = {
"HWL: Soul of the Dancer",
"FS: Dancer's Crown - shop after killing LC entry boss",
"FS: Dancer's Armor - shop after killing LC entry boss",
"FS: Dancer's Gauntlets - shop after killing LC entry boss",
"FS: Dancer's Leggings - shop after killing LC entry boss",
}),
DS3BossInfo("Dragonslayer Armour", 3010800, locations = {
"LC: Soul of Dragonslayer Armour",
"FS: Morne's Helm - shop after killing Eygon or LC boss",
"FS: Morne's Armor - shop after killing Eygon or LC boss",
"FS: Morne's Gauntlets - shop after killing Eygon or LC boss",
"FS: Morne's Leggings - shop after killing Eygon or LC boss",
"LC: Titanite Chunk - down stairs after boss",
}),
DS3BossInfo("Consumed King Oceiros", 3000830, locations = {
"CKG: Soul of Consumed Oceiros",
"CKG: Titanite Scale - tomb, chest #1",
"CKG: Titanite Scale - tomb, chest #2",
"CKG: Drakeblood Helm - tomb, after killing AP mausoleum NPC",
"CKG: Drakeblood Armor - tomb, after killing AP mausoleum NPC",
"CKG: Drakeblood Gauntlets - tomb, after killing AP mausoleum NPC",
"CKG: Drakeblood Leggings - tomb, after killing AP mausoleum NPC",
}),
DS3BossInfo("Champion Gundyr", 4000830, locations = {
"UG: Soul of Champion Gundyr",
"FS: Gundyr's Helm - shop after killing UG boss",
"FS: Gundyr's Armor - shop after killing UG boss",
"FS: Gundyr's Gauntlets - shop after killing UG boss",
"FS: Gundyr's Leggings - shop after killing UG boss",
"UG: Hornet Ring - environs, right of main path after killing FK boss",
"UG: Chaos Blade - environs, left of shrine",
"UG: Blacksmith Hammer - shrine, Andre's room",
"UG: Eyes of a Fire Keeper - shrine, Irina's room",
"UG: Coiled Sword Fragment - shrine, dead bonfire",
"UG: Soul of a Crestfallen Knight - environs, above shrine entrance",
"UG: Life Ring+3 - shrine, behind big throne",
"UG: Ring of Steel Protection+1 - environs, behind bell tower",
"FS: Ring of Sacrifice - Yuria shop",
"UG: Ember - shop",
"UG: Priestess Ring - shop",
"UG: Wolf Knight Helm - shop after killing FK boss",
"UG: Wolf Knight Armor - shop after killing FK boss",
"UG: Wolf Knight Gauntlets - shop after killing FK boss",
"UG: Wolf Knight Leggings - shop after killing FK boss",
}),
DS3BossInfo("Ancient Wyvern", 3200800),
DS3BossInfo("King of the Storm", 3200850, locations = {
"AP: Soul of the Nameless King",
"FS: Golden Crown - shop after killing AP boss",
"FS: Dragonscale Armor - shop after killing AP boss",
"FS: Golden Bracelets - shop after killing AP boss",
"FS: Dragonscale Waistcloth - shop after killing AP boss",
"AP: Titanite Slab - plaza",
"AP: Covetous Gold Serpent Ring+2 - plaza",
"AP: Dragonslayer Helm - plaza",
"AP: Dragonslayer Armor - plaza",
"AP: Dragonslayer Gauntlets - plaza",
"AP: Dragonslayer Leggings - plaza",
}),
DS3BossInfo("Nameless King", 3200851, locations = {
"AP: Soul of the Nameless King",
"FS: Golden Crown - shop after killing AP boss",
"FS: Dragonscale Armor - shop after killing AP boss",
"FS: Golden Bracelets - shop after killing AP boss",
"FS: Dragonscale Waistcloth - shop after killing AP boss",
"AP: Titanite Slab - plaza",
"AP: Covetous Gold Serpent Ring+2 - plaza",
"AP: Dragonslayer Helm - plaza",
"AP: Dragonslayer Armor - plaza",
"AP: Dragonslayer Gauntlets - plaza",
"AP: Dragonslayer Leggings - plaza",
}),
DS3BossInfo("Lothric, Younger Prince", 3410830, locations = {
"GA: Soul of the Twin Princes",
"GA: Cinders of a Lord - Lothric Prince",
}),
DS3BossInfo("Lorian, Elder Prince", 3410832, locations = {
"GA: Soul of the Twin Princes",
"GA: Cinders of a Lord - Lothric Prince",
"FS: Lorian's Helm - shop after killing GA boss",
"FS: Lorian's Armor - shop after killing GA boss",
"FS: Lorian's Gauntlets - shop after killing GA boss",
"FS: Lorian's Leggings - shop after killing GA boss",
}),
DS3BossInfo("Champion's Gravetender and Gravetender Greatwolf", 4500860, dlc = True,
locations = {"PW1: Valorheart - boss drop"}),
DS3BossInfo("Sister Friede", 4500801, dlc = True, locations = {
"PW2: Soul of Sister Friede",
"PW2: Titanite Slab - boss drop",
"PW1: Titanite Slab - Corvian",
"FS: Ordained Hood - shop after killing PW2 boss",
"FS: Ordained Dress - shop after killing PW2 boss",
"FS: Ordained Trousers - shop after killing PW2 boss",
}),
DS3BossInfo("Blackflame Friede", 4500800, dlc = True, locations = {
"PW2: Soul of Sister Friede",
"PW1: Titanite Slab - Corvian",
"FS: Ordained Hood - shop after killing PW2 boss",
"FS: Ordained Dress - shop after killing PW2 boss",
"FS: Ordained Trousers - shop after killing PW2 boss",
}),
DS3BossInfo("Demon Prince", 5000801, dlc = True, locations = {
"DH: Soul of the Demon Prince",
"DH: Small Envoy Banner - boss drop",
}),
DS3BossInfo("Halflight, Spear of the Church", 5100800, dlc = True, locations = {
"RC: Titanite Slab - mid boss drop",
"RC: Titanite Slab - ashes, NPC drop",
"RC: Titanite Slab - ashes, mob drop",
"RC: Filianore's Spear Ornament - mid boss drop",
"RC: Crucifix of the Mad King - ashes, NPC drop",
"RC: Shira's Crown - Shira's room after killing ashes NPC",
"RC: Shira's Armor - Shira's room after killing ashes NPC",
"RC: Shira's Gloves - Shira's room after killing ashes NPC",
"RC: Shira's Trousers - Shira's room after killing ashes NPC",
}),
DS3BossInfo("Darkeater Midir", 5100850, dlc = True, locations = {
"RC: Soul of Darkeater Midir",
"RC: Spears of the Church - hidden boss drop",
}),
DS3BossInfo("Slave Knight Gael 1", 5110801, dlc = True, locations = {
"RC: Soul of Slave Knight Gael",
"RC: Blood of the Dark Soul - end boss drop",
# These are accessible before you trigger the boss, but once you do you
# have to beat it before getting them.
"RC: Titanite Slab - ashes, mob drop",
"RC: Titanite Slab - ashes, NPC drop",
"RC: Sacred Chime of Filianore - ashes, NPC drop",
"RC: Crucifix of the Mad King - ashes, NPC drop",
"RC: Shira's Crown - Shira's room after killing ashes NPC",
"RC: Shira's Armor - Shira's room after killing ashes NPC",
"RC: Shira's Gloves - Shira's room after killing ashes NPC",
"RC: Shira's Trousers - Shira's room after killing ashes NPC",
}),
DS3BossInfo("Slave Knight Gael 2", 5110800, dlc = True, locations = {
"RC: Soul of Slave Knight Gael",
"RC: Blood of the Dark Soul - end boss drop",
# These are accessible before you trigger the boss, but once you do you
# have to beat it before getting them.
"RC: Titanite Slab - ashes, mob drop",
"RC: Titanite Slab - ashes, NPC drop",
"RC: Sacred Chime of Filianore - ashes, NPC drop",
"RC: Crucifix of the Mad King - ashes, NPC drop",
"RC: Shira's Crown - Shira's room after killing ashes NPC",
"RC: Shira's Armor - Shira's room after killing ashes NPC",
"RC: Shira's Gloves - Shira's room after killing ashes NPC",
"RC: Shira's Trousers - Shira's room after killing ashes NPC",
}),
DS3BossInfo("Lords of Cinder", 4100800, locations = {
"KFF: Soul of the Lords",
"FS: Billed Mask - Yuria after killing KFF boss",
"FS: Black Dress - Yuria after killing KFF boss",
"FS: Black Gauntlets - Yuria after killing KFF boss",
"FS: Black Leggings - Yuria after killing KFF boss"
}),
]

default_yhorm_location = DS3BossInfo("Yhorm the Giant", 3900800, locations = {
"PC: Soul of Yhorm the Giant",
"PC: Cinders of a Lord - Yhorm the Giant",
"PC: Siegbräu - Siegward after killing boss",
})
Loading

0 comments on commit 5efb3fd

Please sign in to comment.